Unstable 0.1500.5.0 (almost forgor edition 💀)

This commit is contained in:
Markus Isberg
2021-10-01 23:56:14 +09:00
parent 3043a9a7bc
commit 08bdfc6cea
150 changed files with 5669 additions and 4403 deletions
@@ -226,11 +226,11 @@ namespace Barotrauma
List<Item> potentialItems = SpawnLocation switch
{
SpawnLocationType.MainSub => Item.ItemList.FindAll(it => it.Submarine == Submarine.MainSub),
SpawnLocationType.MainPath => Item.ItemList.FindAll(it => it.Submarine == null && it.ParentRuin == null),
SpawnLocationType.Outpost => Item.ItemList.FindAll(it => it.Submarine != null && it.Submarine.Info.IsOutpost),
SpawnLocationType.Wreck => Item.ItemList.FindAll(it => it.Submarine != null && it.Submarine.Info.IsWreck),
SpawnLocationType.Ruin => Item.ItemList.FindAll(it => it.ParentRuin != null),
SpawnLocationType.BeaconStation => Item.ItemList.FindAll(it => it.Submarine != null && it.Submarine.Info.IsBeacon),
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()
};
@@ -252,11 +252,11 @@ namespace Barotrauma
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 && wp.ParentRuin == null),
SpawnLocationType.Outpost => WayPoint.WayPointList.FindAll(wp => wp.Submarine != null && wp.CurrentHull != null && wp.Submarine.Info.IsOutpost),
SpawnLocationType.Wreck => WayPoint.WayPointList.FindAll(wp => wp.Submarine != null && wp.Submarine.Info.IsWreck),
SpawnLocationType.Ruin => WayPoint.WayPointList.FindAll(wp => wp.ParentRuin != null),
SpawnLocationType.BeaconStation => WayPoint.WayPointList.FindAll(wp => wp.Submarine != null && wp.Submarine.Info.IsBeacon),
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()
};
@@ -981,6 +981,7 @@ namespace Barotrauma
return false;
case SubmarineType.Wreck:
case SubmarineType.BeaconStation:
case SubmarineType.Ruin:
return true;
}
}
@@ -0,0 +1,176 @@
using Barotrauma.Extensions;
using Barotrauma.RuinGeneration;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
partial class AlienRuinMission : Mission
{
private readonly string[] targetItemIdentifiers;
private readonly string[] targetEnemyIdentifiers;
private readonly int minEnemyCount;
private readonly HashSet<Entity> existingTargets = new HashSet<Entity>();
private readonly HashSet<Character> spawnedTargets = new HashSet<Character>();
private readonly HashSet<Entity> allTargets = new HashSet<Entity>();
private Ruin TargetRuin { get; set; }
public override IEnumerable<Vector2> SonarPositions
{
get
{
if (State == 0)
{
return allTargets.Where(t => (t is Item i && !IsItemDestroyed(i)) || (t is Character c && !IsEnemyDefeated(c))).Select(t => t.WorldPosition);
}
else
{
return Enumerable.Empty<Vector2>();
}
}
}
public AlienRuinMission(MissionPrefab prefab, Location[] locations, Submarine sub) : base(prefab, locations, sub)
{
targetItemIdentifiers = prefab.ConfigElement.GetAttributeStringArray("targetitems", new string[0], convertToLowerInvariant: true);
targetEnemyIdentifiers = prefab.ConfigElement.GetAttributeStringArray("targetenemies", new string[0], convertToLowerInvariant: true);
minEnemyCount = prefab.ConfigElement.GetAttributeInt("minenemycount", 0);
}
protected override void StartMissionSpecific(Level level)
{
existingTargets.Clear();
spawnedTargets.Clear();
allTargets.Clear();
if (IsClient) { return; }
TargetRuin = Level.Loaded?.Ruins?.GetRandom(randSync: Rand.RandSync.Server);
if (TargetRuin == null)
{
DebugConsole.ThrowError($"Failed to initialize an Alien Ruin mission (\"{Prefab.Identifier}\"): level contains no alien ruins");
return;
}
if (targetItemIdentifiers.Length < 1 && targetEnemyIdentifiers.Length < 1)
{
DebugConsole.ThrowError($"Failed to initialize an Alien Ruin mission (\"{Prefab.Identifier}\"): no target identifiers set in the mission definition");
return;
}
foreach (var item in Item.ItemList)
{
if (!targetItemIdentifiers.Contains(item.Prefab.Identifier)) { continue; }
if (item.Submarine != TargetRuin.Submarine) { continue; }
existingTargets.Add(item);
allTargets.Add(item);
}
int existingEnemyCount = 0;
foreach (var character in Character.CharacterList)
{
if (string.IsNullOrEmpty(character.SpeciesName)) { continue; }
if (!targetEnemyIdentifiers.Contains(character.SpeciesName.ToLowerInvariant())) { continue; }
if (character.Submarine != TargetRuin.Submarine) { continue; }
existingTargets.Add(character);
allTargets.Add(character);
existingEnemyCount++;
}
if (existingEnemyCount < minEnemyCount)
{
var enemyPrefabs = new HashSet<CharacterPrefab>();
foreach (string identifier in targetEnemyIdentifiers)
{
var prefab = CharacterPrefab.FindBySpeciesName(identifier);
if (prefab != null)
{
enemyPrefabs.Add(prefab);
}
else
{
DebugConsole.ThrowError($"Error in an Alien Ruin mission (\"{Prefab.Identifier}\"): could not find a character prefab with the species \"{identifier}\"");
}
}
if (enemyPrefabs.None())
{
DebugConsole.ThrowError($"Error in an Alien Ruin mission (\"{Prefab.Identifier}\"): no enemy species defined that could be used to spawn more ({minEnemyCount - existingEnemyCount}) enemies");
return;
}
for (int i = 0; i < (minEnemyCount - existingEnemyCount); i++)
{
var prefab = enemyPrefabs.GetRandom();
var spawnPos = TargetRuin.Submarine.GetWaypoints(false).GetRandom(w => w.CurrentHull != null)?.WorldPosition;
if (!spawnPos.HasValue)
{
DebugConsole.ThrowError($"Error in an Alien Ruin mission (\"{Prefab.Identifier}\"): no valid spawn positions could be found for the additional ({minEnemyCount - existingEnemyCount}) enemies to be spawned");
return;
}
var newEnemy = Character.Create(prefab.Identifier, spawnPos.Value, ToolBox.RandomSeed(8), createNetworkEvent: false);
spawnedTargets.Add(newEnemy);
allTargets.Add(newEnemy);
}
}
#if DEBUG
DebugConsole.NewMessage("********** CLEAR RUIN MISSION INFO **********");
DebugConsole.NewMessage($"Existing item targets: {existingTargets.Count - existingEnemyCount}");
DebugConsole.NewMessage($"Existing enemy targets: {existingEnemyCount}");
DebugConsole.NewMessage($"Spawned enemy targets: {spawnedTargets.Count}");
#endif
}
protected override void UpdateMissionSpecific(float deltaTime)
{
if (IsClient) { return; }
switch (State)
{
case 0:
if (!AllTargetsEliminated()) { return; }
State = 1;
break;
case 1:
if (!Submarine.MainSub.AtEndExit && !Submarine.MainSub.AtStartExit) { return; }
State = 2;
break;
}
}
private bool AllTargetsEliminated()
{
foreach (var target in allTargets)
{
if (target is Item targetItem)
{
if (!IsItemDestroyed(targetItem))
{
return false;
}
}
else if (target is Character targetEnemy)
{
if (!IsEnemyDefeated(targetEnemy))
{
return false;
}
}
#if DEBUG
else
{
DebugConsole.ThrowError($"Error in Alien Ruin mission (\"{Prefab.Identifier}\"): unexpected target of type {target?.GetType()?.ToString()}");
}
#endif
}
return true;
}
private bool IsItemDestroyed(Item item) => item == null || item.Removed || item.Condition <= 0.0f;
private bool IsEnemyDefeated(Character enemy) => enemy == null ||enemy.Removed || enemy.IsDead;
public override void End()
{
if (AllTargetsEliminated())
{
GiveReward();
completed = true;
}
failed = !completed && state > 0;
}
}
}
@@ -198,55 +198,14 @@ namespace Barotrauma
if (requiredDeliveryAmount <= 0.0f) { requiredDeliveryAmount = 1.0f; }
}
private ItemPrefab FindItemPrefab(XElement element)
{
ItemPrefab itemPrefab;
if (element.Attribute("name") != null)
{
DebugConsole.ThrowError("Error in cargo mission \"" + Name + "\" - use item identifiers instead of names to configure the items.");
string itemName = element.GetAttributeString("name", "");
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
if (itemPrefab == null)
{
DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemName + "\" not found");
}
}
else
{
string itemIdentifier = element.GetAttributeString("identifier", "");
itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
if (itemPrefab == null)
{
DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemIdentifier + "\" not found");
}
}
return itemPrefab;
}
private void LoadItemAsChild(XElement element, Item parent)
{
ItemPrefab itemPrefab = FindItemPrefab(element);
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, useSyncedRand: true);
if (cargoSpawnPos == null)
{
DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found");
return;
}
Vector2? position = GetCargoSpawnPosition(itemPrefab, out Submarine cargoRoomSub);
if (!position.HasValue) { return; }
var cargoRoom = cargoSpawnPos.CurrentHull;
if (cargoRoom == null)
{
DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!");
return;
}
Vector2 position = new Vector2(
cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, Rand.RandSync.Server),
cargoRoom.Rect.Y - cargoRoom.Rect.Height + itemPrefab.Size.Y / 2);
var item = new Item(itemPrefab, position, cargoRoom.Submarine)
var item = new Item(itemPrefab, position.Value, cargoRoomSub)
{
SpawnedInOutpost = true,
AllowStealing = false
@@ -27,7 +27,7 @@ namespace Barotrauma
state = value;
TryTriggerEvents(state);
#if SERVER
GameMain.Server?.UpdateMissionState(this, state);
GameMain.Server?.UpdateMissionState(this);
#endif
ShowMessage(State);
}
@@ -347,7 +347,10 @@ namespace Barotrauma
if (!(GameMain.GameSession.GameMode is CampaignMode campaign)) { return; }
int reward = GetReward(Submarine.MainSub);
float baseExperienceGain = reward * 0.15f;
float baseExperienceGain = reward * 0.1f;
float difficultyMultiplier = 1 + level.Difficulty / 100f;
baseExperienceGain *= difficultyMultiplier;
IEnumerable<Character> crewCharacters = GameSession.GetSessionCrewCharacters();
@@ -471,5 +474,55 @@ namespace Barotrauma
return spawnedCharacter;
}
protected ItemPrefab FindItemPrefab(XElement element)
{
ItemPrefab itemPrefab;
if (element.Attribute("name") != null)
{
DebugConsole.ThrowError($"Error in mission \"{Name}\" - use item identifiers instead of names to configure the items");
string itemName = element.GetAttributeString("name", "");
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
if (itemPrefab == null)
{
DebugConsole.ThrowError($"Couldn't spawn item for mission \"{Name}\": item prefab \"{itemName}\" not found");
}
}
else
{
string itemIdentifier = element.GetAttributeString("identifier", "");
itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
if (itemPrefab == null)
{
DebugConsole.ThrowError($"Couldn't spawn item for mission \"{Name}\": item prefab \"{itemIdentifier}\" not found");
}
}
return itemPrefab;
}
protected Vector2? GetCargoSpawnPosition(ItemPrefab itemPrefab, out Submarine cargoRoomSub)
{
cargoRoomSub = null;
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, useSyncedRand: true);
if (cargoSpawnPos == null)
{
DebugConsole.ThrowError($"Couldn't spawn items for mission \"{Name}\": no waypoints marked as Cargo were found");
return null;
}
var cargoRoom = cargoSpawnPos.CurrentHull;
if (cargoRoom == null)
{
DebugConsole.ThrowError($"Couldn't spawn items for mission \"{Name}\": waypoints marked as Cargo must be placed inside a room");
return null;
}
cargoRoomSub = cargoRoom.Submarine;
return new Vector2(
cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, Rand.RandSync.Server),
cargoRoom.Rect.Y - cargoRoom.Rect.Height + itemPrefab.Size.Y / 2);
}
}
}
@@ -22,7 +22,9 @@ namespace Barotrauma
Escort = 0x100,
Pirate = 0x200,
GoTo = 0x400,
All = Salvage | Monster | Cargo | Beacon | Nest | Mineral | Combat | AbandonedOutpost | Escort | Pirate | GoTo
ScanAlienRuins = 0x800,
ClearAlienRuins = 0x1000,
All = Salvage | Monster | Cargo | Beacon | Nest | Mineral | Combat | AbandonedOutpost | Escort | Pirate | GoTo | ScanAlienRuins | ClearAlienRuins
}
partial class MissionPrefab
@@ -40,7 +42,9 @@ namespace Barotrauma
{ MissionType.AbandonedOutpost, typeof(AbandonedOutpostMission) },
{ MissionType.Escort, typeof(EscortMission) },
{ MissionType.Pirate, typeof(PirateMission) },
{ MissionType.GoTo, typeof(GoToMission) }
{ MissionType.GoTo, typeof(GoToMission) },
{ MissionType.ScanAlienRuins, typeof(ScanMission) },
{ MissionType.ClearAlienRuins, typeof(AlienRuinMission) }
};
public static readonly Dictionary<MissionType, Type> PvPMissionClasses = new Dictionary<MissionType, Type>()
{
@@ -372,6 +376,11 @@ namespace Barotrauma
var connection = from.Connections.Find(c => c.Locations.Contains(from) && c.Locations.Contains(to));
if (connection?.LevelData == null || !connection.LevelData.HasBeaconStation || connection.LevelData.IsBeaconActive) { return false; }
}
else if (Type == MissionType.ScanAlienRuins || Type == MissionType.ClearAlienRuins)
{
var connection = from.Connections.Find(c => c.Locations.Contains(from) && c.Locations.Contains(to));
if (connection?.LevelData == null || connection.LevelData.GenerationParams.RuinCount < 1) { return false; }
}
return false;
}
@@ -126,12 +126,12 @@ namespace Barotrauma
item = suitableItems.FirstOrDefault(it => Vector2.DistanceSquared(it.WorldPosition, position) < 1000.0f);
break;
case Level.PositionType.Ruin:
item = suitableItems.FirstOrDefault(it => it.ParentRuin != null && it.ParentRuin.Area.Contains(position));
break;
case Level.PositionType.Wreck:
foreach (Item it in suitableItems)
{
if (it.Submarine == null || it.Submarine.Info.Type != SubmarineType.Wreck) { continue; }
if (it.Submarine?.Info == null) { continue; }
if (spawnPositionType == Level.PositionType.Ruin && it.Submarine.Info.Type != SubmarineType.Ruin) { continue; }
if (spawnPositionType == Level.PositionType.Wreck && it.Submarine.Info.Type != SubmarineType.Wreck) { continue; }
Rectangle worldBorders = it.Submarine.Borders;
worldBorders.Location += it.Submarine.WorldPosition.ToPoint();
if (Submarine.RectContains(worldBorders, it.WorldPosition))
@@ -178,10 +178,10 @@ namespace Barotrauma
{
case Level.PositionType.Cave:
case Level.PositionType.MainPath:
if (it.Submarine != null || it.ParentRuin != null) { continue; }
if (it.Submarine != null) { continue; }
break;
case Level.PositionType.Ruin:
if (it.ParentRuin == null) { continue; }
if (it.Submarine?.Info == null || !it.Submarine.Info.IsRuin) { continue; }
break;
case Level.PositionType.Wreck:
if (it.Submarine == null || it.Submarine.Info.Type != SubmarineType.Wreck) { continue; }
@@ -0,0 +1,258 @@
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.RuinGeneration;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
partial class ScanMission : Mission
{
private readonly XElement itemConfig;
private readonly List<Item> startingItems = new List<Item>();
private readonly List<Scanner> scanners = new List<Scanner>();
private readonly Dictionary<Item, ushort> parentInventoryIDs = new Dictionary<Item, ushort>();
private readonly Dictionary<Item, byte> parentItemContainerIndices = new Dictionary<Item, byte>();
private readonly int targetsToScan;
private readonly Dictionary<WayPoint, bool> scanTargets = new Dictionary<WayPoint, bool>();
private readonly HashSet<WayPoint> newTargetsScanned = new HashSet<WayPoint>();
private readonly float minTargetDistance, minTargetDistanceSquared;
private Ruin TargetRuin { get; set; }
private bool AllTargetsScanned
{
get
{
return scanTargets.Any() && scanTargets.All(kvp => kvp.Value);
}
}
public override IEnumerable<Vector2> SonarPositions
{
get
{
if (State > 0)
{
return Enumerable.Empty<Vector2>();
}
else if (scanTargets.Any())
{
return scanTargets
.Where(kvp => !kvp.Value)
.Select(kvp => kvp.Key.WorldPosition);
}
else
{
return Enumerable.Empty<Vector2>();
}
}
}
public ScanMission(MissionPrefab prefab, Location[] locations, Submarine sub) : base(prefab, locations, sub)
{
itemConfig = prefab.ConfigElement.Element("Items");
targetsToScan = prefab.ConfigElement.GetAttributeInt("targets", 1);
minTargetDistance = prefab.ConfigElement.GetAttributeFloat("mintargetdistance", 0.0f);
minTargetDistanceSquared = minTargetDistance * minTargetDistance;
}
protected override void StartMissionSpecific(Level level)
{
Reset();
if (IsClient) { return; }
if (itemConfig == null)
{
DebugConsole.ThrowError("Failed to initialize a Scan mission: item config is not set");
return;
}
foreach (var element in itemConfig.Elements())
{
LoadItem(element, null);
}
GetScanners();
TargetRuin = Level.Loaded?.Ruins?.GetRandom(randSync: Rand.RandSync.Server);
if (TargetRuin == null)
{
DebugConsole.ThrowError("Failed to initialize a Scan mission: level contains no alien ruins");
return;
}
var availableWaypoints = TargetRuin.Submarine.GetWaypoints(false);
availableWaypoints.RemoveAll(wp => wp.CurrentHull == null);
if (availableWaypoints.Count < targetsToScan)
{
DebugConsole.ThrowError($"Failed to initialize a Scan mission: target ruin has less waypoints than required as scan targets ({availableWaypoints.Count} < {targetsToScan})");
return;
}
for (int i = 0; i < targetsToScan; i++)
{
var selectedWaypoint = availableWaypoints.GetRandom(randSync: Rand.RandSync.Server);
scanTargets.Add(selectedWaypoint, false);
availableWaypoints.Remove(selectedWaypoint);
if (i < (targetsToScan - 1))
{
availableWaypoints.RemoveAll(wp => wp.CurrentHull == selectedWaypoint.CurrentHull);
availableWaypoints.RemoveAll(wp => Vector2.DistanceSquared(wp.WorldPosition, selectedWaypoint.WorldPosition) < minTargetDistanceSquared);
if (availableWaypoints.None())
{
DebugConsole.ThrowError($"Error initializing a Scan mission: not enough targets available to reach the required scan target count (current targets: {scanTargets.Count}, required targets: {targetsToScan})");
break;
}
}
}
}
private void Reset()
{
startingItems.Clear();
parentInventoryIDs.Clear();
parentItemContainerIndices.Clear();
scanners.Clear();
TargetRuin = null;
scanTargets.Clear();
}
private void LoadItem(XElement element, Item parent)
{
var itemPrefab = FindItemPrefab(element);
Vector2? position = GetCargoSpawnPosition(itemPrefab, out Submarine cargoRoomSub);
if (!position.HasValue) { return; }
var item = new Item(itemPrefab, position.Value, cargoRoomSub);
item.FindHull();
startingItems.Add(item);
if (parent?.GetComponent<ItemContainer>() is ItemContainer itemContainer)
{
parentInventoryIDs.Add(item, parent.ID);
parentItemContainerIndices.Add(item, (byte)parent.GetComponentIndex(itemContainer));
parent.Combine(item, user: null);
}
foreach (XElement subElement in element.Elements())
{
int amount = subElement.GetAttributeInt("amount", 1);
for (int i = 0; i < amount; i++)
{
LoadItem(subElement, item);
}
}
}
private void GetScanners()
{
foreach (var startingItem in startingItems)
{
if (startingItem.GetComponent<Scanner>() is Scanner scanner)
{
scanner.OnScanStarted += OnScanStarted;
if (!IsClient)
{
scanner.OnScanCompleted += OnScanCompleted;
}
scanners.Add(scanner);
}
}
}
private void OnScanStarted(Scanner scanner)
{
float scanRadiusSquared = scanner.ScanRadius * scanner.ScanRadius;
foreach (var kvp in scanTargets)
{
if (!IsValidScanPosition(scanner, kvp, scanRadiusSquared)) { continue; }
scanner.DisplayProgressBar = true;
break;
}
}
private void OnScanCompleted(Scanner scanner)
{
if (IsClient) { return; }
newTargetsScanned.Clear();
float scanRadiusSquared = scanner.ScanRadius * scanner.ScanRadius;
foreach (var kvp in scanTargets)
{
if (!IsValidScanPosition(scanner, kvp, scanRadiusSquared)) { continue; }
newTargetsScanned.Add(kvp.Key);
}
foreach (var wp in newTargetsScanned)
{
scanTargets[wp] = true;
}
#if SERVER
// Server should make sure that the clients' scan target status is in-sync
GameMain.Server?.UpdateMissionState(this);
#endif
}
private bool IsValidScanPosition(Scanner scanner, KeyValuePair<WayPoint, bool> scanStatus, float scanRadiusSquared)
{
if (scanStatus.Value) { return false; }
if (scanStatus.Key.Submarine != scanner.Item.Submarine) { return false; }
if (Vector2.DistanceSquared(scanStatus.Key.WorldPosition, scanner.Item.WorldPosition) > scanRadiusSquared) { return false; }
return true;
}
protected override void UpdateMissionSpecific(float deltaTime)
{
if (IsClient) { return; }
switch (State)
{
case 0:
if (!AllTargetsScanned) { return; }
State = 1;
break;
case 1:
if (!Submarine.MainSub.AtEndExit && !Submarine.MainSub.AtStartExit) { return; }
State = 2;
break;
}
}
public override void End()
{
if (AllTargetsScanned && AllScannersReturned())
{
GiveReward();
completed = true;
}
foreach (var scanner in scanners)
{
if (scanner.Item != null && !scanner.Item.Removed)
{
scanner.OnScanStarted -= OnScanStarted;
scanner.OnScanCompleted -= OnScanCompleted;
scanner.Item.Remove();
}
}
Reset();
failed = !completed && state > 0;
bool AllScannersReturned()
{
foreach (var scanner in scanners)
{
if (scanner?.Item == null || scanner.Item.Removed) { return false; }
var owner = scanner.Item.GetRootInventoryOwner();
if (owner.Submarine != null && owner.Submarine.Info.Type == SubmarineType.Player)
{
continue;
}
else if (owner is Character c && c.Info != null && GameMain.GameSession.CrewManager.CharacterInfos.Contains(c.Info))
{
continue;
}
return false;
}
return true;
}
}
}
}
@@ -285,11 +285,10 @@ namespace Barotrauma
spawnPos = chosenPosition.Position.ToVector2();
if (chosenPosition.Submarine != null || chosenPosition.Ruin != null)
{
var spawnPoint = WayPoint.GetRandom(SpawnType.Enemy, sub: chosenPosition.Submarine, ruin: chosenPosition.Ruin, useSyncedRand: false);
var spawnPoint = WayPoint.GetRandom(SpawnType.Enemy, sub: chosenPosition.Submarine ?? chosenPosition.Ruin?.Submarine, useSyncedRand: false);
if (spawnPoint != null)
{
System.Diagnostics.Debug.Assert(spawnPoint.Submarine == chosenPosition.Submarine);
System.Diagnostics.Debug.Assert(spawnPoint.ParentRuin == chosenPosition.Ruin);
System.Diagnostics.Debug.Assert(spawnPoint.Submarine == (chosenPosition.Submarine ?? chosenPosition.Ruin?.Submarine));
spawnPos = spawnPoint.WorldPosition;
}
else