Faction Test 100.4.0.0

This commit is contained in:
Markus Isberg
2022-11-14 18:28:28 +02:00
parent 87426b68b2
commit c772b61fc1
412 changed files with 16984 additions and 5530 deletions
@@ -1,6 +1,7 @@
using Barotrauma.Abilities;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System;
@@ -278,6 +279,13 @@ namespace Barotrauma
[Serialize(1, IsPropertySaveable.No)]
public int Count { get; private set; }
/// <summary>
/// The maximum amount of creatures of the same species in the same team that are allowed to be spawned via this status effect.
/// Also the creatures spawned by other means are counted in the check.
/// </summary>
[Serialize(0, IsPropertySaveable.No)]
public int TotalMaxCount { get; private set; }
[Serialize(0, IsPropertySaveable.No)]
public int Stun { get; private set; }
@@ -337,6 +345,8 @@ namespace Barotrauma
public float intervalTimer;
private readonly bool oneShot;
public static readonly List<DurationListElement> DurationList = new List<DurationListElement>();
/// <summary>
@@ -362,7 +372,7 @@ namespace Barotrauma
private readonly int useItemCount;
private readonly bool removeItem, dropContainedItems, removeCharacter, breakLimb, hideLimb;
private readonly bool removeItem, dropContainedItems, dropItem, removeCharacter, breakLimb, hideLimb;
private readonly float hideLimbTimer;
public readonly ActionType type = ActionType.OnActive;
@@ -379,7 +389,8 @@ namespace Barotrauma
private readonly List<EventPrefab> triggeredEvents;
private readonly Identifier triggeredEventTargetTag = "statuseffecttarget".ToIdentifier(),
triggeredEventEntityTag = "statuseffectentity".ToIdentifier();
triggeredEventEntityTag = "statuseffectentity".ToIdentifier(),
triggeredEventUserTag = "statuseffectuser".ToIdentifier();
private Character user;
@@ -457,6 +468,8 @@ namespace Barotrauma
}
}
public bool Disabled { get; private set; }
public static StatusEffect Load(ContentXElement element, string parentDebugName)
{
if (element.GetAttribute("delay") != null || element.GetAttribute("delaytype") != null)
@@ -608,6 +621,9 @@ namespace Barotrauma
propertyAttributes.Add(attribute);
}
break;
case "oneshot":
oneShot = attribute.GetAttributeBool(false);
break;
default:
propertyAttributes.Add(attribute);
break;
@@ -656,6 +672,9 @@ namespace Barotrauma
case "dropcontaineditems":
dropContainedItems = true;
break;
case "dropitem":
dropItem = true;
break;
case "removecharacter":
removeCharacter = true;
break;
@@ -866,10 +885,9 @@ namespace Barotrauma
return true;
}
public IReadOnlyList<ISerializableEntity> GetNearbyTargets(Vector2 worldPosition, List<ISerializableEntity> targets = null)
public void AddNearbyTargets(Vector2 worldPosition, List<ISerializableEntity> targets)
{
targets ??= new List<ISerializableEntity>();
if (Range <= 0.0f) { return targets; }
if (Range <= 0.0f) { return; }
if (HasTargetType(TargetType.NearbyCharacters))
{
foreach (Character c in Character.CharacterList)
@@ -906,7 +924,6 @@ namespace Barotrauma
}
}
}
return targets;
bool CheckDistance(ISpatialEntity e)
{
@@ -1113,6 +1130,7 @@ namespace Barotrauma
public virtual void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target, Vector2? worldPosition = null)
{
if (Disabled) { return; }
if (this.type != type || !HasRequiredItems(entity)) { return; }
if (!IsValidTarget(target)) { return; }
@@ -1137,6 +1155,7 @@ namespace Barotrauma
protected readonly List<ISerializableEntity> currentTargets = new List<ISerializableEntity>();
public virtual void Apply(ActionType type, float deltaTime, Entity entity, IReadOnlyList<ISerializableEntity> targets, Vector2? worldPosition = null)
{
if (Disabled) { return; }
if (this.type != type) { return; }
if (intervalTimer > 0.0f)
@@ -1241,6 +1260,7 @@ namespace Barotrauma
protected void Apply(float deltaTime, Entity entity, IReadOnlyList<ISerializableEntity> targets, Vector2? worldPosition = null)
{
if (Disabled) { return; }
if (lifeTime > 0)
{
lifeTimer -= deltaTime;
@@ -1282,6 +1302,16 @@ namespace Barotrauma
}
}
if (dropItem)
{
for (int i = 0; i < targets.Count; i++)
{
if (targets[i] is Item item)
{
item.Drop(dropper: null);
}
}
}
if (dropContainedItems)
{
for (int i = 0; i < targets.Count; i++)
@@ -1296,6 +1326,13 @@ namespace Barotrauma
}
}
}
else if (targets[i] is Character character && character.Inventory != null)
{
foreach (var containedItem in character.Inventory.AllItemsMod)
{
containedItem.Drop(dropper: null);
}
}
}
}
if (removeItem)
@@ -1333,17 +1370,20 @@ namespace Barotrauma
if (limb.body == sourceBody)
{
targetLimb = limb;
if (breakLimb)
{
character.TrySeverLimbJoints(limb, severLimbsProbability: 100, damage: 100, allowBeheading: true, attacker: user);
}
break;
}
}
}
if (hideLimb)
if (targetLimb != null)
{
targetLimb?.HideAndDisable(hideLimbTimer);
if (breakLimb)
{
targetLimb.character.TrySeverLimbJoints(targetLimb, severLimbsProbability: 1, damage: -1, allowBeheading: true, ignoreSeveranceProbabilityModifier: true, attacker: user);
}
if (hideLimb)
{
targetLimb.HideAndDisable(hideLimbTimer);
}
}
}
}
@@ -1475,6 +1515,9 @@ namespace Barotrauma
targetCharacter = targetLimb.character;
}
}
Character entityCharacter = entity as Character;
targetCharacter ??= entityCharacter;
if (targetCharacter != null && !targetCharacter.Removed && !targetCharacter.IsPlayer)
{
if (targetCharacter.AIController is EnemyAIController enemyAI)
@@ -1482,7 +1525,13 @@ namespace Barotrauma
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 (entityCharacter != targetCharacter)
{
if (target is Limb targetLimb && targetCharacter.LastDamage.HitLimb is Limb hitLimb)
{
if (hitLimb != targetLimb) { continue; }
}
}
if (targetCharacter.LastDamage.Damage < trigger.MinDamage) { continue; }
enemyAI.LaunchTrigger(trigger);
break;
@@ -1580,18 +1629,20 @@ namespace Barotrauma
{
if (!triggeredEventTargetTag.IsEmpty)
{
List<Entity> eventTargets = targets.Where(t => t is Entity).Cast<Entity>().ToList();
if (eventTargets.Count > 0)
IEnumerable<ISerializableEntity> eventTargets = targets.Where(t => t is Entity);
if (eventTargets.Any())
{
scriptedEvent.Targets.Add(triggeredEventTargetTag, eventTargets);
scriptedEvent.Targets.Add(triggeredEventTargetTag, eventTargets.Cast<Entity>().ToList());
}
}
if (!triggeredEventEntityTag.IsEmpty && entity != null)
{
scriptedEvent.Targets.Add(triggeredEventEntityTag, new List<Entity> { entity });
}
if (!triggeredEventUserTag.IsEmpty && user != null)
{
scriptedEvent.Targets.Add(triggeredEventUserTag, new List<Entity> { user });
}
}
}
}
@@ -1606,6 +1657,14 @@ namespace Barotrauma
Entity.Spawner.AddCharacterToSpawnQueue(characterSpawnInfo.SpeciesName, position + Rand.Vector(characterSpawnInfo.Spread, Rand.RandSync.Unsynced) + characterSpawnInfo.Offset,
onSpawn: newCharacter =>
{
if (characterSpawnInfo.TotalMaxCount > 0)
{
if (Character.CharacterList.Count(c => c.SpeciesName == characterSpawnInfo.SpeciesName && c.TeamID == newCharacter.TeamID) > characterSpawnInfo.TotalMaxCount)
{
Entity.Spawner?.AddEntityToRemoveQueue(newCharacter);
return;
}
}
if (newCharacter.AIController is EnemyAIController enemyAi &&
enemyAi.PetBehavior != null &&
entity is Item item &&
@@ -1666,11 +1725,11 @@ namespace Barotrauma
Character.Controlled = newCharacter;
}
#elif SERVER
/*foreach (Client c in GameMain.Server.ConnectedClients)
foreach (Client c in GameMain.Server.ConnectedClients)
{
if (c.Character != target) { continue; }
GameMain.Server.SetClientCharacter(c, newCharacter);
}*/
}
#endif
}
if (characterSpawnInfo.RemovePreviousCharacter) { Entity.Spawner?.AddEntityToRemoveQueue(character); }
@@ -1717,7 +1776,19 @@ namespace Barotrauma
}
float spread = Rand.Range(-chosenItemSpawnInfo.AimSpreadRad, chosenItemSpawnInfo.AimSpreadRad);
float rotation = chosenItemSpawnInfo.RotationRad;
Vector2 spawnPos = sourceBody != null ? sourceBody.SimPosition : entity.SimPosition;
Vector2 worldPos;
if (sourceBody != null)
{
worldPos = sourceBody.Position;
if (user?.Submarine != null)
{
worldPos += user.Submarine.Position;
}
}
else
{
worldPos = entity.WorldPosition;
}
switch (chosenItemSpawnInfo.RotationType)
{
case ItemSpawnInfo.SpawnRotationType.Fixed:
@@ -1731,7 +1802,7 @@ namespace Barotrauma
}
break;
case ItemSpawnInfo.SpawnRotationType.Target:
rotation = MathUtils.VectorToAngle(entity.SimPosition - spawnPos);
rotation = MathUtils.VectorToAngle(entity.WorldPosition - worldPos);
break;
case ItemSpawnInfo.SpawnRotationType.Limb:
if (sourceBody != null)
@@ -1775,6 +1846,15 @@ namespace Barotrauma
rotation += spread;
if (projectile != null)
{
Vector2 spawnPos;
if (projectile.Hitscan)
{
spawnPos = sourceBody != null ? sourceBody.SimPosition : entity.SimPosition;
}
else
{
spawnPos = ConvertUnits.ToSimUnits(worldPos);
}
projectile.Shoot(user, spawnPos, spawnPos, rotation,
ignoredBodies: user?.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true);
}
@@ -1797,9 +1877,15 @@ namespace Barotrauma
}
else if (entity is Item item)
{
var itemContainer = item.GetComponent<ItemContainer>();
inventory = itemContainer?.Inventory;
if (!chosenItemSpawnInfo.SpawnIfCantBeContained && !itemContainer.CanBeContained(chosenItemSpawnInfo.ItemPrefab))
foreach (ItemContainer itemContainer in item.GetComponents<ItemContainer>())
{
if (itemContainer.CanBeContained(chosenItemSpawnInfo.ItemPrefab))
{
inventory = itemContainer?.Inventory;
break;
}
}
if (!chosenItemSpawnInfo.SpawnIfCantBeContained && inventory == null)
{
return;
}
@@ -1883,6 +1969,10 @@ namespace Barotrauma
ApplyProjSpecific(deltaTime, entity, targets, hull, position, playSound: true);
intervalTimer = Interval;
if (oneShot)
{
Disabled = true;
}
static Character CharacterFromTarget(ISerializableEntity target)
{
@@ -2055,12 +2145,13 @@ namespace Barotrauma
if (entity is Item sourceItem && sourceItem.HasTag("medical"))
{
multiplier *= 1 + targetCharacter.GetStatValue(StatTypes.MedicalItemEffectivenessMultiplier);
if (user != null)
if (user is not null)
{
multiplier *= 1 + user.GetStatValue(StatTypes.MedicalItemApplyingMultiplier);
}
}
return multiplier * AfflictionMultiplier;
}
@@ -2072,6 +2163,18 @@ namespace Barotrauma
afflictionMultiplier *= targetCharacter.MaxVitality / 100f;
}
if (user is not null)
{
if (affliction.Prefab.IsBuff)
{
afflictionMultiplier *= 1 + user.GetStatValue(StatTypes.MedicalItemDurationMultiplier);
}
else if (affliction.Prefab.AfflictionType == "poison")
{
afflictionMultiplier *= 1 + user.GetStatValue(StatTypes.PoisonMultiplier);
}
}
if (!MathUtils.NearlyEqual(afflictionMultiplier, 1.0f))
{
return affliction.CreateMultiplied(afflictionMultiplier, affliction.Probability);
@@ -2088,7 +2191,7 @@ namespace Barotrauma
if (result.Afflictions != null && result.Afflictions.Any(a => a.Prefab == limbAffliction.Prefab) &&
(!affliction.Prefab.LimbSpecific || limb.character.CharacterHealth.GetAfflictionLimb(affliction) == limb))
{
if (type == ActionType.OnUse)
if (type == ActionType.OnUse || type == ActionType.OnSuccess)
{
limbAffliction.AppliedAsSuccessfulTreatmentTime = Timing.TotalTime;
}