Revert "what the fuck"
This reverts commit16e90bea61. Revert "fix merge conflicts, warning: still broken" This reverts commit1f0f411d4f.
This commit is contained in:
@@ -6,13 +6,13 @@ using System.Xml.Linq;
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
using System.Globalization;
|
||||
using Barotrauma.Abilities;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class CharacterHealth
|
||||
{
|
||||
class LimbHealth
|
||||
public class LimbHealth
|
||||
{
|
||||
public Sprite IndicatorSprite;
|
||||
public Sprite HighlightSprite;
|
||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
||||
public Rectangle HighlightArea;
|
||||
|
||||
public readonly string Name;
|
||||
|
||||
|
||||
public readonly List<Affliction> Afflictions = new List<Affliction>();
|
||||
|
||||
public readonly Dictionary<string, float> VitalityMultipliers = new Dictionary<string, float>();
|
||||
@@ -76,7 +76,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<Affliction> GetActiveAfflictions(AfflictionPrefab prefab)
|
||||
{
|
||||
return Afflictions.FindAll(a => a.Prefab == prefab);
|
||||
@@ -85,7 +85,7 @@ namespace Barotrauma
|
||||
{
|
||||
return Afflictions.FindAll(a => a.Prefab.AfflictionType == afflictionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public const float InsufficientOxygenThreshold = 30.0f;
|
||||
public const float LowOxygenThreshold = 50.0f;
|
||||
@@ -117,15 +117,15 @@ namespace Barotrauma
|
||||
private set => Character.Params.Health.CrushDepth = value;
|
||||
}
|
||||
|
||||
private readonly List<LimbHealth> limbHealths = new List<LimbHealth>();
|
||||
private List<LimbHealth> limbHealths = new List<LimbHealth>();
|
||||
//non-limb-specific afflictions
|
||||
private readonly List<Affliction> afflictions = new List<Affliction>();
|
||||
private List<Affliction> afflictions = new List<Affliction>();
|
||||
/// <summary>
|
||||
/// Note: returns only the non-limb-secific afflictions. Use GetAllAfflictions or some other method for getting also the limb-specific afflictions.
|
||||
/// </summary>
|
||||
public IEnumerable<Affliction> Afflictions => afflictions;
|
||||
|
||||
private readonly HashSet<Affliction> irremovableAfflictions = new HashSet<Affliction>();
|
||||
private HashSet<Affliction> irremovableAfflictions = new HashSet<Affliction>();
|
||||
private Affliction bloodlossAffliction;
|
||||
private Affliction oxygenLowAffliction;
|
||||
private Affliction pressureAffliction;
|
||||
@@ -133,7 +133,7 @@ namespace Barotrauma
|
||||
|
||||
public bool IsUnconscious
|
||||
{
|
||||
get { return (Vitality <= 0.0f || Character.IsDead) && !Character.HasAbilityFlag(AbilityFlags.AlwaysStayConscious); }
|
||||
get { return Vitality <= 0.0f || Character.IsDead; }
|
||||
}
|
||||
|
||||
public float PressureKillDelay { get; private set; } = 5.0f;
|
||||
@@ -152,7 +152,6 @@ namespace Barotrauma
|
||||
max += Character.Info.Job.Prefab.VitalityModifier;
|
||||
}
|
||||
max *= Character.StaticHealthMultiplier;
|
||||
max *= 1f + Character.GetStatValue(StatTypes.MaximumHealthMultiplier);
|
||||
return max * Character.HealthMultiplier;
|
||||
}
|
||||
}
|
||||
@@ -169,20 +168,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Color DefaultFaceTint = Color.TransparentBlack;
|
||||
|
||||
public Color FaceTint
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Color BodyTint
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public float OxygenAmount
|
||||
{
|
||||
get
|
||||
@@ -206,11 +191,7 @@ namespace Barotrauma
|
||||
public float Stun
|
||||
{
|
||||
get { return stunAffliction.Strength; }
|
||||
set
|
||||
{
|
||||
if (Character.GodMode) { return; }
|
||||
stunAffliction.Strength = MathHelper.Clamp(value, 0.0f, stunAffliction.Prefab.MaxStrength);
|
||||
}
|
||||
set { stunAffliction.Strength = MathHelper.Clamp(value, 0.0f, stunAffliction.Prefab.MaxStrength); }
|
||||
}
|
||||
|
||||
public float StunTimer { get; private set; }
|
||||
@@ -242,7 +223,7 @@ namespace Barotrauma
|
||||
this.Character = character;
|
||||
InitIrremovableAfflictions();
|
||||
|
||||
Vitality = maxVitality;
|
||||
Vitality = maxVitality;
|
||||
|
||||
minVitality = character.IsHuman ? -100.0f : 0.0f;
|
||||
|
||||
@@ -285,12 +266,6 @@ namespace Barotrauma
|
||||
private LimbHealth GetMatchingLimbHealth(Limb limb) => limb == null ? null : limbHealths[limb.HealthIndex];
|
||||
private LimbHealth GetMatchingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb, excludeSevered: false));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
||||
/// </summary>
|
||||
private IEnumerable<Affliction> GetMatchingAfflictions(LimbHealth limb)
|
||||
=> limb.Afflictions.Union(afflictions.Where(a => GetMatchingLimbHealth(a) == limb));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
||||
/// </summary>
|
||||
@@ -323,7 +298,7 @@ namespace Barotrauma
|
||||
public Affliction GetAffliction(string identifier, bool allowLimbAfflictions = true)
|
||||
=> GetAffliction(a => a.Prefab.Identifier == identifier, allowLimbAfflictions);
|
||||
|
||||
public Affliction GetAfflictionOfType(string afflictionType, bool allowLimbAfflictions = true)
|
||||
public Affliction GetAfflictionOfType(string afflictionType, bool allowLimbAfflictions = true)
|
||||
=> GetAffliction(a => a.Prefab.AfflictionType == afflictionType, allowLimbAfflictions);
|
||||
|
||||
private Affliction GetAffliction(Func<Affliction, bool> predicate, bool allowLimbAfflictions = true)
|
||||
@@ -427,61 +402,62 @@ namespace Barotrauma
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void ApplyAffliction(Limb targetLimb, Affliction affliction, bool allowStacking = true)
|
||||
public void ApplyAffliction(Limb targetLimb, Affliction affliction)
|
||||
{
|
||||
if (!affliction.Prefab.IsBuff && Unkillable || Character.GodMode) { return; }
|
||||
if (affliction.Prefab.LimbSpecific)
|
||||
{
|
||||
if (targetLimb == null)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("afflictionApplied", new object[] { this, affliction }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
|
||||
//if a limb-specific affliction is applied to no specific limb, apply to all limbs
|
||||
foreach (LimbHealth limbHealth in limbHealths)
|
||||
{
|
||||
AddLimbAffliction(limbHealth, affliction, allowStacking: allowStacking);
|
||||
AddLimbAffliction(limbHealth, affliction);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLimbAffliction(targetLimb, affliction, allowStacking: allowStacking);
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("afflictionApplied", new object[] { this, affliction, targetLimb }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
AddLimbAffliction(targetLimb, affliction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddAffliction(affliction, allowStacking: allowStacking);
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("afflictionApplied", new object[] { this, affliction }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
AddAffliction(affliction);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetResistance(AfflictionPrefab affliction)
|
||||
public float GetResistance(string resistanceId)
|
||||
{
|
||||
float resistance = 0.0f;
|
||||
for (int i = 0; i < afflictions.Count; i++)
|
||||
{
|
||||
resistance += afflictions[i].GetResistance(affliction);
|
||||
if (!afflictions[i].Prefab.IsBuff) continue;
|
||||
float temp = afflictions[i].GetResistance(resistanceId);
|
||||
if (temp > resistance) resistance = temp;
|
||||
}
|
||||
return 1 - ((1 - resistance) * Character.GetAbilityResistance(affliction));
|
||||
}
|
||||
|
||||
public float GetStatValue(StatTypes statType)
|
||||
{
|
||||
float value = 0f;
|
||||
for (int i = 0; i < afflictions.Count; i++)
|
||||
{
|
||||
value += afflictions[i].GetStatValue(statType);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool HasFlag(AbilityFlags flagType)
|
||||
{
|
||||
for (int i = 0; i < afflictions.Count; i++)
|
||||
{
|
||||
if (afflictions[i].HasFlag(flagType)) { return true; }
|
||||
}
|
||||
return false;
|
||||
return resistance;
|
||||
}
|
||||
|
||||
private readonly List<Affliction> matchingAfflictions = new List<Affliction>();
|
||||
public void ReduceAffliction(Limb targetLimb, string affliction, float amount, ActionType? treatmentAction = null)
|
||||
public void ReduceAffliction(Limb targetLimb, string affliction, float amount)
|
||||
{
|
||||
matchingAfflictions.Clear();
|
||||
matchingAfflictions.AddRange(afflictions);
|
||||
@@ -510,14 +486,6 @@ namespace Barotrauma
|
||||
for (int i = matchingAfflictions.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var matchingAffliction = matchingAfflictions[i];
|
||||
|
||||
// this logic runs very often, so culling unnecessary object creation and talent checking with this method
|
||||
if (Character.HasTalents())
|
||||
{
|
||||
var afflictionReduction = new AbilityValueAffliction(reduceAmount, matchingAffliction);
|
||||
Character.CheckTalents(AbilityEffectType.OnReduceAffliction, afflictionReduction);
|
||||
}
|
||||
|
||||
if (matchingAffliction.Strength < reduceAmount)
|
||||
{
|
||||
float surplus = reduceAmount - matchingAffliction.Strength;
|
||||
@@ -532,17 +500,6 @@ namespace Barotrauma
|
||||
{
|
||||
matchingAffliction.Strength -= reduceAmount;
|
||||
amount -= reduceAmount;
|
||||
if (treatmentAction != null)
|
||||
{
|
||||
if (treatmentAction.Value == ActionType.OnUse)
|
||||
{
|
||||
matchingAffliction.AppliedAsSuccessfulTreatmentTime = Timing.TotalTime;
|
||||
}
|
||||
else if (treatmentAction.Value == ActionType.OnFailure)
|
||||
{
|
||||
matchingAffliction.AppliedAsFailedTreatmentTime = Timing.TotalTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CalculateVitality();
|
||||
@@ -558,6 +515,11 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("afflictionApplied", new object[] { this, attackResult, hitLimb }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
foreach (Affliction newAffliction in attackResult.Afflictions)
|
||||
{
|
||||
if (newAffliction.Prefab.LimbSpecific)
|
||||
@@ -568,15 +530,15 @@ namespace Barotrauma
|
||||
{
|
||||
AddAffliction(newAffliction, allowStacking);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetAllDamage(float damageAmount, float bleedingDamageAmount, float burnDamageAmount)
|
||||
{
|
||||
if (Unkillable || Character.GodMode) { return; }
|
||||
foreach (LimbHealth limbHealth in limbHealths)
|
||||
{
|
||||
limbHealth.Afflictions.RemoveAll(a =>
|
||||
limbHealth.Afflictions.RemoveAll(a =>
|
||||
a.Prefab.AfflictionType == AfflictionPrefab.InternalDamage.AfflictionType ||
|
||||
a.Prefab.AfflictionType == AfflictionPrefab.Burn.AfflictionType ||
|
||||
a.Prefab.AfflictionType == AfflictionPrefab.Bleeding.AfflictionType);
|
||||
@@ -600,9 +562,9 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
// Instead of using the limbhealth count here, I think it's best to define the max vitality per limb roughly with a constant value.
|
||||
// Therefore with e.g. 80 health, the max damage per limb would be 40.
|
||||
// Having at least 40 damage on both legs would cause maximum limping.
|
||||
float max = MaxVitality / 2;
|
||||
// Therefore with e.g. 80 health, the max damage per limb would be 20.
|
||||
// Having at least 20 damage on both legs would cause maximum limping.
|
||||
float max = MaxVitality / 4;
|
||||
if (string.IsNullOrEmpty(afflictionType))
|
||||
{
|
||||
float damage = GetAfflictionStrength("damage", limb, true);
|
||||
@@ -633,22 +595,6 @@ namespace Barotrauma
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
public void RemoveNegativeAfflictions()
|
||||
{
|
||||
// also don't remove genetic effects, even if they're negative
|
||||
foreach (LimbHealth limbHealth in limbHealths)
|
||||
{
|
||||
limbHealth.Afflictions.RemoveAll(a => !a.Prefab.IsBuff && a.Prefab.AfflictionType != "geneticmaterialbuff" && a.Prefab.AfflictionType != "geneticmaterialdebuff");
|
||||
}
|
||||
|
||||
afflictions.RemoveAll(a => !irremovableAfflictions.Contains(a) && !a.Prefab.IsBuff && a.Prefab.AfflictionType != "geneticmaterialbuff" && a.Prefab.AfflictionType != "geneticmaterialdebuff");
|
||||
foreach (Affliction affliction in irremovableAfflictions)
|
||||
{
|
||||
affliction.Strength = 0.0f;
|
||||
}
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction, bool allowStacking = true)
|
||||
{
|
||||
if (!newAffliction.Prefab.LimbSpecific || limb == null) { return; }
|
||||
@@ -670,7 +616,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (newAffliction.Prefab == affliction.Prefab)
|
||||
{
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab));
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
||||
if (allowStacking)
|
||||
{
|
||||
// Add the existing strength
|
||||
@@ -692,10 +638,10 @@ namespace Barotrauma
|
||||
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
||||
//or modify the affliction instance of an Attack or a StatusEffect
|
||||
var copyAffliction = newAffliction.Prefab.Instantiate(
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))),
|
||||
newAffliction.Source);
|
||||
limbHealth.Afflictions.Add(copyAffliction);
|
||||
|
||||
|
||||
Character.HealthUpdateInterval = 0.0f;
|
||||
|
||||
CalculateVitality();
|
||||
@@ -714,7 +660,6 @@ namespace Barotrauma
|
||||
private void AddAffliction(Affliction newAffliction, bool allowStacking = true)
|
||||
{
|
||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||
if (Character.Params.Health.StunImmunity && newAffliction.Prefab.AfflictionType == "stun") { return; }
|
||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||
if (newAffliction.Prefab is AfflictionPrefabHusk huskPrefab)
|
||||
{
|
||||
@@ -727,7 +672,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (newAffliction.Prefab == affliction.Prefab)
|
||||
{
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab));
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
||||
if (allowStacking)
|
||||
{
|
||||
// Add the existing strength
|
||||
@@ -749,7 +694,7 @@ namespace Barotrauma
|
||||
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
||||
//or modify the affliction instance of an Attack or a StatusEffect
|
||||
afflictions.Add(newAffliction.Prefab.Instantiate(
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))),
|
||||
source: newAffliction.Source));
|
||||
|
||||
Character.HealthUpdateInterval = 0.0f;
|
||||
@@ -761,6 +706,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime);
|
||||
|
||||
partial void UpdateLimbAfflictionOverlays();
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -769,8 +716,6 @@ namespace Barotrauma
|
||||
|
||||
StunTimer = Stun > 0 ? StunTimer + deltaTime : 0;
|
||||
|
||||
if (Character.GodMode) { return; }
|
||||
|
||||
for (int i = 0; i < limbHealths.Count; i++)
|
||||
{
|
||||
for (int j = limbHealths[i].Afflictions.Count - 1; j >= 0; j--)
|
||||
@@ -798,11 +743,11 @@ namespace Barotrauma
|
||||
Character.StackSpeedMultiplier(affliction.GetSpeedMultiplier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = afflictions.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var affliction = afflictions[i];
|
||||
if (irremovableAfflictions.Contains(affliction)) { continue; }
|
||||
if (irremovableAfflictions.Contains(affliction)) continue;
|
||||
if (affliction.Strength <= 0.0f)
|
||||
{
|
||||
SteamAchievementManager.OnAfflictionRemoved(affliction, Character);
|
||||
@@ -816,21 +761,9 @@ namespace Barotrauma
|
||||
affliction.DamagePerSecondTimer += deltaTime;
|
||||
Character.StackSpeedMultiplier(affliction.GetSpeedMultiplier());
|
||||
}
|
||||
|
||||
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.MovementSpeed));
|
||||
|
||||
// maybe a bit of a hacky way to do this. should inquire if there is a better way. M61T
|
||||
if (Character.InWater)
|
||||
{
|
||||
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.SwimmingSpeed));
|
||||
}
|
||||
else
|
||||
{
|
||||
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.WalkingSpeed));
|
||||
}
|
||||
|
||||
|
||||
UpdateLimbAfflictionOverlays();
|
||||
UpdateSkinTint();
|
||||
|
||||
CalculateVitality();
|
||||
|
||||
if (Vitality <= MinVitality)
|
||||
@@ -839,32 +772,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSkinTint()
|
||||
{
|
||||
FaceTint = DefaultFaceTint;
|
||||
BodyTint = Color.TransparentBlack;
|
||||
|
||||
for (int i = 0; i < limbHealths.Count; i++)
|
||||
{
|
||||
for (int j = limbHealths[i].Afflictions.Count - 1; j >= 0; j--)
|
||||
{
|
||||
var affliction = limbHealths[i].Afflictions[j];
|
||||
Color faceTint = affliction.GetFaceTint();
|
||||
if (faceTint.A > FaceTint.A) { FaceTint = faceTint; }
|
||||
Color bodyTint = affliction.GetBodyTint();
|
||||
if (bodyTint.A > BodyTint.A) { BodyTint = bodyTint; }
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < afflictions.Count; i++)
|
||||
{
|
||||
var affliction = afflictions[i];
|
||||
Color faceTint = affliction.GetFaceTint();
|
||||
if (faceTint.A > FaceTint.A) { FaceTint = faceTint; }
|
||||
Color bodyTint = affliction.GetBodyTint();
|
||||
if (bodyTint.A > BodyTint.A) { BodyTint = bodyTint; }
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOxygen(float deltaTime)
|
||||
{
|
||||
if (!Character.NeedsOxygen) { return; }
|
||||
@@ -873,21 +780,16 @@ namespace Barotrauma
|
||||
if (IsUnconscious)
|
||||
{
|
||||
//the character dies of oxygen deprivation in 100 seconds after losing consciousness
|
||||
OxygenAmount = MathHelper.Clamp(OxygenAmount - 1.0f * deltaTime, -100.0f, 100.0f);
|
||||
OxygenAmount = MathHelper.Clamp(OxygenAmount - 1.0f * deltaTime, -100.0f, 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
float decreaseSpeed = -5.0f;
|
||||
float increaseSpeed = 10.0f;
|
||||
float oxygenlowResistance = GetResistance(oxygenLowAffliction.Prefab);
|
||||
decreaseSpeed *= (1f - oxygenlowResistance);
|
||||
increaseSpeed *= (1f + oxygenlowResistance);
|
||||
OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? decreaseSpeed : increaseSpeed), -100.0f, 100.0f);
|
||||
OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? -5.0f : 10.0f), -100.0f, 100.0f);
|
||||
}
|
||||
|
||||
UpdateOxygenProjSpecific(prevOxygen, deltaTime);
|
||||
}
|
||||
|
||||
|
||||
partial void UpdateOxygenProjSpecific(float prevOxygen, float deltaTime);
|
||||
|
||||
partial void UpdateBleedingProjSpecific(AfflictionBleeding affliction, Limb targetLimb, float deltaTime);
|
||||
@@ -903,6 +805,8 @@ namespace Barotrauma
|
||||
Vitality = MaxVitality;
|
||||
if (Unkillable || Character.GodMode) { return; }
|
||||
|
||||
float damageResistanceMultiplier = 1f - GetResistance("damage");
|
||||
|
||||
foreach (LimbHealth limbHealth in limbHealths)
|
||||
{
|
||||
foreach (Affliction affliction in limbHealth.Afflictions)
|
||||
@@ -918,6 +822,7 @@ namespace Barotrauma
|
||||
{
|
||||
vitalityDecrease *= limbHealth.VitalityTypeMultipliers[type];
|
||||
}
|
||||
vitalityDecrease *= damageResistanceMultiplier;
|
||||
Vitality -= vitalityDecrease;
|
||||
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
||||
}
|
||||
@@ -926,6 +831,7 @@ namespace Barotrauma
|
||||
foreach (Affliction affliction in afflictions)
|
||||
{
|
||||
float vitalityDecrease = affliction.GetVitalityDecrease(this);
|
||||
vitalityDecrease *= damageResistanceMultiplier;
|
||||
Vitality -= vitalityDecrease;
|
||||
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
||||
}
|
||||
@@ -941,10 +847,9 @@ namespace Barotrauma
|
||||
private void Kill()
|
||||
{
|
||||
if (Unkillable || Character.GodMode) { return; }
|
||||
|
||||
var (type, affliction) = GetCauseOfDeath();
|
||||
UpdateSkinTint();
|
||||
Character.Kill(type, affliction);
|
||||
|
||||
var causeOfDeath = GetCauseOfDeath();
|
||||
Character.Kill(causeOfDeath.First, causeOfDeath.Second);
|
||||
#if CLIENT
|
||||
DisplayVitalityDelay = 0.0f;
|
||||
DisplayedVitality = Vitality;
|
||||
@@ -977,7 +882,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public (CauseOfDeathType type, Affliction affliction) GetCauseOfDeath()
|
||||
public Pair<CauseOfDeathType, Affliction> GetCauseOfDeath()
|
||||
{
|
||||
List<Affliction> currentAfflictions = GetAllAfflictions(true);
|
||||
|
||||
@@ -998,7 +903,7 @@ namespace Barotrauma
|
||||
causeOfDeath = Character.AnimController.InWater ? CauseOfDeathType.Drowning : CauseOfDeathType.Suffocation;
|
||||
}
|
||||
|
||||
return (causeOfDeath, strongestAffliction);
|
||||
return new Pair<CauseOfDeathType, Affliction>(causeOfDeath, strongestAffliction);
|
||||
}
|
||||
|
||||
// TODO: this method is called a lot (every half second) -> optimize, don't create new class instances and lists every time!
|
||||
@@ -1044,16 +949,15 @@ namespace Barotrauma
|
||||
/// <param name="treatmentSuitability">A dictionary where the key is the identifier of the item and the value the suitability</param>
|
||||
/// <param name="normalize">If true, the suitability values are normalized between 0 and 1. If not, they're arbitrary values defined in the medical item XML, where negative values are unsuitable, and positive ones suitable.</param>
|
||||
/// <param name="randomization">Amount of randomization to apply to the values (0 = the values are accurate, 1 = the values are completely random)</param>
|
||||
public void GetSuitableTreatments(Dictionary<string, float> treatmentSuitability, bool normalize, Limb limb = null, bool ignoreHiddenAfflictions = false, float randomization = 0.0f)
|
||||
public void GetSuitableTreatments(Dictionary<string, float> treatmentSuitability, bool normalize, float randomization = 0.0f)
|
||||
{
|
||||
//key = item identifier
|
||||
//float = suitability
|
||||
treatmentSuitability.Clear();
|
||||
float minSuitability = -10, maxSuitability = 10;
|
||||
foreach (Affliction affliction in getAfflictions(limb))
|
||||
foreach (Affliction affliction in GetAllAfflictions())
|
||||
{
|
||||
if (affliction.Strength <= affliction.Prefab.TreatmentThreshold) { continue; }
|
||||
if (ignoreHiddenAfflictions && affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
|
||||
if (affliction.Strength < affliction.Prefab.TreatmentThreshold) { continue; }
|
||||
foreach (KeyValuePair<string, float> treatment in affliction.Prefab.TreatmentSuitability)
|
||||
{
|
||||
if (!treatmentSuitability.ContainsKey(treatment.Key))
|
||||
@@ -1084,22 +988,10 @@ namespace Barotrauma
|
||||
treatmentSuitability[treatment] += Rand.Range(-100.0f, 100.0f) * randomization;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<Affliction> getAfflictions(Limb limb)
|
||||
{
|
||||
if (limb == null)
|
||||
{
|
||||
return GetAllAfflictions();
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMatchingAfflictions(GetMatchingLimbHealth(limb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<Affliction> activeAfflictions = new List<Affliction>();
|
||||
private readonly List<(LimbHealth limbHealth, Affliction affliction)> limbAfflictions = new List<(LimbHealth limbHealth, Affliction affliction)>();
|
||||
private readonly List<Pair<LimbHealth, Affliction>> limbAfflictions = new List<Pair<LimbHealth, Affliction>>();
|
||||
public void ServerWrite(IWriteMessage msg)
|
||||
{
|
||||
activeAfflictions.Clear();
|
||||
@@ -1115,7 +1007,7 @@ namespace Barotrauma
|
||||
{
|
||||
msg.Write(affliction.Prefab.UIntIdentifier);
|
||||
msg.WriteRangedSingle(
|
||||
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
|
||||
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
|
||||
0.0f, affliction.Prefab.MaxStrength, 8);
|
||||
msg.Write((byte)affliction.Prefab.PeriodicEffects.Count());
|
||||
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in affliction.Prefab.PeriodicEffects)
|
||||
@@ -1130,22 +1022,22 @@ namespace Barotrauma
|
||||
foreach (Affliction limbAffliction in limbHealth.Afflictions)
|
||||
{
|
||||
if (limbAffliction.Strength <= 0.0f || limbAffliction.Strength < limbAffliction.Prefab.ActivationThreshold) continue;
|
||||
limbAfflictions.Add((limbHealth, limbAffliction));
|
||||
limbAfflictions.Add(new Pair<LimbHealth, Affliction>(limbHealth, limbAffliction));
|
||||
}
|
||||
}
|
||||
|
||||
msg.Write((byte)limbAfflictions.Count);
|
||||
foreach (var (limbHealth, affliction) in limbAfflictions)
|
||||
foreach (var limbAffliction in limbAfflictions)
|
||||
{
|
||||
msg.WriteRangedInteger(limbHealths.IndexOf(limbHealth), 0, limbHealths.Count - 1);
|
||||
msg.Write(affliction.Prefab.UIntIdentifier);
|
||||
msg.WriteRangedInteger(limbHealths.IndexOf(limbAffliction.First), 0, limbHealths.Count - 1);
|
||||
msg.Write(limbAffliction.Second.Prefab.UIntIdentifier);
|
||||
msg.WriteRangedSingle(
|
||||
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
|
||||
0.0f, affliction.Prefab.MaxStrength, 8);
|
||||
msg.Write((byte)affliction.Prefab.PeriodicEffects.Count());
|
||||
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in affliction.Prefab.PeriodicEffects)
|
||||
MathHelper.Clamp(limbAffliction.Second.Strength, 0.0f, limbAffliction.Second.Prefab.MaxStrength),
|
||||
0.0f, limbAffliction.Second.Prefab.MaxStrength, 8);
|
||||
msg.Write((byte)limbAffliction.Second.Prefab.PeriodicEffects.Count());
|
||||
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in limbAffliction.Second.Prefab.PeriodicEffects)
|
||||
{
|
||||
msg.WriteRangedSingle(affliction.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
|
||||
msg.WriteRangedSingle(limbAffliction.Second.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1161,7 +1053,7 @@ namespace Barotrauma
|
||||
/// Automatically filters out buffs.
|
||||
/// </summary>
|
||||
public static IEnumerable<Affliction> SortAfflictionsBySeverity(IEnumerable<Affliction> afflictions, bool excludeBuffs = true) =>
|
||||
afflictions.Where(a => !excludeBuffs || !a.Prefab.IsBuff).OrderByDescending(a => a.DamagePerSecond).ThenByDescending(a => a.Strength / a.Prefab.MaxStrength);
|
||||
afflictions.Where(a => !excludeBuffs || !a.Prefab.IsBuff).OrderByDescending(a => a.DamagePerSecond).ThenByDescending(a => a.Strength);
|
||||
|
||||
public void Save(XElement healthElement)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,6 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
private bool linkToChat = false;
|
||||
|
||||
[ConditionallyEditable(ConditionallyEditable.ConditionType.AllowLinkingWifiToChat)]
|
||||
|
||||
@@ -11,7 +11,7 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using Barotrauma.Abilities;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
#if CLIENT
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
||||
public ItemPrefab Prefab => prefab as ItemPrefab;
|
||||
|
||||
public static bool ShowLinks = true;
|
||||
|
||||
|
||||
private HashSet<string> tags;
|
||||
|
||||
private bool isWire, isLogic;
|
||||
@@ -37,6 +37,7 @@ namespace Barotrauma
|
||||
set
|
||||
{
|
||||
currentHull = value;
|
||||
ParentRuin = currentHull?.ParentRuin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,16 +98,14 @@ namespace Barotrauma
|
||||
|
||||
private Dictionary<string, Connection> connections;
|
||||
|
||||
private readonly List<Repairable> repairables;
|
||||
private List<Repairable> repairables;
|
||||
|
||||
private Quality qualityComponent;
|
||||
|
||||
private readonly Queue<float> impactQueue = new Queue<float>();
|
||||
private Queue<float> impactQueue = new Queue<float>();
|
||||
|
||||
//a dictionary containing lists of the status effects in all the components of the item
|
||||
private readonly bool[] hasStatusEffectsOfType;
|
||||
private readonly Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
|
||||
|
||||
private bool[] hasStatusEffectsOfType;
|
||||
private Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; protected set; }
|
||||
|
||||
private bool? hasInGameEditableProperties;
|
||||
@@ -171,7 +170,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return prefab.Name; }
|
||||
@@ -233,6 +232,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (character != null && character.IsOnPlayerTeam)
|
||||
{
|
||||
|
||||
return IsPlayerTeamInteractable;
|
||||
}
|
||||
else
|
||||
@@ -254,12 +254,6 @@ namespace Barotrauma
|
||||
{
|
||||
if (!Prefab.AllowRotatingInEditor) { return; }
|
||||
rotationRad = MathHelper.ToRadians(value);
|
||||
#if CLIENT
|
||||
if (Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
SetContainedItemPositions();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +261,7 @@ namespace Barotrauma
|
||||
{
|
||||
get { return Prefab.ImpactTolerance; }
|
||||
}
|
||||
|
||||
|
||||
public float InteractDistance
|
||||
{
|
||||
get { return Prefab.InteractDistance; }
|
||||
@@ -350,7 +344,7 @@ namespace Barotrauma
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
|
||||
[Editable, Serialize("1.0,1.0,1.0,1.0", true, description: "Changes the color of the item this item is contained inside. Only has an effect if either of the UseContainedSpriteColor or UseContainedInventoryIconColor property of the container is set to true.")]
|
||||
public Color ContainerColor
|
||||
{
|
||||
@@ -366,9 +360,9 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
Container?.prefab.Identifier ??
|
||||
ParentInventory?.Owner?.ToString() ??
|
||||
return
|
||||
Container?.prefab.Identifier ??
|
||||
ParentInventory?.Owner?.ToString() ??
|
||||
"";
|
||||
}
|
||||
set { /*do nothing*/ }
|
||||
@@ -455,48 +449,42 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public bool IsFullCondition => MathUtils.NearlyEqual(Condition, MaxCondition);
|
||||
public float MaxCondition => Prefab.Health * healthMultiplier * maxRepairConditionMultiplier * (1.0f + GetQualityModifier(Items.Components.Quality.StatType.Condition));
|
||||
public float MaxCondition => Prefab.Health * healthMultiplier;
|
||||
public float ConditionPercentage => MathUtils.Percentage(Condition, MaxCondition);
|
||||
|
||||
private float offsetOnSelectedMultiplier = 1.0f;
|
||||
|
||||
|
||||
[Serialize(1.0f, false)]
|
||||
public float OffsetOnSelectedMultiplier
|
||||
{
|
||||
get => offsetOnSelectedMultiplier;
|
||||
set => offsetOnSelectedMultiplier = value;
|
||||
}
|
||||
|
||||
|
||||
private float healthMultiplier = 1.0f;
|
||||
|
||||
[Serialize(1.0f, true, "Multiply the maximum condition by this value")]
|
||||
public float HealthMultiplier
|
||||
{
|
||||
get => healthMultiplier;
|
||||
set { healthMultiplier = MathHelper.Clamp(value, 0.0f, float.PositiveInfinity); }
|
||||
set
|
||||
{
|
||||
healthMultiplier = value;
|
||||
}
|
||||
}
|
||||
|
||||
private float maxRepairConditionMultiplier = 1.0f;
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
public float MaxRepairConditionMultiplier
|
||||
{
|
||||
get => maxRepairConditionMultiplier;
|
||||
set { maxRepairConditionMultiplier = MathHelper.Clamp(value, 0.0f, float.PositiveInfinity); }
|
||||
}
|
||||
|
||||
|
||||
//the default value should be Prefab.Health, but because we can't use it in the attribute,
|
||||
//we'll just use NaN (which does nothing) and set the default value in the constructor/load
|
||||
[Serialize(float.NaN, false), Editable]
|
||||
public float Condition
|
||||
{
|
||||
get { return condition; }
|
||||
set
|
||||
set
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (!MathUtils.IsValid(value)) { return; }
|
||||
if (Indestructible) { return; }
|
||||
if (InvulnerableToDamage && value <= condition) { return; }
|
||||
if (InvulnerableToDamage && value <= condition) { return;}
|
||||
|
||||
float prev = condition;
|
||||
bool wasInFullCondition = IsFullCondition;
|
||||
@@ -513,7 +501,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
ApplyStatusEffects(ActionType.OnBroken, 1.0f, null);
|
||||
}
|
||||
|
||||
|
||||
SetActiveSprite();
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
@@ -553,12 +541,6 @@ namespace Barotrauma
|
||||
set => indestructible = value;
|
||||
}
|
||||
|
||||
public bool AllowDeconstruct
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, isSaveable: true, "When enabled will prevent the item from taking damage from all sources")]
|
||||
public bool InvulnerableToDamage { get; set; }
|
||||
|
||||
@@ -632,24 +614,9 @@ namespace Barotrauma
|
||||
get { return Prefab.UseInHealthInterface; }
|
||||
}
|
||||
|
||||
public int Quality
|
||||
{
|
||||
get
|
||||
{
|
||||
return qualityComponent?.QualityLevel ?? 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (qualityComponent != null)
|
||||
{
|
||||
qualityComponent.QualityLevel = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool InWater
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
//if the item has an active physics body, inWater is updated in the Update method
|
||||
if (body != null && body.Enabled) { return inWater; }
|
||||
@@ -766,16 +733,16 @@ namespace Barotrauma
|
||||
{
|
||||
get { return allPropertyObjects; }
|
||||
}
|
||||
|
||||
|
||||
public bool IgnoreByAI(Character character) => HasTag("ignorebyai") || OrderedToBeIgnored && character.IsOnPlayerTeam;
|
||||
public bool OrderedToBeIgnored { get; set; }
|
||||
|
||||
public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine, ushort id = Entity.NullEntityID)
|
||||
: this(new Rectangle(
|
||||
(int)(position.X - itemPrefab.sprite.size.X / 2 * itemPrefab.Scale),
|
||||
(int)(position.Y + itemPrefab.sprite.size.Y / 2 * itemPrefab.Scale),
|
||||
(int)(itemPrefab.sprite.size.X * itemPrefab.Scale),
|
||||
(int)(itemPrefab.sprite.size.Y * itemPrefab.Scale)),
|
||||
(int)(position.X - itemPrefab.sprite.size.X / 2 * itemPrefab.Scale),
|
||||
(int)(position.Y + itemPrefab.sprite.size.Y / 2 * itemPrefab.Scale),
|
||||
(int)(itemPrefab.sprite.size.X * itemPrefab.Scale),
|
||||
(int)(itemPrefab.sprite.size.Y * itemPrefab.Scale)),
|
||||
itemPrefab, submarine, id: id)
|
||||
{
|
||||
|
||||
@@ -790,10 +757,10 @@ namespace Barotrauma
|
||||
{
|
||||
spriteColor = prefab.SpriteColor;
|
||||
|
||||
components = new List<ItemComponent>();
|
||||
drawableComponents = new List<IDrawableComponent>(); hasComponentsToDraw = false;
|
||||
tags = new HashSet<string>();
|
||||
repairables = new List<Repairable>();
|
||||
components = new List<ItemComponent>();
|
||||
drawableComponents = new List<IDrawableComponent>(); hasComponentsToDraw = false;
|
||||
tags = new HashSet<string>();
|
||||
repairables = new List<Repairable>();
|
||||
|
||||
defaultRect = newRect;
|
||||
rect = newRect;
|
||||
@@ -801,8 +768,6 @@ namespace Barotrauma
|
||||
condition = MaxCondition;
|
||||
lastSentCondition = condition;
|
||||
|
||||
AllowDeconstruct = itemPrefab.AllowDeconstruct;
|
||||
|
||||
allPropertyObjects.Add(this);
|
||||
|
||||
XElement element = itemPrefab.ConfigElement;
|
||||
@@ -831,10 +796,10 @@ namespace Barotrauma
|
||||
body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionPlatform | Physics.CollisionProjectile;
|
||||
}
|
||||
if (collisionCategory != null)
|
||||
{
|
||||
{
|
||||
if (!Physics.TryParseCollisionCategory(collisionCategory, out Category cat))
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid collision category in item \"" + Name + "\" (" + collisionCategory + ")");
|
||||
DebugConsole.ThrowError("Invalid collision category in item \"" + Name+"\" (" + collisionCategory + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -962,8 +927,6 @@ namespace Barotrauma
|
||||
ownInventory = itemContainer.Inventory;
|
||||
}
|
||||
|
||||
qualityComponent = GetComponent<Quality>();
|
||||
|
||||
InitProjSpecific();
|
||||
|
||||
if (callOnItemLoaded)
|
||||
@@ -981,9 +944,6 @@ namespace Barotrauma
|
||||
|
||||
if (Components.Any(ic => ic is Wire) && Components.All(ic => ic is Wire || ic is Holdable)) { isWire = true; }
|
||||
if (HasTag("logic")) { isLogic = true; }
|
||||
|
||||
ApplyStatusEffects(ActionType.OnSpawn, 1.0f);
|
||||
Components.ForEach(c => c.ApplyStatusEffects(ActionType.OnSpawn, 1.0f));
|
||||
}
|
||||
|
||||
partial void InitProjSpecific();
|
||||
@@ -1030,7 +990,7 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
|
||||
clone.components[i].requiredItems[kvp.Key][j].JoinedIdentifiers =
|
||||
clone.components[i].requiredItems[kvp.Key][j].JoinedIdentifiers =
|
||||
kvp.Value[j].JoinedIdentifiers;
|
||||
}
|
||||
}
|
||||
@@ -1038,7 +998,7 @@ namespace Barotrauma
|
||||
|
||||
if (FlippedX) clone.FlipX(false);
|
||||
if (FlippedY) clone.FlipY(false);
|
||||
|
||||
|
||||
foreach (ItemComponent component in clone.components)
|
||||
{
|
||||
component.OnItemLoaded();
|
||||
@@ -1049,7 +1009,7 @@ namespace Barotrauma
|
||||
var containedClone = containedItem.Clone();
|
||||
clone.ownInventory.TryPutItem(containedClone as Item, null);
|
||||
}
|
||||
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -1063,7 +1023,7 @@ namespace Barotrauma
|
||||
updateableComponents.Add(component);
|
||||
}
|
||||
|
||||
component.OnActiveStateChanged += (bool isActive) =>
|
||||
component.OnActiveStateChanged += (bool isActive) =>
|
||||
{
|
||||
bool hasSounds = false;
|
||||
#if CLIENT
|
||||
@@ -1071,7 +1031,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
//component doesn't need to be updated if it isn't active, doesn't have a parent that could activate it,
|
||||
//nor status effects, sounds or conditionals that would need to run
|
||||
if (!isActive &&
|
||||
if (!isActive &&
|
||||
!hasSounds &&
|
||||
component.Parent == null &&
|
||||
(component.IsActiveConditionals == null || !component.IsActiveConditionals.Any()) &&
|
||||
@@ -1081,8 +1041,8 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!updateableComponents.Contains(component))
|
||||
{
|
||||
if (!updateableComponents.Contains(component))
|
||||
{
|
||||
updateableComponents.Add(component);
|
||||
this.isActive = true;
|
||||
}
|
||||
@@ -1143,7 +1103,7 @@ namespace Barotrauma
|
||||
if (typeof(T) == typeof(ItemComponent))
|
||||
{
|
||||
return (T)components.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
@@ -1156,17 +1116,12 @@ namespace Barotrauma
|
||||
if (!componentsByType.ContainsKey(typeof(T))) { return Enumerable.Empty<T>(); }
|
||||
return components.Where(c => c is T).Cast<T>();
|
||||
}
|
||||
|
||||
public float GetQualityModifier(Quality.StatType statType)
|
||||
{
|
||||
return GetComponent<Quality>()?.GetValue(statType) ?? 0.0f;
|
||||
}
|
||||
|
||||
|
||||
public void RemoveContained(Item contained)
|
||||
{
|
||||
ownInventory?.RemoveItem(contained);
|
||||
|
||||
contained.Container = null;
|
||||
contained.Container = null;
|
||||
}
|
||||
|
||||
public void SetTransform(Vector2 simPosition, float rotation, bool findNewHull = true, bool setPrevTransform = true)
|
||||
@@ -1308,7 +1263,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Item item in ItemList) item.FindHull();
|
||||
}
|
||||
|
||||
|
||||
public Hull FindHull()
|
||||
{
|
||||
if (parentInventory != null && parentInventory.Owner != null)
|
||||
@@ -1323,7 +1278,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
Submarine = parentInventory.Owner.Submarine;
|
||||
if (body != null) { body.Submarine = Submarine; }
|
||||
if (body != null) body.Submarine = Submarine;
|
||||
|
||||
return CurrentHull;
|
||||
}
|
||||
@@ -1350,7 +1305,7 @@ namespace Barotrauma
|
||||
|
||||
return rootContainer;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Should this item or any of its containers be ignored by the AI?
|
||||
/// </summary>
|
||||
@@ -1402,7 +1357,7 @@ namespace Barotrauma
|
||||
(component as ItemContainer)?.SetContainedItemPositions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddTag(string tag)
|
||||
{
|
||||
if (tags.Contains(tag)) { return; }
|
||||
@@ -1463,7 +1418,7 @@ namespace Barotrauma
|
||||
ApplyStatusEffect(effect, type, deltaTime, character, limb, useTarget, isNetworkEvent, false, worldPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
|
||||
|
||||
public void ApplyStatusEffect(StatusEffect effect, ActionType type, float deltaTime, Character character = null, Limb limb = null, Entity useTarget = null, bool isNetworkEvent = false, bool checkCondition = true, Vector2? worldPosition = null)
|
||||
@@ -1473,11 +1428,11 @@ namespace Barotrauma
|
||||
if (condition == 0.0f && !effect.AllowWhenBroken && effect.type != ActionType.OnBroken) { return; }
|
||||
}
|
||||
if (effect.type != type) { return; }
|
||||
|
||||
|
||||
bool hasTargets = effect.TargetIdentifiers == null;
|
||||
|
||||
targets.Clear();
|
||||
|
||||
|
||||
if (effect.HasTargetType(StatusEffect.TargetType.Contained))
|
||||
{
|
||||
foreach (Item containedItem in ContainedItems)
|
||||
@@ -1489,11 +1444,6 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
|
||||
if (effect.TargetSlot > -1)
|
||||
{
|
||||
if (OwnInventory.FindIndex(containedItem) != effect.TargetSlot) { continue; }
|
||||
}
|
||||
|
||||
hasTargets = true;
|
||||
targets.Add(containedItem);
|
||||
}
|
||||
@@ -1551,10 +1501,10 @@ namespace Barotrauma
|
||||
{
|
||||
targets.Add(limb);
|
||||
}
|
||||
|
||||
if (Container != null && effect.HasTargetType(StatusEffect.TargetType.Parent)) { targets.Add(Container); }
|
||||
|
||||
effect.Apply(type, deltaTime, this, targets, worldPosition);
|
||||
|
||||
if (Container != null && effect.HasTargetType(StatusEffect.TargetType.Parent)) targets.Add(Container);
|
||||
|
||||
effect.Apply(type, deltaTime, this, targets, worldPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -1576,7 +1526,7 @@ namespace Barotrauma
|
||||
private bool IsInWater()
|
||||
{
|
||||
if (CurrentHull == null) { return true; }
|
||||
|
||||
|
||||
float surfaceY = CurrentHull.Surface;
|
||||
return CurrentHull.WaterVolume > 0.0f && Position.Y < surfaceY;
|
||||
}
|
||||
@@ -1612,10 +1562,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (aiTarget != null)
|
||||
{
|
||||
aiTarget.Update(deltaTime);
|
||||
}
|
||||
aiTarget?.Update(deltaTime);
|
||||
|
||||
GameMain.Lua.hook.Call("itemThink." + prefab.Identifier, new object[] { this, deltaTime });
|
||||
|
||||
if (!isActive) { return; }
|
||||
|
||||
@@ -1631,7 +1580,7 @@ namespace Barotrauma
|
||||
bool shouldBeActive = true;
|
||||
foreach (var conditional in ic.IsActiveConditionals)
|
||||
{
|
||||
if (!ConditionalMatches(conditional))
|
||||
if (!ConditionalMatches(conditional))
|
||||
{
|
||||
shouldBeActive = false;
|
||||
break;
|
||||
@@ -1729,22 +1678,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
if (body == null) { return; }
|
||||
|
||||
Submarine prevSub = Submarine;
|
||||
|
||||
var projectile = GetComponent<Projectile>();
|
||||
if (projectile?.StickTarget?.UserData is Limb limb)
|
||||
{
|
||||
Submarine = body.Submarine = limb.character?.Submarine;
|
||||
currentHull = limb.character?.CurrentHull;
|
||||
}
|
||||
else
|
||||
{
|
||||
FindHull();
|
||||
}
|
||||
FindHull();
|
||||
|
||||
if (Submarine == null && prevSub != null)
|
||||
{
|
||||
@@ -1772,7 +1713,7 @@ namespace Barotrauma
|
||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
||||
|
||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
||||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
|
||||
{
|
||||
body.LinearVelocity = new Vector2(
|
||||
@@ -1811,23 +1752,17 @@ namespace Barotrauma
|
||||
|
||||
Vector2 drag = body.LinearVelocity * volume;
|
||||
|
||||
body.ApplyForce((uplift - drag) * 10.0f);
|
||||
body.ApplyForce((uplift - drag) * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||
|
||||
//apply simple angular drag
|
||||
body.ApplyTorque(body.AngularVelocity * volume * -0.05f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool OnCollision(Fixture f1, Fixture f2, Contact contact)
|
||||
{
|
||||
if (transformDirty) { return false; }
|
||||
|
||||
var projectile = GetComponent<Projectile>();
|
||||
if (projectile?.IgnoredBodies != null)
|
||||
{
|
||||
if (projectile.IgnoredBodies.Contains(f2.Body)) { return false; }
|
||||
}
|
||||
|
||||
contact.GetWorldManifold(out Vector2 normal, out _);
|
||||
if (contact.FixtureA.Body == f1.Body) { normal = -normal; }
|
||||
float impact = Vector2.Dot(f1.Body.LinearVelocity, -normal);
|
||||
@@ -1856,7 +1791,7 @@ namespace Barotrauma
|
||||
foreach (Item contained in ContainedItems)
|
||||
{
|
||||
if (contained.body != null) { contained.HandleCollision(impact); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1867,10 +1802,10 @@ namespace Barotrauma
|
||||
//call the base method even if the item can't flip, to handle repositioning when flipping the whole sub
|
||||
base.FlipX(relativeToSub);
|
||||
|
||||
if (!Prefab.CanFlipX)
|
||||
if (!Prefab.CanFlipX)
|
||||
{
|
||||
flippedX = false;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Prefab.AllowRotatingInEditor)
|
||||
@@ -1887,8 +1822,7 @@ namespace Barotrauma
|
||||
foreach (ItemComponent component in components)
|
||||
{
|
||||
component.FlipX(relativeToSub);
|
||||
}
|
||||
SetContainedItemPositions();
|
||||
}
|
||||
}
|
||||
|
||||
public override void FlipY(bool relativeToSub)
|
||||
@@ -1913,7 +1847,6 @@ namespace Barotrauma
|
||||
{
|
||||
component.FlipY(relativeToSub);
|
||||
}
|
||||
SetContainedItemPositions();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1942,7 +1875,7 @@ namespace Barotrauma
|
||||
if (component != null && !connectedComponents.Contains(component))
|
||||
{
|
||||
connectedComponents.Add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1973,28 +1906,28 @@ namespace Barotrauma
|
||||
|
||||
return connectedComponents;
|
||||
}
|
||||
|
||||
public static readonly (string input, string output)[] connectionPairs = new (string input, string output)[]
|
||||
|
||||
public static readonly Pair<string, string>[] connectionPairs = new Pair<string, string>[]
|
||||
{
|
||||
("power_in", "power_out"),
|
||||
("signal_in1", "signal_out1"),
|
||||
("signal_in2", "signal_out2"),
|
||||
("signal_in3", "signal_out3"),
|
||||
("signal_in4", "signal_out4"),
|
||||
("signal_in", "signal_out"),
|
||||
("signal_in1", "signal_out"),
|
||||
("signal_in2", "signal_out")
|
||||
new Pair<string, string>("power_in", "power_out"),
|
||||
new Pair<string, string>("signal_in1", "signal_out1"),
|
||||
new Pair<string, string>("signal_in2", "signal_out2"),
|
||||
new Pair<string, string>("signal_in3", "signal_out3"),
|
||||
new Pair<string, string>("signal_in4", "signal_out4"),
|
||||
new Pair<string, string>("signal_in", "signal_out"),
|
||||
new Pair<string, string>("signal_in1", "signal_out"),
|
||||
new Pair<string, string>("signal_in2", "signal_out")
|
||||
};
|
||||
|
||||
private void GetConnectedComponentsRecursive<T>(Connection c, HashSet<Connection> alreadySearched, List<T> connectedComponents) where T : ItemComponent
|
||||
{
|
||||
alreadySearched.Add(c);
|
||||
|
||||
|
||||
var recipients = c.Recipients;
|
||||
foreach (Connection recipient in recipients)
|
||||
{
|
||||
if (alreadySearched.Contains(recipient)) { continue; }
|
||||
var component = recipient.Item.GetComponent<T>();
|
||||
var component = recipient.Item.GetComponent<T>();
|
||||
if (component != null && !connectedComponents.Contains(component))
|
||||
{
|
||||
connectedComponents.Add(component);
|
||||
@@ -2016,23 +1949,23 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
recipient.Item.GetConnectedComponentsRecursive(recipient, alreadySearched, connectedComponents);
|
||||
recipient.Item.GetConnectedComponentsRecursive(recipient, alreadySearched, connectedComponents);
|
||||
}
|
||||
|
||||
foreach ((string input, string output) in connectionPairs)
|
||||
foreach (Pair<string, string> connectionPair in connectionPairs)
|
||||
{
|
||||
if (input == c.Name)
|
||||
if (connectionPair.First == c.Name)
|
||||
{
|
||||
var pairedConnection = c.Item.Connections.FirstOrDefault(c2 => c2.Name == output);
|
||||
var pairedConnection = c.Item.Connections.FirstOrDefault(c2 => c2.Name == connectionPair.Second);
|
||||
if (pairedConnection != null)
|
||||
{
|
||||
if (alreadySearched.Contains(pairedConnection)) { continue; }
|
||||
GetConnectedComponentsRecursive(pairedConnection, alreadySearched, connectedComponents);
|
||||
}
|
||||
}
|
||||
else if (output == c.Name)
|
||||
else if (connectionPair.Second == c.Name)
|
||||
{
|
||||
var pairedConnection = c.Item.Connections.FirstOrDefault(c2 => c2.Name == input);
|
||||
var pairedConnection = c.Item.Connections.FirstOrDefault(c2 => c2.Name == connectionPair.First);
|
||||
if (pairedConnection != null)
|
||||
{
|
||||
if (alreadySearched.Contains(pairedConnection)) { continue; }
|
||||
@@ -2042,27 +1975,18 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Controller FindController(string[] tags = null)
|
||||
public Controller FindController()
|
||||
{
|
||||
//try finding the controller with the simpler non-recursive method first
|
||||
var controllers = GetConnectedComponents<Controller>();
|
||||
bool needsTag = tags != null && tags.Length > 0;
|
||||
if (controllers.None() || (needsTag && controllers.None(c => c.Item.HasTag(tags))))
|
||||
{
|
||||
controllers = GetConnectedComponents<Controller>(recursive: true);
|
||||
}
|
||||
if (needsTag)
|
||||
{
|
||||
controllers.RemoveAll(c => !c.Item.HasTag(tags));
|
||||
}
|
||||
return controllers.Count < 2 ?
|
||||
controllers.FirstOrDefault() :
|
||||
controllers.FirstOrDefault(c => c.GetFocusTarget() == this) ?? controllers.FirstOrDefault();
|
||||
if (controllers.None()) { controllers = GetConnectedComponents<Controller>(recursive: true); }
|
||||
return controllers.Count < 2 ? controllers.FirstOrDefault() :
|
||||
(controllers.FirstOrDefault(c => c.GetFocusTarget() == this) ?? controllers.FirstOrDefault());
|
||||
}
|
||||
|
||||
public bool TryFindController(out Controller controller, string[] tags = null)
|
||||
public bool TryFindController(out Controller controller)
|
||||
{
|
||||
controller = FindController(tags: tags);
|
||||
controller = FindController();
|
||||
return controller != null;
|
||||
}
|
||||
|
||||
@@ -2134,6 +2058,8 @@ namespace Barotrauma
|
||||
} while (CoroutineManager.DeltaTime <= 0.0f);
|
||||
|
||||
delayedSignals.Remove((signal, connection));
|
||||
|
||||
signal.source = this;
|
||||
connection.SendSignal(signal);
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
@@ -2163,6 +2089,11 @@ namespace Barotrauma
|
||||
|
||||
public bool TryInteract(Character picker, bool ignoreRequiredItems = false, bool forceSelectKey = false, bool forceActionKey = false)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemInteract", new object[] { this, picker, ignoreRequiredItems, forceSelectKey, forceActionKey }));
|
||||
|
||||
if (!should.IsNull())
|
||||
return should.Bool();
|
||||
|
||||
if (CampaignInteractionType != CampaignMode.InteractionType.None) { return false; }
|
||||
|
||||
bool picked = false, selected = false;
|
||||
@@ -2220,7 +2151,7 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
if (!pickHit && !selectHit) { continue; }
|
||||
|
||||
|
||||
bool showUiMsg = false;
|
||||
#if CLIENT
|
||||
if (!ic.HasRequiredSkills(picker, out Skill tempRequiredSkill)) { hasRequiredSkills = false; skillMultiplier = ic.GetSkillMultiplier(); }
|
||||
@@ -2270,7 +2201,7 @@ namespace Barotrauma
|
||||
|
||||
if (Container != null) Container.RemoveContained(this);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public float GetContainedItemConditionPercentage()
|
||||
@@ -2287,7 +2218,7 @@ namespace Barotrauma
|
||||
if (maxCondition > 0.0f)
|
||||
{
|
||||
return condition / maxCondition;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -2301,6 +2232,11 @@ namespace Barotrauma
|
||||
|
||||
if (condition == 0.0f) { return; }
|
||||
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemUse", new object[] { this, character, targetLimb }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
bool remove = false;
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
@@ -2317,7 +2253,7 @@ namespace Barotrauma
|
||||
#if CLIENT
|
||||
ic.PlaySound(ActionType.OnUse, character);
|
||||
#endif
|
||||
|
||||
|
||||
ic.ApplyStatusEffects(ActionType.OnUse, deltaTime, character, targetLimb);
|
||||
|
||||
if (ic.DeleteOnUse) { remove = true; }
|
||||
@@ -2334,6 +2270,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (condition == 0.0f) { return; }
|
||||
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemSecondaryUse", new object[] { this, character}));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
|
||||
bool remove = false;
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
@@ -2365,9 +2307,14 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyTreatment(Character user, Character character, Limb targetLimb)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemApplyTreatment", new object[] { this, user, character, targetLimb }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
//can't apply treatment to dead characters
|
||||
if (character.IsDead) { return; }
|
||||
if (!UseInHealthInterface) { return; }
|
||||
if (character.IsDead) return;
|
||||
if (!UseInHealthInterface) return;
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null)
|
||||
@@ -2377,12 +2324,10 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
|
||||
float applyOnSelfFraction = user?.GetStatValue(StatTypes.ApplyTreatmentsOnSelfFraction) ?? 0.0f;
|
||||
|
||||
bool remove = false;
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (!ic.HasRequiredContainedItems(user, addMessage: user == Character.Controlled)) { continue; }
|
||||
if (!ic.HasRequiredContainedItems(user, addMessage: user == Character.Controlled)) continue;
|
||||
|
||||
bool success = Rand.Range(0.0f, 0.5f) < ic.DegreeOfSuccess(user);
|
||||
ActionType actionType = success ? ActionType.OnUse : ActionType.OnFailure;
|
||||
@@ -2391,19 +2336,7 @@ namespace Barotrauma
|
||||
ic.PlaySound(actionType, user);
|
||||
#endif
|
||||
ic.WasUsed = true;
|
||||
ic.ApplyStatusEffects(actionType, 1.0f, character, targetLimb, user: user, applyOnUserFraction: applyOnSelfFraction);
|
||||
|
||||
if (applyOnSelfFraction > 0.0f)
|
||||
{
|
||||
//hacky af
|
||||
ic.statusEffectLists.TryGetValue(actionType, out var effectList);
|
||||
if (effectList != null)
|
||||
{
|
||||
effectList.ForEach(e => e.AfflictionMultiplier = applyOnSelfFraction);
|
||||
ic.ApplyStatusEffects(actionType, 1.0f, user, targetLimb == null ? null : user.AnimController.GetLimb(targetLimb.type), user: user);
|
||||
effectList.ForEach(e => e.AfflictionMultiplier = 1.0f);
|
||||
}
|
||||
}
|
||||
ic.ApplyStatusEffects(actionType, 1.0f, character, targetLimb, user: user);
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
@@ -2413,23 +2346,19 @@ namespace Barotrauma
|
||||
});
|
||||
}
|
||||
|
||||
if (ic.DeleteOnUse) { remove = true; }
|
||||
if (ic.DeleteOnUse) remove = true;
|
||||
}
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
var abilityItem = new AbilityApplyTreatment(user, character, this);
|
||||
user.CheckTalents(AbilityEffectType.OnApplyTreatment, abilityItem);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (remove) { Spawner?.AddToRemoveQueue(this); }
|
||||
}
|
||||
|
||||
public bool Combine(Item item, Character user)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemCombine", new object[] { this, item, user }));
|
||||
|
||||
if (!should.IsNull())
|
||||
return should.Bool();
|
||||
|
||||
if (item == this) { return false; }
|
||||
bool isCombined = false;
|
||||
foreach (ItemComponent ic in components)
|
||||
@@ -2444,6 +2373,11 @@ namespace Barotrauma
|
||||
|
||||
public void Drop(Character dropper, bool createNetworkEvent = true)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemDrop", new object[] { this, dropper}));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
if (createNetworkEvent)
|
||||
{
|
||||
if (parentInventory != null && !parentInventory.Owner.Removed && !Removed &&
|
||||
@@ -2477,25 +2411,28 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
foreach (ItemComponent ic in components) { ic.Drop(dropper); }
|
||||
|
||||
|
||||
if (Container != null)
|
||||
{
|
||||
SetTransform(Container.SimPosition, 0.0f);
|
||||
Container.RemoveContained(this);
|
||||
Container = null;
|
||||
}
|
||||
|
||||
|
||||
if (parentInventory != null)
|
||||
{
|
||||
parentInventory.RemoveItem(this);
|
||||
parentInventory = null;
|
||||
}
|
||||
|
||||
SetContainedItemPositions();
|
||||
}
|
||||
|
||||
public void Equip(Character character)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemEquip", new object[] { this, character}));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
if (Removed)
|
||||
{
|
||||
DebugConsole.ThrowError($"Tried to equip a removed item ({Name}).\n{Environment.StackTrace.CleanupStackTrace()}");
|
||||
@@ -2507,6 +2444,11 @@ namespace Barotrauma
|
||||
|
||||
public void Unequip(Character character)
|
||||
{
|
||||
var should = new LuaResult(GameMain.Lua.hook.Call("itemUnequip", new object[] { this, character }));
|
||||
|
||||
if (should.Bool())
|
||||
return;
|
||||
|
||||
foreach (ItemComponent ic in components) { ic.Unequip(character); }
|
||||
}
|
||||
|
||||
@@ -2518,7 +2460,7 @@ namespace Barotrauma
|
||||
foreach (var itemProperty in itemProperties)
|
||||
{
|
||||
allProperties.Add(new Pair<object, SerializableProperty>(this, itemProperty));
|
||||
}
|
||||
}
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
List<SerializableProperty> componentProperties = SerializableProperty.GetProperties<T>(ic);
|
||||
@@ -2600,14 +2542,6 @@ namespace Barotrauma
|
||||
{
|
||||
msg.Write((int)value);
|
||||
}
|
||||
else if (value is string[] a)
|
||||
{
|
||||
msg.Write(a.Length);
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
msg.Write(a[i] ?? "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Serializing item properties of the type \"" + value.GetType() + "\" not supported");
|
||||
@@ -2656,8 +2590,8 @@ namespace Barotrauma
|
||||
{
|
||||
string val = msg.ReadString();
|
||||
logValue = val;
|
||||
if (allowEditing)
|
||||
{
|
||||
if (allowEditing)
|
||||
{
|
||||
property.TrySetValue(parentObject, val);
|
||||
}
|
||||
}
|
||||
@@ -2715,26 +2649,13 @@ namespace Barotrauma
|
||||
logValue = XMLExtensions.RectToString(val);
|
||||
if (allowEditing) { property.TrySetValue(parentObject, val); }
|
||||
}
|
||||
else if (type == typeof(string[]))
|
||||
{
|
||||
int arrayLength = msg.ReadInt32();
|
||||
string[] val = new string[arrayLength];
|
||||
for (int i = 0; i < arrayLength; i++)
|
||||
{
|
||||
val[i] = msg.ReadString();
|
||||
}
|
||||
if (allowEditing)
|
||||
{
|
||||
property.TrySetValue(parentObject, val);
|
||||
}
|
||||
}
|
||||
else if (typeof(Enum).IsAssignableFrom(type))
|
||||
{
|
||||
int intVal = msg.ReadInt32();
|
||||
try
|
||||
{
|
||||
if (allowEditing)
|
||||
{
|
||||
if (allowEditing)
|
||||
{
|
||||
property.TrySetValue(parentObject, Enum.ToObject(type, intVal));
|
||||
logValue = property.GetValue(parentObject).ToString();
|
||||
}
|
||||
@@ -2763,9 +2684,10 @@ namespace Barotrauma
|
||||
{
|
||||
CoroutineManager.StopCoroutines(logPropertyChangeCoroutine);
|
||||
}
|
||||
logPropertyChangeCoroutine = CoroutineManager.Invoke(() =>
|
||||
logPropertyChangeCoroutine = CoroutineManager.InvokeAfter(() =>
|
||||
{
|
||||
GameServer.Log($"{sender.Character.Name} set the value \"{property.Name}\" of the item \"{Name}\" to \"{logValue}\".", ServerLog.MessageType.ItemInteraction);
|
||||
if(sender.Character != null)
|
||||
GameServer.Log($"{sender.Character.Name} set the value \"{property.Name}\" of the item \"{Name}\" to \"{logValue}\".", ServerLog.MessageType.ItemInteraction);
|
||||
}, delay: 1.0f);
|
||||
}
|
||||
#endif
|
||||
@@ -3003,7 +2925,7 @@ namespace Barotrauma
|
||||
{
|
||||
component.OnItemLoaded();
|
||||
}
|
||||
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -3053,7 +2975,7 @@ namespace Barotrauma
|
||||
(int)(rect.X - subPosition.X) + "," +
|
||||
(int)(rect.Y - subPosition.Y) + "," +
|
||||
width + "," + height));
|
||||
|
||||
|
||||
if (linkedTo != null && linkedTo.Count > 0)
|
||||
{
|
||||
bool isOutpost = Submarine != null && Submarine.Info.IsOutpost;
|
||||
@@ -3103,7 +3025,7 @@ namespace Barotrauma
|
||||
ic.OnMapLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove the item so that it doesn't appear to exist in the game world (stop sounds, remove bodies etc)
|
||||
/// but don't reset anything that's required for cloning the item
|
||||
@@ -3111,7 +3033,7 @@ namespace Barotrauma
|
||||
public override void ShallowRemove()
|
||||
{
|
||||
base.ShallowRemove();
|
||||
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
ic.ShallowRemove();
|
||||
@@ -3133,7 +3055,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
DebugConsole.Log("Removing item " + Name + " (ID: " + ID + ")");
|
||||
|
||||
|
||||
base.Remove();
|
||||
|
||||
foreach (Character character in Character.CharacterList)
|
||||
@@ -3152,8 +3074,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
connections?.Clear();
|
||||
|
||||
if (parentInventory != null)
|
||||
{
|
||||
if (parentInventory is CharacterInventory characterInventory)
|
||||
@@ -3179,8 +3099,6 @@ namespace Barotrauma
|
||||
body = null;
|
||||
}
|
||||
|
||||
CurrentHull = null;
|
||||
|
||||
if (StaticFixtures != null)
|
||||
{
|
||||
foreach (Fixture fixture in StaticFixtures)
|
||||
|
||||
Reference in New Issue
Block a user