Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Source/Map/StructurePrefab.cs
T
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

303 lines
10 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma
{
partial class StructurePrefab : MapEntityPrefab
{
public XElement ConfigElement { get; private set; }
private bool canSpriteFlipX, canSpriteFlipY;
private float health;
//default size
private Vector2 size;
//does the structure have a physics body
[Serialize(false, false)]
public bool Body
{
get;
private set;
}
//rotation of the physics body in degrees
[Serialize(0.0f, false)]
public float BodyRotation
{
get;
private set;
}
//in display units
[Serialize(0.0f, false)]
public float BodyWidth
{
get;
private set;
}
//in display units
[Serialize(0.0f, false)]
public float BodyHeight
{
get;
private set;
}
//in display units
[Serialize("0.0,0.0", false)]
public Vector2 BodyOffset
{
get;
private set;
}
[Serialize(false, false)]
public bool Platform
{
get;
private set;
}
[Serialize(false, false)]
public bool AllowAttachItems
{
get;
private set;
}
[Serialize(100.0f, false)]
public float Health
{
get { return health; }
set { health = Math.Max(value, 0.0f); }
}
[Serialize(false, false)]
public bool CastShadow
{
get;
private set;
}
[Serialize(Direction.None, false)]
public Direction StairDirection
{
get;
private set;
}
public bool CanSpriteFlipX
{
get { return canSpriteFlipX; }
}
public bool CanSpriteFlipY
{
get { return canSpriteFlipY; }
}
[Serialize("0,0", true)]
public Vector2 Size
{
get { return size; }
private set { size = value; }
}
public Vector2 ScaledSize => size * Scale;
protected Vector2 textureScale = Vector2.One;
[Editable(DecimalCount = 3), Serialize("1.0, 1.0", true)]
public Vector2 TextureScale
{
get { return textureScale; }
set
{
textureScale = new Vector2(
MathHelper.Clamp(value.X, 0.01f, 10),
MathHelper.Clamp(value.Y, 0.01f, 10));
}
}
public Sprite BackgroundSprite
{
get;
private set;
}
public static void LoadAll(IEnumerable<string> filePaths)
{
foreach (string filePath in filePaths)
{
XDocument doc = XMLExtensions.TryLoadXml(filePath);
if (doc == null || doc.Root == null) return;
foreach (XElement el in doc.Root.Elements())
{
StructurePrefab sp = Load(el);
List.Add(sp);
}
}
}
public static StructurePrefab Load(XElement element)
{
StructurePrefab sp = new StructurePrefab
{
name = element.GetAttributeString("name", "")
};
sp.ConfigElement = element;
if (string.IsNullOrEmpty(sp.name)) sp.name = element.Name.ToString();
sp.identifier = element.GetAttributeString("identifier", "");
string translatedName = TextManager.Get("EntityName." + sp.identifier, true);
if (!string.IsNullOrEmpty(translatedName)) sp.name = translatedName;
sp.Tags = new HashSet<string>();
string joinedTags = element.GetAttributeString("tags", "");
if (string.IsNullOrEmpty(joinedTags)) joinedTags = element.GetAttributeString("Tags", "");
foreach (string tag in joinedTags.Split(','))
{
sp.Tags.Add(tag.Trim().ToLowerInvariant());
}
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString())
{
case "sprite":
sp.sprite = new Sprite(subElement);
if (subElement.Attribute("sourcerect") == null)
{
DebugConsole.ThrowError("Warning - sprite sourcerect not configured for structure \"" + sp.name + "\"!");
}
if (subElement.GetAttributeBool("fliphorizontal", false))
sp.sprite.effects = SpriteEffects.FlipHorizontally;
if (subElement.GetAttributeBool("flipvertical", false))
sp.sprite.effects = SpriteEffects.FlipVertically;
sp.canSpriteFlipX = subElement.GetAttributeBool("canflipx", true);
sp.canSpriteFlipY = subElement.GetAttributeBool("canflipy", true);
if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(sp.Name))
{
sp.sprite.Name = sp.Name;
}
sp.sprite.EntityID = sp.identifier;
break;
case "backgroundsprite":
sp.BackgroundSprite = new Sprite(subElement);
if (subElement.GetAttributeBool("fliphorizontal", false))
sp.BackgroundSprite.effects = SpriteEffects.FlipHorizontally;
if (subElement.GetAttributeBool("flipvertical", false))
sp.BackgroundSprite.effects = SpriteEffects.FlipVertically;
break;
}
}
if (!Enum.TryParse(element.GetAttributeString("category", "Structure"), true, out MapEntityCategory category))
{
category = MapEntityCategory.Structure;
}
sp.Category = category;
string aliases = element.GetAttributeString("aliases", "");
if (!string.IsNullOrWhiteSpace(aliases))
{
sp.Aliases = aliases.Split(',');
}
SerializableProperty.DeserializeProperties(sp, element);
if (sp.Body)
{
sp.Tags.Add("wall");
}
string translatedDescription = TextManager.Get("EntityDescription." + sp.identifier, true);
if (!string.IsNullOrEmpty(translatedDescription)) sp.Description = translatedDescription;
//backwards compatibility
if (element.Attribute("size") == null)
{
sp.size = Vector2.Zero;
if (element.Attribute("width") == null && element.Attribute("height") == null)
{
sp.size.X = sp.sprite.SourceRect.Width;
sp.size.Y = sp.sprite.SourceRect.Height;
}
else
{
sp.size.X = element.GetAttributeFloat("width", 0.0f);
sp.size.Y = element.GetAttributeFloat("height", 0.0f);
}
}
if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(sp.identifier))
{
DebugConsole.ThrowError(
"Structure prefab \"" + sp.name + "\" has no identifier. All structure prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
}
if (!string.IsNullOrEmpty(sp.identifier))
{
MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == sp.identifier);
if (existingPrefab != null)
{
DebugConsole.ThrowError(
"Map entity prefabs \"" + sp.name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
}
}
return sp;
}
public override void UpdatePlacing(Camera cam)
{
Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
Vector2 size = ScaledSize;
Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);
if (placePosition == Vector2.Zero)
{
if (PlayerInput.LeftButtonHeld())
placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
newRect.X = (int)position.X;
newRect.Y = (int)position.Y;
}
else
{
Vector2 placeSize = size;
if (ResizeHorizontal) placeSize.X = position.X - placePosition.X;
if (ResizeVertical) placeSize.Y = placePosition.Y - position.Y;
newRect = Submarine.AbsRect(placePosition, placeSize);
if (PlayerInput.LeftButtonReleased())
{
//don't allow resizing width/height to zero
if ((!ResizeHorizontal || placeSize.X != 0.0f) && (!ResizeVertical || placeSize.Y != 0.0f))
{
newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
var structure = new Structure(newRect, this, Submarine.MainSub);
structure.Submarine = Submarine.MainSub;
}
selected = null;
return;
}
}
if (PlayerInput.RightButtonHeld()) selected = null;
}
}
}