v0.13.0.11

This commit is contained in:
Joonas Rikkonen
2021-04-22 17:33:08 +03:00
parent 0697d7fc64
commit 8bb31f2893
391 changed files with 17271 additions and 5949 deletions
@@ -39,6 +39,66 @@ namespace Barotrauma
}
}
class AITrigger : ISerializableEntity
{
public string Name => "ai trigger";
public Dictionary<string, SerializableProperty> SerializableProperties { get; set; }
[Serialize(AIState.Idle, false)]
public AIState State { get; private set; }
[Serialize(0f, false)]
public float Duration { get; private set; }
[Serialize(1f, false)]
public float Probability { get; private set; }
[Serialize(0f, false)]
public float MinDamage { get; private set; }
[Serialize(true, false)]
public bool AllowToOverride { get; private set; }
[Serialize(true, false)]
public bool AllowToBeOverridden { get; private set; }
public bool IsTriggered { get; private set; }
public float Timer { get; private set; } = -1;
public bool IsActive { get; private set; }
public void Launch()
{
IsTriggered = true;
IsActive = true;
Timer = Duration;
}
public void Reset()
{
IsTriggered = false;
IsActive = false;
Timer = 0;
}
public void UpdateTimer(float deltaTime)
{
Timer -= deltaTime;
if (Timer < 0)
{
Timer = 0;
IsActive = false;
}
}
public AITrigger(XElement element)
{
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
}
}
partial class StatusEffect
{
[Flags]
@@ -53,7 +113,8 @@ namespace Barotrauma
UseTarget = 64,
Hull = 128,
Limb = 256,
AllLimbs = 512
AllLimbs = 512,
LastLimb = 1024
}
class ItemSpawnInfo
@@ -198,10 +259,11 @@ namespace Barotrauma
public readonly ActionType type = ActionType.OnActive;
private readonly List<Explosion> explosions;
public readonly List<Explosion> Explosions;
private readonly List<ItemSpawnInfo> spawnItems;
private readonly List<CharacterSpawnInfo> spawnCharacters;
private readonly List<AITrigger> aiTriggers;
private readonly List<EventPrefab> triggeredEvents;
private readonly string triggeredEventTargetTag = "statuseffecttarget",
@@ -219,12 +281,16 @@ namespace Barotrauma
public readonly bool OnlyInside;
public readonly bool OnlyOutside;
// Currently only used for OnDamaged. TODO: is there a better, more generic way to do this?
public readonly bool OnlyPlayerTriggered;
public HashSet<string> TargetIdentifiers
{
get { return targetIdentifiers; }
}
public HashSet<string> AllowedAfflictions { get; private set; }
public List<Affliction> Afflictions
{
get;
@@ -236,7 +302,9 @@ namespace Barotrauma
get { return spawnCharacters; }
}
private readonly List<Pair<string, float>> reduceAffliction;
public readonly List<Pair<string, float>> ReduceAffliction;
public float Duration => duration;
//only applicable if targeting NearbyCharacters or NearbyItems
public float Range
@@ -279,13 +347,15 @@ namespace Barotrauma
requiredItems = new List<RelatedItem>();
spawnItems = new List<ItemSpawnInfo>();
spawnCharacters = new List<CharacterSpawnInfo>();
aiTriggers = new List<AITrigger>();
Afflictions = new List<Affliction>();
explosions = new List<Explosion>();
Explosions = new List<Explosion>();
triggeredEvents = new List<EventPrefab>();
reduceAffliction = new List<Pair<string, float>>();
ReduceAffliction = new List<Pair<string, float>>();
tags = new HashSet<string>(element.GetAttributeString("tags", "").Split(','));
OnlyInside = element.GetAttributeBool("onlyinside", false);
OnlyOutside = element.GetAttributeBool("onlyoutside", false);
OnlyPlayerTriggered = element.GetAttributeBool("onlyplayertriggered", false);
Range = element.GetAttributeFloat("range", 0.0f);
Offset = element.GetAttributeVector2("offset", Vector2.Zero);
@@ -295,7 +365,7 @@ namespace Barotrauma
List<LimbType> targetLimbs = new List<LimbType>();
foreach (string targetLimbName in targetLimbNames)
{
if (Enum.TryParse(targetLimbName, out LimbType targetLimb)) { targetLimbs.Add(targetLimb); }
if (Enum.TryParse(targetLimbName, ignoreCase: true, out LimbType targetLimb)) { targetLimbs.Add(targetLimb); }
}
if (targetLimbs.Count > 0) { this.targetLimbs = targetLimbs.ToArray(); }
}
@@ -353,6 +423,14 @@ namespace Barotrauma
targetIdentifiers.Add(identifiers[i].Trim().ToLowerInvariant());
}
break;
case "allowedafflictions":
string[] types = attribute.Value.Split(',');
AllowedAfflictions = new HashSet<string>();
for (int i = 0; i < types.Length; i++)
{
AllowedAfflictions.Add(types[i].Trim().ToLowerInvariant());
}
break;
case "duration":
duration = attribute.GetAttributeFloat(0.0f);
break;
@@ -419,7 +497,7 @@ namespace Barotrauma
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "explosion":
explosions.Add(new Explosion(subElement, parentDebugName));
Explosions.Add(new Explosion(subElement, parentDebugName));
break;
case "fire":
FireSize = subElement.GetAttributeFloat("size", 10.0f);
@@ -494,7 +572,7 @@ namespace Barotrauma
if (subElement.Attribute("name") != null)
{
DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers or types instead of names.");
reduceAffliction.Add(new Pair<string, float>(
ReduceAffliction.Add(new Pair<string, float>(
subElement.GetAttributeString("name", "").ToLowerInvariant(),
subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount")));
}
@@ -505,7 +583,7 @@ namespace Barotrauma
if (AfflictionPrefab.List.Any(ap => ap.Identifier == name || ap.AfflictionType == name))
{
reduceAffliction.Add(new Pair<string, float>(
ReduceAffliction.Add(new Pair<string, float>(
name,
subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount")));
}
@@ -529,7 +607,6 @@ namespace Barotrauma
triggeredEvents.Add(prefab);
}
}
foreach (XElement eventElement in subElement.Elements())
{
if (!eventElement.Name.ToString().Equals("ScriptedEvent", StringComparison.OrdinalIgnoreCase)) { continue; }
@@ -540,6 +617,9 @@ namespace Barotrauma
var newSpawnCharacter = new CharacterSpawnInfo(subElement, parentDebugName);
if (!string.IsNullOrWhiteSpace(newSpawnCharacter.SpeciesName)) { spawnCharacters.Add(newSpawnCharacter); }
break;
case "aitrigger":
aiTriggers.Add(new AITrigger(subElement));
break;
}
}
InitProjSpecific(element, parentDebugName);
@@ -977,7 +1057,7 @@ namespace Barotrauma
}
}
foreach (Explosion explosion in explosions)
foreach (Explosion explosion in Explosions)
{
explosion.Explode(position, damageSource: entity, attacker: user);
}
@@ -990,12 +1070,11 @@ namespace Barotrauma
foreach (Affliction affliction in Afflictions)
{
if (Rand.Value(Rand.RandSync.Unsynced) > affliction.Probability) { continue; }
Affliction multipliedAffliction = affliction;
if (!disableDeltaTime)
Affliction newAffliction = affliction;
if (!disableDeltaTime && !setValue)
{
multipliedAffliction = affliction.CreateMultiplied(deltaTime);
newAffliction = affliction.CreateMultiplied(deltaTime);
}
if (target is Character character)
{
if (character.Removed) { continue; }
@@ -1005,7 +1084,7 @@ namespace Barotrauma
if (limb.Removed) { continue; }
if (limb.IsSevered) { continue; }
if (targetLimbs != null && !targetLimbs.Contains(limb.type)) { continue; }
AttackResult result = limb.character.DamageLimb(position, limb, multipliedAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
AttackResult result = limb.character.DamageLimb(position, limb, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source, allowStacking: !setValue);
limb.character.TrySeverLimbJoints(limb, SeverLimbsProbability, disableDeltaTime ? result.Damage : result.Damage / deltaTime, allowBeheading: true);
//only apply non-limb-specific afflictions to the first limb
if (!affliction.Prefab.LimbSpecific) { break; }
@@ -1015,21 +1094,21 @@ namespace Barotrauma
{
if (limb.IsSevered) { continue; }
if (limb.character.Removed || limb.Removed) { continue; }
AttackResult result = limb.character.DamageLimb(position, limb, multipliedAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
AttackResult result = limb.character.DamageLimb(position, limb, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source, allowStacking: !setValue);
limb.character.TrySeverLimbJoints(limb, SeverLimbsProbability, disableDeltaTime ? result.Damage : result.Damage / deltaTime, allowBeheading: true);
}
}
foreach (Pair<string, float> reduceAffliction in reduceAffliction)
foreach (Pair<string, float> reduceAffliction in ReduceAffliction)
{
float reduceAmount = disableDeltaTime ? reduceAffliction.Second : reduceAffliction.Second * deltaTime;
float reduceAmount = disableDeltaTime || setValue ? reduceAffliction.Second : reduceAffliction.Second * deltaTime;
Limb targetLimb = null;
Character targetCharacter = null;
if (target is Character character)
{
targetCharacter = character;
}
else if (target is Limb limb)
else if (target is Limb limb && !limb.Removed)
{
targetLimb = limb;
targetCharacter = limb.character;
@@ -1050,6 +1129,32 @@ namespace Barotrauma
#endif
}
}
if (aiTriggers.Any())
{
Character targetCharacter = target as Character;
if (targetCharacter == null)
{
if (target is Limb targetLimb && !targetLimb.Removed)
{
targetCharacter = targetLimb.character;
}
}
if (targetCharacter != null && !targetCharacter.Removed && !targetCharacter.IsPlayer)
{
if (targetCharacter.AIController is EnemyAIController enemyAI)
{
foreach (AITrigger trigger in aiTriggers)
{
if (Rand.Value(Rand.RandSync.Unsynced) > trigger.Probability) { continue; }
if (target is Limb targetLimb && targetCharacter.LastDamage.HitLimb != targetLimb) { continue; }
if (targetCharacter.LastDamage.Damage < trigger.MinDamage) { continue; }
enemyAI.LaunchTrigger(trigger);
break;
}
}
}
}
}
if (FireSize > 0.0f && entity != null)
@@ -1290,7 +1395,7 @@ namespace Barotrauma
foreach (Affliction affliction in element.Parent.Afflictions)
{
Affliction multipliedAffliction = affliction;
if (!element.Parent.disableDeltaTime) { multipliedAffliction = affliction.CreateMultiplied(deltaTime); }
if (!element.Parent.disableDeltaTime && !element.Parent.setValue) { multipliedAffliction = affliction.CreateMultiplied(deltaTime); }
if (target is Character character)
{
@@ -1304,7 +1409,7 @@ namespace Barotrauma
}
}
foreach (Pair<string, float> reduceAffliction in element.Parent.reduceAffliction)
foreach (Pair<string, float> reduceAffliction in element.Parent.ReduceAffliction)
{
Limb targetLimb = null;
Character targetCharacter = null;