Unstable 1.2.4.0

This commit is contained in:
Markus Isberg
2023-11-30 13:53:00 +02:00
parent 8a2e2ea0ae
commit fb5ea537bf
210 changed files with 4201 additions and 1283 deletions
@@ -7,7 +7,21 @@ namespace Barotrauma
{
class ScriptedEvent : Event
{
private readonly Dictionary<Identifier, List<Predicate<Entity>>> targetPredicates = new Dictionary<Identifier, List<Predicate<Entity>>>();
public sealed record TargetPredicate(
TargetPredicate.EntityType Type,
Predicate<Entity> Predicate)
{
public enum EntityType
{
Character,
Hull,
Item,
Structure,
Submarine
}
}
private readonly Dictionary<Identifier, List<TargetPredicate>> targetPredicates = new Dictionary<Identifier, List<TargetPredicate>>();
private readonly Dictionary<Identifier, List<Entity>> cachedTargets = new Dictionary<Identifier, List<Entity>>();
@@ -17,7 +31,7 @@ namespace Barotrauma
/// </summary>
private readonly Dictionary<Identifier, int> initialAmounts = new Dictionary<Identifier, int>();
private int prevEntityCount;
private bool newEntitySpawned;
private int prevPlayerCount, prevBotCount;
private Character prevControlled;
@@ -191,13 +205,13 @@ namespace Barotrauma
}
}
public void AddTargetPredicate(Identifier tag, Predicate<Entity> predicate)
public void AddTargetPredicate(Identifier tag, TargetPredicate.EntityType entityType, Predicate<Entity> predicate)
{
if (!targetPredicates.ContainsKey(tag))
{
targetPredicates.Add(tag, new List<Predicate<Entity>>());
targetPredicates.Add(tag, new List<TargetPredicate>());
}
targetPredicates[tag].Add(predicate);
targetPredicates[tag].Add(new TargetPredicate(entityType, predicate));
// force re-search for this tag
if (cachedTargets.ContainsKey(tag))
{
@@ -229,7 +243,6 @@ namespace Barotrauma
}
List<Entity> targetsToReturn = new List<Entity>();
if (Targets.ContainsKey(tag))
{
foreach (Entity e in Targets[tag])
@@ -240,11 +253,24 @@ namespace Barotrauma
}
if (targetPredicates.ContainsKey(tag))
{
foreach (Entity entity in Entity.GetEntities())
foreach (var targetPredicate in targetPredicates[tag])
{
if (targetPredicates[tag].Any(p => p(entity)) && !targetsToReturn.Contains(entity))
IEnumerable<Entity> entityList = targetPredicate.Type switch
{
targetsToReturn.Add(entity);
TargetPredicate.EntityType.Character => Character.CharacterList,
TargetPredicate.EntityType.Item => Item.ItemList,
TargetPredicate.EntityType.Structure => MapEntity.MapEntityList.Where(m => m is Structure),
TargetPredicate.EntityType.Hull => Hull.HullList,
TargetPredicate.EntityType.Submarine => Submarine.Loaded,
_ => Entity.GetEntities(),
};
foreach (Entity entity in entityList)
{
if (targetsToReturn.Contains(entity)) { continue; }
if (targetPredicate.Predicate(entity))
{
targetsToReturn.Add(entity);
}
}
}
}
@@ -293,14 +319,8 @@ namespace Barotrauma
{
int botCount = 0;
int playerCount = 0;
bool forceRefreshTargets = false;
foreach (Character c in Character.CharacterList)
{
if (c.Removed)
{
forceRefreshTargets = true;
continue;
}
if (c.IsPlayer)
{
playerCount++;
@@ -310,10 +330,11 @@ namespace Barotrauma
botCount++;
}
}
if (forceRefreshTargets || Entity.EntityCount != prevEntityCount || botCount != prevBotCount || playerCount != prevPlayerCount || prevControlled != Character.Controlled)
if (botCount != prevBotCount || playerCount != prevPlayerCount || prevControlled != Character.Controlled || NeedsToRefreshCachedTargets())
{
cachedTargets.Clear();
prevEntityCount = Entity.EntityCount;
newEntitySpawned = false;
prevBotCount = botCount;
prevPlayerCount = playerCount;
prevControlled = Character.Controlled;
@@ -369,6 +390,47 @@ namespace Barotrauma
}
}
private bool NeedsToRefreshCachedTargets()
{
if (newEntitySpawned) { return true; }
foreach (var cachedTargetList in cachedTargets.Values)
{
foreach (var target in cachedTargetList)
{
//one of the previously cached entities has been removed -> force refresh
if (target.Removed)
{
return true;
}
}
}
return false;
}
public void EntitySpawned(Entity entity)
{
if (newEntitySpawned) { return; }
if (entity is Character character &&
Level.Loaded?.StartOutpost != null &&
Level.Loaded.StartOutpost.Info.OutpostNPCs.Values.Any(npcList => npcList.Contains(character)))
{
newEntitySpawned = true;
return;
}
//new entity matches one of the existing predicates -> force refresh
foreach (var targetPredicateList in targetPredicates.Values)
{
foreach (var targetPredicate in targetPredicateList)
{
if (targetPredicate.Predicate(entity))
{
newEntitySpawned = true;
return;
}
}
}
}
public override bool LevelMeetsRequirements()
{
if (requiredDestinationTypes == null) { return true; }