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,9 +1,8 @@
using System;
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -11,6 +10,7 @@ namespace Barotrauma
{
public enum SpawnLocationType
{
Any,
MainSub,
Outpost,
MainPath,
@@ -40,7 +40,7 @@ namespace Barotrauma
[Serialize("", IsPropertySaveable.Yes, description: "Tag of an entity with an inventory to spawn the item into.")]
public Identifier TargetInventory { get; set; }
[Serialize(SpawnLocationType.MainSub, IsPropertySaveable.Yes)]
[Serialize(SpawnLocationType.Any, IsPropertySaveable.Yes)]
public SpawnLocationType SpawnLocation { get; set; }
[Serialize(SpawnType.Human, IsPropertySaveable.Yes)]
@@ -50,7 +50,7 @@ namespace Barotrauma
public Identifier SpawnPointTag { get; set; }
[Serialize(CharacterTeamType.FriendlyNPC, IsPropertySaveable.Yes)]
public CharacterTeamType Team { get; protected set; }
public CharacterTeamType TeamID { get; protected set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Should we spawn the entity even when no spawn points with matching tags were found?")]
public bool RequireSpawnPointTag { get; set; }
@@ -92,6 +92,8 @@ namespace Barotrauma
public SpawnAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
{
ignoreSpawnPointType = element.GetAttribute("spawnpointtype") == null;
//backwards compatibility
TeamID = element.GetAttributeEnum("teamtag", element.GetAttributeEnum<CharacterTeamType>("team", TeamID));
}
public override bool IsFinished(ref string goTo)
@@ -118,7 +120,28 @@ namespace Barotrauma
if (!NPCSetIdentifier.IsEmpty && !NPCIdentifier.IsEmpty)
{
HumanPrefab humanPrefab = NPCSet.Get(NPCSetIdentifier, NPCIdentifier);
HumanPrefab humanPrefab = null;
if (Level.Loaded?.StartLocation is Location startLocation)
{
humanPrefab =
TryFindHumanPrefab(startLocation.Faction) ??
TryFindHumanPrefab(startLocation.SecondaryFaction);
}
HumanPrefab TryFindHumanPrefab(Faction faction)
{
if (faction == null) { return null; }
return
NPCSet.Get(NPCSetIdentifier,
NPCIdentifier.Replace("[faction]".ToIdentifier(), faction.Prefab.Identifier),
logError: false) ??
//try to spawn a coalition NPC if a correct one can't be found
NPCSet.Get(NPCSetIdentifier,
NPCIdentifier.Replace("[faction]".ToIdentifier(), "coalition".ToIdentifier()),
logError: false);
}
humanPrefab ??= NPCSet.Get(NPCSetIdentifier, NPCIdentifier, logError: true);
if (humanPrefab != null)
{
if (!AllowDuplicates &&
@@ -130,11 +153,11 @@ namespace Barotrauma
ISpatialEntity spawnPos = GetSpawnPos();
if (spawnPos != null)
{
Entity.Spawner.AddCharacterToSpawnQueue(CharacterPrefab.HumanSpeciesName, OffsetSpawnPos(spawnPos.WorldPosition, Offset), humanPrefab.CreateCharacterInfo(), onSpawn: newCharacter =>
Entity.Spawner.AddCharacterToSpawnQueue(CharacterPrefab.HumanSpeciesName, OffsetSpawnPos(spawnPos.WorldPosition, Rand.Range(0.0f, Offset)), humanPrefab.CreateCharacterInfo(), onSpawn: newCharacter =>
{
if (newCharacter == null) { return; }
newCharacter.HumanPrefab = humanPrefab;
newCharacter.TeamID = Team;
newCharacter.TeamID = TeamID;
newCharacter.EnableDespawn = false;
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
if (LootingIsStealing)
@@ -151,6 +174,14 @@ namespace Barotrauma
ParentEvent.AddTarget(TargetTag, newCharacter);
}
spawnedEntity = newCharacter;
if (Level.Loaded?.StartOutpost?.Info is { } outPostInfo)
{
outPostInfo.AddOutpostNPCIdentifierOrTag(newCharacter, humanPrefab.Identifier);
foreach (Identifier tag in humanPrefab.GetTags())
{
outPostInfo.AddOutpostNPCIdentifierOrTag(newCharacter, tag);
}
}
});
}
}
@@ -165,7 +196,7 @@ namespace Barotrauma
ISpatialEntity spawnPos = GetSpawnPos();
if (spawnPos != null)
{
Entity.Spawner.AddCharacterToSpawnQueue(SpeciesName, OffsetSpawnPos(spawnPos.WorldPosition, Offset), onSpawn: newCharacter =>
Entity.Spawner.AddCharacterToSpawnQueue(SpeciesName, OffsetSpawnPos(spawnPos.WorldPosition, Rand.Range(0.0f, Offset)), onSpawn: newCharacter =>
{
if (!TargetTag.IsEmpty && newCharacter != null)
{
@@ -177,7 +208,7 @@ namespace Barotrauma
}
else if (!ItemIdentifier.IsEmpty)
{
if (!(MapEntityPrefab.FindByIdentifier(ItemIdentifier) is ItemPrefab itemPrefab))
if (MapEntityPrefab.FindByIdentifier(ItemIdentifier) is not ItemPrefab itemPrefab)
{
DebugConsole.ThrowError("Error in SpawnAction (item prefab \"" + ItemIdentifier + "\" not found)");
}
@@ -211,7 +242,7 @@ namespace Barotrauma
ISpatialEntity spawnPos = GetSpawnPos();
if (spawnPos != null)
{
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, OffsetSpawnPos(spawnPos.WorldPosition, Offset), onSpawned: onSpawned);
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, OffsetSpawnPos(spawnPos.WorldPosition, Rand.Range(0.0f, Offset)), onSpawned: onSpawned);
}
}
else
@@ -239,10 +270,10 @@ namespace Barotrauma
spawned = true;
}
public static Vector2 OffsetSpawnPos(Vector2 pos, float offsetAmount)
public static Vector2 OffsetSpawnPos(Vector2 pos, float offset)
{
Hull hull = Hull.FindHull(pos);
pos += Rand.Vector(offsetAmount);
Hull hull = Hull.FindHull(pos);
pos += Rand.Vector(offset);
if (hull != null)
{
float margin = 50.0f;
@@ -257,21 +288,11 @@ namespace Barotrauma
{
if (!SpawnPointTag.IsEmpty)
{
List<Item> potentialItems = SpawnLocation switch
{
SpawnLocationType.MainSub => Item.ItemList.FindAll(it => it.Submarine == Submarine.MainSub),
SpawnLocationType.MainPath => Item.ItemList.FindAll(it => it.Submarine == null),
SpawnLocationType.Outpost => Item.ItemList.FindAll(it => it.Submarine?.Info != null && it.Submarine.Info.IsOutpost),
SpawnLocationType.Wreck => Item.ItemList.FindAll(it => it.Submarine?.Info != null && it.Submarine.Info.IsWreck),
SpawnLocationType.Ruin => Item.ItemList.FindAll(it => it.Submarine?.Info != null && it.Submarine.Info.IsRuin),
SpawnLocationType.BeaconStation => Item.ItemList.FindAll(it => it.Submarine?.Info != null && it.Submarine.Info.IsBeacon),
_ => throw new NotImplementedException()
};
List<Item> potentialItems = Item.ItemList.FindAll(it => IsValidSubmarineType(SpawnLocation, it.Submarine));
var item = potentialItems.Where(it => it.HasTag(SpawnPointTag)).GetRandomUnsynced();
if (item != null) { return item; }
var target = ParentEvent.GetTargets(SpawnPointTag).GetRandomUnsynced();
var target = ParentEvent.GetTargets(SpawnPointTag).Where(t => IsValidSubmarineType(SpawnLocation, t.Submarine)).GetRandomUnsynced();
if (target != null) { return target; }
}
@@ -281,19 +302,26 @@ namespace Barotrauma
return GetSpawnPos(SpawnLocation, spawnPointType, targetModuleTags, SpawnPointTag.ToEnumerable(), requireTaggedSpawnPoint: RequireSpawnPointTag);
}
private static bool IsValidSubmarineType(SpawnLocationType spawnLocation, Submarine submarine)
{
return spawnLocation switch
{
SpawnLocationType.Any => true,
SpawnLocationType.MainSub => submarine == Submarine.MainSub,
SpawnLocationType.MainPath => submarine == null,
SpawnLocationType.Outpost => submarine is { Info: { IsOutpost: true } },
SpawnLocationType.Wreck => submarine is { Info: { IsWreck: true } },
SpawnLocationType.Ruin => submarine is { Info: { IsRuin: true } },
SpawnLocationType.BeaconStation => submarine?.Info?.BeaconStationInfo != null,
_ => throw new NotImplementedException(),
};
}
public static WayPoint GetSpawnPos(SpawnLocationType spawnLocation, SpawnType? spawnPointType, IEnumerable<Identifier> moduleFlags = null, IEnumerable<Identifier> spawnpointTags = null, bool asFarAsPossibleFromAirlock = false, bool requireTaggedSpawnPoint = false)
{
List<WayPoint> potentialSpawnPoints = spawnLocation switch
{
SpawnLocationType.MainSub => WayPoint.WayPointList.FindAll(wp => wp.Submarine == Submarine.MainSub && wp.CurrentHull != null),
SpawnLocationType.MainPath => WayPoint.WayPointList.FindAll(wp => wp.Submarine == null),
SpawnLocationType.Outpost => WayPoint.WayPointList.FindAll(wp => wp.Submarine?.Info != null && wp.CurrentHull != null && wp.Submarine.Info.IsOutpost),
SpawnLocationType.Wreck => WayPoint.WayPointList.FindAll(wp => wp.Submarine?.Info != null && wp.Submarine.Info.IsWreck),
SpawnLocationType.Ruin => WayPoint.WayPointList.FindAll(wp => wp.Submarine?.Info != null && wp.Submarine.Info.IsRuin),
SpawnLocationType.BeaconStation => WayPoint.WayPointList.FindAll(wp => wp.Submarine?.Info != null && wp.Submarine.Info.IsBeacon),
_ => throw new NotImplementedException()
};
bool requireHull = spawnLocation == SpawnLocationType.MainSub || spawnLocation == SpawnLocationType.Outpost;
List<WayPoint> potentialSpawnPoints = WayPoint.WayPointList.FindAll(wp => IsValidSubmarineType(spawnLocation, wp.Submarine) && (wp.CurrentHull != null || !requireHull));
potentialSpawnPoints = potentialSpawnPoints.FindAll(wp => wp.ConnectedDoor == null && wp.Ladders == null && !wp.isObstructed);
if (moduleFlags != null && moduleFlags.Any())