diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 33a923e2b0..463990bc84 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -48,6 +48,11 @@ namespace OpenRA.Graphics palette = new HardwarePalette(renderer, world.Map); } + public void DrawLine(float2 start, float2 end, Color startColor, Color endColor) + { + lineRenderer.DrawLine(start,end,startColor,endColor); + } + public int GetPaletteIndex(string name) { return palette.GetPaletteIndex(name); diff --git a/OpenRA.Mods.Cnc/TiberiumRefinery.cs b/OpenRA.Mods.Cnc/TiberiumRefinery.cs index fa11e85d5b..dbf5cd6399 100644 --- a/OpenRA.Mods.Cnc/TiberiumRefinery.cs +++ b/OpenRA.Mods.Cnc/TiberiumRefinery.cs @@ -1,118 +1,151 @@ -#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; -using System.Linq; -using System.Collections.Generic; -using OpenRA.Mods.RA; -using OpenRA.Mods.RA.Activities; -using OpenRA.Traits; -using OpenRA.Traits.Activities; - -namespace OpenRA.Mods.Cnc -{ - class TiberiumRefineryInfo : ITraitInfo - { - public readonly int PipCount = 0; - public readonly PipType PipColor = PipType.Red; - public readonly int Capacity = 0; - public readonly int ProcessTick = 25; - public readonly int ProcessAmount = 50; - public readonly string DeathWeapon = null; - public object Create(Actor self) { return new TiberiumRefinery(self, this); } - } - - class TiberiumRefinery : ITick, IAcceptOre, INotifyDamage, IPips - { - readonly Actor self; - readonly TiberiumRefineryInfo Info; - readonly PlayerResources Player; - - [Sync] - int nextProcessTime = 0; - [Sync] - public int Tiberium = 0; - - public TiberiumRefinery(Actor self, TiberiumRefineryInfo info) - { - this.self = self; - Info = info; - Player = self.Owner.PlayerActor.traits.Get(); - - } - - public void GiveOre(int amount) - { - Tiberium += amount; - if (Tiberium > Info.Capacity) - Tiberium = Info.Capacity; - } - - public void Tick(Actor self) - { - if (--nextProcessTime <= 0) - { - // Convert resources to cash - int amount = Math.Min(Tiberium, Info.ProcessAmount); - amount = Math.Min(amount, Player.OreCapacity - Player.Ore); - - if (amount > 0) - { - Tiberium -=amount; - Player.GiveOre(amount); - } - nextProcessTime = Info.ProcessTick; - } - } - - public void Damaged(Actor self, AttackInfo e) - { - if (self.IsDead && Tiberium > 0) - { - if (Info.DeathWeapon != null) - { - Combat.DoExplosion(e.Attacker, Info.DeathWeapon, - self.CenterLocation.ToInt2(), 0); - } - } - } - - public int2 DeliverOffset { get { return new int2(0, 2); } } - public void OnDock(Actor harv, DeliverResources dockOrder) - { - // Todo: need to be careful about cancellation and multiple harvs - harv.QueueActivity(new Move(self.Location + new int2(1,1), self)); - harv.QueueActivity(new Turn(96)); - harv.QueueActivity( new CallFunc( () => - self.traits.Get().PlayCustomAnimThen(self, "active", () => { - harv.traits.Get().Deliver(harv, self); - harv.QueueActivity(new Move(self.Location + DeliverOffset, self)); - harv.QueueActivity(new Harvest()); - }))); - } - - public IEnumerable GetPips(Actor self) - { - return Graphics.Util.MakeArray( Info.PipCount, - i => (Tiberium * 1.0f / Info.Capacity > i * 1.0f / Info.PipCount) - ? Info.PipColor : PipType.Transparent ); - } - } -} +#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; +using System.Linq; +using System.Collections.Generic; +using OpenRA.Mods.RA; +using OpenRA.Mods.RA.Activities; +using OpenRA.Traits; +using OpenRA.Traits.Activities; +using System.Drawing; + +namespace OpenRA.Mods.Cnc +{ + class TiberiumRefineryInfo : ITraitInfo + { + public readonly int PipCount = 0; + public readonly PipType PipColor = PipType.Red; + public readonly int Capacity = 0; + public readonly int ProcessTick = 25; + public readonly int ProcessAmount = 50; + public readonly string DeathWeapon = null; + public object Create(Actor self) { return new TiberiumRefinery(self, this); } + } + + class TiberiumRefinery : ITick, IAcceptOre, INotifyDamage, INotifySold, INotifyCapture, IPips + { + readonly Actor self; + readonly TiberiumRefineryInfo Info; + readonly PlayerResources Player; + List LinkedHarv; + + [Sync] + int nextProcessTime = 0; + [Sync] + public int Tiberium = 0; + + public TiberiumRefinery(Actor self, TiberiumRefineryInfo info) + { + this.self = self; + Info = info; + Player = self.Owner.PlayerActor.traits.Get(); + LinkedHarv = new List(); + } + + public void LinkHarvester(Actor self, Actor harv) + { + LinkedHarv.Add(harv); + } + + public void UnlinkHarvester(Actor self, Actor harv) + { + if (LinkedHarv.Contains(harv)) + LinkedHarv.Remove(harv); + } + + public void GiveOre(int amount) + { + Tiberium += amount; + if (Tiberium > Info.Capacity) + Tiberium = Info.Capacity; + } + + public void Tick(Actor self) + { + if (--nextProcessTime <= 0) + { + // Convert resources to cash + int amount = Math.Min(Tiberium, Info.ProcessAmount); + amount = Math.Min(amount, Player.OreCapacity - Player.Ore); + + if (amount > 0) + { + Tiberium -=amount; + Player.GiveOre(amount); + } + nextProcessTime = Info.ProcessTick; + } + } + + public void Damaged(Actor self, AttackInfo e) + { + if (self.IsDead) + { + if (Info.DeathWeapon != null && Tiberium > 0) + { + Combat.DoExplosion(e.Attacker, Info.DeathWeapon, + self.CenterLocation.ToInt2(), 0); + } + + foreach (var harv in LinkedHarv) + harv.traits.Get().UnlinkProc(harv, self); + } + } + + public int2 DeliverOffset { get { return new int2(0, 2); } } + public void OnDock(Actor harv, DeliverResources dockOrder) + { + // Todo: need to be careful about cancellation and multiple harvs + harv.QueueActivity(new Move(self.Location + new int2(1,1), self)); + harv.QueueActivity(new Turn(96)); + harv.QueueActivity( new CallFunc( () => + self.traits.Get().PlayCustomAnimThen(self, "active", () => { + harv.traits.Get().Deliver(harv, self); + harv.QueueActivity(new Move(self.Location + DeliverOffset, self)); + harv.QueueActivity(new Harvest()); + }))); + } + + public void OnCapture(Actor self, Actor captor) + { + // Todo: Do the right thing if a harv is docked + + // Unlink any other harvs + foreach (var harv in LinkedHarv) + harv.traits.Get().UnlinkProc(harv, self); + + } + + public void Selling(Actor self) {} + public void Sold(Actor self) + { + foreach (var harv in LinkedHarv) + harv.traits.Get().UnlinkProc(harv, self); + } + + public IEnumerable GetPips(Actor self) + { + return Graphics.Util.MakeArray( Info.PipCount, + i => (Tiberium * 1.0f / Info.Capacity > i * 1.0f / Info.PipCount) + ? Info.PipColor : PipType.Transparent ); + } + } +} diff --git a/OpenRA.Mods.RA/Activities/DeliverOre.cs b/OpenRA.Mods.RA/Activities/DeliverOre.cs index 6039b6a145..587e4c814f 100755 --- a/OpenRA.Mods.RA/Activities/DeliverOre.cs +++ b/OpenRA.Mods.RA/Activities/DeliverOre.cs @@ -29,64 +29,28 @@ namespace OpenRA.Mods.RA.Activities public IActivity NextActivity { get; set; } bool isDocking; - Actor refinery; public DeliverResources() { } - public DeliverResources( Actor refinery ) - { - this.refinery = refinery; - } - - Actor ChooseRefinery(Actor self) - { - var mobile = self.traits.Get(); - - var search = new PathSearch(self.World) - { - heuristic = PathSearch.DefaultEstimator(self.Location), - umt = mobile.GetMovementType(), - checkForBlocked = false, - }; - var refineries = self.World.Queries.OwnedBy[self.Owner] - .Where(x => x.traits.Contains()) - .ToList(); - if (refinery != null) - search.AddInitialCell(self.World, refinery.Location + refinery.traits.Get().DeliverOffset); - else - foreach (var r in refineries) - search.AddInitialCell(self.World, r.Location + r.traits.Get().DeliverOffset); - - var path = self.World.PathFinder.FindPath(search); - path.Reverse(); - if (path.Count != 0) - return refineries.FirstOrDefault(x => x.Location + x.traits.Get().DeliverOffset == path[0]); - else - return null; - } - public IActivity Tick( Actor self ) { if( NextActivity != null ) return NextActivity; - - if( refinery != null && refinery.IsDead ) - refinery = null; - - if( refinery == null || self.Location != refinery.Location + refinery.traits.Get().DeliverOffset ) + + var proc = self.traits.Get().LinkedProc; + + if (proc == null) + return new Wait(10) { NextActivity = this }; + + if( self.Location != proc.Location + proc.traits.Get().DeliverOffset ) { - refinery = ChooseRefinery(self); - if (refinery == null) - return new Wait(10) { NextActivity = this }; - - return new Move(refinery.Location + refinery.traits.Get().DeliverOffset, 0) { NextActivity = this }; + return new Move(proc.Location + proc.traits.Get().DeliverOffset, 0) { NextActivity = this }; } else if (!isDocking) { isDocking = true; - refinery.traits.Get().OnDock(self, this); + proc.traits.Get().OnDock(self, this); } - return new Wait(10) { NextActivity = this }; } diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index ad651d1251..f0a4b9a5ed 100755 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -1,124 +1,184 @@ -#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.Collections.Generic; -using System.Linq; -using OpenRA.Mods.RA.Activities; -using OpenRA.Traits; -using OpenRA.Traits.Activities; - -namespace OpenRA.Mods.RA -{ - public class HarvesterInfo : ITraitInfo - { - public readonly int Capacity = 28; - public readonly int PipCount = 7; - public readonly PipType PipColor = PipType.Yellow; - public readonly string[] Resources = { }; - public readonly string DeathWeapon = null; - - public object Create(Actor self) { return new Harvester(self, this); } - } - - public class Harvester : IIssueOrder, IResolveOrder, INotifyDamage, IPips - { - Dictionary contents = new Dictionary(); - - readonly HarvesterInfo Info; - public Harvester(Actor self, HarvesterInfo info) - { - Info = info; - } - - public bool IsFull { get { return contents.Values.Sum() == Info.Capacity; } } - public bool IsEmpty { get { return contents.Values.Sum() == 0; } } - - public void AcceptResource(ResourceType type) - { - if (!contents.ContainsKey(type.info)) contents[type.info] = 1; - else contents[type.info]++; - } - - public void Deliver(Actor self, Actor proc) - { - proc.traits.Get().GiveOre(contents.Sum(kv => kv.Key.ValuePerUnit * kv.Value)); - contents.Clear(); - } - - public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) - { - if (mi.Button == MouseButton.Left) return null; - - if (underCursor != null - && underCursor.Owner == self.Owner - && underCursor.traits.Contains() && !IsEmpty) - return new Order("Deliver", self, underCursor); - - var res = self.World.WorldActor.traits.Get().GetResource(xy); - var info = self.Info.Traits.Get(); - - if (underCursor == null && res != null && info.Resources.Contains(res.info.Name)) - return new Order("Harvest", self, xy); - - return null; - } - - public void ResolveOrder(Actor self, Order order) - { - if (order.OrderString == "Harvest") - { - self.CancelActivity(); - self.QueueActivity(new Move(order.TargetLocation, 0)); - self.QueueActivity(new Harvest()); - } - else if (order.OrderString == "Deliver") - { - self.CancelActivity(); - self.QueueActivity(new DeliverResources(order.TargetActor)); - } - } - - public void Damaged(Actor self, AttackInfo e) - { - if (self.IsDead && contents.Count > 0) - { - if (Info.DeathWeapon != null) - { - Combat.DoExplosion(e.Attacker, Info.DeathWeapon, - self.CenterLocation.ToInt2(), 0); - } - } - } - - public IEnumerable GetPips(Actor self) - { - int numPips = Info.PipCount; - int n = contents.Values.Sum(); - - for (int i = 0; i < numPips; i++) - { - if (n * 1.0f / Info.Capacity > i * 1.0f / numPips) - yield return Info.PipColor; - else - yield return PipType.Transparent; - } - } - } -} +#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.Collections.Generic; +using System.Linq; +using OpenRA.Mods.RA.Activities; +using OpenRA.Traits; +using OpenRA.Traits.Activities; + +namespace OpenRA.Mods.RA +{ + public class HarvesterInfo : ITraitInfo + { + public readonly int Capacity = 28; + public readonly int PipCount = 7; + public readonly PipType PipColor = PipType.Yellow; + public readonly string[] Resources = { }; + public readonly string DeathWeapon = null; + + public object Create(Actor self) { return new Harvester(self, this); } + } + + public class Harvester : IIssueOrder, IResolveOrder, INotifyDamage, IPips + { + Dictionary contents = new Dictionary(); + public Actor LinkedProc = null; + + readonly HarvesterInfo Info; + public Harvester(Actor self, HarvesterInfo info) + { + Info = info; + self.QueueActivity( new CallFunc( () => ChooseNewProc(self, null))); + } + + void ChooseNewProc(Actor self, Actor ignore) + { + LinkedProc = ClosestProc(self, ignore); + if (LinkedProc != null) + LinkedProc.traits.WithInterface().FirstOrDefault().LinkHarvester(LinkedProc,self); + } + + Actor ClosestProc(Actor self, Actor ignore) + { + var mobile = self.traits.Get(); + + var search = new PathSearch(self.World) + { + heuristic = PathSearch.DefaultEstimator(self.Location), + umt = mobile.GetMovementType(), + checkForBlocked = false, + }; + var refineries = self.World.Queries.OwnedBy[self.Owner] + .Where(x => x != ignore && x.traits.Contains()) + .ToList(); + + foreach (var r in refineries) + search.AddInitialCell(self.World, r.Location + r.traits.Get().DeliverOffset); + + var path = self.World.PathFinder.FindPath(search); + path.Reverse(); + if (path.Count != 0) + return refineries.FirstOrDefault(x => x.Location + x.traits.Get().DeliverOffset == path[0]); + else + return null; + } + + public bool IsFull { get { return contents.Values.Sum() == Info.Capacity; } } + public bool IsEmpty { get { return contents.Values.Sum() == 0; } } + + public void AcceptResource(ResourceType type) + { + if (!contents.ContainsKey(type.info)) contents[type.info] = 1; + else contents[type.info]++; + } + + public void Deliver(Actor self, Actor proc) + { + proc.traits.Get().GiveOre(contents.Sum(kv => kv.Key.ValuePerUnit * kv.Value)); + contents.Clear(); + } + + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + if (mi.Button == MouseButton.Left) return null; + + if (underCursor != null + && underCursor.Owner == self.Owner + && underCursor.traits.Contains() && !IsEmpty) + { + return new Order("Deliver", self, underCursor); + } + var res = self.World.WorldActor.traits.Get().GetResource(xy); + var info = self.Info.Traits.Get(); + + if (underCursor == null && res != null && info.Resources.Contains(res.info.Name)) + return new Order("Harvest", self, xy); + + return null; + } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "Harvest") + { + self.CancelActivity(); + self.QueueActivity(new Move(order.TargetLocation, 0)); + self.QueueActivity(new Harvest()); + } + else if (order.OrderString == "Deliver") + { + self.CancelActivity(); + + if (order.TargetActor != LinkedProc) + { + if (LinkedProc != null) + LinkedProc.traits.WithInterface().FirstOrDefault().UnlinkHarvester(LinkedProc,self); + LinkedProc = order.TargetActor; + LinkedProc.traits.WithInterface().FirstOrDefault().LinkHarvester(LinkedProc,self); + } + + self.QueueActivity(new DeliverResources()); + } + } + + public void Damaged(Actor self, AttackInfo e) + { + if (self.IsDead) + { + if (Info.DeathWeapon != null && contents.Count > 0) + { + Combat.DoExplosion(e.Attacker, Info.DeathWeapon, + self.CenterLocation.ToInt2(), 0); + } + + if (LinkedProc != null) + LinkedProc.traits.WithInterface().FirstOrDefault().UnlinkHarvester(LinkedProc,self); + } + } + + public void LinkProc(Actor self, Actor proc) + { + LinkedProc = proc; + } + + public void UnlinkProc(Actor self, Actor proc) + { + if (LinkedProc != proc) + return; + + ChooseNewProc(self, proc); + } + + public IEnumerable GetPips(Actor self) + { + int numPips = Info.PipCount; + int n = contents.Values.Sum(); + + for (int i = 0; i < numPips; i++) + { + if (n * 1.0f / Info.Capacity > i * 1.0f / numPips) + yield return Info.PipColor; + else + yield return PipType.Transparent; + } + } + } +} diff --git a/OpenRA.Mods.RA/OreRefinery.cs b/OpenRA.Mods.RA/OreRefinery.cs index d7bc6a8362..54b62c2db3 100755 --- a/OpenRA.Mods.RA/OreRefinery.cs +++ b/OpenRA.Mods.RA/OreRefinery.cs @@ -34,72 +34,115 @@ namespace OpenRA.Mods.RA public readonly int Capacity = 0; public readonly int ProcessTick = 25; public readonly int ProcessAmount = 50; - public object Create(Actor self) { return new OreRefinery(self, this); } + public readonly string DeathWeapon = null; + public object Create (Actor self) + { + return new OreRefinery (self, this); + } } - class OreRefinery : ITick, IAcceptOre, IPips + class OreRefinery : ITick, IAcceptOre, INotifyDamage, INotifySold, INotifyCapture, IPips { - Actor self; - OreRefineryInfo Info; + readonly Actor self; + readonly OreRefineryInfo Info; + readonly PlayerResources Player; + List LinkedHarv; [Sync] int nextProcessTime = 0; [Sync] public int Ore = 0; - public OreRefinery(Actor self, OreRefineryInfo info) + + public OreRefinery (Actor self, OreRefineryInfo info) { this.self = self; Info = info; + Player = self.Owner.PlayerActor.traits.Get (); + LinkedHarv = new List (); } - - public void GiveOre(int amount) + + public void LinkHarvester (Actor self, Actor harv) + { + LinkedHarv.Add (harv); + } + + public void UnlinkHarvester (Actor self, Actor harv) + { + if (LinkedHarv.Contains (harv)) + LinkedHarv.Remove (harv); + } + + public void GiveOre (int amount) { Ore += amount; if (Ore > Info.Capacity) Ore = Info.Capacity; } - - public void Tick(Actor self) + + public void Tick (Actor self) { - if (--nextProcessTime <= 0) - { + if (--nextProcessTime <= 0) { // Convert resources to cash - var pr = self.Owner.PlayerActor.traits.Get(); - int amount = Math.Min(Ore, Info.ProcessAmount); - amount = Math.Min(amount, pr.OreCapacity - pr.Ore); - if (amount > 0) - { - Ore -=amount; - pr.GiveOre(amount); + int amount = Math.Min (Ore, Info.ProcessAmount); + amount = Math.Min (amount, Player.OreCapacity - Player.Ore); + + if (amount > 0) { + Ore -= amount; + Player.GiveOre (amount); } nextProcessTime = Info.ProcessTick; } } - - public IEnumerable GetPips(Actor self) + + public void Damaged (Actor self, AttackInfo e) { - return Graphics.Util.MakeArray( Info.PipCount, - i => (Ore * 1.0f / Info.Capacity > i * 1.0f / Info.PipCount) - ? Info.PipColor : PipType.Transparent ); - } - - public int2 DeliverOffset { get { return new int2(1, 2); } } - public void OnDock(Actor harv, DeliverResources dockOrder) - { - var unit = harv.traits.Get(); - if (unit.Facing != 64) - harv.QueueActivity(new Turn(64)); - - harv.QueueActivity( new CallFunc( () => { - var renderUnit = harv.traits.Get(); - if (renderUnit.anim.CurrentSequence.Name != "empty") - renderUnit.PlayCustomAnimation(harv, "empty", () => - { - harv.traits.Get().Deliver(harv, self); - harv.QueueActivity(new Harvest()); - }); + if (self.IsDead) { + if (Info.DeathWeapon != null && Ore > 0) { + Combat.DoExplosion (e.Attacker, Info.DeathWeapon, self.CenterLocation.ToInt2 (), 0); } - )); + + foreach (var harv in LinkedHarv) + harv.traits.Get ().UnlinkProc (harv, self); + } + } + + public int2 DeliverOffset {get{ return new int2 (1, 2); }} + public void OnDock (Actor harv, DeliverResources dockOrder) + { + var unit = harv.traits.Get (); + if (unit.Facing != 64) + harv.QueueActivity (new Turn (64)); + + harv.QueueActivity (new CallFunc (() => + { + var renderUnit = harv.traits.Get (); + if (renderUnit.anim.CurrentSequence.Name != "empty") + renderUnit.PlayCustomAnimation (harv, "empty", () => + { + harv.traits.Get ().Deliver (harv, self); + harv.QueueActivity (new Harvest ()); + }); + })); + } + public void OnCapture (Actor self, Actor captor) + { + // Todo: Do the right thing if a harv is docked + + // Unlink any other harvs + foreach (var harv in LinkedHarv) + harv.traits.Get ().UnlinkProc (harv, self); + } + + public void Selling (Actor self) {} + public void Sold (Actor self) + { + foreach (var harv in LinkedHarv) + harv.traits.Get ().UnlinkProc (harv, self); + } + + public IEnumerable GetPips (Actor self) + { + return Graphics.Util.MakeArray (Info.PipCount, i => (Ore * 1f / Info.Capacity > i * 1f / Info.PipCount) ? Info.PipColor : PipType.Transparent); } } } diff --git a/OpenRA.Mods.RA/TraitsInterfaces.cs b/OpenRA.Mods.RA/TraitsInterfaces.cs index 75dfa465ca..09b63624df 100755 --- a/OpenRA.Mods.RA/TraitsInterfaces.cs +++ b/OpenRA.Mods.RA/TraitsInterfaces.cs @@ -26,6 +26,8 @@ namespace OpenRA.Mods.RA { void OnDock(Actor harv, DeliverResources dockOrder); void GiveOre(int amount); + void LinkHarvester(Actor self, Actor harv); + void UnlinkHarvester(Actor self, Actor harv); int2 DeliverOffset { get; } } }