diff --git a/OpenRA.Mods.D2k/WormManager.cs b/OpenRA.Mods.D2k/WormManager.cs index fa44011c8f..70cc02d031 100644 --- a/OpenRA.Mods.D2k/WormManager.cs +++ b/OpenRA.Mods.D2k/WormManager.cs @@ -9,7 +9,9 @@ #endregion using System; +using System.Drawing; using System.Linq; +using OpenRA.Mods.Common; using OpenRA.Primitives; using OpenRA.Traits; @@ -22,7 +24,7 @@ namespace OpenRA.Mods.D2k public readonly int Minimum = 1; [Desc("Maximum number of worms")] - public readonly int Maximum = 5; + public readonly int Maximum = 8; [Desc("Average time (seconds) between worm spawn")] public readonly int SpawnInterval = 180; @@ -39,6 +41,7 @@ namespace OpenRA.Mods.D2k { int countdown; int wormsPresent; + RadarPings radarPings; readonly WormManagerInfo info; readonly Lazy spawnPoints; @@ -66,7 +69,8 @@ namespace OpenRA.Mods.D2k void SpawnWorm (Actor self) { - var spawnLocation = GetRandomSpawnPosition(self); + var spawnPosition = GetRandomSpawnPosition(self); + var spawnLocation = self.World.Map.CellContaining(spawnPosition); self.World.AddFrameEndTask(w => w.CreateActor(info.WormSignature, new TypeDictionary { new OwnerInit(w.Players.First(x => x.PlayerName == info.WormOwnerPlayer)), @@ -74,12 +78,12 @@ namespace OpenRA.Mods.D2k })); wormsPresent++; - AnnounceWormSign(self); + AnnounceWormSign(self, spawnPosition); } - CPos GetRandomSpawnPosition(Actor self) + WPos GetRandomSpawnPosition(Actor self) { - return spawnPoints.Value.Random(self.World.SharedRandom).Location; + return spawnPoints.Value.Random(self.World.SharedRandom).CenterPosition; } public void DecreaseWorms() @@ -87,10 +91,22 @@ namespace OpenRA.Mods.D2k wormsPresent--; } - void AnnounceWormSign(Actor self) + void AnnounceWormSign(Actor self, WPos wormSpawnPosition) { - if (self.World.LocalPlayer != null) - Sound.PlayNotification(self.World.Map.Rules, self.World.LocalPlayer, "Speech", info.WormSignNotification, self.World.LocalPlayer.Country.Race); + if (self.World.LocalPlayer == null) + return; + + Sound.PlayNotification(self.World.Map.Rules, self.World.LocalPlayer, "Speech", info.WormSignNotification, self.World.LocalPlayer.Country.Race); + + if (radarPings == null) + { + if (self.World.WorldActor == null) + return; + + radarPings = self.World.WorldActor.TraitOrDefault(); + } + + radarPings.Add(() => true, wormSpawnPosition, Color.Red, 50); } } diff --git a/OpenRA.Mods.RA/Attack/AttackWander.cs b/OpenRA.Mods.RA/Attack/AttackWander.cs index e6ec96baa3..b9174fe3e2 100644 --- a/OpenRA.Mods.RA/Attack/AttackWander.cs +++ b/OpenRA.Mods.RA/Attack/AttackWander.cs @@ -15,7 +15,7 @@ namespace OpenRA.Mods.RA { [Desc("Will AttackMove to a random location within MoveRadius when idle.", "This conflicts with player orders and should only be added to animal creeps.")] - class AttackWanderInfo : ITraitInfo + class AttackWanderInfo : ITraitInfo, Requires { public readonly int WanderMoveRadius = 10; @@ -29,11 +29,14 @@ namespace OpenRA.Mods.RA { int ticksIdle; int effectiveMoveRadius; + readonly AttackMove attackMove; readonly AttackWanderInfo Info; public AttackWander(Actor self, AttackWanderInfo info) { Info = info; + effectiveMoveRadius = info.WanderMoveRadius; + attackMove = self.TraitOrDefault(); } public void TickIdle(Actor self) @@ -50,7 +53,7 @@ namespace OpenRA.Mods.RA return; // We'll be back the next tick; better to sit idle for a few seconds than prolongue this tick indefinitely with a loop } - self.Trait().ResolveOrder(self, new Order("AttackMove", self, false) { TargetLocation = targetCell }); + attackMove.ResolveOrder(self, new Order("AttackMove", self, false) { TargetLocation = targetCell }); ticksIdle = 0; effectiveMoveRadius = Info.WanderMoveRadius; diff --git a/OpenRA.Mods.RA/Traits/AttackMove.cs b/OpenRA.Mods.RA/Traits/AttackMove.cs index 8be8e7b75d..4e750ad777 100644 --- a/OpenRA.Mods.RA/Traits/AttackMove.cs +++ b/OpenRA.Mods.RA/Traits/AttackMove.cs @@ -49,7 +49,8 @@ namespace OpenRA.Mods.RA.Traits public void TickIdle(Actor self) { - if (TargetLocation.HasValue) + // This might cause the actor to be stuck if the target location is unreachable + if (TargetLocation.HasValue && self.Location != TargetLocation.Value) Activate(self); } diff --git a/mods/d2k/bits/wormspawner.shp b/mods/d2k/bits/wormspawner.shp index efefdfe496..cd1a7e79ae 100644 Binary files a/mods/d2k/bits/wormspawner.shp and b/mods/d2k/bits/wormspawner.shp differ