diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index e3c2ee72a6..be8c42280e 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -729,15 +729,18 @@ namespace OpenRa.Game buildPaletteRenderer.DrawSprite(clock.Image, drawPos, PaletteType.Chrome); + var rect = new Rectangle(5, y, 64, 48); if (sp.Value.IsDone) { ready.Play("ready"); buildPaletteRenderer.DrawSprite(ready.Image, drawPos + new float2((64 - ready.Image.size.X) / 2, 2), PaletteType.Chrome); + + AddButton(rect, HandleSupportPower( sp.Value )); } - var rect = new Rectangle(5, y, 64, 48); + if (rect.Contains(lastMousePos.ToPoint())) { tooltipItem = sp.Key; @@ -754,6 +757,11 @@ namespace OpenRa.Game DrawSupportPowerTooltip(tooltipItem, tooltipPos); } + Action HandleSupportPower(SupportPower sp) + { + return b => { if (b) sp.Activate(); }; + } + string FormatTime(int ticks) { var seconds = ticks / 25; diff --git a/OpenRa.Game/GameRules/SupportPowerInfo.cs b/OpenRa.Game/GameRules/SupportPowerInfo.cs index 6eb34f32be..603d68f494 100644 --- a/OpenRa.Game/GameRules/SupportPowerInfo.cs +++ b/OpenRa.Game/GameRules/SupportPowerInfo.cs @@ -16,5 +16,6 @@ namespace OpenRa.Game.GameRules public readonly string[] Prerequisite = { }; public readonly int TechLevel = -1; public readonly bool GivenAuto = true; + public readonly string Impl = null; } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 913dd4655d..00e9e9b692 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -120,6 +120,8 @@ + + diff --git a/OpenRa.Game/SupportPower.cs b/OpenRa.Game/SupportPower.cs index 1d4f6e548f..4e30951c1a 100644 --- a/OpenRa.Game/SupportPower.cs +++ b/OpenRa.Game/SupportPower.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using OpenRa.Game.GameRules; +using OpenRa.Game.Traits; +using OpenRa.Game.SupportPowers; namespace OpenRa.Game { @@ -10,15 +12,25 @@ namespace OpenRa.Game { public readonly SupportPowerInfo Info; public readonly Player Owner; + readonly ISupportPowerImpl Impl; + + static ISupportPowerImpl ConstructPowerImpl(string implName) + { + var type = typeof(ISupportPowerImpl).Assembly.GetType( + typeof(ISupportPowerImpl).Namespace + "." + implName, true, false); + var ctor = type.GetConstructor(Type.EmptyTypes); + return (ISupportPowerImpl)ctor.Invoke(new object[] { }); + } public SupportPower(SupportPowerInfo info, Player owner) { Info = info; Owner = owner; - RemainingTime = TotalTime = (int)info.ChargeTime * 60 * 25; + Impl = ConstructPowerImpl(info.Impl); } + public bool IsUsed; public bool IsAvailable { get; private set; } public bool IsDone { get { return RemainingTime == 0; } } public int RemainingTime { get; private set; } @@ -26,6 +38,9 @@ namespace OpenRa.Game public void Tick() { + if (Info.OneShot && IsUsed) + return; + if (Info.GivenAuto) { var buildings = Rules.TechTree.GatherBuildings(Owner); @@ -47,6 +62,25 @@ namespace OpenRa.Game public void Activate() { + if (Impl != null) + Impl.Activate(this); + } + + public void FinishActivate() + { + if (Info.OneShot) + { + IsUsed = true; + IsAvailable = false; + } + RemainingTime = TotalTime; + } + + public void Give(bool requireCharge) // called by crate/spy/etc code + { + IsAvailable = true; + IsUsed = false; + RemainingTime = requireCharge ? TotalTime : 0; } } } diff --git a/OpenRa.Game/SupportPowers/ISupportPowerImpl.cs b/OpenRa.Game/SupportPowers/ISupportPowerImpl.cs new file mode 100644 index 0000000000..b8831e63c2 --- /dev/null +++ b/OpenRa.Game/SupportPowers/ISupportPowerImpl.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.SupportPowers +{ + interface ISupportPowerImpl + { + void Activate(SupportPower p); + } +} diff --git a/OpenRa.Game/SupportPowers/NullPower.cs b/OpenRa.Game/SupportPowers/NullPower.cs new file mode 100644 index 0000000000..dadb23b5bd --- /dev/null +++ b/OpenRa.Game/SupportPowers/NullPower.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.SupportPowers +{ + class NullPower : ISupportPowerImpl + { + public void Activate(SupportPower p) + { + // if this was a real power, i'd do something here! + throw new NotImplementedException(); + } + } +} diff --git a/units.ini b/units.ini index b3eca27c1d..720f1383b8 100644 --- a/units.ini +++ b/units.ini @@ -830,6 +830,7 @@ LongDesc=A Badger drops a squad of Riflemen \nanywhere on the map Prerequisite=AFLD TechLevel=5 Image=pinficon +Impl=NullPower [ParabombPower] ; picked up in a crate ChargeTime=14 @@ -840,6 +841,7 @@ Powered=no Image=pbmbicon TechLevel=8 GivenAuto=no +Impl=NullPower [SonarPulsePower] ; picked up in a crate, or by spy -> spen/syrd ChargeTime=10 @@ -850,6 +852,7 @@ Powered=no Image=sonricon TechLevel=5 GivenAuto=no +Impl=NullPower [ChronoshiftPower] ; free with Chronosphere... sortof the point. ChargeTime=7 @@ -858,6 +861,7 @@ LongDesc=Temporarily teleports a vehicle across \nthe map. Prerequisite=PDOX Image=warpicon TechLevel=12 +Impl=NullPower [SpyPlanePower] ; free with first AFLD ChargeTime=3 @@ -866,6 +870,7 @@ Description=Spy Plane LongDesc=Reveals an area of the map. Prerequisite=AFLD Image=smigicon +Impl=NullPower [NukePower] ; the point of MSLO ChargeTime=13 @@ -874,6 +879,7 @@ LongDesc=Launches a nuclear missile at your target Prerequisite=MSLO Image=atomicon TechLevel=12 +Impl=NullPower [GpsSatellitePower] ; free with ATEK ChargeTime=8 @@ -883,6 +889,7 @@ OneShot=yes Prerequisite=ATEK Image=gpssicon TechLevel=12 +Impl=NullPower [InvulnerabilityPower] ; the point of IRON ChargeTime=11 @@ -890,4 +897,5 @@ Description=Invulnerability LongDesc=Makes a single unit invulnerable for a \nshort time. Image=infxicon Prerequisite=IRON -TechLevel=12 \ No newline at end of file +TechLevel=12 +Impl=NullPower \ No newline at end of file