Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/Map/Structure.cs
Joonas Rikkonen 77a07a95af 1473f77...ece6ead
commit ece6ead54c021d084f406f4f99daa5a0a7ef4b19
Author: Regalis11 <poe.regalis@gmail.com>
Date:   Fri Mar 22 21:52:56 2019 +0200

    v0.8.9.7

commit c10dd821ca1a89b4ae62046cf8e558589ff8e6af
Author: Regalis11 <poe.regalis@gmail.com>
Date:   Fri Mar 22 21:00:02 2019 +0200

    Fixed release builds crashing due to simulatedlatency etc commands not existing in release builds

commit dee0dded80cbbf30d484232b6706dd705a577eb7
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Mar 22 15:24:44 2019 +0200

    Fixed nullref exception if a client disconnects while netstats is enabled

commit c45d5bf0c5a4a68200c9eca461cd04090a5de23a
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Mar 22 15:24:26 2019 +0200

    Togglehud, toggleupperhud and togglecharacternames don't require a permission to use, made simulatedlatency, simulatedloss and simulatedduplicateschange usable to clients

commit cec1ac6bccac058bc12ddf18c8e060a7a47c9301
Merge: 411cd9726 1473f77ba
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Mar 22 14:01:58 2019 +0200

    Merge branch 'dev' into enemy-ai

commit 411cd9726979668764eea782b515c7510ec4f5a8
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Mar 22 14:01:09 2019 +0200

    If the target has changed, re-evaluate the attacking limb. Fixes Hammerhead getting stuck next to the sub, because it treats the claw as the attacking limb when targeting characters inside the sub. It should use the head, because it has a wall target.

commit 2522bec262f9cb1dea9df75e1d2c22307be5254c
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Mar 22 13:58:18 2019 +0200

    Enemy ai/steering fixes:
    - Store both sim and world positions. Offset the simposition with the subposition and use it for steering. Fixes enemy indoorsteering, which was broken.
    - Use head or torso for steering instead of always using the main limb. Fixes characters like Mudraptor overshooting their targets badly.

commit c667ff9e4edf8af8f95278fbad42e0c8dd37d84c
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Mar 22 13:54:21 2019 +0200

    Improve the ai debug graphics.

commit 4c6c13e07e43a4e3ce2a11dfc4064961c442044a
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 21 17:11:17 2019 +0200

    Refactor, fix and adjust the enemy targeting logic:
    - Change the logic for fading the memories
    - When attacking a wall target, set it as the currently selected ai target so that we adjust the right memory
    - Significantly reduce the value of character targets that are not in the same submarine
    - In aggressive boarding, double the priority of walls when outside. Set the priority to 0 when inside. Reduce the attractiveness of  doors, but still keep the values high.
    - Redefine priorities for Mudraptor and Crawler (wip)

commit b085a95cff6bcf5e3f13e90dd1b71ac15e5ec1ab
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 21 13:16:22 2019 +0200

    Allow enemies to target walls by decision (not only when they happen to be on their way). TODO: target only outer walls and only when outside of the sub.
2019-03-23 19:22:13 +02:00

377 lines
15 KiB
C#

using Barotrauma.Lights;
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
partial class WallSection
{
public ConvexHull hull;
}
partial class Structure : MapEntity, IDamageable, IServerSerializable
{
public static bool ShowWalls = true, ShowStructures = true;
private List<ConvexHull> convexHulls;
public override bool SelectableInEditor
{
get
{
return HasBody ? ShowWalls : ShowStructures;;
}
}
// Only for testing in the debug build. Not saved.
protected Vector2 textureScale = Vector2.One;
[Editable(DecimalCount = 3, MinValueFloat = 0.01f, MaxValueFloat = 10f, ValueStep = 0.1f), Serialize("1.0, 1.0", false)]
public Vector2 TextureScale
{
get { return textureScale; }
set
{
textureScale = new Vector2(
MathHelper.Clamp(value.X, 0.01f, 10),
MathHelper.Clamp(value.Y, 0.01f, 10));
}
}
// Only for testing in the debug build. Not saved.
#if DEBUG
[Editable, Serialize(true, false)]
#endif
public bool DrawTiled { get; protected set; } = true;
protected Vector2 textureOffset = Vector2.Zero;
[Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)]
public Vector2 TextureOffset
{
get { return textureOffset; }
set { textureOffset = value; }
}
partial void CreateConvexHull(Vector2 position, Vector2 size, float rotation)
{
if (!CastShadow) { return; }
if (convexHulls == null)
{
convexHulls = new List<ConvexHull>();
}
Vector2 halfSize = size / 2;
Vector2[] verts = new Vector2[]
{
position + new Vector2(-halfSize.X, halfSize.Y),
position + new Vector2(halfSize.X, halfSize.Y),
position + new Vector2(halfSize.X, -halfSize.Y),
position + new Vector2(-halfSize.X, -halfSize.Y),
};
var h = new ConvexHull(verts, Color.Black, this);
h.Rotate(position, rotation);
convexHulls.Add(h);
}
public override void UpdateEditing(Camera cam)
{
if (editingHUD == null || editingHUD.UserData as Structure != this)
{
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
}
}
public GUIComponent CreateEditingHUD(bool inGame = false)
{
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, elementHeight: 20);
var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, 20)), isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f
};
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
{
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
OnClicked = (button, data) =>
{
FlipX(relativeToSub: false);
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
{
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
OnClicked = (button, data) =>
{
FlipY(relativeToSub: false);
return true;
}
};
var reloadTextureButton = new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"))
{
OnClicked = (button, data) =>
{
Sprite.ReloadXML();
Sprite.ReloadTexture();
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ResetToPrefab"))
{
OnClicked = (button, data) =>
{
Reset();
CreateEditingHUD();
return true;
}
};
editor.AddCustomContent(buttonContainer, editor.ContentCount);
PositionEditingHUD();
return editingHUD;
}
public override bool IsVisible(Rectangle worldView)
{
Rectangle worldRect = WorldRect;
if (worldRect.X > worldView.Right || worldRect.Right < worldView.X) return false;
if (worldRect.Y < worldView.Y - worldView.Height || worldRect.Y - worldRect.Height > worldView.Y) return false;
return true;
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (prefab.sprite == null) return;
if (editing)
{
if (!HasBody && !ShowStructures) return;
if (HasBody && !ShowWalls) return;
}
Draw(spriteBatch, editing, back, null);
}
public override void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect)
{
Draw(spriteBatch, false, false, damageEffect);
}
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
{
if (prefab.sprite == null) return;
if (editing)
{
if (!HasBody && !ShowStructures) return;
if (HasBody && !ShowWalls) return;
}
Color color = isHighlighted ? Color.Orange : spriteColor;
if (IsSelected && editing)
{
//color = Color.Lerp(color, Color.Gold, 0.5f);
color = spriteColor;
Vector2 rectSize = rect.Size.ToVector2();
if (BodyWidth > 0.0f) { rectSize.X = BodyWidth; }
if (BodyHeight > 0.0f) { rectSize.Y = BodyHeight; }
Vector2 bodyPos = WorldPosition + BodyOffset;
GUI.DrawRectangle(spriteBatch, new Vector2(bodyPos.X, -bodyPos.Y), rectSize.X, rectSize.Y, BodyRotation, Color.White,
thickness: Math.Max(1, (int)(2 / Screen.Selected.Cam.Zoom)));
}
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
float depth = SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
depth -= (ID % 255) * 0.000001f;
Vector2 textureOffset = this.textureOffset;
if (FlippedX) textureOffset.X = -textureOffset.X;
if (FlippedY) textureOffset.Y = -textureOffset.Y;
if (back && damageEffect == null)
{
if (Prefab.BackgroundSprite != null)
{
bool drawDropShadow = Submarine != null && HasBody;
Vector2 dropShadowOffset = Vector2.Zero;
if (drawDropShadow)
{
dropShadowOffset = Submarine.HiddenSubPosition - Position;
if (dropShadowOffset != Vector2.Zero)
{
if (IsHorizontal)
{
dropShadowOffset = new Vector2(0.0f, Math.Sign(dropShadowOffset.Y) * 10.0f);
}
else
{
dropShadowOffset = new Vector2(Math.Sign(dropShadowOffset.X) * 10.0f, 0.0f);
}
dropShadowOffset.Y = -dropShadowOffset.Y;
}
}
if (DrawTiled)
{
SpriteEffects oldEffects = Prefab.BackgroundSprite.effects;
Prefab.BackgroundSprite.effects ^= SpriteEffects;
Point backGroundOffset = new Point(
MathUtils.PositiveModulo((int)-textureOffset.X, Prefab.BackgroundSprite.SourceRect.Width),
MathUtils.PositiveModulo((int)-textureOffset.Y, Prefab.BackgroundSprite.SourceRect.Height));
Prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
new Vector2(rect.Width, rect.Height),
color: color,
textureScale: TextureScale * Scale,
startOffset: backGroundOffset);
if (drawDropShadow)
{
Prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset,
new Vector2(rect.Width, rect.Height),
color: Color.Black * 0.5f,
textureScale: TextureScale * Scale,
startOffset: backGroundOffset,
depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f);
}
Prefab.BackgroundSprite.effects = oldEffects;
}
else
{
Prefab.BackgroundSprite.Draw(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
color,
Vector2.Zero,
scale: Scale,
rotate: 0,
spriteEffect: SpriteEffects);
if (drawDropShadow)
{
Prefab.BackgroundSprite.Draw(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset,
Color.Black * 0.5f,
Vector2.Zero,
scale: Scale,
rotate: 0,
spriteEffect: SpriteEffects,
depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f);
}
}
}
}
if (back == depth > 0.5f || editing)
{
SpriteEffects oldEffects = prefab.sprite.effects;
prefab.sprite.effects ^= SpriteEffects;
for (int i = 0; i < Sections.Length; i++)
{
if (damageEffect != null)
{
float newCutoff = Sections[i].damage > 0 ?
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / Prefab.Health) : 0.0f;
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
{
damageEffect.Parameters["aCutoff"].SetValue(newCutoff);
damageEffect.Parameters["cCutoff"].SetValue(newCutoff * 1.2f);
damageEffect.Parameters["inColor"].SetValue(color.ToVector4());
damageEffect.CurrentTechnique.Passes[0].Apply();
Submarine.DamageEffectCutoff = newCutoff;
Submarine.DamageEffectColor = color;
}
}
if (DrawTiled)
{
Point sectionOffset = new Point(
Math.Abs(rect.Location.X - Sections[i].rect.Location.X),
Math.Abs(rect.Location.Y - Sections[i].rect.Location.Y));
if (FlippedX && IsHorizontal) sectionOffset.X = Sections[i].rect.Right - rect.Right;
if (FlippedY && !IsHorizontal) sectionOffset.Y = (rect.Y - rect.Height) - (Sections[i].rect.Y - Sections[i].rect.Height);
sectionOffset.X += MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width);
sectionOffset.Y += MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height);
prefab.sprite.DrawTiled(
spriteBatch,
new Vector2(Sections[i].rect.X + drawOffset.X, -(Sections[i].rect.Y + drawOffset.Y)),
new Vector2(Sections[i].rect.Width, Sections[i].rect.Height),
color: color,
startOffset: sectionOffset,
depth: depth,
textureScale: TextureScale * Scale);
}
else
{
prefab.sprite.Draw(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
color,
Vector2.Zero,
scale: Scale,
rotate: 0,
spriteEffect: SpriteEffects);
}
}
prefab.sprite.effects = oldEffects;
}
if (GameMain.DebugDraw)
{
if (Bodies != null)
{
for (int i = 0; i < Bodies.Count; i++)
{
Vector2 pos = FarseerPhysics.ConvertUnits.ToDisplayUnits(Bodies[i].Position);
if (Submarine != null) pos += Submarine.Position;
pos.Y = -pos.Y;
GUI.DrawRectangle(spriteBatch,
pos,
FarseerPhysics.ConvertUnits.ToDisplayUnits(bodyDebugDimensions[i].X),
FarseerPhysics.ConvertUnits.ToDisplayUnits(bodyDebugDimensions[i].Y),
-Bodies[i].Rotation, Color.White);
}
}
AiTarget?.Draw(spriteBatch);
}
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
for (int i = 0; i < Sections.Length; i++)
{
float damage = msg.ReadRangedSingle(0.0f, 1.0f, 8) * Health;
SetDamage(i, damage);
}
}
}
}