new support power impl

This commit is contained in:
Chris Forbes
2010-01-23 21:07:27 +13:00
parent bbf94fef79
commit d7a2691db3
56 changed files with 409 additions and 489 deletions

View File

@@ -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)

View File

@@ -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();

View File

@@ -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)

View File

@@ -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;

View 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 { }
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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)

View 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();
}
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}
}
}
}

View 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 { }
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 )

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View 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
}
}