v0.10.5.1

This commit is contained in:
Juan Pablo Arce
2020-09-22 11:31:56 -03:00
parent 44032d0ae0
commit 0002ad2c50
343 changed files with 12276 additions and 5023 deletions
@@ -15,13 +15,24 @@ namespace Barotrauma
public Dictionary<string, SerializableProperty> SerializableProperties { get; set; }
protected float _strength;
[Serialize(0f, true), Editable]
public virtual float Strength
{
get { return _strength; }
set { _strength = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength); }
set
{
if (_nonClampedStrength < 0 && value > 0)
{
_nonClampedStrength = value;
}
_strength = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength);
}
}
private float _nonClampedStrength = -1;
public float NonClampedStrength => _nonClampedStrength > 0 ? _nonClampedStrength : _strength;
[Serialize("", true), Editable]
public string Identifier { get; private set; }
@@ -35,6 +46,8 @@ namespace Barotrauma
public float StrengthDiminishMultiplier = 1.0f;
public Affliction MultiplierSource;
public readonly Dictionary<AfflictionPrefab.PeriodicEffect, float> PeriodicEffectTimers = new Dictionary<AfflictionPrefab.PeriodicEffect, float>();
/// <summary>
/// Which character gave this affliction
/// </summary>
@@ -45,6 +58,11 @@ namespace Barotrauma
Prefab = prefab;
_strength = strength;
Identifier = prefab?.Identifier;
foreach (var periodicEffect in prefab.PeriodicEffects)
{
PeriodicEffectTimers[periodicEffect] = Rand.Range(periodicEffect.MinInterval, periodicEffect.MaxInterval);
}
}
public void Serialize(XElement element)
@@ -59,24 +77,27 @@ namespace Barotrauma
public Affliction CreateMultiplied(float multiplier)
{
return Prefab.Instantiate(Strength * multiplier, Source);
return Prefab.Instantiate(NonClampedStrength * multiplier, Source);
}
public override string ToString() => Prefab == null ? "Affliction (Invalid)" : $"Affliction ({Prefab.Name})";
public float GetVitalityDecrease(CharacterHealth characterHealth)
{
if (Strength < Prefab.ActivationThreshold) return 0.0f;
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
if (currentEffect == null) return 0.0f;
if (currentEffect.MaxStrength - currentEffect.MinStrength <= 0.0f) return 0.0f;
if (currentEffect == null) { return 0.0f; }
if (currentEffect.MaxStrength - currentEffect.MinStrength <= 0.0f) { return 0.0f; }
float currVitalityDecrease = MathHelper.Lerp(
currentEffect.MinVitalityDecrease,
currentEffect.MaxVitalityDecrease,
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
if (currentEffect.MultiplyByMaxVitality) currVitalityDecrease *= characterHealth == null ? 100.0f : characterHealth.MaxVitality;
if (currentEffect.MultiplyByMaxVitality)
{
currVitalityDecrease *= characterHealth == null ? 100.0f : characterHealth.MaxVitality;
}
return currVitalityDecrease;
}
@@ -173,8 +194,28 @@ namespace Barotrauma
public virtual void Update(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
{
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in Prefab.PeriodicEffects)
{
PeriodicEffectTimers[periodicEffect] -= deltaTime;
if (PeriodicEffectTimers[periodicEffect] <= 0.0f)
{
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
{
PeriodicEffectTimers[periodicEffect] = 0.0f;
}
else
{
foreach (StatusEffect statusEffect in periodicEffect.StatusEffects)
{
ApplyStatusEffect(statusEffect, 1.0f, characterHealth, targetLimb);
PeriodicEffectTimers[periodicEffect] = Rand.Range(periodicEffect.MinInterval, periodicEffect.MaxInterval);
}
}
}
}
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
if (currentEffect == null) return;
if (currentEffect == null) { return; }
if (currentEffect.StrengthChange < 0) // Reduce diminishing of buffs if boosted
{
@@ -184,32 +225,44 @@ namespace Barotrauma
{
_strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab.Identifier));
}
// Don't use the property, because its virtual and some afflictions like husk overload it for external use.
// Don't use the property, because it's virtual and some afflictions like husk overload it for external use.
_strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength);
foreach (StatusEffect statusEffect in currentEffect.StatusEffects)
{
statusEffect.SetUser(Source);
if (statusEffect.HasTargetType(StatusEffect.TargetType.Character))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, characterHealth.Character, characterHealth.Character);
}
if (targetLimb != null && statusEffect.HasTargetType(StatusEffect.TargetType.Limb))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, characterHealth.Character, targetLimb);
}
if (targetLimb != null && statusEffect.HasTargetType(StatusEffect.TargetType.AllLimbs))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, targetLimb.character, targetLimb.character.AnimController.Limbs.Cast<ISerializableEntity>().ToList());
}
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
{
var targets = new List<ISerializableEntity>();
statusEffect.GetNearbyTargets(characterHealth.Character.WorldPosition, targets);
statusEffect.Apply(ActionType.OnActive, deltaTime, targetLimb.character, targets);
}
ApplyStatusEffect(statusEffect, deltaTime, characterHealth, targetLimb);
}
}
public void ApplyStatusEffect(StatusEffect statusEffect, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
{
statusEffect.SetUser(Source);
if (statusEffect.HasTargetType(StatusEffect.TargetType.Character))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, characterHealth.Character, characterHealth.Character);
}
if (targetLimb != null && statusEffect.HasTargetType(StatusEffect.TargetType.Limb))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, characterHealth.Character, targetLimb);
}
if (targetLimb != null && statusEffect.HasTargetType(StatusEffect.TargetType.AllLimbs))
{
statusEffect.Apply(ActionType.OnActive, deltaTime, targetLimb.character, targetLimb.character.AnimController.Limbs.Cast<ISerializableEntity>().ToList());
}
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
{
var targets = new List<ISerializableEntity>();
statusEffect.GetNearbyTargets(characterHealth.Character.WorldPosition, targets);
statusEffect.Apply(ActionType.OnActive, deltaTime, targetLimb.character, targets);
}
}
/// <summary>
/// Use this method to skip clamping and additional logic of the setters.
/// Intended only to be used when the value is already clamped! (networking code)
/// Ideally we would keep this private, but doing so would require too much refactoring.
/// </summary>
public void SetStrength(float strength) => _strength = strength;
}
}
@@ -29,8 +29,9 @@ namespace Barotrauma
set
{
// Don't allow to set the strength too high (from outside) to avoid rapid transformation into husk when taking lots of damage from husks.
// If the strength is more than the value, this will effectively reset the current strength to the max. That's why we use two steps.
float max = _strength > ActiveThreshold ? ActiveThreshold + 1 : DormantThreshold - 1;
float previousValue = _strength;
float threshold = _strength > ActiveThreshold ? ActiveThreshold + 1 : DormantThreshold - 1;
float max = Math.Max(threshold, previousValue);
_strength = Math.Clamp(value, 0, max);
}
}
@@ -79,7 +80,7 @@ namespace Barotrauma
{
if (State != InfectionState.Active)
{
character.SetStun(Rand.Range(2, 4, Rand.RandSync.Server));
character.SetStun(Rand.Range(2, 4));
}
State = InfectionState.Active;
ActivateHusk();
@@ -101,7 +102,7 @@ namespace Barotrauma
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.IsSevered) { continue; }
float random = Rand.Value(Rand.RandSync.Server);
float random = Rand.Value();
huskInfection.Clear();
huskInfection.Add(AfflictionPrefab.InternalDamage.Instantiate(random * 10 * deltaTime / limbCount));
character.LastDamageSource = null;
@@ -68,13 +68,13 @@ namespace Barotrauma
HuskedSpeciesName = element.GetAttributeString("huskedspeciesname", null).ToLowerInvariant();
if (HuskedSpeciesName == null)
{
DebugConsole.NewMessage($"No 'huskedspeciesname' defined for the husk affliction ({Identifier}) in {element.ToString()}", Color.Orange);
DebugConsole.NewMessage($"No 'huskedspeciesname' defined for the husk affliction ({Identifier}) in {element}", Color.Orange);
HuskedSpeciesName = "[speciesname]husk";
}
TargetSpecies = element.GetAttributeStringArray("targets", new string[0] { }, trim: true, convertToLowerInvariant: true);
if (TargetSpecies.Length == 0)
{
DebugConsole.NewMessage($"No 'targets' defined for the husk affliction ({Identifier}) in {element.ToString()}", Color.Orange);
DebugConsole.NewMessage($"No 'targets' defined for the husk affliction ({Identifier}) in {element}", Color.Orange);
TargetSpecies = new string[] { "human" };
}
var attachElement = element.GetChildElement("attachlimb");
@@ -188,6 +188,30 @@ namespace Barotrauma
}
}
public class PeriodicEffect
{
public readonly List<StatusEffect> StatusEffects = new List<StatusEffect>();
public readonly float MinInterval, MaxInterval;
public PeriodicEffect(XElement element, string parentDebugName)
{
foreach (XElement subElement in element.Elements())
{
StatusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
}
if (element.Attribute("interval") != null)
{
MinInterval = MaxInterval = Math.Max(element.GetAttributeFloat("interval", 1.0f), 1.0f);
}
else
{
MinInterval = Math.Max(element.GetAttributeFloat("mininterval", 1.0f), 1.0f);
MaxInterval = Math.Max(element.GetAttributeFloat("maxinterval", 1.0f), MinInterval);
}
}
}
public static AfflictionPrefab InternalDamage;
public static AfflictionPrefab ImpactDamage;
public static AfflictionPrefab Bleeding;
@@ -267,8 +291,12 @@ namespace Barotrauma
public readonly Color[] IconColors;
private readonly List<Effect> effects = new List<Effect>();
private readonly List<PeriodicEffect> periodicEffects = new List<PeriodicEffect>();
public IEnumerable<Effect> Effects => effects;
public IList<PeriodicEffect> PeriodicEffects => periodicEffects;
private readonly string typeName;
private readonly ConstructorInfo constructor;
@@ -304,10 +332,10 @@ namespace Barotrauma
CharacterHealth.DamageOverlay = null;
CharacterHealth.DamageOverlayFile = string.Empty;
#endif
var prevPrefabs = Prefabs.ToList();
var prevPrefabs = Prefabs.AllPrefabs.SelectMany(kvp => kvp.Value).ToList();
foreach (var prefab in prevPrefabs)
{
prefab.Dispose();
prefab?.Dispose();
}
System.Diagnostics.Debug.Assert(Prefabs.Count() == 0, "All previous AfflictionPrefabs were not removed in AfflictionPrefab.LoadAll");
@@ -552,6 +580,9 @@ namespace Barotrauma
case "effect":
effects.Add(new Effect(subElement, Name));
break;
case "periodiceffect":
periodicEffects.Add(new PeriodicEffect(subElement, Name));
break;
}
}
@@ -170,12 +170,12 @@ namespace Barotrauma
{
get
{
if (!Character.NeedsOxygen || Unkillable) { return 100.0f; }
if (!Character.NeedsOxygen || Unkillable || Character.GodMode) { return 100.0f; }
return -oxygenLowAffliction.Strength + 100;
}
set
{
if (!Character.NeedsOxygen || Unkillable) { return; }
if (!Character.NeedsOxygen || Unkillable || Character.GodMode) { return; }
oxygenLowAffliction.Strength = MathHelper.Clamp(-value + 100, 0.0f, 200.0f);
}
}
@@ -399,7 +399,7 @@ namespace Barotrauma
public void ApplyAffliction(Limb targetLimb, Affliction affliction)
{
if (Unkillable) { return; }
if (Unkillable || Character.GodMode) { return; }
if (affliction.Prefab.LimbSpecific)
{
if (targetLimb == null)
@@ -481,7 +481,7 @@ namespace Barotrauma
public void ApplyDamage(Limb hitLimb, AttackResult attackResult)
{
if (Unkillable) { return; }
if (Unkillable || Character.GodMode) { return; }
if (hitLimb.HealthIndex < 0 || hitLimb.HealthIndex >= limbHealths.Count)
{
DebugConsole.ThrowError("Limb health index out of bounds. Character\"" + Character.Name +
@@ -504,7 +504,7 @@ namespace Barotrauma
public void SetAllDamage(float damageAmount, float bleedingDamageAmount, float burnDamageAmount)
{
if (Unkillable) { return; }
if (Unkillable || Character.GodMode) { return; }
foreach (LimbHealth limbHealth in limbHealths)
{
limbHealth.Afflictions.RemoveAll(a =>
@@ -741,7 +741,7 @@ namespace Barotrauma
public void CalculateVitality()
{
Vitality = MaxVitality;
if (Unkillable) { return; }
if (Unkillable || Character.GodMode) { return; }
float damageResistanceMultiplier = 1f - GetResistance("damage");
@@ -777,7 +777,7 @@ namespace Barotrauma
private void Kill()
{
if (Unkillable) { return; }
if (Unkillable || Character.GodMode) { return; }
var causeOfDeath = GetCauseOfDeath();
Character.Kill(causeOfDeath.First, causeOfDeath.Second);
@@ -913,6 +913,11 @@ namespace Barotrauma
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)
{
msg.WriteRangedSingle(affliction.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
}
}
limbAfflictions.Clear();
@@ -933,6 +938,11 @@ namespace Barotrauma
msg.WriteRangedSingle(
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(limbAffliction.Second.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
}
}
}