Unstable v0.19.1.0

This commit is contained in:
Juan Pablo Arce
2022-08-19 13:59:08 -03:00
parent 6b55adcdd9
commit 1219615d64
192 changed files with 3875 additions and 2648 deletions
@@ -87,11 +87,11 @@ namespace Barotrauma
if (_attackLimb != value)
{
_previousAttackLimb = _attackLimb;
_previousAttackLimb?.AttachedRope?.Snap();
if (_previousAttackLimb != null && _previousAttackLimb.attack.SnapRopeOnNewAttack) { _previousAttackLimb.AttachedRope?.Snap(); }
}
else if (_attackLimb != null && _attackLimb.attack.CoolDownTimer <= 0)
{
_attackLimb.AttachedRope?.Snap();
if (_attackLimb != null && _attackLimb.attack.SnapRopeOnNewAttack) { _attackLimb.AttachedRope?.Snap(); }
}
_attackLimb = value;
attackVector = null;
@@ -3660,7 +3660,7 @@ namespace Barotrauma
targetDir = Vector2.UnitY;
}
}
float margin = 30000;
float margin = Level.OutsideBoundsCurrentMargin;
if (pos.X < -margin)
{
// Too far left
@@ -197,6 +197,10 @@ namespace Barotrauma
return;
}
character.SelectedItem = null;
if (character.SelectedSecondaryItem != null && !character.SelectedSecondaryItem.IsLadder)
{
character.SelectedSecondaryItem = null;
}
if (Target is Entity e)
{
if (e.Removed)
@@ -1234,7 +1234,7 @@ namespace Barotrauma
{
//find the room which the limb is in
//the room where the ragdoll is in is used as the "guess", meaning that it's checked first
Hull limbHull = currentHull == null ? null : Hull.FindHull(limb.WorldPosition, currentHull);
Hull newHull = currentHull == null ? null : Hull.FindHull(limb.WorldPosition, currentHull);
bool prevInWater = limb.InWater;
limb.InWater = false;
@@ -1243,38 +1243,37 @@ namespace Barotrauma
{
limb.InWater = false;
}
else if (limbHull == null)
else if (newHull == null)
{
//limb isn't in any room -> it's in the water
limb.InWater = true;
if (limb.type == LimbType.Head) headInWater = true;
if (limb.type == LimbType.Head) { headInWater = true; }
}
else if (limbHull.WaterVolume > 0.0f && Submarine.RectContains(limbHull.Rect, limb.Position))
else if (newHull.WaterVolume > 0.0f && Submarine.RectContains(newHull.Rect, limb.Position))
{
if (limb.Position.Y < limbHull.Surface)
if (limb.Position.Y < newHull.Surface)
{
limb.InWater = true;
surfaceY = limbHull.Surface;
surfaceY = newHull.Surface;
if (limb.type == LimbType.Head)
{
headInWater = true;
}
}
//the limb has gone through the surface of the water
if (Math.Abs(limb.LinearVelocity.Y) > 5.0f && limb.InWater != prevInWater)
if (Math.Abs(limb.LinearVelocity.Y) > 5.0f && limb.InWater != prevInWater && newHull == limb.Hull)
{
Splash(limb, limbHull);
Splash(limb, newHull);
//if the Character dropped into water, create a wave
if (limb.LinearVelocity.Y < 0.0f)
{
Vector2 impulse = limb.LinearVelocity * limb.Mass;
int n = (int)((limb.Position.X - limbHull.Rect.X) / Hull.WaveWidth);
limbHull.WaveVel[n] += MathHelper.Clamp(impulse.Y, -5.0f, 5.0f);
int n = (int)((limb.Position.X - newHull.Rect.X) / Hull.WaveWidth);
newHull.WaveVel[n] += MathHelper.Clamp(impulse.Y, -5.0f, 5.0f);
}
}
}
limb.Hull = newHull;
limb.Update(deltaTime);
}
@@ -1492,12 +1491,12 @@ namespace Barotrauma
}
if (flowForce.LengthSquared() > 0.001f)
{
Collider.ApplyForce(flowForce);
{
Collider.ApplyForce(flowForce * (Collider.Mass / Mass));
foreach (Limb limb in limbs)
{
if (!limb.InWater) { continue; }
limb.body.ApplyForce(flowForce);
limb.body.ApplyForce(flowForce * (limb.Mass / Mass * limbs.Length));
}
}
}
@@ -100,6 +100,9 @@ namespace Barotrauma
[Serialize(false, IsPropertySaveable.Yes, description: "Should the AI try to turn around when aiming with this attack?"), Editable]
public bool Reverse { get; private set; }
[Serialize(true, IsPropertySaveable.Yes, description: "Should the rope attached to this limb snap upon choosing a new attack?"), Editable]
public bool SnapRopeOnNewAttack { get; private set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Should the AI try to steer away from the target when aiming with this attack? Best combined with PassiveAggressive behavior."), Editable]
public bool Retreat { get; private set; }
@@ -309,7 +312,7 @@ namespace Barotrauma
List<Affliction> multipliedAfflictions = new List<Affliction>();
foreach (Affliction affliction in Afflictions.Keys)
{
multipliedAfflictions.Add(affliction.CreateMultiplied(multiplier));
multipliedAfflictions.Add(affliction.CreateMultiplied(multiplier, affliction.Probability));
}
return multipliedAfflictions;
}
@@ -40,7 +40,7 @@ namespace Barotrauma
}
set
{
if (value == enabled) return;
if (value == enabled) { return; }
if (Removed)
{
@@ -63,6 +63,32 @@ namespace Barotrauma
}
}
private bool disabledByEvent;
/// <summary>
/// MonsterEvents disable monsters (which includes removing them from the character list, so they essentially "don't exist") until they're ready to spawn
/// </summary>
public bool DisabledByEvent
{
get { return disabledByEvent; }
set
{
if (value == disabledByEvent) { return; }
disabledByEvent = value;
if (disabledByEvent)
{
Enabled = false;
CharacterList.Remove(this);
if (AiTarget != null) { AITarget.List.Remove(AiTarget); }
}
else
{
if (!CharacterList.Contains(this)) { CharacterList.Add(this); }
if (AiTarget != null && !AITarget.List.Contains(AiTarget)) { AITarget.List.Add(AiTarget); }
}
}
}
public Hull PreviousHull = null;
public Hull CurrentHull = null;
@@ -1247,23 +1273,30 @@ namespace Barotrauma
if (Params.Husk && speciesName != "husk" && Prefab.VariantOf != "husk")
{
// Get the non husked name and find the ragdoll with it
var matchingAffliction = AfflictionPrefab.List
.Where(p => p is AfflictionPrefabHusk)
.Select(p => p as AfflictionPrefabHusk)
.FirstOrDefault(p => p.TargetSpecies.Any(t => t == AfflictionHusk.GetNonHuskedSpeciesName(speciesName, p)));
Identifier nonHuskedSpeciesName = Identifier.Empty;
if (matchingAffliction == null)
AfflictionPrefabHusk matchingAffliction = null;
foreach (var huskPrefab in AfflictionPrefab.Prefabs.OfType<AfflictionPrefabHusk>())
{
DebugConsole.ThrowError("Cannot find a husk infection that matches this species! Please add the speciesnames as 'targets' in the husk affliction prefab definition!");
var nonHuskedName = AfflictionHusk.GetNonHuskedSpeciesName(speciesName, huskPrefab);
if (huskPrefab.TargetSpecies.Contains(nonHuskedName))
{
var huskedSpeciesName = AfflictionHusk.GetHuskedSpeciesName(nonHuskedName, huskPrefab);
if (huskedSpeciesName.Equals(speciesName))
{
nonHuskedSpeciesName = nonHuskedName;
matchingAffliction = huskPrefab;
break;
}
}
}
if (matchingAffliction == null || nonHuskedSpeciesName.IsEmpty)
{
DebugConsole.ThrowError($"Cannot find a husk infection that matches {speciesName}! Please make sure that the speciesname is added as 'targets' in the husk affliction prefab definition!\n"
+ "Note that all the infected speciesnames and files must stick the following pattern: [nonhuskedspeciesname][huskedspeciesname]. E.g. Humanhusk, Crawlerhusk, or Humancustomhusk, or Crawlerzombie. Not \"Customhumanhusk!\" or \"Zombiecrawler\"");
// Crashes if we fail to create a ragdoll -> Let's just use some ragdoll so that the user sees the error msg.
nonHuskedSpeciesName = IsHumanoid ? CharacterPrefab.HumanSpeciesName : "crawler".ToIdentifier();
speciesName = nonHuskedSpeciesName;
}
else
{
nonHuskedSpeciesName = AfflictionHusk.GetNonHuskedSpeciesName(speciesName, matchingAffliction);
}
if (ragdollParams == null && prefab.VariantOf == null)
{
Identifier name = Params.UseHuskAppendage ? nonHuskedSpeciesName : speciesName;
@@ -1287,6 +1287,11 @@ namespace Barotrauma
if (splitTag[0] != "name") { continue; }
if (splitTag[1] != Name) { continue; }
item.ReplaceTag(tag, $"name:{newName}");
var idCard = item.GetComponent<IdCard>();
if (idCard != null)
{
idCard.OwnerName = newName;
}
break;
}
}
@@ -50,6 +50,9 @@ namespace Barotrauma
[Serialize(1.0f, IsPropertySaveable.Yes, description: "The probability for the affliction to be applied."), Editable(minValue: 0f, maxValue: 1f)]
public float Probability { get; set; } = 1.0f;
[Serialize(true, IsPropertySaveable.Yes, description: "Explosion damage is applied per each affected limb. Should this affliction damage be divided by the count of affected limbs (1-15) or applied in full? Default: true. Only affects explosions."), Editable]
public bool DivideByLimbCount { get; set; }
public float DamagePerSecond;
public float DamagePerSecondTimer;
public float PreviousVitalityDecrease;
@@ -96,9 +99,11 @@ namespace Barotrauma
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
}
public Affliction CreateMultiplied(float multiplier)
public Affliction CreateMultiplied(float multiplier, float probability)
{
return Prefab.Instantiate(NonClampedStrength * multiplier, Source);
var instance = Prefab.Instantiate(NonClampedStrength * multiplier, Source);
instance.Probability = probability;
return instance;
}
public override string ToString() => Prefab == null ? "Affliction (Invalid)" : $"Affliction ({Prefab.Name})";
@@ -450,13 +450,12 @@ namespace Barotrauma
public static Identifier GetHuskedSpeciesName(Identifier speciesName, AfflictionPrefabHusk prefab)
{
return prefab.HuskedSpeciesName.Replace(AfflictionPrefabHusk.Tag, speciesName);
return new Identifier(speciesName.Value + prefab.HuskedSpeciesName.Value);
}
public static Identifier GetNonHuskedSpeciesName(Identifier huskedSpeciesName, AfflictionPrefabHusk prefab)
{
Identifier nonTag = prefab.HuskedSpeciesName.Remove(AfflictionPrefabHusk.Tag);
return huskedSpeciesName.Remove(nonTag);
return huskedSpeciesName.Remove(prefab.HuskedSpeciesName);
}
}
}
@@ -63,8 +63,10 @@ namespace Barotrauma
if (HuskedSpeciesName.IsEmpty)
{
DebugConsole.NewMessage($"No 'huskedspeciesname' defined for the husk affliction ({Identifier}) in {element}", Color.Orange);
HuskedSpeciesName = "[speciesname]husk".ToIdentifier();
HuskedSpeciesName = "husk".ToIdentifier();
}
// Remove "[speciesname]" for backward support (we don't use it anymore)
HuskedSpeciesName = HuskedSpeciesName.Remove("[speciesname]").ToIdentifier();
TargetSpecies = element.GetAttributeIdentifierArray("targets", Array.Empty<Identifier>(), trim: true);
if (TargetSpecies.Length == 0)
{
@@ -108,7 +110,6 @@ namespace Barotrauma
public readonly Identifier HuskedSpeciesName;
public readonly Identifier[] TargetSpecies;
public static readonly Identifier Tag = "[speciesname]".ToIdentifier();
public readonly bool TransferBuffs;
public readonly bool SendMessages;
@@ -404,8 +405,18 @@ namespace Barotrauma
AfflictionType = element.GetAttributeIdentifier("type", "");
TranslationIdentifier = element.GetAttributeIdentifier("translationoverride", Identifier);
Name = TextManager.Get($"AfflictionName.{TranslationIdentifier}").Fallback(element.GetAttributeString("name", ""));
Description = TextManager.Get($"AfflictionDescription.{TranslationIdentifier}").Fallback(element.GetAttributeString("description", ""));
Name = TextManager.Get($"AfflictionName.{TranslationIdentifier}");
string fallbackName = element.GetAttributeString("name", "");
if (!string.IsNullOrEmpty(fallbackName))
{
Name = Name.Fallback(fallbackName);
}
Description = TextManager.Get($"AfflictionDescription.{TranslationIdentifier}");
string fallbackDescription = element.GetAttributeString("description", "");
if (!string.IsNullOrEmpty(fallbackDescription))
{
Description = Description.Fallback(fallbackDescription);
}
IsBuff = element.GetAttributeBool("isbuff", false);
HealableInMedicalClinic = element.GetAttributeBool("healableinmedicalclinic",
@@ -909,19 +909,11 @@ namespace Barotrauma
float vitalityDecrease = affliction.GetVitalityDecrease(this);
if (limbHealth != null)
{
if (limbHealth.VitalityMultipliers.ContainsKey(affliction.Prefab.Identifier))
{
vitalityDecrease *= limbHealth.VitalityMultipliers[affliction.Prefab.Identifier];
}
if (limbHealth.VitalityTypeMultipliers.ContainsKey(affliction.Prefab.AfflictionType))
{
vitalityDecrease *= limbHealth.VitalityTypeMultipliers[affliction.Prefab.AfflictionType];
}
vitalityDecrease *= GetVitalityMultiplier(affliction, limbHealth);
}
Vitality -= vitalityDecrease;
affliction.CalculateDamagePerSecond(vitalityDecrease);
}
#if CLIENT
if (IsUnconscious)
{
@@ -930,6 +922,33 @@ namespace Barotrauma
#endif
}
private float GetVitalityMultiplier(Affliction affliction, LimbHealth limbHealth)
{
float multiplier = 1.0f;
if (limbHealth.VitalityMultipliers.TryGetValue(affliction.Prefab.Identifier, out float vitalityMultiplier))
{
multiplier *= vitalityMultiplier;
}
if (limbHealth.VitalityTypeMultipliers.TryGetValue(affliction.Prefab.AfflictionType, out float vitalityTypeMultiplier))
{
multiplier *= vitalityTypeMultiplier;
}
return multiplier;
}
/// <summary>
/// How much vitality the affliction reduces, taking into account the effects of vitality modifiers on the limb the affliction is on (if limb-based)
/// </summary>
private float GetVitalityDecreaseWithVitalityMultipliers(Affliction affliction)
{
float vitalityDecrease = affliction.GetVitalityDecrease(this);
if (afflictions.TryGetValue(affliction, out LimbHealth limbHealth) && limbHealth != null)
{
vitalityDecrease *= GetVitalityMultiplier(affliction, limbHealth);
}
return vitalityDecrease;
}
private void Kill()
{
if (Unkillable || Character.GodMode) { return; }
@@ -218,6 +218,8 @@ namespace Barotrauma
public Vector2 StepOffset => ConvertUnits.ToSimUnits(Params.StepOffset) * ragdoll.RagdollParams.JointScale;
public Hull Hull;
public bool InWater { get; set; }
private FixedMouseJoint pullJoint;
@@ -720,11 +722,12 @@ namespace Barotrauma
tempModifiers.Clear();
var newAffliction = affliction;
float random = Rand.Value(Rand.RandSync.Unsynced);
if (random > affliction.Probability) { continue; }
bool foundMatchingModifier = false;
bool applyAffliction = true;
foreach (DamageModifier damageModifier in DamageModifiers)
{
if (!damageModifier.MatchesAffliction(affliction)) { continue; }
foundMatchingModifier = true;
if (random > affliction.Probability * damageModifier.ProbabilityMultiplier)
{
applyAffliction = false;
@@ -740,6 +743,7 @@ namespace Barotrauma
foreach (DamageModifier damageModifier in wearable.WearableComponent.DamageModifiers)
{
if (!damageModifier.MatchesAffliction(affliction)) { continue; }
foundMatchingModifier = true;
if (random > affliction.Probability * damageModifier.ProbabilityMultiplier)
{
applyAffliction = false;
@@ -751,6 +755,7 @@ namespace Barotrauma
}
}
}
if (!foundMatchingModifier && random > affliction.Probability) { continue; }
float finalDamageModifier = damageMultiplier;
foreach (DamageModifier damageModifier in tempModifiers)
{
@@ -763,7 +768,7 @@ namespace Barotrauma
}
if (!MathUtils.NearlyEqual(finalDamageModifier, 1.0f))
{
newAffliction = affliction.CreateMultiplied(finalDamageModifier);
newAffliction = affliction.CreateMultiplied(finalDamageModifier, affliction.Probability);
}
else
{