Update copyright header. Normalize line endings to LF.
This commit is contained in:
@@ -1,64 +1,64 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class AirstrikePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference]
|
||||
public readonly string UnitType = "badr.bomber";
|
||||
[ActorReference]
|
||||
public readonly string FlareType = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
||||
}
|
||||
|
||||
class AirstrikePower : SupportPower
|
||||
{
|
||||
public AirstrikePower(Actor self, AirstrikePowerInfo info) : base(self, info) { }
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as AirstrikePowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
a.Trait<CarpetBomb>().SetTarget(order.TargetLocation);
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
|
||||
if (flare != null)
|
||||
a.QueueActivity(new CallFunc(() => flare.Destroy()));
|
||||
|
||||
a.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
a.QueueActivity(new RemoveSelf());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class AirstrikePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference]
|
||||
public readonly string UnitType = "badr.bomber";
|
||||
[ActorReference]
|
||||
public readonly string FlareType = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
||||
}
|
||||
|
||||
class AirstrikePower : SupportPower
|
||||
{
|
||||
public AirstrikePower(Actor self, AirstrikePowerInfo info) : base(self, info) { }
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as AirstrikePowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
a.Trait<CarpetBomb>().SetTarget(order.TargetLocation);
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
|
||||
if (flare != null)
|
||||
a.QueueActivity(new CallFunc(() => flare.Destroy()));
|
||||
|
||||
a.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
a.QueueActivity(new RemoveSelf());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,245 +1,245 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ChronoshiftPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int Range = 1; // Range in cells
|
||||
public readonly int Duration = 30; // Seconds
|
||||
public readonly bool KillCargo = true;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ChronoshiftPower(init.self,this); }
|
||||
}
|
||||
|
||||
class ChronoshiftPower : SupportPower
|
||||
{
|
||||
public ChronoshiftPower(Actor self, ChronoshiftPowerInfo info) : base(self, info) { }
|
||||
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
a.Trait.Enable();
|
||||
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.TargetLocation);
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.ExtraLocation);
|
||||
foreach (var target in UnitsInRange(order.ExtraLocation))
|
||||
{
|
||||
var cs = target.Trait<Chronoshiftable>();
|
||||
var targetCell = target.Location + order.TargetLocation - order.ExtraLocation;
|
||||
var cpi = Info as ChronoshiftPowerInfo;
|
||||
|
||||
if (cs.CanChronoshiftTo(target, targetCell, true))
|
||||
cs.Teleport(target, targetCell,
|
||||
cpi.Duration * 25, cpi.KillCargo, self);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as ChronoshiftPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<Chronoshiftable>());
|
||||
}
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(string order, SupportPowerManager manager, ChronoshiftPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == MouseButton.Left)
|
||||
world.OrderGenerator = new SelectDestination(order, manager, power, xy);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var targetUnits = power.UnitsInRange(xy);
|
||||
foreach (var unit in targetUnits)
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var tiles = world.FindTilesInCircle(xy, range);
|
||||
foreach (var t in tiles)
|
||||
tile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return "chrono-select";
|
||||
}
|
||||
}
|
||||
|
||||
class SelectDestination : IOrderGenerator
|
||||
{
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int2 sourceLocation;
|
||||
readonly int range;
|
||||
readonly Sprite validTile, invalidTile, sourceTile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectDestination(string order, SupportPowerManager manager, ChronoshiftPower power, int2 sourceLocation)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.sourceLocation = sourceLocation;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
|
||||
// todo: this burns up more texture space every time someone uses chronoshift.
|
||||
validTile = UiOverlay.SynthesizeTile(0x0f);
|
||||
invalidTile = UiOverlay.SynthesizeTile(0x08);
|
||||
sourceTile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
yield break;
|
||||
}
|
||||
|
||||
var ret = OrderInner( world, xy, mi ).FirstOrDefault();
|
||||
if (ret == null)
|
||||
yield break;
|
||||
|
||||
world.CancelInputMode();
|
||||
yield return ret;
|
||||
}
|
||||
|
||||
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
// Cannot chronoshift into unexplored location
|
||||
if (IsValidTarget(xy))
|
||||
yield return new Order(order, manager.self, false)
|
||||
{
|
||||
TargetLocation = xy,
|
||||
ExtraLocation = sourceLocation
|
||||
};
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
|
||||
// Source tiles
|
||||
foreach (var t in world.FindTilesInCircle(sourceLocation, range))
|
||||
sourceTile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
|
||||
// Destination tiles
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
sourceTile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
|
||||
// Unit previews
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
foreach (var r in unit.Render())
|
||||
r.Sprite.DrawAt(r.Pos - Traits.Util.CenterOfCell(unit.Location) + Traits.Util.CenterOfCell(targetCell),
|
||||
wr.GetPaletteIndex(r.Palette ?? unit.Owner.Palette),
|
||||
r.Scale*r.Sprite.size);
|
||||
}
|
||||
|
||||
// Unit tiles
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
var canEnter = unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell, false);
|
||||
var tile = canEnter ? validTile : invalidTile;
|
||||
tile.DrawAt( wr, Game.CellSize * targetCell, "terrain" );
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidTarget(int2 xy)
|
||||
{
|
||||
var canTeleport = false;
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
if (unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell, false))
|
||||
{
|
||||
canTeleport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return canTeleport;
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return IsValidTarget(xy) ? "chrono-target" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ChronoshiftPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int Range = 1; // Range in cells
|
||||
public readonly int Duration = 30; // Seconds
|
||||
public readonly bool KillCargo = true;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ChronoshiftPower(init.self,this); }
|
||||
}
|
||||
|
||||
class ChronoshiftPower : SupportPower
|
||||
{
|
||||
public ChronoshiftPower(Actor self, ChronoshiftPowerInfo info) : base(self, info) { }
|
||||
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
a.Trait.Enable();
|
||||
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.TargetLocation);
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.ExtraLocation);
|
||||
foreach (var target in UnitsInRange(order.ExtraLocation))
|
||||
{
|
||||
var cs = target.Trait<Chronoshiftable>();
|
||||
var targetCell = target.Location + order.TargetLocation - order.ExtraLocation;
|
||||
var cpi = Info as ChronoshiftPowerInfo;
|
||||
|
||||
if (cs.CanChronoshiftTo(target, targetCell, true))
|
||||
cs.Teleport(target, targetCell,
|
||||
cpi.Duration * 25, cpi.KillCargo, self);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as ChronoshiftPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<Chronoshiftable>());
|
||||
}
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(string order, SupportPowerManager manager, ChronoshiftPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == MouseButton.Left)
|
||||
world.OrderGenerator = new SelectDestination(order, manager, power, xy);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var targetUnits = power.UnitsInRange(xy);
|
||||
foreach (var unit in targetUnits)
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var tiles = world.FindTilesInCircle(xy, range);
|
||||
foreach (var t in tiles)
|
||||
tile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return "chrono-select";
|
||||
}
|
||||
}
|
||||
|
||||
class SelectDestination : IOrderGenerator
|
||||
{
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int2 sourceLocation;
|
||||
readonly int range;
|
||||
readonly Sprite validTile, invalidTile, sourceTile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectDestination(string order, SupportPowerManager manager, ChronoshiftPower power, int2 sourceLocation)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.sourceLocation = sourceLocation;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
|
||||
// todo: this burns up more texture space every time someone uses chronoshift.
|
||||
validTile = UiOverlay.SynthesizeTile(0x0f);
|
||||
invalidTile = UiOverlay.SynthesizeTile(0x08);
|
||||
sourceTile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
yield break;
|
||||
}
|
||||
|
||||
var ret = OrderInner( world, xy, mi ).FirstOrDefault();
|
||||
if (ret == null)
|
||||
yield break;
|
||||
|
||||
world.CancelInputMode();
|
||||
yield return ret;
|
||||
}
|
||||
|
||||
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
// Cannot chronoshift into unexplored location
|
||||
if (IsValidTarget(xy))
|
||||
yield return new Order(order, manager.self, false)
|
||||
{
|
||||
TargetLocation = xy,
|
||||
ExtraLocation = sourceLocation
|
||||
};
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
|
||||
// Source tiles
|
||||
foreach (var t in world.FindTilesInCircle(sourceLocation, range))
|
||||
sourceTile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
|
||||
// Destination tiles
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
sourceTile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
|
||||
// Unit previews
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
foreach (var r in unit.Render())
|
||||
r.Sprite.DrawAt(r.Pos - Traits.Util.CenterOfCell(unit.Location) + Traits.Util.CenterOfCell(targetCell),
|
||||
wr.GetPaletteIndex(r.Palette ?? unit.Owner.Palette),
|
||||
r.Scale*r.Sprite.size);
|
||||
}
|
||||
|
||||
// Unit tiles
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
var canEnter = unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell, false);
|
||||
var tile = canEnter ? validTile : invalidTile;
|
||||
tile.DrawAt( wr, Game.CellSize * targetCell, "terrain" );
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidTarget(int2 xy)
|
||||
{
|
||||
var canTeleport = false;
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
{
|
||||
var targetCell = unit.Location + xy - sourceLocation;
|
||||
if (unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell, false))
|
||||
{
|
||||
canTeleport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return canTeleport;
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return IsValidTarget(xy) ? "chrono-target" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class GpsPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int RevealDelay = 0;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new GpsPower(init.self, this); }
|
||||
}
|
||||
|
||||
class GpsPower : SupportPower, INotifyDamage, ISync
|
||||
{
|
||||
public GpsPower(Actor self, GpsPowerInfo info) : base(self, info) { }
|
||||
|
||||
[Sync]
|
||||
public bool Granted;
|
||||
|
||||
public override void Charged(Actor self, string key)
|
||||
{
|
||||
self.Owner.PlayerActor.Trait<SupportPowerManager>().Powers[key].Activate(new Order());
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.LaunchSound);
|
||||
|
||||
w.Add(new SatelliteLaunch(self));
|
||||
|
||||
/* there is only one shroud, but it is misleadingly available through Player.Shroud */
|
||||
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
|
||||
() => { Granted = true; RefreshGps(self); }));
|
||||
});
|
||||
}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (e.DamageState == DamageState.Dead)
|
||||
{
|
||||
Granted = false;
|
||||
RefreshGps(self);
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshGps(Actor self)
|
||||
{
|
||||
if (self.World.LocalPlayer != null)
|
||||
self.World.LocalShroud.Disabled = self.World.Queries.WithTrait<GpsPower>()
|
||||
.Any(p => p.Actor.Owner.Stances[self.World.LocalPlayer] == Stance.Ally &&
|
||||
p.Trait.Granted);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class GpsPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int RevealDelay = 0;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new GpsPower(init.self, this); }
|
||||
}
|
||||
|
||||
class GpsPower : SupportPower, INotifyDamage, ISync
|
||||
{
|
||||
public GpsPower(Actor self, GpsPowerInfo info) : base(self, info) { }
|
||||
|
||||
[Sync]
|
||||
public bool Granted;
|
||||
|
||||
public override void Charged(Actor self, string key)
|
||||
{
|
||||
self.Owner.PlayerActor.Trait<SupportPowerManager>().Powers[key].Activate(new Order());
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.LaunchSound);
|
||||
|
||||
w.Add(new SatelliteLaunch(self));
|
||||
|
||||
/* there is only one shroud, but it is misleadingly available through Player.Shroud */
|
||||
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
|
||||
() => { Granted = true; RefreshGps(self); }));
|
||||
});
|
||||
}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (e.DamageState == DamageState.Dead)
|
||||
{
|
||||
Granted = false;
|
||||
RefreshGps(self);
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshGps(Actor self)
|
||||
{
|
||||
if (self.World.LocalPlayer != null)
|
||||
self.World.LocalShroud.Disabled = self.World.Queries.WithTrait<GpsPower>()
|
||||
.Any(p => p.Actor.Owner.Stances[self.World.LocalPlayer] == Stance.Ally &&
|
||||
p.Trait.Granted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using TUtil = OpenRA.Traits.Util;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IronCurtainPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int Duration = 10; // Seconds
|
||||
public readonly int Range = 1; // Range in cells
|
||||
|
||||
public override object Create(ActorInitializer init) { return new IronCurtainPower(init.self, this); }
|
||||
}
|
||||
|
||||
class IronCurtainPower : SupportPower
|
||||
{
|
||||
public IronCurtainPower(Actor self, IronCurtainPowerInfo info) : base(self, info) { }
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
Sound.Play("ironcur9.aud", Game.CellSize * order.TargetLocation);
|
||||
foreach (var target in UnitsInRange(order.TargetLocation))
|
||||
target.Trait<IronCurtainable>().Activate(target, (Info as IronCurtainPowerInfo).Duration * 25);
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as IronCurtainPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<IronCurtainable>());
|
||||
}
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
readonly IronCurtainPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(string order, SupportPowerManager manager, IronCurtainPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as IronCurtainPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == MouseButton.Left && power.UnitsInRange(xy).Any())
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
foreach (var unit in power.UnitsInRange(xy))
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
tile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return power.UnitsInRange(xy).Any() ? "ability" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using TUtil = OpenRA.Traits.Util;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IronCurtainPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int Duration = 10; // Seconds
|
||||
public readonly int Range = 1; // Range in cells
|
||||
|
||||
public override object Create(ActorInitializer init) { return new IronCurtainPower(init.self, this); }
|
||||
}
|
||||
|
||||
class IronCurtainPower : SupportPower
|
||||
{
|
||||
public IronCurtainPower(Actor self, IronCurtainPowerInfo info) : base(self, info) { }
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
Sound.Play("ironcur9.aud", Game.CellSize * order.TargetLocation);
|
||||
foreach (var target in UnitsInRange(order.TargetLocation))
|
||||
target.Trait<IronCurtainable>().Activate(target, (Info as IronCurtainPowerInfo).Duration * 25);
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as IronCurtainPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<IronCurtainable>());
|
||||
}
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
readonly IronCurtainPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(string order, SupportPowerManager manager, IronCurtainPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as IronCurtainPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == MouseButton.Left && power.UnitsInRange(xy).Any())
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
foreach (var unit in power.UnitsInRange(xy))
|
||||
wr.DrawSelectionBox(unit, Color.Red);
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
tile.DrawAt( wr, Game.CellSize * t, "terrain" );
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return power.UnitsInRange(xy).Any() ? "ability" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class NukePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[WeaponReference]
|
||||
public readonly string MissileWeapon = "";
|
||||
public readonly int2 SpawnOffset = int2.Zero;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new NukePower(init.self, this); }
|
||||
}
|
||||
|
||||
class NukePower : SupportPower
|
||||
{
|
||||
public NukePower(Actor self, NukePowerInfo info) : base(self, info) { }
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "nuke", MouseButton.Left);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
// Play to everyone but the current player
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
Sound.Play(Info.LaunchSound);
|
||||
|
||||
var npi = Info as NukePowerInfo;
|
||||
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
self.World.AddFrameEndTask(w => w.Add(
|
||||
new NukeLaunch(self.Owner, self, npi.MissileWeapon, npi.SpawnOffset,
|
||||
order.TargetLocation)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class NukePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[WeaponReference]
|
||||
public readonly string MissileWeapon = "";
|
||||
public readonly int2 SpawnOffset = int2.Zero;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new NukePower(init.self, this); }
|
||||
}
|
||||
|
||||
class NukePower : SupportPower
|
||||
{
|
||||
public NukePower(Actor self, NukePowerInfo info) : base(self, info) { }
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "nuke", MouseButton.Left);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
// Play to everyone but the current player
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
Sound.Play(Info.LaunchSound);
|
||||
|
||||
var npi = Info as NukePowerInfo;
|
||||
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
self.World.AddFrameEndTask(w => w.Add(
|
||||
new NukeLaunch(self.Owner, self, npi.MissileWeapon, npi.SpawnOffset,
|
||||
order.TargetLocation)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ParatroopersPowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference]
|
||||
public string[] DropItems = { };
|
||||
[ActorReference]
|
||||
public string UnitType = "badr";
|
||||
[ActorReference]
|
||||
public string FlareType = "flare";
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ParatroopersPower(init.self, this); }
|
||||
}
|
||||
|
||||
public class ParatroopersPower : SupportPower
|
||||
{
|
||||
public ParatroopersPower(Actor self, ParatroopersPowerInfo info) : base(self, info) { }
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var items = (Info as ParatroopersPowerInfo).DropItems;
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as ParatroopersPowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(new FlyCircle(order.TargetLocation));
|
||||
a.Trait<ParaDrop>().SetLZ(order.TargetLocation, flare);
|
||||
|
||||
var cargo = a.Trait<Cargo>();
|
||||
foreach (var i in items)
|
||||
cargo.Load(a, self.World.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary { new OwnerInit( a.Owner ) }));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ParatroopersPowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference]
|
||||
public string[] DropItems = { };
|
||||
[ActorReference]
|
||||
public string UnitType = "badr";
|
||||
[ActorReference]
|
||||
public string FlareType = "flare";
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ParatroopersPower(init.self, this); }
|
||||
}
|
||||
|
||||
public class ParatroopersPower : SupportPower
|
||||
{
|
||||
public ParatroopersPower(Actor self, ParatroopersPowerInfo info) : base(self, info) { }
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var items = (Info as ParatroopersPowerInfo).DropItems;
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as ParatroopersPowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(new FlyCircle(order.TargetLocation));
|
||||
a.Trait<ParaDrop>().SetLZ(order.TargetLocation, flare);
|
||||
|
||||
var cargo = a.Trait<Cargo>();
|
||||
foreach (var i in items)
|
||||
cargo.Load(a, self.World.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary { new OwnerInit( a.Owner ) }));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class SonarPulsePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); }
|
||||
}
|
||||
|
||||
public class SonarPulsePower : SupportPower
|
||||
{
|
||||
public SonarPulsePower(Actor self, SonarPulsePowerInfo info) : base(self, info) { }
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
// TODO: Reveal submarines
|
||||
|
||||
// Should this play for all players?
|
||||
Sound.Play("sonpulse.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class SonarPulsePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); }
|
||||
}
|
||||
|
||||
public class SonarPulsePower : SupportPower
|
||||
{
|
||||
public SonarPulsePower(Actor self, SonarPulsePowerInfo info) : base(self, info) { }
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
// TODO: Reveal submarines
|
||||
|
||||
// Should this play for all players?
|
||||
Sound.Play("sonpulse.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class SpyPlanePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int RevealTime = 6; // seconds
|
||||
public override object Create(ActorInitializer init) { return new SpyPlanePower(init.self,this); }
|
||||
}
|
||||
|
||||
class SpyPlanePower : SupportPower
|
||||
{
|
||||
public SpyPlanePower(Actor self, SpyPlanePowerInfo info) : base(self, info) { }
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var enterCell = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
var plane = self.World.CreateActor("u2", new TypeDictionary
|
||||
{
|
||||
new LocationInit( enterCell ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - enterCell, 0) ),
|
||||
new AltitudeInit( Rules.Info["u2"].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
plane.CancelActivity();
|
||||
plane.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w =>
|
||||
{
|
||||
var camera = w.CreateActor("camera", new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
});
|
||||
|
||||
camera.QueueActivity(new Wait(25 * (Info as SpyPlanePowerInfo).RevealTime));
|
||||
camera.QueueActivity(new RemoveSelf());
|
||||
})));
|
||||
plane.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
plane.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class SpyPlanePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int RevealTime = 6; // seconds
|
||||
public override object Create(ActorInitializer init) { return new SpyPlanePower(init.self,this); }
|
||||
}
|
||||
|
||||
class SpyPlanePower : SupportPower
|
||||
{
|
||||
public SpyPlanePower(Actor self, SpyPlanePowerInfo info) : base(self, info) { }
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
var enterCell = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
var plane = self.World.CreateActor("u2", new TypeDictionary
|
||||
{
|
||||
new LocationInit( enterCell ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - enterCell, 0) ),
|
||||
new AltitudeInit( Rules.Info["u2"].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
plane.CancelActivity();
|
||||
plane.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w =>
|
||||
{
|
||||
var camera = w.CreateActor("camera", new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
});
|
||||
|
||||
camera.QueueActivity(new Wait(25 * (Info as SpyPlanePowerInfo).RevealTime));
|
||||
camera.QueueActivity(new RemoveSelf());
|
||||
})));
|
||||
plane.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
plane.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public abstract class SupportPowerInfo : ITraitInfo
|
||||
{
|
||||
public readonly int ChargeTime = 0;
|
||||
public readonly string Image = null;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly bool AllowMultiple = false;
|
||||
public readonly bool OneShot = false;
|
||||
|
||||
public readonly string BeginChargeSound = null;
|
||||
public readonly string EndChargeSound = null;
|
||||
public readonly string SelectTargetSound = null;
|
||||
public readonly string LaunchSound = null;
|
||||
|
||||
public readonly string OrderName;
|
||||
public abstract object Create(ActorInitializer init);
|
||||
|
||||
public SupportPowerInfo() { OrderName = GetType().Name + "Order"; }
|
||||
}
|
||||
|
||||
public class SupportPower
|
||||
{
|
||||
public readonly Actor self;
|
||||
public readonly SupportPowerInfo Info;
|
||||
|
||||
public SupportPower(Actor self, SupportPowerInfo info)
|
||||
{
|
||||
Info = info;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public virtual void Charging(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.BeginChargeSound);
|
||||
}
|
||||
|
||||
public virtual void Charged(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.EndChargeSound);
|
||||
}
|
||||
|
||||
public virtual void Activate(Actor self, Order order) { }
|
||||
public virtual IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "ability", MouseButton.Left);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public abstract class SupportPowerInfo : ITraitInfo
|
||||
{
|
||||
public readonly int ChargeTime = 0;
|
||||
public readonly string Image = null;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly bool AllowMultiple = false;
|
||||
public readonly bool OneShot = false;
|
||||
|
||||
public readonly string BeginChargeSound = null;
|
||||
public readonly string EndChargeSound = null;
|
||||
public readonly string SelectTargetSound = null;
|
||||
public readonly string LaunchSound = null;
|
||||
|
||||
public readonly string OrderName;
|
||||
public abstract object Create(ActorInitializer init);
|
||||
|
||||
public SupportPowerInfo() { OrderName = GetType().Name + "Order"; }
|
||||
}
|
||||
|
||||
public class SupportPower
|
||||
{
|
||||
public readonly Actor self;
|
||||
public readonly SupportPowerInfo Info;
|
||||
|
||||
public SupportPower(Actor self, SupportPowerInfo info)
|
||||
{
|
||||
Info = info;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public virtual void Charging(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.BeginChargeSound);
|
||||
}
|
||||
|
||||
public virtual void Charged(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.EndChargeSound);
|
||||
}
|
||||
|
||||
public virtual void Activate(Actor self, Order order) { }
|
||||
public virtual IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "ability", MouseButton.Left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,205 +1,205 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class SupportPowerManagerInfo : ITraitInfo, ITraitPrerequisite<DeveloperModeInfo>
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new SupportPowerManager(init); }
|
||||
}
|
||||
|
||||
public class SupportPowerManager : ITick, IResolveOrder
|
||||
{
|
||||
public readonly Actor self;
|
||||
public Dictionary<string, SupportPowerInstance> Powers = new Dictionary<string, SupportPowerInstance>();
|
||||
|
||||
public readonly DeveloperMode devMode;
|
||||
public SupportPowerManager(ActorInitializer init)
|
||||
{
|
||||
self = init.self;
|
||||
devMode = init.self.Trait<DeveloperMode>();
|
||||
|
||||
init.world.ActorAdded += ActorAdded;
|
||||
init.world.ActorRemoved += ActorRemoved;
|
||||
}
|
||||
|
||||
void ActorAdded(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
|
||||
if (Powers.ContainsKey(key))
|
||||
{
|
||||
Powers[key].Instances.Add(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
var si = new SupportPowerInstance(key, this)
|
||||
{
|
||||
Instances = new List<SupportPower>() { t },
|
||||
RemainingTime = t.Info.ChargeTime * 25,
|
||||
TotalTime = t.Info.ChargeTime * 25,
|
||||
};
|
||||
|
||||
Powers.Add(key, si);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActorRemoved(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
Powers[key].Instances.Remove(t);
|
||||
if (Powers[key].Instances.Count == 0 && !Powers[key].Disabled)
|
||||
Powers.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
foreach(var power in Powers.Values)
|
||||
power.Tick();
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
// order.OrderString is the key of the support power
|
||||
if (Powers.ContainsKey(order.OrderString))
|
||||
Powers[order.OrderString].Activate(order);
|
||||
}
|
||||
|
||||
public void Target(string key)
|
||||
{
|
||||
if (Powers.ContainsKey(key))
|
||||
Powers[key].Target();
|
||||
}
|
||||
|
||||
public class SupportPowerInstance
|
||||
{
|
||||
readonly SupportPowerManager Manager;
|
||||
readonly string Key;
|
||||
|
||||
public List<SupportPower> Instances;
|
||||
public int RemainingTime;
|
||||
public int TotalTime;
|
||||
public bool Active { get; private set; }
|
||||
public bool Disabled { get; private set; }
|
||||
|
||||
public SupportPowerInfo Info { get { return Instances.First().Info; } }
|
||||
public bool Ready { get { return Active && RemainingTime == 0; } }
|
||||
|
||||
public SupportPowerInstance(string key, SupportPowerManager manager)
|
||||
{
|
||||
Manager = manager;
|
||||
Key = key;
|
||||
}
|
||||
|
||||
bool notifiedCharging;
|
||||
bool notifiedReady;
|
||||
public void Tick()
|
||||
{
|
||||
Active = !Disabled && Instances.Any(i => !i.self.TraitsImplementing<IDisable>().Any(d => d.Disabled));
|
||||
|
||||
if (Active)
|
||||
{
|
||||
var power = Instances.First();
|
||||
if (Manager.devMode.FastCharge && RemainingTime > 25)
|
||||
RemainingTime = 25;
|
||||
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
power.Charging(power.self, Key);
|
||||
notifiedCharging = true;
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& !notifiedReady)
|
||||
{
|
||||
power.Charged(power.self, Key);
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Target()
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
Manager.self.World.OrderGenerator = Instances.First().OrderGenerator(Key, Manager);
|
||||
}
|
||||
|
||||
public void Activate(Order order)
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
var power = Instances.First();
|
||||
// Note: order.Subject is the *player* actor
|
||||
power.Activate(power.self, order);
|
||||
RemainingTime = TotalTime;
|
||||
notifiedCharging = notifiedReady = false;
|
||||
|
||||
if (Info.OneShot)
|
||||
Disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SelectGenericPowerTarget : IOrderGenerator
|
||||
{
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
readonly string cursor;
|
||||
readonly MouseButton expectedButton;
|
||||
|
||||
public SelectGenericPowerTarget(string order, SupportPowerManager manager, string cursor, MouseButton button)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.cursor = cursor;
|
||||
expectedButton = button;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == expectedButton && world.Map.IsInMap(xy))
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
public virtual void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
}
|
||||
}
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class SupportPowerManagerInfo : ITraitInfo, ITraitPrerequisite<DeveloperModeInfo>
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new SupportPowerManager(init); }
|
||||
}
|
||||
|
||||
public class SupportPowerManager : ITick, IResolveOrder
|
||||
{
|
||||
public readonly Actor self;
|
||||
public Dictionary<string, SupportPowerInstance> Powers = new Dictionary<string, SupportPowerInstance>();
|
||||
|
||||
public readonly DeveloperMode devMode;
|
||||
public SupportPowerManager(ActorInitializer init)
|
||||
{
|
||||
self = init.self;
|
||||
devMode = init.self.Trait<DeveloperMode>();
|
||||
|
||||
init.world.ActorAdded += ActorAdded;
|
||||
init.world.ActorRemoved += ActorRemoved;
|
||||
}
|
||||
|
||||
void ActorAdded(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
|
||||
if (Powers.ContainsKey(key))
|
||||
{
|
||||
Powers[key].Instances.Add(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
var si = new SupportPowerInstance(key, this)
|
||||
{
|
||||
Instances = new List<SupportPower>() { t },
|
||||
RemainingTime = t.Info.ChargeTime * 25,
|
||||
TotalTime = t.Info.ChargeTime * 25,
|
||||
};
|
||||
|
||||
Powers.Add(key, si);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActorRemoved(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
Powers[key].Instances.Remove(t);
|
||||
if (Powers[key].Instances.Count == 0 && !Powers[key].Disabled)
|
||||
Powers.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
foreach(var power in Powers.Values)
|
||||
power.Tick();
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
// order.OrderString is the key of the support power
|
||||
if (Powers.ContainsKey(order.OrderString))
|
||||
Powers[order.OrderString].Activate(order);
|
||||
}
|
||||
|
||||
public void Target(string key)
|
||||
{
|
||||
if (Powers.ContainsKey(key))
|
||||
Powers[key].Target();
|
||||
}
|
||||
|
||||
public class SupportPowerInstance
|
||||
{
|
||||
readonly SupportPowerManager Manager;
|
||||
readonly string Key;
|
||||
|
||||
public List<SupportPower> Instances;
|
||||
public int RemainingTime;
|
||||
public int TotalTime;
|
||||
public bool Active { get; private set; }
|
||||
public bool Disabled { get; private set; }
|
||||
|
||||
public SupportPowerInfo Info { get { return Instances.First().Info; } }
|
||||
public bool Ready { get { return Active && RemainingTime == 0; } }
|
||||
|
||||
public SupportPowerInstance(string key, SupportPowerManager manager)
|
||||
{
|
||||
Manager = manager;
|
||||
Key = key;
|
||||
}
|
||||
|
||||
bool notifiedCharging;
|
||||
bool notifiedReady;
|
||||
public void Tick()
|
||||
{
|
||||
Active = !Disabled && Instances.Any(i => !i.self.TraitsImplementing<IDisable>().Any(d => d.Disabled));
|
||||
|
||||
if (Active)
|
||||
{
|
||||
var power = Instances.First();
|
||||
if (Manager.devMode.FastCharge && RemainingTime > 25)
|
||||
RemainingTime = 25;
|
||||
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
power.Charging(power.self, Key);
|
||||
notifiedCharging = true;
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& !notifiedReady)
|
||||
{
|
||||
power.Charged(power.self, Key);
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Target()
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
Manager.self.World.OrderGenerator = Instances.First().OrderGenerator(Key, Manager);
|
||||
}
|
||||
|
||||
public void Activate(Order order)
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
var power = Instances.First();
|
||||
// Note: order.Subject is the *player* actor
|
||||
power.Activate(power.self, order);
|
||||
RemainingTime = TotalTime;
|
||||
notifiedCharging = notifiedReady = false;
|
||||
|
||||
if (Info.OneShot)
|
||||
Disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SelectGenericPowerTarget : IOrderGenerator
|
||||
{
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
readonly string cursor;
|
||||
readonly MouseButton expectedButton;
|
||||
|
||||
public SelectGenericPowerTarget(string order, SupportPowerManager manager, string cursor, MouseButton button)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.cursor = cursor;
|
||||
expectedButton = button;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == expectedButton && world.Map.IsInMap(xy))
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
public virtual void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user