From 7608cb93b43c827a4ba46fc0292ac2beb9fe295e Mon Sep 17 00:00:00 2001 From: penev92 Date: Sat, 14 Mar 2015 02:04:37 +0200 Subject: [PATCH] Split CarryUnit into PickupUnit and DeliverUnit --- OpenRA.Mods.D2k/Activities/CarryUnit.cs | 196 ---------------------- OpenRA.Mods.D2k/Activities/DeliverUnit.cs | 140 ++++++++++++++++ OpenRA.Mods.D2k/Activities/PickupUnit.cs | 106 ++++++++++++ OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj | 3 +- OpenRA.Mods.D2k/Traits/Carryall.cs | 7 +- 5 files changed, 253 insertions(+), 199 deletions(-) delete mode 100644 OpenRA.Mods.D2k/Activities/CarryUnit.cs create mode 100644 OpenRA.Mods.D2k/Activities/DeliverUnit.cs create mode 100644 OpenRA.Mods.D2k/Activities/PickupUnit.cs diff --git a/OpenRA.Mods.D2k/Activities/CarryUnit.cs b/OpenRA.Mods.D2k/Activities/CarryUnit.cs deleted file mode 100644 index 1552ab5437..0000000000 --- a/OpenRA.Mods.D2k/Activities/CarryUnit.cs +++ /dev/null @@ -1,196 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using OpenRA.Activities; -using OpenRA.Mods.Common.Activities; -using OpenRA.Mods.Common.Traits; -using OpenRA.Mods.D2k.Traits; -using OpenRA.Mods.RA.Activities; -using OpenRA.Traits; - -namespace OpenRA.Mods.D2k.Activities -{ - public class CarryUnit : Activity - { - readonly Actor self; - readonly Actor carryable; - readonly IMove movement; - readonly Carryable c; - readonly AutoCarryall aca; - readonly Helicopter helicopter; - readonly IPositionable positionable; - readonly IFacing cFacing; // Carryable facing - readonly IFacing sFacing; // Self facing - - enum State { Intercept, LockCarryable, MoveToCarryable, Turn, Pickup, Transport, Land, Release, Takeoff, Done } - - State state; - - public CarryUnit(Actor self, Actor carryable) - { - this.self = self; - this.carryable = carryable; - movement = self.Trait(); - c = carryable.Trait(); - aca = self.Trait(); - helicopter = self.Trait(); - positionable = carryable.Trait(); - cFacing = carryable.Trait(); - sFacing = self.Trait(); - - state = State.Intercept; - } - - // Find a suitable location to drop our carryable - CPos GetLocationToDrop(CPos requestedPosition) - { - if (positionable.CanEnterCell(requestedPosition)) - return requestedPosition; - - var candidateCells = Util.AdjacentCells(self.World, Target.FromCell(self.World, requestedPosition)); - - // TODO: This will behave badly if there is no suitable drop point nearby - do - { - foreach (var c in candidateCells) - if (positionable.CanEnterCell(c)) - return c; - - // Expanding dropable cells search area - // TODO: This also includes all of the cells we have just checked - candidateCells = Util.ExpandFootprint(candidateCells, true); - } while (true); - } - - // Check if we can drop the unit at our current location. - bool CanDropHere() - { - return positionable.CanEnterCell(self.Location); - } - - public override Activity Tick(Actor self) - { - if (carryable.IsDead) - { - aca.UnreserveCarryable(); - return NextActivity; - } - - switch (state) - { - case State.Intercept: // Move towards our carryable - - state = State.LockCarryable; - return Util.SequenceActivities(movement.MoveWithinRange(Target.FromActor(carryable), WRange.FromCells(4)), this); - - case State.LockCarryable: - // Last check - if (c.StandbyForPickup(self)) - { - state = State.MoveToCarryable; - return this; - } - else - { - // We got cancelled - aca.UnreserveCarryable(); - return NextActivity; - } - - case State.MoveToCarryable: // We arrived, move on top - - if (self.Location == carryable.Location) - { - state = State.Turn; - return this; - } - else - return Util.SequenceActivities(movement.MoveTo(carryable.Location, 0), this); - - case State.Turn: // Align facing and Land - - if (sFacing.Facing != cFacing.Facing) - return Util.SequenceActivities(new Turn(self, cFacing.Facing), this); - else - { - state = State.Pickup; - return Util.SequenceActivities(new HeliLand(false), new Wait(10), this); - } - - case State.Pickup: - - // Remove our carryable from world - self.World.AddFrameEndTask(w => carryable.World.Remove(carryable)); - - aca.AttachCarryable(carryable); - state = State.Transport; - return this; - - case State.Transport: - - // Move self to destination - var targetl = GetLocationToDrop(c.Destination); - - state = State.Land; - return Util.SequenceActivities(movement.MoveTo(targetl, 0), this); - - case State.Land: - - if (!CanDropHere()) - { - state = State.Transport; - return this; - } - - if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude)) - return this; - else - { - state = State.Release; - return Util.SequenceActivities(new Wait(15), this); - } - - case State.Release: - - if (!CanDropHere()) - { - state = State.Transport; - return this; - } - - positionable.SetPosition(carryable, self.Location, SubCell.FullCell); - - cFacing.Facing = sFacing.Facing; - - // Put back into world - self.World.AddFrameEndTask(w => carryable.World.Add(carryable)); - - // Unlock carryable - aca.CarryableReleased(); - c.Dropped(); - - state = State.Done; - return Util.SequenceActivities(new Wait(10), this); - - case State.Done: - - self.Trait().UnreserveCarryable(); - return NextActivity; - } - - return NextActivity; - } - - public override void Cancel(Actor self) - { - // TODO: Drop the unit at the nearest available cell - } - } -} diff --git a/OpenRA.Mods.D2k/Activities/DeliverUnit.cs b/OpenRA.Mods.D2k/Activities/DeliverUnit.cs new file mode 100644 index 0000000000..0b3fe70817 --- /dev/null +++ b/OpenRA.Mods.D2k/Activities/DeliverUnit.cs @@ -0,0 +1,140 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.Activities; +using OpenRA.Mods.Common.Activities; +using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.D2k.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k.Activities +{ + public class DeliverUnit : Activity + { + readonly Actor self; + readonly Actor cargo; + readonly IMove movement; + readonly Carryable carryable; + readonly Carryall carryall; + readonly Helicopter helicopter; + readonly IPositionable positionable; + readonly IFacing cargoFacing; + readonly IFacing selfFacing; + + enum State { Transport, Land, Release, Done } + + State state; + + public DeliverUnit(Actor self) + { + carryall = self.Trait(); + this.self = self; + cargo = carryall.Carrying; + movement = self.Trait(); + carryable = cargo.Trait(); + helicopter = self.Trait(); + positionable = cargo.Trait(); + cargoFacing = cargo.Trait(); + selfFacing = self.Trait(); + state = State.Transport; + } + + // Find a suitable location to drop our carryable + CPos GetLocationToDrop(CPos requestedPosition) + { + if (positionable.CanEnterCell(requestedPosition)) + return requestedPosition; + + var candidateCells = Util.AdjacentCells(self.World, Target.FromCell(self.World, requestedPosition)); + + // TODO: This will behave badly if there is no suitable drop point nearby + do + { + foreach (var c in candidateCells) + if (positionable.CanEnterCell(c)) + return c; + + // Expanding dropable cells search area + // TODO: This also includes all of the cells we have just checked + candidateCells = Util.ExpandFootprint(candidateCells, true); + } while (true); + } + + // Check if we can drop the unit at our current location. + bool CanDropHere() + { + return positionable.CanEnterCell(self.Location); + } + + public override Activity Tick(Actor self) + { + if (cargo.IsDead || !carryall.IsBusy) + { + carryall.UnreserveCarryable(); + return NextActivity; + } + + switch (state) + { + case State.Transport: + var targetl = GetLocationToDrop(carryable.Destination); + state = State.Land; + return Util.SequenceActivities(movement.MoveTo(targetl, 0), this); + + case State.Land: + if (!CanDropHere()) + { + state = State.Transport; + return this; + } + + if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude)) + return this; + state = State.Release; + return Util.SequenceActivities(new Wait(15), this); + + case State.Release: + if (!CanDropHere()) + { + state = State.Transport; + return this; + } + + Release(); + state = State.Done; + return Util.SequenceActivities(new Wait(10), this); + + case State.Done: + self.Trait().UnreserveCarryable(); + return NextActivity; + } + + return NextActivity; + } + + void Release() + { + positionable.SetPosition(cargo, self.Location, SubCell.FullCell); + cargoFacing.Facing = selfFacing.Facing; + + // Put back into world + self.World.AddFrameEndTask(w => cargo.World.Add(cargo)); + + // Unlock carryable + carryall.CarryableReleased(); + carryable.Dropped(); + } + + public override void Cancel(Actor self) + { + // TODO: Drop the unit at the nearest available cell + } + } +} diff --git a/OpenRA.Mods.D2k/Activities/PickupUnit.cs b/OpenRA.Mods.D2k/Activities/PickupUnit.cs new file mode 100644 index 0000000000..e7ac69f65a --- /dev/null +++ b/OpenRA.Mods.D2k/Activities/PickupUnit.cs @@ -0,0 +1,106 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.Activities; +using OpenRA.Mods.Common.Activities; +using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.D2k.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k.Activities +{ + public class PickupUnit : Activity + { + readonly Actor cargo; + readonly IMove movement; + readonly Carryable carryable; + readonly Carryall carryall; + readonly Helicopter helicopter; + readonly IFacing cargoFacing; + readonly IFacing selfFacing; + + enum State { Intercept, LockCarryable, MoveToCarryable, Turn, Pickup, TakeOff } + + State state; + + public PickupUnit(Actor self, Actor cargo) + { + this.cargo = cargo; + carryable = cargo.Trait(); + cargoFacing = cargo.Trait(); + movement = self.Trait(); + carryall = self.Trait(); + helicopter = self.Trait(); + selfFacing = self.Trait(); + state = State.Intercept; + } + + public override Activity Tick(Actor self) + { + if (cargo.IsDead || !carryall.IsBusy) + { + carryall.UnreserveCarryable(); + return NextActivity; + } + + switch (state) + { + case State.Intercept: + state = State.LockCarryable; + return Util.SequenceActivities(movement.MoveWithinRange(Target.FromActor(cargo), WRange.FromCells(4)), this); + + case State.LockCarryable: + // Last check + if (carryable.StandbyForPickup(self)) + { + state = State.MoveToCarryable; + return this; + } + + // We got cancelled + carryall.UnreserveCarryable(); + return NextActivity; + + case State.MoveToCarryable: // We arrived, move on top + if (self.Location == cargo.Location) + { + state = State.Turn; + return this; + } + + return Util.SequenceActivities(movement.MoveTo(cargo.Location, 0), this); + + case State.Turn: // Align facing and Land + if (selfFacing.Facing != cargoFacing.Facing) + return Util.SequenceActivities(new Turn(self, cargoFacing.Facing), this); + state = State.Pickup; + return Util.SequenceActivities(new HeliLand(false), new Wait(10), this); + + case State.Pickup: + // Remove our carryable from world + self.World.AddFrameEndTask(w => cargo.World.Remove(cargo)); + carryall.AttachCarryable(cargo); + state = State.TakeOff; + return this; + case State.TakeOff: + if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.CruiseAltitude)) + return this; + return NextActivity; + } + + return NextActivity; + } + + public override void Cancel(Actor self) + { + // TODO: Drop the unit at the nearest available cell + } + } +} diff --git a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj index ee7d98b092..6c51e130fd 100644 --- a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj +++ b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj @@ -68,7 +68,8 @@ - + + diff --git a/OpenRA.Mods.D2k/Traits/Carryall.cs b/OpenRA.Mods.D2k/Traits/Carryall.cs index 3129e086d9..94f7d486b9 100644 --- a/OpenRA.Mods.D2k/Traits/Carryall.cs +++ b/OpenRA.Mods.D2k/Traits/Carryall.cs @@ -13,6 +13,7 @@ using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.D2k.Activities; using OpenRA.Traits; namespace OpenRA.Mods.D2k.Traits @@ -68,7 +69,8 @@ namespace OpenRA.Mods.D2k.Traits if (ReserveCarryable(carryable)) { - self.QueueActivity(false, new CarryUnit(self, carryable)); + self.QueueActivity(false, new PickupUnit(self, carryable)); + self.QueueActivity(true, new DeliverUnit(self)); return true; } @@ -110,7 +112,8 @@ namespace OpenRA.Mods.D2k.Traits // Check if its actually me who's the best candidate if (p.Trait.GetClosestIdleCarrier() == self && ReserveCarryable(p.Actor)) { - self.QueueActivity(false, new CarryUnit(self, p.Actor)); + self.QueueActivity(false, new PickupUnit(self, p.Actor)); + self.QueueActivity(true, new DeliverUnit(self)); break; } }