diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs index 6a8ee3d51..3c20dbb30 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs @@ -439,11 +439,14 @@ namespace Barotrauma.Items.Components { var mission = GameMain.GameSession.Mission; - if (!string.IsNullOrWhiteSpace(mission.SonarLabel) && mission.SonarPosition != Vector2.Zero) + if (!string.IsNullOrWhiteSpace(mission.SonarLabel)) { - DrawMarker(spriteBatch, - mission.SonarLabel, - mission.SonarPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f)); + foreach (Vector2 sonarPosition in mission.SonarPositions) + { + DrawMarker(spriteBatch, + mission.SonarLabel, + sonarPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f)); + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs index 1a68cd2d8..3eb217589 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs @@ -76,7 +76,7 @@ namespace Barotrauma else if (Vector2.DistanceSquared(center, ai.SimPosition) > maxDistFromCenter * maxDistFromCenter) { float distFromCenter = Vector2.Distance(center, ai.SimPosition); - ai.SteeringManager.SteeringSeek(center, distFromCenter - maxDistFromCenter); + ai.SteeringManager.SteeringSeek(center, (distFromCenter - maxDistFromCenter) / 10.0f); } //keep the characters moving in roughly the same direction diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs index c317d6e7a..7df6131cd 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs @@ -55,9 +55,9 @@ namespace Barotrauma get { return true; } } - public virtual Vector2 SonarPosition + public virtual IEnumerable SonarPositions { - get { return Vector2.Zero; } + get { return Enumerable.Empty(); } } public string SonarLabel diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs index e4dcdfc46..e37aeed7d 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs @@ -1,4 +1,6 @@ using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Linq; namespace Barotrauma { @@ -8,32 +10,38 @@ namespace Barotrauma private int state; - private Character monster; + private int monsterCount; - private Vector2 sonarPosition; + private readonly List monsters = new List(); + private readonly List sonarPositions = new List(); - public override Vector2 SonarPosition + public override IEnumerable SonarPositions { - get { return monster != null && !monster.IsDead ? sonarPosition : Vector2.Zero; } + get + { + return sonarPositions; + } } public MonsterMission(MissionPrefab prefab, Location[] locations) : base(prefab, locations) { monsterFile = prefab.ConfigElement.GetAttributeString("monsterfile", ""); + monsterCount = prefab.ConfigElement.GetAttributeInt("monstercount", 1); } public override void Start(Level level) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); - bool isClient = false; -#if CLIENT - isClient = GameMain.Client != null; -#endif - monster = Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false); - monster.Enabled = false; - sonarPosition = spawnPos; + bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient; + for (int i = 0; i < monsterCount; i++) + { + monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false)); + } + monsters.ForEach(m => m.Enabled = false); + SwarmBehavior.CreateSwarm(monsters.Cast()); + sonarPositions.Add(spawnPos); } public override void Update(float deltaTime) @@ -41,12 +49,23 @@ namespace Barotrauma switch (state) { case 0: - if (monster.Enabled) + sonarPositions.Clear(); + var activeMonsters = monsters.Where(m => m != null && !m.Removed && !m.IsDead); + if (activeMonsters.Any()) { - sonarPosition = monster.Position; + Vector2 centerOfMass = Vector2.Zero; + foreach (var monster in activeMonsters) + { + //don't add another label if there's another monster roughly at the same spot + if (sonarPositions.All(p => Vector2.DistanceSquared(p, monster.Position) > 1000.0f * 1000.0f)) + { + sonarPositions.Add(monster.Position); + } + } } - if (!monster.IsDead) return; + + if (activeMonsters.Any()) { return; } #if CLIENT ShowMessage(state); #endif @@ -57,10 +76,9 @@ namespace Barotrauma public override void End() { - if (!monster.IsDead) return; + if (!monsters.All(m => m.Removed || m.IsDead)) { return; } GiveReward(); - completed = true; } } diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs index d013158a2..7d5d16917 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs @@ -1,6 +1,8 @@ using FarseerPhysics; using Microsoft.Xna.Framework; using System; +using System.Collections.Generic; +using System.Linq; namespace Barotrauma { @@ -14,11 +16,18 @@ namespace Barotrauma private int state; - public override Vector2 SonarPosition + public override IEnumerable SonarPositions { get { - return state > 0 ? Vector2.Zero : ConvertUnits.ToDisplayUnits(item.SimPosition); + if (state > 0 ) + { + Enumerable.Empty(); + } + else + { + yield return ConvertUnits.ToDisplayUnits(item.SimPosition); + } } }