Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs
Joonas Rikkonen eac98b22fa bdbcef4...18b4bac
commit 18b4bacd5bb645f36f62e77587af971cb789d37c
Author: Daniel Asteljoki <daniel.asteljoki@gmail.com>
Date:   Fri Mar 8 13:04:51 2019 +0200

    Added a beginner level sub

commit eef09f7d07cde64d1f2f6971eda733505339a0c0
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 7 19:05:14 2019 +0200

    Remove the old sprite when recreating the sprite.

commit a6c3ce00782882bc14f200f95abab0fa4d5d9a2d
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 7 19:04:51 2019 +0200

    Fix gender specific wearables not refreshing when we change the gender.

commit f606b801dac9e4cbb4238506ff4d73981709a2f8
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 7 18:42:14 2019 +0200

    Move some console commands from the shared project to the client. These should not be debug only, because they might be useful for modders too.

commit 154251c183eacf37e92fa7b27bb6d57bb15797d8
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Mar 7 14:42:22 2019 +0200

    Disable latchonto ai for now.
2019-03-18 22:31:34 +02:00

320 lines
11 KiB
C#

using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma
{
public enum WearableType
{
Item,
Hair,
Beard,
Moustache,
FaceAttachment,
JobIndicator,
Husk
}
class WearableSprite
{
public string SpritePath { get; private set; }
public XElement SourceElement { get; private set; }
public WearableType Type { get; private set; }
private Sprite _sprite;
public Sprite Sprite
{
get { return _sprite; }
set
{
if (value == _sprite) { return; }
if (_sprite != null)
{
_sprite.Remove();
}
_sprite = value;
}
}
public LimbType Limb { get; private set; }
public bool HideLimb { get; private set; }
public bool HideOtherWearables { get; private set; }
public bool InheritLimbDepth { get; private set; }
public bool InheritTextureScale { get; private set; }
public bool InheritOrigin { get; private set; }
public bool InheritSourceRect { get; private set; }
public LimbType DepthLimb { get; private set; }
private Wearable _wearableComponent;
public Wearable WearableComponent
{
get { return _wearableComponent; }
set
{
if (value == _wearableComponent) { return; }
if (_wearableComponent != null)
{
_wearableComponent.Remove();
}
_wearableComponent = value;
}
}
public string Sound { get; private set; }
public Point? SheetIndex { get; private set; }
public LightComponent LightComponent { get; set; }
private Gender _gender;
/// <summary>
/// None = Any/Not Defined -> no effect.
/// Changing the gender forces re-initialization, because the textures can be different for male and female characters.
/// </summary>
public Gender Gender
{
get { return _gender; }
set
{
if (value == _gender) { return; }
_gender = value;
IsInitialized = false;
SpritePath = ParseSpritePath(SourceElement.GetAttributeString("texture", string.Empty));
Init(_gender);
}
}
public WearableSprite(XElement subElement, WearableType type)
{
Type = type;
SourceElement = subElement;
SpritePath = subElement.GetAttributeString("texture", string.Empty);
Init();
switch (type)
{
case WearableType.Hair:
case WearableType.Beard:
case WearableType.Moustache:
case WearableType.FaceAttachment:
case WearableType.JobIndicator:
case WearableType.Husk:
Limb = LimbType.Head;
HideLimb = false;
HideOtherWearables = false;
InheritLimbDepth = true;
InheritTextureScale = true;
InheritOrigin = true;
InheritSourceRect = true;
break;
}
}
/// <summary>
/// Note: this constructor cannot initialize automatically, because the gender is unknown at this point. We only know it when the item is equipped.
/// </summary>
public WearableSprite(XElement subElement, Wearable wearable)
{
Type = WearableType.Item;
WearableComponent = wearable;
SpritePath = ParseSpritePath(subElement.GetAttributeString("texture", string.Empty));
SourceElement = subElement;
}
private string ParseSpritePath(string texturePath) => texturePath.Contains("/") ? texturePath : $"{Path.GetDirectoryName(WearableComponent.Item.Prefab.ConfigFile)}/{texturePath}";
public bool IsInitialized { get; private set; }
public void Init(Gender gender = Gender.None)
{
if (IsInitialized) { return; }
_gender = SpritePath.Contains("[GENDER]") ? gender : Gender.None;
if (_gender != Gender.None)
{
SpritePath = SpritePath.Replace("[GENDER]", (_gender == Gender.Female) ? "female" : "male");
}
if (Sprite != null)
{
Sprite.Remove();
}
Sprite = new Sprite(SourceElement, "", SpritePath);
Limb = (LimbType)Enum.Parse(typeof(LimbType), SourceElement.GetAttributeString("limb", "Head"), true);
HideLimb = SourceElement.GetAttributeBool("hidelimb", false);
HideOtherWearables = SourceElement.GetAttributeBool("hideotherwearables", false);
InheritLimbDepth = SourceElement.GetAttributeBool("inheritlimbdepth", true);
InheritTextureScale = SourceElement.GetAttributeBool("inherittexturescale", false);
InheritOrigin = SourceElement.GetAttributeBool("inheritorigin", false);
InheritSourceRect = SourceElement.GetAttributeBool("inheritsourcerect", false);
DepthLimb = (LimbType)Enum.Parse(typeof(LimbType), SourceElement.GetAttributeString("depthlimb", "None"), true);
Sound = SourceElement.GetAttributeString("sound", "");
var index = SourceElement.GetAttributePoint("sheetindex", new Point(-1, -1));
if (index.X > -1 && index.Y > -1)
{
SheetIndex = index;
}
IsInitialized = true;
}
}
}
namespace Barotrauma.Items.Components
{
class Wearable : Pickable
{
private WearableSprite[] wearableSprites;
private LimbType[] limbType;
private Limb[] limb;
private List<DamageModifier> damageModifiers;
public List<DamageModifier> DamageModifiers
{
get { return damageModifiers; }
}
public Wearable (Item item, XElement element) : base(item, element)
{
this.item = item;
damageModifiers = new List<DamageModifier>();
int spriteCount = element.Elements().Count(x => x.Name.ToString() == "sprite");
wearableSprites = new WearableSprite[spriteCount];
limbType = new LimbType[spriteCount];
limb = new Limb[spriteCount];
int i = 0;
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
{
case "sprite":
if (subElement.Attribute("texture") == null)
{
DebugConsole.ThrowError("Item \"" + item.Name + "\" doesn't have a texture specified!");
return;
}
limbType[i] = (LimbType)Enum.Parse(typeof(LimbType),
subElement.GetAttributeString("limb", "Head"), true);
wearableSprites[i] = new WearableSprite(subElement, this);
foreach (XElement lightElement in subElement.Elements())
{
if (lightElement.Name.ToString().ToLowerInvariant() != "lightcomponent") continue;
wearableSprites[i].LightComponent = new LightComponent(item, lightElement)
{
Parent = this
};
item.AddComponent(wearableSprites[i].LightComponent);
}
i++;
break;
case "damagemodifier":
damageModifiers.Add(new DamageModifier(subElement, item.Name + ", Wearable"));
break;
}
}
}
public override void Equip(Character character)
{
picker = character;
for (int i = 0; i < wearableSprites.Length; i++ )
{
var wearableSprite = wearableSprites[i];
if (!wearableSprite.IsInitialized) { wearableSprite.Init(picker.Info?.Gender ?? Gender.None); }
if (picker.Info?.Gender != Gender.None && (wearableSprite.Gender != Gender.None))
{
// If the item is gender specific (it has a different textures for male and female), we have to change the gender here so that the texture is updated.
wearableSprite.Gender = picker.Info.Gender;
}
Limb equipLimb = character.AnimController.GetLimb(limbType[i]);
if (equipLimb == null) { continue; }
if (item.body != null)
{
item.body.Enabled = false;
}
IsActive = true;
if (wearableSprite.LightComponent != null)
{
wearableSprite.LightComponent.ParentBody = equipLimb.body;
}
limb[i] = equipLimb;
if (!equipLimb.WearingItems.Contains(wearableSprite))
{
equipLimb.WearingItems.Add(wearableSprite);
}
}
}
public override void Drop(Character dropper)
{
Unequip(picker);
base.Drop(dropper);
picker = null;
IsActive = false;
}
public override void Unequip(Character character)
{
if (picker == null) return;
for (int i = 0; i < wearableSprites.Length; i++)
{
Limb equipLimb = character.AnimController.GetLimb(limbType[i]);
if (equipLimb == null) continue;
if (wearableSprites[i].LightComponent != null)
{
wearableSprites[i].LightComponent.ParentBody = null;
}
equipLimb.WearingItems.RemoveAll(w => w != null && w == wearableSprites[i]);
limb[i] = null;
}
IsActive = false;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
Update(deltaTime, cam);
}
public override void Update(float deltaTime, Camera cam)
{
if (picker.Removed)
{
IsActive = false;
return;
}
item.SetTransform(picker.SimPosition, 0.0f);
item.SetContainedItemPositions();
item.ApplyStatusEffects(ActionType.OnWearing, deltaTime, picker);
#if CLIENT
PlaySound(ActionType.OnWearing, picker.WorldPosition, picker);
#endif
}
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
foreach (WearableSprite wearableSprite in wearableSprites)
{
if (wearableSprite != null && wearableSprite.Sprite != null) wearableSprite.Sprite.Remove();
}
}
}
}