new support power impl
This commit is contained in:
@@ -195,7 +195,7 @@ namespace OpenRa.Traits
|
||||
|
||||
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
|
||||
|
||||
return new Order(isHeal ? "Heal" : "Attack", self, underCursor, int2.Zero, null);
|
||||
return new Order(isHeal ? "Heal" : "Attack", self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace OpenRa.Traits
|
||||
{
|
||||
var attack = self.traits.Get<AttackBase>();
|
||||
if (target != null)
|
||||
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
|
||||
attack.ResolveOrder(self, new Order("Attack", self, target));
|
||||
else
|
||||
if (self.GetCurrentActivity() is Attack)
|
||||
self.CancelActivity();
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace OpenRa.Traits
|
||||
{
|
||||
var attack = self.traits.Get<AttackBase>();
|
||||
if (target != null)
|
||||
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
|
||||
attack.ResolveOrder(self, new Order("Attack", self, target));
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRa.Traits
|
||||
var unit = underCursor.traits.GetOrDefault<Unit>();
|
||||
if (unit != null && unit.Altitude > 0) return null;
|
||||
|
||||
return new Order("Deploy", self, null, int2.Zero, null);
|
||||
return new Order("Deploy", self);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
58
OpenRa.Game/Traits/ChronoshiftPower.cs
Normal file
58
OpenRa.Game/Traits/ChronoshiftPower.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Orders;
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class ChronoshiftPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly float Duration = 0f;
|
||||
public readonly bool KillCargo = true;
|
||||
public override object Create(Actor self) { return new ChronoshiftPower(self,this); }
|
||||
}
|
||||
|
||||
class ChronoshiftPower : SupportPower, IResolveOrder
|
||||
{
|
||||
public ChronoshiftPower(Actor self, ChronoshiftPowerInfo info) : base(self, info) { }
|
||||
protected override void OnBeginCharging() { Sound.Play("chrochr1.aud"); }
|
||||
protected override void OnFinishCharging() { Sound.Play("chrordy1.aud"); }
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Game.controller.orderGenerator = new ChronosphereSelectOrderGenerator();
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "ChronosphereSelect" && self.Owner == self.World.LocalPlayer)
|
||||
{
|
||||
Game.controller.orderGenerator = new ChronoshiftDestinationOrderGenerator(order.TargetActor);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
|
||||
if (order.OrderString == "ChronosphereFinish")
|
||||
{
|
||||
Game.controller.CancelInputMode();
|
||||
FinishActivate();
|
||||
|
||||
Sound.Play("chrono2.aud");
|
||||
|
||||
var chronosphere = self.World.Actors.Where(a => a.Owner == self.Owner
|
||||
&& a.traits.Contains<Chronosphere>()).FirstOrDefault();
|
||||
if (chronosphere != null)
|
||||
Game.orderManager.IssueOrder(new Order("PlayAnimation", chronosphere, "active"));
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait to identify the building
|
||||
class ChronosphereInfo : StatelessTraitInfo<Chronosphere> { }
|
||||
public class Chronosphere { }
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace OpenRa.Traits
|
||||
public object Create(Actor self) { return new Chronoshiftable(self); }
|
||||
}
|
||||
|
||||
public class Chronoshiftable : IResolveOrder, ISpeedModifier, ITick
|
||||
public class Chronoshiftable : IResolveOrder, ITick
|
||||
{
|
||||
// Return-to-sender logic
|
||||
[Sync]
|
||||
@@ -39,12 +39,6 @@ namespace OpenRa.Traits
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "ChronosphereSelect")
|
||||
{
|
||||
var power = self.Owner.SupportPowers[order.TargetString];
|
||||
Game.controller.orderGenerator = new ChronoshiftDestinationOrderGenerator(self, power);
|
||||
}
|
||||
|
||||
var movement = self.traits.GetOrDefault<IMovement>();
|
||||
if (order.OrderString == "Chronoshift" && movement.CanEnterCell(order.TargetLocation))
|
||||
{
|
||||
@@ -70,16 +64,8 @@ namespace OpenRa.Traits
|
||||
// Set up the teleport
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Activities.Teleport(order.TargetLocation));
|
||||
|
||||
var power = self.Owner.SupportPowers[order.TargetString].Impl;
|
||||
power.OnFireNotification(self, self.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSpeedModifier()
|
||||
{
|
||||
// ARGH! You must not do this, it will desync!
|
||||
return (Game.controller.orderGenerator is ChronoshiftDestinationOrderGenerator) ? 0f : 1f;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class ChronosphereInfo : StatelessTraitInfo<Chronosphere> { }
|
||||
|
||||
public class Chronosphere : IResolveOrder
|
||||
{
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "PlayAnimation")
|
||||
{
|
||||
var rb = self.traits.Get<RenderBuilding>();
|
||||
if (rb != null)
|
||||
rb.PlayCustomAnim(self, order.TargetString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace OpenRa.Traits
|
||||
if (!self.World.IsActorCrushableByActor(underCursor, self)) return null;
|
||||
}
|
||||
|
||||
return new Order("Move", self, null, xy, null);
|
||||
return new Order("Move", self, xy);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
38
OpenRa.Game/Traits/GpsPower.cs
Normal file
38
OpenRa.Game/Traits/GpsPower.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Effects;
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class GpsPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int RevealDelay = 0;
|
||||
|
||||
public override object Create(Actor self) { return new GpsPower(self, this); }
|
||||
}
|
||||
|
||||
class GpsPower : SupportPower
|
||||
{
|
||||
public GpsPower(Actor self, GpsPowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnFinishCharging()
|
||||
{
|
||||
var launchSite = Owner.World.Actors
|
||||
.FirstOrDefault(a => a.Owner == Owner && a.traits.Contains<GpsLaunchSite>());
|
||||
|
||||
if (launchSite == null)
|
||||
return;
|
||||
|
||||
Owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
w.Add(new SatelliteLaunch(launchSite));
|
||||
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
|
||||
() => Owner.Shroud.HasGPS = true));
|
||||
});
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,10 @@ namespace OpenRa.Traits
|
||||
if (underCursor != null
|
||||
&& underCursor.Owner == self.Owner
|
||||
&& underCursor.traits.Contains<AcceptsOre>() && !IsEmpty)
|
||||
return new Order("Deliver", self, underCursor, int2.Zero, null);
|
||||
return new Order("Deliver", self, underCursor);
|
||||
|
||||
if (underCursor == null && self.World.Map.ContainsResource(xy))
|
||||
return new Order("Harvest", self, null, xy, null);
|
||||
return new Order("Harvest", self, xy);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@ namespace OpenRa.Traits
|
||||
if (mi.Button == MouseButton.Left) return null;
|
||||
|
||||
if (underCursor == null)
|
||||
return new Order("Move", self, null, xy, null);
|
||||
return new Order("Move", self, xy);
|
||||
|
||||
if (HeliCanEnter(underCursor)
|
||||
&& underCursor.Owner == self.Owner
|
||||
&& !Reservable.IsReserved(underCursor))
|
||||
return new Order("Enter", self, underCursor, int2.Zero, null);
|
||||
return new Order("Enter", self, underCursor);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class IronCurtainInfo : StatelessTraitInfo<IronCurtain> { }
|
||||
|
||||
class IronCurtain : IResolveOrder
|
||||
{
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "PlayAnimation")
|
||||
{
|
||||
var rb = self.traits.Get<RenderBuilding>();
|
||||
if (rb != null)
|
||||
rb.PlayCustomAnim(self, order.TargetString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
OpenRa.Game/Traits/IronCurtainPower.cs
Normal file
42
OpenRa.Game/Traits/IronCurtainPower.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Orders;
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class IronCurtainPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly float Duration = 0f;
|
||||
public override object Create(Actor self) { return new IronCurtainPower(self, this); }
|
||||
}
|
||||
|
||||
class IronCurtainPower : SupportPower, IResolveOrder
|
||||
{
|
||||
public IronCurtainPower(Actor self, IronCurtainPowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnBeginCharging() { Sound.Play("ironchg1.aud"); }
|
||||
protected override void OnFinishCharging() { Sound.Play("ironrdy1.aud"); }
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Game.controller.orderGenerator = new IronCurtainOrderGenerator(this);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "IronCurtain")
|
||||
{
|
||||
order.TargetActor.traits.Get<IronCurtainable>().Activate(order.TargetActor,
|
||||
(int)((Info as IronCurtainPowerInfo).Duration * 25 * 60));
|
||||
Game.controller.CancelInputMode();
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait for the building
|
||||
class IronCurtainInfo : StatelessTraitInfo<IronCurtain> { }
|
||||
class IronCurtain { }
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace OpenRa.Traits
|
||||
public object Create(Actor self) { return new IronCurtainable(); }
|
||||
}
|
||||
|
||||
class IronCurtainable : IResolveOrder, IDamageModifier, ITick
|
||||
class IronCurtainable : IDamageModifier, ITick
|
||||
{
|
||||
[Sync]
|
||||
int RemainingTicks = 0;
|
||||
@@ -18,20 +18,16 @@ namespace OpenRa.Traits
|
||||
if (RemainingTicks > 0)
|
||||
RemainingTicks--;
|
||||
}
|
||||
|
||||
public float GetDamageModifier()
|
||||
{
|
||||
return (RemainingTicks > 0) ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
public void Activate(Actor self, int duration)
|
||||
{
|
||||
if (order.OrderString == "IronCurtain")
|
||||
{
|
||||
var power = self.Owner.SupportPowers[order.TargetString].Impl;
|
||||
power.OnFireNotification(self, self.Location);
|
||||
self.World.AddFrameEndTask(w => w.Add(new InvulnEffect(self)));
|
||||
RemainingTicks = (int)(Rules.General.IronCurtain * 60 * 25);
|
||||
}
|
||||
self.World.AddFrameEndTask(w => w.Add(new InvulnEffect(self)));
|
||||
RemainingTicks = duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace OpenRa.Traits
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right && self == underCursor)
|
||||
return new Order("DeployMcv", self, null, int2.Zero, null);
|
||||
return new Order("DeployMcv", self);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenRa.Traits
|
||||
|
||||
if (Util.GetEffectiveSpeed(self) == 0) return null; /* allow disabling move orders from modifiers */
|
||||
if (xy == toCell) return null;
|
||||
return new Order("Move", self, null, xy, null);
|
||||
return new Order("Move", self, xy);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRa.Traits
|
||||
if (!underCursor.Info.Traits.Get<CargoInfo>().PassengerTypes.Contains(umt))
|
||||
return null;
|
||||
|
||||
return new Order("EnterTransport", self, underCursor, int2.Zero, null);
|
||||
return new Order("EnterTransport", self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -26,12 +26,12 @@ namespace OpenRa.Traits
|
||||
{
|
||||
if (mi.Button == MouseButton.Left) return null;
|
||||
if (underCursor == null)
|
||||
return new Order("Move", self, null, xy, null);
|
||||
return new Order("Move", self, xy);
|
||||
|
||||
if (PlaneCanEnter(underCursor)
|
||||
&& underCursor.Owner == self.Owner
|
||||
&& !Reservable.IsReserved(underCursor))
|
||||
return new Order("Enter", self, underCursor, int2.Zero, null);
|
||||
return new Order("Enter", self, underCursor);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace OpenRa.Traits
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right && underCursor == self)
|
||||
return new Order("Deploy", self, null, int2.Zero, null);
|
||||
return new Order("Deploy", self);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRa.Traits
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button == MouseButton.Left || underCursor != null) return null;
|
||||
return new Order("SetRallyPoint", self, null, xy, null);
|
||||
return new Order("SetRallyPoint", self, xy);
|
||||
}
|
||||
|
||||
public void ResolveOrder( Actor self, Order order )
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace OpenRa.Traits
|
||||
public override object Create(Actor self) { return new RenderBuilding(self); }
|
||||
}
|
||||
|
||||
class RenderBuilding : RenderSimple, INotifyDamage, INotifySold
|
||||
class RenderBuilding : RenderSimple, INotifyDamage, INotifySold, IResolveOrder
|
||||
{
|
||||
const int SmallBibStart = 1;
|
||||
const int LargeBibStart = 5;
|
||||
@@ -99,5 +99,11 @@ namespace OpenRa.Traits
|
||||
}
|
||||
|
||||
public void Sold(Actor self) { DoBib(self, true); }
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "PlayAnimation")
|
||||
PlayCustomAnim(self, order.TargetString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRa.Traits
|
||||
if (underCursor.Info.Name == "fix"
|
||||
&& underCursor.Owner == self.Owner
|
||||
&& !Reservable.IsReserved(underCursor))
|
||||
return new Order("Enter", self, underCursor, int2.Zero, null);
|
||||
return new Order("Enter", self, underCursor);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
103
OpenRa.Game/Traits/SupportPower.cs
Normal file
103
OpenRa.Game/Traits/SupportPower.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
abstract class SupportPowerInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool RequiresPower = true;
|
||||
public readonly bool OneShot = false;
|
||||
public readonly float ChargeTime = 0;
|
||||
public readonly string Image = null;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly string[] Prerequisites = { };
|
||||
public readonly int TechLevel = -1;
|
||||
public readonly bool GivenAuto = true;
|
||||
|
||||
public abstract object Create(Actor self);
|
||||
}
|
||||
|
||||
class SupportPower : ITick
|
||||
{
|
||||
public readonly SupportPowerInfo Info;
|
||||
public int RemainingTime { get; private set; }
|
||||
public int TotalTime { get { return (int)(Info.ChargeTime * 60 * 25); } }
|
||||
public bool IsUsed;
|
||||
public bool IsAvailable;
|
||||
public bool IsReady { get { return RemainingTime == 0; } }
|
||||
public readonly Player Owner;
|
||||
|
||||
bool notifiedCharging;
|
||||
bool notifiedReady;
|
||||
|
||||
public SupportPower(Actor self, SupportPowerInfo info)
|
||||
{
|
||||
Info = info;
|
||||
RemainingTime = TotalTime;
|
||||
Owner = self.Owner;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (Info.OneShot && IsUsed)
|
||||
return;
|
||||
|
||||
if (Info.GivenAuto)
|
||||
{
|
||||
var buildings = Rules.TechTree.GatherBuildings(self.Owner);
|
||||
var effectivePrereq = Info.Prerequisites
|
||||
.Select(a => a.ToLowerInvariant())
|
||||
.Where(a => Rules.Info[a].Traits.Get<BuildableInfo>().Owner.Contains(self.Owner.Race));
|
||||
|
||||
IsAvailable = Info.TechLevel > -1
|
||||
&& effectivePrereq.Any()
|
||||
&& effectivePrereq.All(a => buildings[a].Count > 0);
|
||||
}
|
||||
|
||||
if (IsAvailable && (!Info.RequiresPower || self.Owner.GetPowerState() == PowerState.Normal))
|
||||
{
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
OnBeginCharging();
|
||||
notifiedCharging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& !notifiedReady)
|
||||
{
|
||||
OnFinishCharging();
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void FinishActivate()
|
||||
{
|
||||
if (Info.OneShot)
|
||||
{
|
||||
IsUsed = true;
|
||||
IsAvailable = false;
|
||||
}
|
||||
RemainingTime = TotalTime;
|
||||
notifiedReady = false;
|
||||
notifiedCharging = false;
|
||||
}
|
||||
|
||||
public void Give(float charge)
|
||||
{
|
||||
IsAvailable = true;
|
||||
IsUsed = false;
|
||||
RemainingTime = (int)(charge * TotalTime);
|
||||
}
|
||||
|
||||
protected virtual void OnBeginCharging() { }
|
||||
protected virtual void OnFinishCharging() { }
|
||||
protected virtual void OnActivate() { }
|
||||
|
||||
public void Activate() { OnActivate(); } // todo: some more hax
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user