diff --git a/OpenRA.Mods.RA/Cargo.cs b/OpenRA.Mods.RA/Cargo.cs index 967c8350ca..9f2b6f46bf 100644 --- a/OpenRA.Mods.RA/Cargo.cs +++ b/OpenRA.Mods.RA/Cargo.cs @@ -29,20 +29,20 @@ namespace OpenRA.Mods.RA public object Create(ActorInitializer init) { return new Cargo(init, this); } } - public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyKilled, INotifyCapture, ITick, INotifySold, IDisableMove + public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyKilled, INotifyCapture, INotifyAddedToWorld, ITick, INotifySold, IDisableMove { public readonly CargoInfo Info; readonly Actor self; + readonly List cargo = new List(); + readonly HashSet reserves = new HashSet(); - public bool Unloading { get; internal set; } + CPos cachedLocation; int totalWeight = 0; int reservedWeight = 0; - List cargo = new List(); - HashSet reserves = new HashSet(); - public IEnumerable Passengers { get { return cargo; } } - CPos currentCell; public IEnumerable CurrentAdjacentCells { get; private set; } + public bool Unloading { get; internal set; } + public IEnumerable Passengers { get { return cargo; } } public Cargo(ActorInitializer init, CargoInfo info) { @@ -81,6 +81,8 @@ namespace OpenRA.Mods.RA } } + static int GetWeight(Actor a) { return a.Info.Traits.Get().Weight; } + public IEnumerable Orders { get { yield return new DeployOrderTargeter("Unload", 10, CanUnload); } @@ -127,11 +129,14 @@ namespace OpenRA.Mods.RA { if (reserves.Contains(a)) return true; + var w = GetWeight(a); if (!HasSpace(w)) return false; + reserves.Add(a); reservedWeight += w; + return true; } @@ -139,19 +144,24 @@ namespace OpenRA.Mods.RA { if (!reserves.Contains(a)) return; + reservedWeight -= GetWeight(a); reserves.Remove(a); } public string CursorForOrder(Actor self, Order order) { - if (order.OrderString != "Unload") return null; + if (order.OrderString != "Unload") + return null; + return CanUnload() ? "deploy" : "deploy-blocked"; } public string VoicePhraseForOrder(Actor self, Order order) { - if (order.OrderString != "Unload" || IsEmpty(self)) return null; + if (order.OrderString != "Unload" || IsEmpty(self)) + return null; + return self.HasVoice("Unload") ? "Unload" : "Move"; } @@ -161,8 +171,6 @@ namespace OpenRA.Mods.RA public Actor Peek(Actor self) { return cargo[0]; } - static int GetWeight(Actor a) { return a.Info.Traits.Get().Weight; } - public Actor Unload(Actor self) { var a = cargo[0]; @@ -221,6 +229,7 @@ namespace OpenRA.Mods.RA { foreach (var c in cargo) c.Kill(e.Attacker); + cargo.Clear(); } @@ -240,6 +249,7 @@ namespace OpenRA.Mods.RA { w.Add(passenger); passenger.Trait().SetPosition(passenger, self.Location); + // TODO: this won't work well for >1 actor as they should move towards the next enterable (sub) cell instead }); } @@ -256,6 +266,13 @@ namespace OpenRA.Mods.RA }); } + public void AddedToWorld(Actor self) + { + // Force location update to avoid issues when initial spawn is outside map + cachedLocation = self.Location; + CurrentAdjacentCells = GetAdjacentCells(); + } + bool initialized; public void Tick(Actor self) { @@ -269,13 +286,13 @@ namespace OpenRA.Mods.RA foreach (var npe in self.TraitsImplementing()) npe.PassengerEntered(self, c); } + initialized = true; } - var cell = self.World.Map.CellContaining(self.CenterPosition); - if (currentCell != cell) + if (cachedLocation != self.Location) { - currentCell = cell; + cachedLocation = self.Location; CurrentAdjacentCells = GetAdjacentCells(); } } @@ -287,7 +304,7 @@ namespace OpenRA.Mods.RA public class RuntimeCargoInit : IActorInit { [FieldFromYamlKey] - public readonly Actor[] value = { }; + readonly Actor[] value = { }; public RuntimeCargoInit() { } public RuntimeCargoInit(Actor[] init) { value = init; } public Actor[] Value(World world) { return value; } @@ -296,7 +313,7 @@ namespace OpenRA.Mods.RA public class CargoInit : IActorInit { [FieldFromYamlKey] - public readonly string[] value = { }; + readonly string[] value = { }; public CargoInit() { } public CargoInit(string[] init) { value = init; } public string[] Value(World world) { return value; }