From 5ca590a16a81b7c7baafc28690371bedf58abada Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 23 May 2010 16:54:19 +1200 Subject: [PATCH] working smart minelayer; needs auto-rearm though --- OpenRA.Mods.RA/Activities/LayMine.cs | 40 ------------- OpenRA.Mods.RA/Activities/LayMines.cs | 82 +++++++++++++++++++++++++++ OpenRA.Mods.RA/Minelayer.cs | 4 +- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 2 +- 4 files changed, 86 insertions(+), 42 deletions(-) delete mode 100755 OpenRA.Mods.RA/Activities/LayMine.cs create mode 100644 OpenRA.Mods.RA/Activities/LayMines.cs diff --git a/OpenRA.Mods.RA/Activities/LayMine.cs b/OpenRA.Mods.RA/Activities/LayMine.cs deleted file mode 100755 index feebe6ebd1..0000000000 --- a/OpenRA.Mods.RA/Activities/LayMine.cs +++ /dev/null @@ -1,40 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. - * This file is part of OpenRA. - * - * OpenRA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * OpenRA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with OpenRA. If not, see . - */ -#endregion - -using OpenRA.Traits; - -namespace OpenRA.Mods.RA.Activities -{ - class LayMine : IActivity - { - public IActivity NextActivity { get; set; } - - public IActivity Tick( Actor self ) - { - self.World.AddFrameEndTask( - w => w.CreateActor(self.Info.Traits.Get().Mine, self.Location, self.Owner)); - return NextActivity; - } - - public void Cancel( Actor self ) - { - } - } -} diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs new file mode 100644 index 0000000000..9ddcf07669 --- /dev/null +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -0,0 +1,82 @@ +#region Copyright & License Information +/* + * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. + * This file is part of OpenRA. + * + * OpenRA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenRA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenRA. If not, see . + */ +#endregion + +using System.Linq; +using OpenRA.Traits; +using OpenRA.Traits.Activities; + +namespace OpenRA.Mods.RA.Activities +{ + // assumes you have Minelayer on that unit + + class LayMines : IActivity + { + bool canceled = false; + public IActivity NextActivity { get; set; } + + public IActivity Tick( Actor self ) + { + if (canceled) return NextActivity; + + var limitedAmmo = self.traits.GetOrDefault(); + if (!limitedAmmo.HasAmmo()) + { + // todo: rearm at fix, then back out here to refill the minefield some more + return NextActivity; + } + + var ml = self.traits.Get(); + if (ml.minefield.Contains(self.Location) && + ShouldLayMine(self, self.Location)) + { + LayMine(self); + return new Wait(20) { NextActivity = this }; // a little wait after placing each mine, for show + } + + for (var n = 0; n < 20; n++) // dont get stuck forever here + { + var p = ml.minefield.Random(self.World.SharedRandom); + if (ShouldLayMine(self, p)) + return new Move(p, 0) { NextActivity = this }; + } + + return new Wait(20); // nothing to do here + } + + bool ShouldLayMine(Actor self, int2 p) + { + // if there is no unit (other than me) here, we want to place a mine here + return !self.World.WorldActor.traits.Get() + .GetUnitsAt(p).Any(a => a != self); + } + + void LayMine(Actor self) + { + var limitedAmmo = self.traits.GetOrDefault(); + if (limitedAmmo != null) limitedAmmo.Attacking(self); + + self.World.AddFrameEndTask( + w => w.CreateActor( + self.Info.Traits.Get().Mine, self.Location, self.Owner)); + } + + public void Cancel( Actor self ) { canceled = true; NextActivity = null; } + } +} diff --git a/OpenRA.Mods.RA/Minelayer.cs b/OpenRA.Mods.RA/Minelayer.cs index 5095536275..f53c8d6608 100644 --- a/OpenRA.Mods.RA/Minelayer.cs +++ b/OpenRA.Mods.RA/Minelayer.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { - if (mi.Button == MouseButton.Right && underCursor == null) + if (mi.Button == MouseButton.Right && underCursor == null && mi.Modifiers.HasModifier(Modifiers.Ctrl)) return new Order("BeginMinefield", self, xy); return null; @@ -67,6 +67,8 @@ namespace OpenRA.Mods.RA .Where(p => movement.CanEnterCell(p)).ToArray(); /* todo: start the mnly actually laying mines there */ + self.CancelActivity(); + self.QueueActivity(new LayMines()); } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 7d470643bf..fb508b59f5 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -61,7 +61,7 @@ - +