(bf212a41f) v0.9.2.0 pre-release test version

This commit is contained in:
Joonas Rikkonen
2019-07-27 21:06:07 +03:00
parent afa2137bd2
commit 0f63da27b2
154 changed files with 3959 additions and 1428 deletions
@@ -312,6 +312,30 @@ namespace Barotrauma.Items.Components
joint.CollideConnected = true;
}
public int GetDir()
{
if (DockingDir != 0) { return DockingDir; }
if (door != null)
{
if (door.LinkedGap.linkedTo.Count == 1)
{
return IsHorizontal ?
Math.Sign(door.Item.WorldPosition.X - door.LinkedGap.linkedTo[0].WorldPosition.X) :
Math.Sign(door.Item.WorldPosition.Y - door.LinkedGap.linkedTo[0].WorldPosition.Y);
}
}
if (item.Submarine != null)
{
return IsHorizontal ?
Math.Sign(item.WorldPosition.X - item.Submarine.WorldPosition.X) :
Math.Sign(item.WorldPosition.Y - item.Submarine.WorldPosition.Y);
}
return 0;
}
private void ConnectWireBetweenPorts()
{
Wire wire = item.GetComponent<Wire>();
@@ -250,17 +250,14 @@ namespace Barotrauma.Items.Components
if (item.Condition <= RepairThreshold) { return true; }
if (requiredItems.Any() && !hasValidIdCard)
{
ForceOpen(ActionType.OnPicked);
ToggleState(ActionType.OnPicked);
}
return false;
}
private void ForceOpen(ActionType actionType)
private void ToggleState(ActionType actionType)
{
SetState(PredictedState == null ? !isOpen : !PredictedState.Value, false, true); //crowbar function
#if CLIENT
PlaySound(actionType, item.WorldPosition, picker);
#endif
SetState(PredictedState == null ? !isOpen : !PredictedState.Value, false, true, forcedOpen: actionType == ActionType.OnPicked);
}
public override bool Select(Character character)
@@ -272,7 +269,7 @@ namespace Barotrauma.Items.Components
{
float originalPickingTime = PickingTime;
PickingTime = 0;
ForceOpen(ActionType.OnUse);
ToggleState(ActionType.OnUse);
PickingTime = originalPickingTime;
}
else if (hasRequiredItems)
@@ -538,11 +535,11 @@ namespace Barotrauma.Items.Components
if (connection.Name == "toggle")
{
SetState(!wasOpen, false, true);
SetState(!wasOpen, false, true, forcedOpen: false);
}
else if (connection.Name == "set_state")
{
SetState(signal != "0", false, true);
SetState(signal != "0", false, true, forcedOpen: false);
}
#if SERVER
@@ -555,9 +552,9 @@ namespace Barotrauma.Items.Components
public void TrySetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false)
{
SetState(open, isNetworkMessage, sendNetworkMessage);
SetState(open, isNetworkMessage, sendNetworkMessage, forcedOpen: false);
}
partial void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage);
partial void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage, bool forcedOpen);
}
}
@@ -558,6 +558,30 @@ namespace Barotrauma.Items.Components
}
}
public override XElement Save(XElement parentElement)
{
if (!attachable)
{
return base.Save(parentElement);
}
var tempMsg = DisplayMsg;
var tempPickKey = PickKey;
var tempRequiredItems = requiredItems;
DisplayMsg = prevMsg;
PickKey = prevPickKey;
requiredItems = prevRequiredItems;
XElement saveElement = base.Save(parentElement);
DisplayMsg = tempMsg;
PickKey = tempPickKey;
requiredItems = tempRequiredItems;
return saveElement;
}
public override void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
{
base.ServerWrite(msg, c, extraData);
@@ -17,6 +17,8 @@ namespace Barotrauma.Items.Components
private Character activePicker;
private CoroutineHandle pickingCoroutine;
public List<InvSlotType> AllowedSlots
{
get { return allowedSlots; }
@@ -69,7 +71,7 @@ namespace Barotrauma.Items.Components
#if SERVER
item.CreateServerEvent(this);
#endif
CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
pickingCoroutine = CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
}
return false;
}
@@ -81,7 +83,7 @@ namespace Barotrauma.Items.Components
public virtual bool OnPicked(Character picker)
{
if (picker.Inventory.TryPutItem(item, picker, allowedSlots))
if (picker.Inventory.TryPutItemWithAutoEquipCheck(item, picker, allowedSlots))
{
if (!picker.HasSelectedItem(item) && item.body != null) item.body.Enabled = false;
this.picker = picker;
@@ -136,7 +138,7 @@ namespace Barotrauma.Items.Components
}
#if CLIENT
picker.UpdateHUDProgressBar(
Character.Controlled?.UpdateHUDProgressBar(
this,
item.WorldPosition,
pickTimer / requiredTime,
@@ -160,13 +162,18 @@ namespace Barotrauma.Items.Components
yield return CoroutineStatus.Success;
}
private void StopPicking(Character picker)
protected void StopPicking(Character picker)
{
if (picker != null)
{
picker.AnimController.Anim = AnimController.Animation.None;
picker.PickingItem = null;
}
if (pickingCoroutine != null)
{
CoroutineManager.StopCoroutines(pickingCoroutine);
pickingCoroutine = null;
}
activePicker = null;
pickTimer = 0.0f;
}
@@ -149,7 +149,7 @@ namespace Barotrauma.Items.Components
Vector2 sourcePos = character?.AnimController == null ? item.SimPosition : character.AnimController.AimSourceSimPos;
Vector2 barrelPos = TransformedBarrelPos;
//make sure there's no obstacles between the base of the weapon (or the shoulder of the character) and the end of the barrel
if (Submarine.PickBody(sourcePos, barrelPos, projectile.IgnoredBodies) == null)
if (Submarine.PickBody(sourcePos, barrelPos, projectile.IgnoredBodies, Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionItemBlocking) == null)
{
//no obstacles -> we can spawn the projectile at the barrel
projectilePos = barrelPos;
@@ -14,12 +14,23 @@ namespace Barotrauma.Items.Components
{
partial class RepairTool : ItemComponent
{
public enum UseEnvironment
{
Air, Water, Both, None
};
private readonly List<string> fixableEntities;
private Vector2 pickedPosition;
private float activeTimer;
private Vector2 debugRayStartPos, debugRayEndPos;
[Serialize("Both", false)]
public UseEnvironment UsableIn
{
get; set;
}
[Serialize(0.0f, false)]
public float Range { get; set; }
@@ -43,6 +54,9 @@ namespace Barotrauma.Items.Components
[Serialize(false, false)]
public bool RepairMultiple { get; set; }
[Serialize(0.0f, false)]
public float FireProbability { get; set; }
public Vector2 TransformedBarrelPos
{
get
@@ -109,6 +123,29 @@ namespace Barotrauma.Items.Components
return false;
}
if (UsableIn == UseEnvironment.None)
{
ApplyStatusEffects(ActionType.OnFailure, deltaTime, character);
return false;
}
if (character.AnimController.InWater)
{
if (UsableIn == UseEnvironment.Air)
{
ApplyStatusEffects(ActionType.OnFailure, deltaTime, character);
return false;
}
}
else
{
if (UsableIn == UseEnvironment.Water)
{
ApplyStatusEffects(ActionType.OnFailure, deltaTime, character);
return false;
}
}
Vector2 targetPosition = item.WorldPosition;
targetPosition += new Vector2(
(float)Math.Cos(item.body.Rotation),
@@ -149,7 +186,7 @@ namespace Barotrauma.Items.Components
{
Repair(rayStart - character.Submarine.SimPosition, rayEnd - character.Submarine.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
UseProjSpecific(deltaTime);
return true;
@@ -162,9 +199,12 @@ namespace Barotrauma.Items.Components
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
float lastPickedFraction = 0.0f;
if (RepairMultiple)
{
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
lastPickedFraction = Submarine.LastPickedFraction;
Type lastHitType = null;
hitCharacters.Clear();
foreach (Body body in bodies)
@@ -194,6 +234,7 @@ namespace Barotrauma.Items.Components
if (FixBody(user, deltaTime, degreeOfSuccess, body))
{
lastPickedFraction = Submarine.LastPickedBodyDist(body);
if (bodyType != null) { lastHitType = bodyType; }
}
}
@@ -205,13 +246,14 @@ namespace Barotrauma.Items.Components
ignoredBodies, collisionCategories, ignoreSensors: false,
customPredicate: (Fixture f) => { return f?.Body?.UserData != null; },
allowInsideFixture: true));
lastPickedFraction = Submarine.LastPickedFraction;
}
if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
{
fireSourcesInRange.Clear();
//step along the ray in 10% intervals, collecting all fire sources in the range
for (float x = 0.0f; x <= Submarine.LastPickedFraction; x += 0.1f)
for (float x = 0.0f; x <= lastPickedFraction; x += 0.1f)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * x);
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
@@ -230,6 +272,20 @@ namespace Barotrauma.Items.Components
foreach (FireSource fs in fireSourcesInRange)
{
fs.Extinguish(deltaTime, ExtinguishAmount);
#if SERVER
GameMain.Server.KarmaManager.OnExtinguishingFire(user, deltaTime);
#endif
}
}
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
if (Rand.Range(0.0f, 1.0f) < FireProbability * deltaTime)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * lastPickedFraction * 0.9f);
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
new FireSource(displayPos);
}
}
}
@@ -242,12 +298,12 @@ namespace Barotrauma.Items.Components
if (targetBody.UserData is Structure targetStructure)
{
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return false; }
if (targetStructure.IsPlatform) { return false; }
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
if (sectionIndex < 0) { return false; }
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return true; }
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user);
@@ -283,9 +339,7 @@ namespace Barotrauma.Items.Components
else if (targetBody.UserData is Item targetItem)
{
targetItem.IsHighlighted = true;
float prevCondition = targetItem.Condition;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects);
var levelResource = targetItem.GetComponent<LevelResource>();
@@ -300,9 +354,9 @@ namespace Barotrauma.Items.Components
targetItem.WorldPosition,
levelResource.DeattachTimer / levelResource.DeattachDuration,
Color.Red, Color.Green);
#endif
#endif
}
FixItemProjSpecific(user, deltaTime, targetItem, prevCondition);
FixItemProjSpecific(user, deltaTime, targetItem);
return true;
}
return false;
@@ -310,13 +364,12 @@ namespace Barotrauma.Items.Components
partial void FixStructureProjSpecific(Character user, float deltaTime, Structure targetStructure, int sectionIndex);
partial void FixCharacterProjSpecific(Character user, float deltaTime, Character targetCharacter);
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem, float prevCondition);
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem);
private float sinTime;
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
Gap leak = objective.OperateTarget as Gap;
if (leak == null) return true;
if (!(objective.OperateTarget is Gap leak)) return true;
Vector2 fromItemToLeak = leak.WorldPosition - item.WorldPosition;
float dist = fromItemToLeak.Length();
@@ -461,7 +514,7 @@ namespace Barotrauma.Items.Components
}
}
}
#endif
#endif
}
}
}
@@ -64,14 +64,19 @@ namespace Barotrauma.Items.Components
return;
}
if (picker.IsKeyDown(InputType.Aim) && picker.IsKeyHit(InputType.Shoot))
throwing = true;
if (picker.IsKeyDown(InputType.Aim) && picker.IsKeyHit(InputType.Shoot)) { throwing = true; }
if (!picker.IsKeyDown(InputType.Aim) && !throwing) { throwPos = 0.0f; }
bool aim = picker.IsKeyDown(InputType.Aim) && (picker.SelectedConstruction == null || picker.SelectedConstruction.GetComponent<Ladder>() != null);
if (!picker.IsKeyDown(InputType.Aim) && !throwing) throwPos = 0.0f;
if (picker.IsUnconscious || picker.IsDead || !picker.AllowInput)
{
throwing = false;
aim = false;
}
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) Flip();
if (item.body.Dir != picker.AnimController.Dir) { Flip(); }
AnimController ac = picker.AnimController;
@@ -79,7 +84,6 @@ namespace Barotrauma.Items.Components
if (!throwing)
{
bool aim = picker.IsKeyDown(InputType.Aim) && (picker.SelectedConstruction == null || picker.SelectedConstruction.GetComponent<Ladder>() != null);
if (aim)
{
throwPos = MathUtils.WrapAnglePi(System.Math.Min(throwPos + deltaTime * 5.0f, MathHelper.PiOver2));
@@ -123,7 +127,8 @@ namespace Barotrauma.Items.Components
}
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
ApplyStatusEffects(ActionType.OnSecondaryUse, deltaTime, thrower); //Stun grenades, flares, etc. all have their throw-related things handled in "onSecondaryUse"
//Stun grenades, flares, etc. all have their throw-related things handled in "onSecondaryUse"
ApplyStatusEffects(ActionType.OnSecondaryUse, deltaTime, thrower, user: thrower);
}
throwing = false;
}
@@ -65,20 +65,25 @@ namespace Barotrauma.Items.Components
}
public Dictionary<string, SerializableProperty> SerializableProperties { get; protected set; }
public float IsActiveTimer;
public virtual bool IsActive
{
get { return isActive; }
set
{
#if CLIENT
if (!value && isActive)
if (!value)
{
StopSounds(ActionType.OnActive);
IsActiveTimer = 0.0f;
if (isActive)
{
StopSounds(ActionType.OnActive);
}
}
#endif
if (AITarget != null) AITarget.Enabled = value;
isActive = value;
isActive = value;
}
}
@@ -384,7 +389,10 @@ namespace Barotrauma.Items.Components
item.Use(1.0f);
break;
case "toggle":
IsActive = !isActive;
if (signal != "0")
{
IsActive = !isActive;
}
break;
case "set_active":
case "set_state":
@@ -410,8 +418,10 @@ namespace Barotrauma.Items.Components
{
if (item.ParentInventory != null)
{
Character owner = (Character)item.ParentInventory.Owner;
if (owner != null && owner.HasSelectedItem(item)) item.Unequip(owner);
if (item.ParentInventory.Owner is Character owner && owner.HasSelectedItem(item))
{
item.Unequip(owner);
}
item.ParentInventory.RemoveItem(item);
}
Entity.Spawner.AddToRemoveQueue(item);
@@ -424,8 +434,10 @@ namespace Barotrauma.Items.Components
{
if (this.Item.ParentInventory != null)
{
Character owner = (Character)this.Item.ParentInventory.Owner;
if (owner != null && owner.HasSelectedItem(this.Item)) this.Item.Unequip(owner);
if (this.Item.ParentInventory.Owner is Character owner && owner.HasSelectedItem(this.Item))
{
this.Item.Unequip(owner);
}
this.Item.ParentInventory.RemoveItem(this.Item);
}
Entity.Spawner.AddToRemoveQueue(this.Item);
@@ -561,14 +573,14 @@ namespace Barotrauma.Items.Components
public virtual void FlipY(bool relativeToSub) { }
public bool HasRequiredContainedItems(bool addMessage, string msg = null)
public bool HasRequiredContainedItems(Character user, bool addMessage, string msg = null)
{
if (!requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) return true;
if (item.OwnInventory == null) return false;
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Contained])
{
if (!item.OwnInventory.Items.Any(it => it != null && it.Condition > 0.0f && ri.MatchesItem(it)))
if (!ri.CheckRequirements(user, item))
{
#if CLIENT
msg = msg ?? ri.Msg;
@@ -74,14 +74,14 @@ namespace Barotrauma.Items.Components
}
}
[Editable(0.0f, float.MaxValue, ToolTip = "How long the temperature has to stay critical until a meltdown occurs."), Serialize(30.0f, true)]
[Editable(0.0f, float.MaxValue, ToolTip = "How long the temperature has to stay critical until a meltdown occurs."), Serialize(120.0f, true)]
public float MeltdownDelay
{
get { return meltDownDelay; }
set { meltDownDelay = Math.Max(value, 0.0f); }
}
[Editable(0.0f, float.MaxValue, ToolTip = "How long the temperature has to stay critical until the reactor catches fire."), Serialize(10.0f, true)]
[Editable(0.0f, float.MaxValue, ToolTip = "How long the temperature has to stay critical until the reactor catches fire."), Serialize(30.0f, true)]
public float FireDelay
{
get { return fireDelay; }
@@ -132,6 +132,13 @@ namespace Barotrauma.Items.Components
}
}
[Serialize(false, true)]
public bool TemperatureCritical
{
get { return temperature > allowedTemperature.Y; }
set { /*do nothing*/ }
}
private float correctTurbineOutput;
private float targetFissionRate;
@@ -384,6 +391,14 @@ namespace Barotrauma.Items.Components
float prevFireTimer = fireTimer;
fireTimer += MathHelper.Lerp(deltaTime * 2.0f, deltaTime, item.Condition / item.MaxCondition);
#if SERVER
if (fireTimer > Math.Min(5.0f, FireDelay / 2) && blameOnBroken?.Character?.SelectedConstruction == item)
{
GameMain.Server.KarmaManager.OnReactorOverHeating(blameOnBroken.Character, deltaTime);
}
#endif
if (fireTimer >= FireDelay && prevFireTimer < fireDelay)
{
new FireSource(item.WorldPosition);
@@ -437,14 +452,8 @@ namespace Barotrauma.Items.Components
private void MeltDown()
{
if (item.Condition <= 0.0f) return;
#if CLIENT
if (GameMain.Client != null) return;
#endif
#if SERVER
GameServer.Log("Reactor meltdown!", ServerLog.MessageType.ItemInteraction);
#endif
if (item.Condition <= 0.0f) { return; }
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
item.Condition = 0.0f;
fireTimer = 0.0f;
@@ -461,9 +470,10 @@ namespace Barotrauma.Items.Components
}
#if SERVER
if (GameMain.Server != null && GameMain.Server.ConnectedClients.Contains(blameOnBroken))
GameServer.Log("Reactor meltdown!", ServerLog.MessageType.ItemInteraction);
if (GameMain.Server != null)
{
blameOnBroken.Karma = 0.0f;
GameMain.Server.KarmaManager.OnReactorMeltdown(blameOnBroken?.Character);
}
#endif
}
@@ -9,6 +9,12 @@ namespace Barotrauma.Items.Components
{
partial class Sonar : Powered, IServerSerializable, IClientSerializable
{
public enum Mode
{
Active,
Passive
};
public const float DefaultSonarRange = 10000.0f;
class ConnectedTransducer
@@ -35,18 +41,30 @@ namespace Barotrauma.Items.Components
private float range;
private float pingState;
private const float PingFrequency = 0.5f;
private Mode currentMode = Mode.Passive;
private class ActivePing
{
public float State;
public bool IsDirectional;
public Vector2 Direction;
public float PrevPingRadius;
}
// rotating list of currently active pings
private ActivePing[] activePings = new ActivePing[8];
// total number of currently active pings, range [0, activePings.Length[
private int activePingsCount;
// currently active ping index on the above list
private int currentPingIndex = -1;
private const float MinZoom = 1.0f, MaxZoom = 4.0f;
private float zoom = 1.0f;
private bool useDirectionalPing = false;
private Vector2 lastPingDirection = new Vector2(1.0f, 0.0f);
private Vector2 pingDirection = new Vector2(1.0f, 0.0f);
//was the last ping sent with directional pinging
private bool isLastPingDirectional;
private Sprite pingCircle, directionalPingCircle, screenOverlay, screenBackground;
private Sprite sonarBlip;
private Sprite lineSprite;
@@ -86,24 +104,24 @@ namespace Barotrauma.Items.Components
{
get { return zoom; }
}
public override bool IsActive
{
get
{
return base.IsActive;
}
public Mode CurrentMode
{
get => currentMode;
set
{
base.IsActive = value;
if (!value && item.CurrentHull != null)
currentMode = value;
if (value == Mode.Passive)
{
item.CurrentHull.AiTarget.SectorDegrees = 360.0f;
currentPingIndex = -1;
if (item.CurrentHull != null)
{
item.CurrentHull.AiTarget.SectorDegrees = 360.0f;
}
}
#if CLIENT
if (activeTickBox != null) activeTickBox.Selected = value;
if (passiveTickBox != null) passiveTickBox.Selected = !value;
if (activeTickBox != null) activeTickBox.Selected = value == Mode.Active;
if (passiveTickBox != null) passiveTickBox.Selected = value == Mode.Passive;
#endif
}
}
@@ -112,8 +130,9 @@ namespace Barotrauma.Items.Components
: base(item, element)
{
connectedTransducers = new List<ConnectedTransducer>();
IsActive = false;
CurrentMode = Mode.Passive;
IsActive = true;
InitProjSpecific(element);
}
@@ -133,40 +152,80 @@ namespace Barotrauma.Items.Components
}
connectedTransducers.RemoveAll(t => t.DisconnectTimer <= 0.0f);
}
if ((voltage >= minVoltage || powerConsumption <= 0.0f) &&
(!UseTransducers || connectedTransducers.Count > 0))
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
{
pingState = pingState + deltaTime * 0.5f;
if (pingState > 1.0f)
activePings[pingIndex].State += deltaTime * PingFrequency;
}
if (currentMode == Mode.Active)
{
if ((voltage >= minVoltage || powerConsumption <= 0.0f) &&
(!UseTransducers || connectedTransducers.Count > 0))
{
if (currentPingIndex != -1)
{
var activePing = activePings[currentPingIndex];
if (activePing.State > 1.0f)
{
if (item.CurrentHull != null)
{
item.CurrentHull.AiTarget.SoundRange = Math.Max(Range * activePing.State / zoom, item.CurrentHull.AiTarget.SoundRange);
item.CurrentHull.AiTarget.SectorDegrees = activePing.IsDirectional ? DirectionalPingSector : 360.0f;
item.CurrentHull.AiTarget.SectorDir = new Vector2(pingDirection.X, -pingDirection.Y);
}
if (item.AiTarget != null)
{
item.AiTarget.SoundRange = Math.Max(Range * activePing.State / zoom, item.AiTarget.SoundRange);
item.AiTarget.SectorDegrees = activePing.IsDirectional ? DirectionalPingSector : 360.0f;
item.AiTarget.SectorDir = new Vector2(pingDirection.X, -pingDirection.Y);
}
aiPingCheckPending = true;
currentPingIndex = -1;
}
}
if (currentPingIndex == -1 && activePingsCount < activePings.Length)
{
currentPingIndex = activePingsCount++;
if (activePings[currentPingIndex] == null)
{
activePings[currentPingIndex] = new ActivePing();
}
activePings[currentPingIndex].IsDirectional = useDirectionalPing;
activePings[currentPingIndex].Direction = pingDirection;
activePings[currentPingIndex].State = 0.0f;
activePings[currentPingIndex].PrevPingRadius = 0.0f;
item.Use(deltaTime);
}
}
else
{
if (item.CurrentHull != null)
{
item.CurrentHull.AiTarget.SoundRange = Math.Max(Range * pingState / zoom, item.CurrentHull.AiTarget.SoundRange);
item.CurrentHull.AiTarget.SectorDegrees = isLastPingDirectional ? DirectionalPingSector : 360.0f;
item.CurrentHull.AiTarget.SectorDir = new Vector2(pingDirection.X, -pingDirection.Y);
item.CurrentHull.AiTarget.SectorDegrees = 360.0f;
}
if (item.AiTarget != null)
{
item.AiTarget.SoundRange = Math.Max(Range * pingState / zoom, item.AiTarget.SoundRange);
item.AiTarget.SectorDegrees = isLastPingDirectional ? DirectionalPingSector : 360.0f;
item.AiTarget.SectorDir = new Vector2(pingDirection.X, -pingDirection.Y);
}
aiPingCheckPending = true;
isLastPingDirectional = useDirectionalPing;
lastPingDirection = pingDirection;
item.Use(deltaTime);
pingState = 0.0f;
currentPingIndex = -1;
aiPingCheckPending = false;
}
}
else
for (var pingIndex = 0; pingIndex < activePingsCount;)
{
if (item.CurrentHull != null)
if (activePings[pingIndex].State > 1.0f)
{
item.CurrentHull.AiTarget.SectorDegrees = 360.0f;
var lastIndex = --activePingsCount;
var oldActivePing = activePings[pingIndex];
activePings[pingIndex] = activePings[lastIndex];
activePings[lastIndex] = oldActivePing;
if (currentPingIndex == lastIndex)
{
currentPingIndex = pingIndex;
}
}
else
{
++pingIndex;
}
aiPingCheckPending = false;
pingState = 0.0f;
}
Voltage -= deltaTime;
@@ -174,7 +233,7 @@ namespace Barotrauma.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
return pingState > 1.0f;
return currentPingIndex != -1;
}
protected override void RemoveComponentSpecific()
@@ -189,7 +248,7 @@ namespace Barotrauma.Items.Components
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
if (!IsActive || !aiPingCheckPending) return false;
if (currentMode == Mode.Passive || !aiPingCheckPending) return false;
Dictionary<string, List<Character>> targetGroups = new Dictionary<string, List<Character>>();
@@ -301,13 +360,13 @@ namespace Barotrauma.Items.Components
}
}
if (!item.CanClientAccess(c)) return;
if (!item.CanClientAccess(c)) return;
IsActive = isActive;
CurrentMode = isActive ? Mode.Active : Mode.Passive;
//TODO: cleanup
#if CLIENT
activeTickBox.Selected = IsActive;
activeTickBox.Selected = currentMode == Mode.Active;
#endif
if (isActive)
{
@@ -331,8 +390,8 @@ namespace Barotrauma.Items.Components
public void ServerWrite(Lidgren.Network.NetBuffer msg, Client c, object[] extraData = null)
{
msg.Write(IsActive);
if (IsActive)
msg.Write(currentMode == Mode.Active);
if (currentMode == Mode.Active)
{
msg.WriteRangedSingle(zoom, MinZoom, MaxZoom, 8);
msg.Write(useDirectionalPing);
@@ -198,11 +198,7 @@ namespace Barotrauma.Items.Components
if (pt.item.Condition <= 0.0f && prevCondition > 0.0f)
{
#if CLIENT
if (sparkSounds.Count > 0)
{
var sparkSound = sparkSounds[Rand.Int(sparkSounds.Count)];
SoundPlayer.PlaySound(sparkSound.Sound, pt.item.WorldPosition, sparkSound.Volume, sparkSound.Range, pt.item.CurrentHull);
}
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
Vector2 baseVel = Rand.Vector(300.0f);
for (int i = 0; i < 10; i++)
@@ -333,22 +329,22 @@ namespace Barotrauma.Items.Components
var recipients = c.Recipients;
foreach (Connection recipient in recipients)
{
if (recipient?.Item == null) continue;
if (recipient?.Item == null || !recipient.IsPower) { continue; }
Item it = recipient.Item;
if (it.Condition <= 0.0f) continue;
if (it.Condition <= 0.0f) { continue; }
foreach (ItemComponent ic in it.Components)
{
if (!(ic is Powered powered) || !powered.IsActive) continue;
if (connectedList.Contains(powered)) continue;
if (!(ic is Powered powered) || !powered.IsActive) { continue; }
if (connectedList.Contains(powered)) { continue; }
if (powered is PowerTransfer powerTransfer)
{
RelayComponent otherRelayComponent = powerTransfer as RelayComponent;
if ((thisRelayComponent == null) == (otherRelayComponent == null))
{
if (!powerTransfer.CanTransfer) continue;
if (!powerTransfer.CanTransfer) { continue; }
powerTransfer.CheckJunctions(deltaTime, increaseUpdateCount, clampPower, clampLoad);
}
else
@@ -358,7 +354,7 @@ namespace Barotrauma.Items.Components
float maxPowerOut = (thisRelayComponent != null && !c.IsOutput) ? 0.0f : clampLoad;
if (maxPowerIn > 0.0f || maxPowerOut > 0.0f)
{
powerTransfer.CheckJunctions(deltaTime, false, maxPowerIn, maxPowerOut);
powerTransfer.CheckJunctions(deltaTime, false, maxPowerIn, maxPowerOut);
}
}
@@ -455,7 +451,7 @@ namespace Barotrauma.Items.Components
}
bool broken = recipient.Item.Condition <= 0.0f;
foreach (StatusEffect effect in recipient.effects)
foreach (StatusEffect effect in recipient.Effects)
{
if (broken && effect.type != ActionType.OnBroken) continue;
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, 1.0f, null, null, false, false);
@@ -45,7 +45,10 @@ namespace Barotrauma.Items.Components
set
{
base.IsActive = value;
if (!value) currPowerConsumption = 0.0f;
if (!value)
{
currPowerConsumption = 0.0f;
}
}
}
@@ -113,6 +113,13 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(1, false)]
public int HitScanCount
{
get;
set;
}
[Serialize(false, false)]
public bool RemoveOnHit
{
@@ -120,6 +127,13 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(0.0f, false)]
public float Spread
{
get;
set;
}
public Projectile(Item item, XElement element)
: base (item, element)
{
@@ -154,17 +168,25 @@ namespace Barotrauma.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
if (character != null && !characterUsable) return false;
if (character != null && !characterUsable) { return false; }
Vector2 launchDir = new Vector2((float)Math.Cos(item.body.Rotation), (float)Math.Sin(item.body.Rotation));
if (Hitscan)
for (int i = 0; i < HitScanCount; i++)
{
DoHitscan(launchDir);
}
else
{
Launch(launchDir * launchImpulse * item.body.Mass);
float launchAngle = item.body.Rotation + MathHelper.ToRadians(Rand.Range(-Spread, Spread));
Vector2 launchDir = new Vector2((float)Math.Cos(launchAngle), (float)Math.Sin(launchAngle));
if (Hitscan)
{
Vector2 prevSimpos = item.SimPosition;
DoHitscan(launchDir);
if (i < HitScanCount - 1)
{
item.SetTransform(prevSimpos, item.body.Rotation);
}
}
else
{
Launch(launchDir * launchImpulse * item.body.Mass);
}
}
User = character;
@@ -306,6 +328,9 @@ namespace Barotrauma.Items.Components
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) return true;
fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform);
if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; }
hits.Add(new HitscanResult(fixture, rayStart, -dir, 0.0f));
return true;
}, ref aabb);
@@ -189,7 +189,11 @@ namespace Barotrauma.Items.Components
}
else
{
item.Condition += deltaTime / (fixDuration / item.MaxCondition);
float conditionIncrease = deltaTime / (fixDuration / item.MaxCondition);
item.Condition += conditionIncrease;
#if SERVER
GameMain.Server.KarmaManager.OnItemRepaired(CurrentFixer, this, conditionIncrease);
#endif
}
if (wasBroken && item.IsFullCondition)
@@ -24,7 +24,7 @@ namespace Barotrauma.Items.Components
public readonly bool IsOutput;
public readonly List<StatusEffect> effects;
public readonly List<StatusEffect> Effects;
public readonly ushort[] wireId;
@@ -135,7 +135,7 @@ namespace Barotrauma.Items.Components
IsPower = Name == "power_in" || Name == "power" || Name == "power_out";
effects = new List<StatusEffect>();
Effects = new List<StatusEffect>();
wireId = new ushort[MaxLinked];
@@ -158,7 +158,7 @@ namespace Barotrauma.Items.Components
break;
case "statuseffect":
effects.Add(StatusEffect.Load(subElement, item.Name + ", connection " + Name));
Effects.Add(StatusEffect.Load(subElement, item.Name + ", connection " + Name));
break;
}
}
@@ -222,6 +222,7 @@ namespace Barotrauma.Items.Components
recipientsDirty = true;
if (wire != null)
{
ConnectionPanel.DisconnectedWires.Remove(wire);
var otherConnection = wire.OtherConnection(this);
if (otherConnection != null)
{
@@ -251,10 +252,10 @@ namespace Barotrauma.Items.Components
}
bool broken = recipient.Item.Condition <= 0.0f;
foreach (StatusEffect effect in recipient.effects)
foreach (StatusEffect effect in recipient.Effects)
{
if (broken && effect.type != ActionType.OnBroken) continue;
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, 1.0f, null, null, false, false);
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, (float)Timing.Step, null, null, false, false);
}
}
}
@@ -277,11 +278,9 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < MaxLinked; i++)
{
if (wireId[i] == 0) continue;
if (wireId[i] == 0) { continue; }
Item wireItem = Entity.FindEntityByID(wireId[i]) as Item;
if (wireItem == null) continue;
if (!(Entity.FindEntityByID(wireId[i]) is Item wireItem)) { continue; }
wires[i] = wireItem.GetComponent<Wire>();
recipientsDirty = true;
@@ -15,6 +15,11 @@ namespace Barotrauma.Items.Components
private Character user;
/// <summary>
/// Wires that have been disconnected from the panel, but not removed completely (visible at the bottom of the connection panel).
/// </summary>
public readonly HashSet<Wire> DisconnectedWires = new HashSet<Wire>();
[Serialize(false, true), Editable(ToolTip = "Locked connection panels cannot be rewired in-game.")]
public bool Locked
{
@@ -103,6 +108,23 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
#if CLIENT
foreach (Wire wire in DisconnectedWires)
{
if (Rand.Range(0.0f, 500.0f) < 1.0f)
{
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
Vector2 baseVel = new Vector2(0.0f, -100.0f);
for (int i = 0; i < 5; i++)
{
var particle = GameMain.ParticleManager.CreateParticle("spark", item.WorldPosition,
baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull);
if (particle != null) { particle.Size *= Rand.Range(0.5f, 1.0f); }
}
}
}
#endif
if (user == null || user.SelectedConstruction != item)
{
user = null;
@@ -192,11 +214,12 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
DisconnectedWires.Clear();
foreach (Connection c in Connections)
{
foreach (Wire wire in c.Wires)
{
if (wire == null) continue;
if (wire == null) { continue; }
if (wire.OtherConnection(c) == null) //wire not connected to anything else
{
@@ -219,6 +242,12 @@ namespace Barotrauma.Items.Components
msg.Write(wire?.Item == null ? (ushort)0 : wire.Item.ID);
}
}
msg.Write((ushort)DisconnectedWires.Count());
foreach (Wire disconnectedWire in DisconnectedWires)
{
msg.Write(disconnectedWire.Item.ID);
}
}
}
}
@@ -165,6 +165,10 @@ namespace Barotrauma.Items.Components
{
base.OnItemLoaded();
itemLoaded = true;
#if CLIENT
light.Color = IsActive ? lightColor : Color.Transparent;
if (!IsActive) lightBrightness = 0.0f;
#endif
}
public override void Update(float deltaTime, Camera cam)
@@ -217,10 +221,9 @@ namespace Barotrauma.Items.Components
if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage))
{
#if CLIENT
if (voltage > 0.1f && sparkSounds.Count > 0)
if (voltage > 0.1f)
{
var sparkSound = sparkSounds[Rand.Int(sparkSounds.Count)];
SoundPlayer.PlaySound(sparkSound.Sound, item.WorldPosition, sparkSound.Volume, sparkSound.Range, item.CurrentHull);
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
}
#endif
lightBrightness = 0.0f;
@@ -1,6 +1,7 @@
using Barotrauma.Networking;
using Lidgren.Network;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -11,6 +12,17 @@ namespace Barotrauma.Items.Components
private bool isOn;
private static readonly Dictionary<string, string> connectionPairs = new Dictionary<string, string>
{
{ "power_in", "power_out"},
{ "signal_in", "signal_out" },
{ "signal_in1", "signal_out1" },
{ "signal_in2", "signal_out2" },
{ "signal_in3", "signal_out3" },
{ "signal_in4", "signal_out4" },
{ "signal_in5", "signal_out5" }
};
[Editable, Serialize(1000.0f, true)]
public float MaxPower
{
@@ -59,17 +71,11 @@ namespace Barotrauma.Items.Components
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
{
if (connection.IsPower || item.Condition <= 0.0f) return;
if (connection.IsPower || item.Condition <= 0.0f) { return; }
if (connection.Name.Contains("_in"))
if (connectionPairs.TryGetValue(connection.Name, out string outConnection))
{
if (!IsOn) return;
string outConnection = connection.Name.Contains("power_in") ? "power_out" : "signal_out";
int connectionNumber = -1;
int.TryParse(connection.Name.Substring(connection.Name.Length - 1, 1), out connectionNumber);
if (connectionNumber > 0) outConnection += connectionNumber;
if (!IsOn) { return; }
item.SendSignal(stepsTaken, signal, outConnection, sender, power, source, signalStrength);
}
else if (connection.Name == "toggle")
@@ -73,7 +73,7 @@ namespace Barotrauma.Items.Components
public bool CanTransmit()
{
return HasRequiredContainedItems(true);
return HasRequiredContainedItems(user: null, addMessage: false);
}
public IEnumerable<WifiComponent> GetReceiversInRange()
@@ -89,7 +89,7 @@ namespace Barotrauma.Items.Components
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; }
return HasRequiredContainedItems(false);
return HasRequiredContainedItems(user: null, addMessage: false);
}
public override void Update(float deltaTime, Camera cam)
@@ -16,8 +16,8 @@ namespace Barotrauma.Items.Components
private Vector2 start;
private Vector2 end;
private float angle;
private float length;
private readonly float angle;
private readonly float length;
public Vector2 Start
{
@@ -45,7 +45,7 @@ namespace Barotrauma.Items.Components
const int MaxNodesPerNetworkEvent = 30;
private List<Vector2> nodes;
private List<WireSection> sections;
private readonly List<WireSection> sections;
private Connection[] connections;
@@ -85,24 +85,23 @@ namespace Barotrauma.Items.Components
#if CLIENT
if (wireSprite == null)
{
wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f));
wireSprite.Depth = 0.85f;
wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f))
{
Depth = 0.85f
};
}
#endif
nodes = new List<Vector2>();
sections = new List<WireSection>();
connections = new Connection[2];
connections = new Connection[2];
IsActive = false;
}
public Connection OtherConnection(Connection connection)
{
if (connection == null) return null;
if (connection == connections[0]) return connections[1];
if (connection == connections[1]) return connections[0];
if (connection == connections[0]) { return connections[1]; }
if (connection == connections[1]) { return connections[0]; }
return null;
}
@@ -133,8 +132,8 @@ namespace Barotrauma.Items.Components
public void RemoveConnection(Connection connection)
{
if (connection == connections[0]) connections[0] = null;
if (connection == connections[1]) connections[1] = null;
if (connection == connections[0]) { connections[0] = null; }
if (connection == connections[1]) { connections[1] = null; }
SetConnectedDirty();
}
@@ -143,10 +142,10 @@ namespace Barotrauma.Items.Components
{
for (int i = 0; i < 2; i++)
{
if (connections[i] == newConnection) return false;
if (connections[i] == newConnection) { return false; }
}
if (!connections.Any(c => c == null)) return false;
if (!connections.Any(c => c == null)) { return false; }
for (int i = 0; i < 2; i++)
{
@@ -156,37 +155,39 @@ namespace Barotrauma.Items.Components
break;
}
}
if (item.body != null) { item.Submarine = newConnection.Item.Submarine; }
if (item.body != null) item.Submarine = newConnection.Item.Submarine;
newConnection.ConnectionPanel.DisconnectedWires.Remove(this);
for (int i = 0; i < 2; i++)
{
if (connections[i] != null) continue;
if (connections[i] != null) { continue; }
connections[i] = newConnection;
FixNodeEnds();
if (!addNode) break;
if (!addNode) { break; }
Submarine refSub = newConnection.Item.Submarine;
if (refSub == null)
{
Structure attachTarget = Structure.GetAttachTarget(newConnection.Item.WorldPosition);
if (attachTarget == null) continue;
if (attachTarget == null) { continue; }
refSub = attachTarget.Submarine;
}
Vector2 nodePos = refSub == null ?
newConnection.Item.Position :
newConnection.Item.Position - refSub.HiddenSubPosition;
if (nodes.Count > 0 && nodes[0] == nodePos) break;
if (nodes.Count > 1 && nodes[nodes.Count - 1] == nodePos) break;
if (nodes.Count > 0 && nodes[0] == nodePos) { break; }
if (nodes.Count > 1 && nodes[nodes.Count - 1] == nodePos) { break; }
//make sure we place the node at the correct end of the wire (the end that's closest to the new node pos)
int newNodeIndex = 0;
if (nodes.Count > 1)
{
if (Vector2.DistanceSquared(nodes[nodes.Count-1], nodePos) < Vector2.DistanceSquared(nodes[0], nodePos))
if (Vector2.DistanceSquared(nodes[nodes.Count - 1], nodePos) < Vector2.DistanceSquared(nodes[0], nodePos))
{
newNodeIndex = nodes.Count;
}
@@ -244,21 +245,18 @@ namespace Barotrauma.Items.Components
public override void Equip(Character character)
{
ClearConnections(character);
IsActive = true;
}
public override void Unequip(Character character)
{
ClearConnections(character);
IsActive = false;
}
public override void Drop(Character dropper)
{
ClearConnections(dropper);
ClearConnections(dropper);
IsActive = false;
}
@@ -399,7 +397,6 @@ namespace Barotrauma.Items.Components
public override bool Pick(Character picker)
{
ClearConnections(picker);
return true;
}
@@ -467,9 +464,26 @@ namespace Barotrauma.Items.Components
nodes.Clear();
sections.Clear();
foreach (Item item in Item.ItemList)
{
var connectionPanel = item.GetComponent<ConnectionPanel>();
if (connectionPanel != null && connectionPanel.DisconnectedWires.Contains(this))
{
#if SERVER
item.CreateServerEvent(connectionPanel);
#endif
connectionPanel.DisconnectedWires.Remove(this);
}
}
#if SERVER
if (user != null)
{
if (connections[0] != null || connections[1] != null)
{
GameMain.Server.KarmaManager.OnWireDisconnected(user, this);
}
if (connections[0] != null && connections[1] != null)
{
GameServer.Log(user.LogName + " disconnected a wire from " +
@@ -488,17 +502,21 @@ namespace Barotrauma.Items.Components
}
}
#endif
SetConnectedDirty();
for (int i = 0; i < 2; i++)
{
if (connections[i] == null) continue;
if (connections[i] == null) { continue; }
int wireIndex = connections[i].FindWireIndex(item);
if (wireIndex == -1) continue;
if (wireIndex == -1) { continue; }
#if SERVER
if (!connections[i].Item.Removed)
{
connections[i].Item.CreateServerEvent(connections[i].Item.GetComponent<ConnectionPanel>());
}
#endif
connections[i].SetWire(wireIndex, null);
connections[i] = null;
}
@@ -565,7 +583,27 @@ namespace Barotrauma.Items.Components
}
} while (removed);
}
private void FixNodeEnds()
{
if (connections[0] == null || connections[1] == null || nodes.Count == 0) { return; }
Vector2 nodePos = nodes[0];
Submarine refSub = connections[0].Item.Submarine ?? connections[1].Item.Submarine;
if (refSub != null) { nodePos += refSub.HiddenSubPosition; }
float dist1 = Vector2.DistanceSquared(connections[0].Item.Position, nodePos);
float dist2 = Vector2.DistanceSquared(connections[1].Item.Position, nodePos);
//first node is closer to the second item
//= the nodes are "backwards", need to reverse them
if (dist1 > dist2)
{
nodes.Reverse();
UpdateSections();
}
}
private int GetClosestNodeIndex(Vector2 pos, float maxDist, out float closestDist)
@@ -640,12 +678,8 @@ namespace Barotrauma.Items.Components
string[] nodeCoords = nodeString.Split(';');
for (int i = 0; i < nodeCoords.Length / 2; i++)
{
float x = 0.0f, y = 0.0f;
float.TryParse(nodeCoords[i * 2], NumberStyles.Float, CultureInfo.InvariantCulture, out x);
float.TryParse(nodeCoords[i * 2 + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out y);
float.TryParse(nodeCoords[i * 2], NumberStyles.Float, CultureInfo.InvariantCulture, out float x);
float.TryParse(nodeCoords[i * 2 + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out float y);
nodes.Add(new Vector2(x, y));
}
@@ -687,7 +721,6 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
ClearConnections();
base.RemoveComponentSpecific();
}
@@ -17,7 +17,8 @@ namespace Barotrauma
Moustache,
FaceAttachment,
JobIndicator,
Husk
Husk,
Herpes
}
class WearableSprite
@@ -101,6 +102,7 @@ namespace Barotrauma
case WearableType.FaceAttachment:
case WearableType.JobIndicator:
case WearableType.Husk:
case WearableType.Herpes:
Limb = LimbType.Head;
HideLimb = false;
HideOtherWearables = false;
@@ -207,6 +209,12 @@ namespace Barotrauma.Items.Components
{
get { return damageModifiers; }
}
private bool autoEquipWhenFull;
public bool AutoEquipWhenFull
{
get { return autoEquipWhenFull; }
}
public Wearable(Item item, XElement element) : base(item, element)
{
@@ -220,6 +228,7 @@ namespace Barotrauma.Items.Components
wearableSprites = new WearableSprite[spriteCount];
limbType = new LimbType[spriteCount];
limb = new Limb[spriteCount];
autoEquipWhenFull = element.GetAttributeBool("autoequipwhenfull", true);
int i = 0;
foreach (XElement subElement in element.Elements())
{