new support power impl
This commit is contained in:
@@ -27,13 +27,13 @@ namespace OpenRa.FileFormats
|
||||
|
||||
public T Get<T>()
|
||||
{
|
||||
var l = innerInherit[ typeof( T ) ];
|
||||
if( l.Count == 1 )
|
||||
return (T)l[ 0 ];
|
||||
else if( l.Count == 0 )
|
||||
throw new InvalidOperationException( string.Format( "TypeDictionary does not contain instance of type `{0}`", typeof( T ) ) );
|
||||
var l = innerInherit[typeof(T)];
|
||||
if (l.Count == 1)
|
||||
return (T)l[0];
|
||||
else if (l.Count == 0)
|
||||
throw new InvalidOperationException(string.Format("TypeDictionary does not contain instance of type `{0}`", typeof(T)));
|
||||
else
|
||||
throw new InvalidOperationException( string.Format( "TypeDictionary contains multiple instance of type `{0}`", typeof( T ) ) );
|
||||
throw new InvalidOperationException(string.Format("TypeDictionary contains multiple instance of type `{0}`", typeof(T)));
|
||||
}
|
||||
|
||||
public T GetOrDefault<T>()
|
||||
|
||||
@@ -117,10 +117,10 @@ namespace OpenRa
|
||||
u => u.Name,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(u.Traits.Get<BuildableInfo>().Icon ?? (u.Name + "icon"))[0]);
|
||||
|
||||
spsprites = Rules.SupportPowerInfo
|
||||
spsprites = Rules.Info.Values.SelectMany( u => u.Traits.WithInterface<SupportPowerInfo>() )
|
||||
.ToDictionary(
|
||||
u => u.Key,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(u.Value.Image)[0]);
|
||||
u => u.Image,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(u.Image)[0]);
|
||||
|
||||
var groups = Rules.Info.Values.Select( x => x.Category ).Distinct().Where( g => g != null ).ToList();
|
||||
|
||||
@@ -893,8 +893,8 @@ namespace OpenRa
|
||||
|
||||
void DrawSupportPowers( World world )
|
||||
{
|
||||
var numPowers = world.LocalPlayer.SupportPowers.Values
|
||||
.Where(a => a.IsAvailable).Count();
|
||||
var powers = world.LocalPlayer.PlayerActor.traits.WithInterface<SupportPower>();
|
||||
var numPowers = powers.Count(p => p.IsAvailable);
|
||||
|
||||
if (numPowers == 0) return;
|
||||
|
||||
@@ -907,38 +907,38 @@ namespace OpenRa
|
||||
|
||||
var y = 24;
|
||||
|
||||
string tooltipItem = null;
|
||||
SupportPower tooltipItem = null;
|
||||
int2 tooltipPos = int2.Zero;
|
||||
|
||||
foreach (var sp in world.LocalPlayer.SupportPowers)
|
||||
foreach (var sp in powers)
|
||||
{
|
||||
var image = spsprites[sp.Key];
|
||||
if (sp.Value.IsAvailable)
|
||||
var image = spsprites[sp.Info.Image];
|
||||
if (sp.IsAvailable)
|
||||
{
|
||||
var drawPos = new float2(5, y);
|
||||
shpRenderer.DrawSprite(image, drawPos, PaletteType.Chrome);
|
||||
|
||||
clock.PlayFetchIndex("idle",
|
||||
() => (sp.Value.TotalTime - sp.Value.RemainingTime)
|
||||
* NumClockFrames / sp.Value.TotalTime);
|
||||
() => (sp.TotalTime - sp.RemainingTime)
|
||||
* NumClockFrames / sp.TotalTime);
|
||||
clock.Tick();
|
||||
|
||||
shpRenderer.DrawSprite(clock.Image, drawPos, PaletteType.Chrome);
|
||||
|
||||
var rect = new Rectangle(5, y, 64, 48);
|
||||
if (sp.Value.IsDone)
|
||||
if (sp.IsReady)
|
||||
{
|
||||
ready.Play("ready");
|
||||
shpRenderer.DrawSprite(ready.Image,
|
||||
drawPos + new float2((64 - ready.Image.size.X) / 2, 2),
|
||||
PaletteType.Chrome);
|
||||
|
||||
AddButton(rect, HandleSupportPower( sp.Value ));
|
||||
AddButton(rect, HandleSupportPower( sp ));
|
||||
}
|
||||
|
||||
if (rect.Contains(lastMousePos.ToPoint()))
|
||||
{
|
||||
tooltipItem = sp.Key;
|
||||
tooltipItem = sp;
|
||||
tooltipPos = drawPos.ToInt2() + new int2(72, 0);
|
||||
}
|
||||
|
||||
@@ -965,25 +965,23 @@ namespace OpenRa
|
||||
return "{0:D2}:{1:D2}".F(minutes, seconds % 60);
|
||||
}
|
||||
|
||||
void DrawSupportPowerTooltip(World world, string sp, int2 pos)
|
||||
void DrawSupportPowerTooltip(World world, SupportPower sp, int2 pos)
|
||||
{
|
||||
var tooltipSprite = ChromeProvider.GetImage(renderer, chromeCollection, "tooltip-bg");
|
||||
rgbaRenderer.DrawSprite(tooltipSprite, pos, PaletteType.Chrome);
|
||||
rgbaRenderer.Flush();
|
||||
|
||||
var info = Rules.SupportPowerInfo[sp];
|
||||
|
||||
pos += new int2(5, 5);
|
||||
|
||||
renderer.DrawText2(info.Description, pos, Color.White);
|
||||
renderer.DrawText2(sp.Info.Description, pos, Color.White);
|
||||
|
||||
var timer = "Charge Time: {0}".F(FormatTime(world.LocalPlayer.SupportPowers[sp].RemainingTime));
|
||||
var timer = "Charge Time: {0}".F(FormatTime(sp.RemainingTime));
|
||||
DrawRightAligned(timer, pos + new int2((int)tooltipSprite.size.X - 10, 0), Color.White);
|
||||
|
||||
if (info.LongDesc != null)
|
||||
if (sp.Info.LongDesc != null)
|
||||
{
|
||||
pos += new int2(0, 25);
|
||||
renderer.DrawText(info.LongDesc.Replace("\\n", "\n"), pos, Color.White);
|
||||
renderer.DrawText(sp.Info.LongDesc.Replace("\\n", "\n"), pos, Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ namespace OpenRa
|
||||
if( e.KeyCode == Keys.F8 && !Game.orderManager.GameStarted )
|
||||
{
|
||||
Game.orderManager.IssueOrder(
|
||||
new Order( "ToggleReady", Game.world.LocalPlayer.PlayerActor, null, int2.Zero, "" ) { IsImmediate = true } );
|
||||
new Order( "ToggleReady", Game.world.LocalPlayer.PlayerActor, "" ) { IsImmediate = true } );
|
||||
}
|
||||
|
||||
/* temporary hack: DO NOT LEAVE IN */
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace OpenRa
|
||||
public static InfoLoader<WarheadInfo> WarheadInfo;
|
||||
public static InfoLoader<ProjectileInfo> ProjectileInfo;
|
||||
public static InfoLoader<VoiceInfo> VoiceInfo;
|
||||
public static InfoLoader<SupportPowerInfo> SupportPowerInfo;
|
||||
public static GeneralInfo General;
|
||||
public static AftermathInfo Aftermath;
|
||||
public static TechTree TechTree;
|
||||
@@ -40,8 +39,7 @@ namespace OpenRa
|
||||
"Weapon",
|
||||
"Warhead",
|
||||
"Projectile",
|
||||
"Voice",
|
||||
"SupportPower");
|
||||
"Voice");
|
||||
|
||||
WeaponInfo = new InfoLoader<WeaponInfo>(
|
||||
Pair.New<string, Func<string, WeaponInfo>>("Weapon", _ => new WeaponInfo()));
|
||||
@@ -51,8 +49,6 @@ namespace OpenRa
|
||||
Pair.New<string, Func<string, ProjectileInfo>>("Projectile", _ => new ProjectileInfo()));
|
||||
VoiceInfo = new InfoLoader<VoiceInfo>(
|
||||
Pair.New<string, Func<string, VoiceInfo>>("Voice", _ => new VoiceInfo()));
|
||||
SupportPowerInfo = new InfoLoader<SupportPowerInfo>(
|
||||
Pair.New<string, Func<string, SupportPowerInfo>>("SupportPower", _ => new SupportPowerInfo()));
|
||||
|
||||
var yamlRules = m.Rules.Reverse().Select(a => MiniYaml.FromFile(a)).Aggregate(MiniYaml.Merge);
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
namespace OpenRa.GameRules
|
||||
{
|
||||
public class SupportPowerInfo
|
||||
{
|
||||
public readonly bool Powered = true;
|
||||
public readonly bool OneShot = false;
|
||||
public readonly float ChargeTime = 0;
|
||||
public readonly string Image;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly string[] Prerequisite = { };
|
||||
public readonly int TechLevel = -1;
|
||||
public readonly bool GivenAuto = true;
|
||||
public readonly string Impl = null;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRa.SupportPowers;
|
||||
|
||||
namespace OpenRa
|
||||
{
|
||||
@@ -26,6 +25,21 @@ namespace OpenRa
|
||||
this.TargetString = targetString;
|
||||
}
|
||||
|
||||
public Order(string orderString, Actor subject)
|
||||
: this(orderString, subject, null, int2.Zero, null) { }
|
||||
public Order(string orderString, Actor subject, Actor targetActor)
|
||||
: this(orderString, subject, targetActor, int2.Zero, null) { }
|
||||
public Order(string orderString, Actor subject, int2 targetLocation)
|
||||
: this(orderString, subject, null, targetLocation, null) { }
|
||||
public Order(string orderString, Actor subject, string targetString)
|
||||
: this(orderString, subject, null, int2.Zero, targetString) { }
|
||||
public Order(string orderString, Actor subject, Actor targetActor, int2 targetLocation)
|
||||
: this(orderString, subject, targetActor, targetLocation, null) { }
|
||||
public Order(string orderString, Actor subject, Actor targetActor, string targetString)
|
||||
: this(orderString, subject, targetActor, int2.Zero, targetString) { }
|
||||
public Order(string orderString, Actor subject, int2 targetLocation, string targetString)
|
||||
: this(orderString, subject, null, targetLocation, targetString) { }
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
if (IsImmediate) /* chat, whatever */
|
||||
@@ -99,7 +113,7 @@ namespace OpenRa
|
||||
var name = r.ReadString();
|
||||
var data = r.ReadString();
|
||||
|
||||
return new Order( name, LookupPlayer( world, playerID ).PlayerActor, null, int2.Zero, data ) { IsImmediate = true };
|
||||
return new Order( name, LookupPlayer( world, playerID ).PlayerActor, data ) { IsImmediate = true };
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -136,28 +150,22 @@ namespace OpenRa
|
||||
// Now that Orders are resolved by individual Actors, these are weird; you unpack orders manually, but not pack them.
|
||||
public static Order Chat(Player subject, string text)
|
||||
{
|
||||
return new Order("Chat", subject.PlayerActor, null, int2.Zero, text)
|
||||
{ IsImmediate = true };
|
||||
return new Order("Chat", subject.PlayerActor, text) { IsImmediate = true };
|
||||
}
|
||||
|
||||
public static Order StartProduction(Player subject, string item)
|
||||
{
|
||||
return new Order("StartProduction", subject.PlayerActor, null, int2.Zero, item );
|
||||
return new Order("StartProduction", subject.PlayerActor, item );
|
||||
}
|
||||
|
||||
public static Order PauseProduction(Player subject, string item, bool pause)
|
||||
{
|
||||
return new Order("PauseProduction", subject.PlayerActor, null, new int2( pause ? 1 : 0, 0 ), item);
|
||||
return new Order("PauseProduction", subject.PlayerActor, new int2( pause ? 1 : 0, 0 ), item);
|
||||
}
|
||||
|
||||
public static Order CancelProduction(Player subject, string item)
|
||||
{
|
||||
return new Order("CancelProduction", subject.PlayerActor, null, int2.Zero, item);
|
||||
}
|
||||
|
||||
public static Order PlayAnimation(Actor actor, string animationString)
|
||||
{
|
||||
return new Order("PlayAnimation", actor, null, int2.Zero, animationString);
|
||||
return new Order("CancelProduction", subject.PlayerActor, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
<Compile Include="GameRules\ArmorType.cs" />
|
||||
<Compile Include="GameRules\GeneralInfo.cs" />
|
||||
<Compile Include="GameRules\ActorInfo.cs" />
|
||||
<Compile Include="GameRules\SupportPowerInfo.cs" />
|
||||
<Compile Include="GameRules\TechTree.cs" />
|
||||
<Compile Include="GameRules\UserSettings.cs" />
|
||||
<Compile Include="GameRules\VoiceInfo.cs" />
|
||||
@@ -123,12 +122,6 @@
|
||||
<Compile Include="Shroud.cs" />
|
||||
<Compile Include="Smudge.cs" />
|
||||
<Compile Include="Sound.cs" />
|
||||
<Compile Include="SupportPower.cs" />
|
||||
<Compile Include="SupportPowers\ChronospherePower.cs" />
|
||||
<Compile Include="SupportPowers\GpsSatellite.cs" />
|
||||
<Compile Include="SupportPowers\IronCurtainPower.cs" />
|
||||
<Compile Include="SupportPowers\ISupportPowerImpl.cs" />
|
||||
<Compile Include="SupportPowers\NullPower.cs" />
|
||||
<Compile Include="Support\OpenAlInterop.cs" />
|
||||
<Compile Include="Support\PerfHistory.cs" />
|
||||
<Compile Include="Sync.cs" />
|
||||
@@ -216,22 +209,24 @@
|
||||
<Compile Include="Traits\Cargo.cs" />
|
||||
<Compile Include="Traits\Chronoshiftable.cs" />
|
||||
<Compile Include="Traits\ChronoshiftPaletteEffect.cs" />
|
||||
<Compile Include="Traits\Chronosphere.cs" />
|
||||
<Compile Include="Traits\ChronoshiftPower.cs" />
|
||||
<Compile Include="Traits\Explodes.cs" />
|
||||
<Compile Include="Traits\Fake.cs" />
|
||||
<Compile Include="Traits\GeneratesGap.cs" />
|
||||
<Compile Include="Traits\GpsLaunchSite.cs" />
|
||||
<Compile Include="Traits\GpsPower.cs" />
|
||||
<Compile Include="Traits\Harvester.cs" />
|
||||
<Compile Include="Traits\Helicopter.cs" />
|
||||
<Compile Include="Traits\InvisibleToOthers.cs" />
|
||||
<Compile Include="Traits\ConstructionYard.cs" />
|
||||
<Compile Include="Traits\IronCurtain.cs" />
|
||||
<Compile Include="Traits\IronCurtainable.cs" />
|
||||
<Compile Include="Traits\IronCurtainPower.cs" />
|
||||
<Compile Include="Traits\JamsRadar.cs" />
|
||||
<Compile Include="Traits\LightPaletteRotator.cs" />
|
||||
<Compile Include="Traits\LimitedAmmo.cs" />
|
||||
<Compile Include="Traits\Passenger.cs" />
|
||||
<Compile Include="Traits\PlaceBuilding.cs" />
|
||||
<Compile Include="Traits\SupportPower.cs" />
|
||||
<Compile Include="Traits\ProvidesRadar.cs" />
|
||||
<Compile Include="Traits\Repairable.cs" />
|
||||
<Compile Include="Traits\Reservable.cs" />
|
||||
|
||||
@@ -3,19 +3,16 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using OpenRa.Traits;
|
||||
using OpenRa.SupportPowers;
|
||||
|
||||
namespace OpenRa.Orders
|
||||
{
|
||||
class ChronoshiftDestinationOrderGenerator : IOrderGenerator
|
||||
{
|
||||
public readonly Actor self;
|
||||
SupportPower power;
|
||||
|
||||
public ChronoshiftDestinationOrderGenerator(Actor self, SupportPower power)
|
||||
public ChronoshiftDestinationOrderGenerator(Actor self)
|
||||
{
|
||||
this.self = self;
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
@@ -25,8 +22,9 @@ namespace OpenRa.Orders
|
||||
Game.controller.CancelInputMode();
|
||||
yield break;
|
||||
}
|
||||
yield return new Order("Chronoshift", self, null, xy,
|
||||
power != null ? power.Name : null);
|
||||
|
||||
yield return new Order("Chronoshift", self, xy);
|
||||
yield return new Order("ChronosphereFinish", self.Owner.PlayerActor);
|
||||
}
|
||||
|
||||
public void Tick( World world ) {}
|
||||
|
||||
@@ -3,17 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.GameRules;
|
||||
using OpenRa.Traits;
|
||||
using OpenRa.SupportPowers;
|
||||
|
||||
namespace OpenRa.Orders
|
||||
{
|
||||
class ChronosphereSelectOrderGenerator : IOrderGenerator
|
||||
{
|
||||
SupportPower power;
|
||||
public ChronosphereSelectOrderGenerator(SupportPower power)
|
||||
{
|
||||
this.power = power;
|
||||
}
|
||||
public ChronosphereSelectOrderGenerator() {}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
@@ -34,8 +29,10 @@ namespace OpenRa.Orders
|
||||
&& a.traits.Contains<Selectable>()).FirstOrDefault();
|
||||
|
||||
if (underCursor != null)
|
||||
yield return new Order("ChronosphereSelect", underCursor, null, int2.Zero, power.Name);
|
||||
yield return new Order("ChronosphereSelect", world.LocalPlayer.PlayerActor, underCursor);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
@@ -43,8 +40,9 @@ namespace OpenRa.Orders
|
||||
var hasChronosphere = world.Actors
|
||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<Chronosphere>());
|
||||
|
||||
if (!hasChronosphere)
|
||||
Game.controller.CancelInputMode();
|
||||
// HACK: re-enable this
|
||||
//if (!hasChronosphere)
|
||||
// Game.controller.CancelInputMode();
|
||||
}
|
||||
|
||||
public void Render( World world ) { }
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.GameRules;
|
||||
using OpenRa.Traits;
|
||||
using OpenRa.SupportPowers;
|
||||
|
||||
namespace OpenRa.Orders
|
||||
{
|
||||
@@ -34,8 +33,10 @@ namespace OpenRa.Orders
|
||||
&& a.traits.Contains<Selectable>()).FirstOrDefault();
|
||||
|
||||
if (underCursor != null)
|
||||
yield return new Order("IronCurtain", underCursor, null, int2.Zero, power.Name);
|
||||
yield return new Order("IronCurtain", underCursor.Owner.PlayerActor, underCursor);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRa.Orders
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, null, topLeft, Building);
|
||||
yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, topLeft, Building);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRa.Orders
|
||||
&& a.traits.Contains<Selectable>()).FirstOrDefault();
|
||||
|
||||
if (underCursor != null)
|
||||
yield return new Order("PowerDown", underCursor, null, int2.Zero, null);
|
||||
yield return new Order("PowerDown", underCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRa.Orders
|
||||
var building = underCursor != null ? underCursor.Info.Traits.Get<BuildingInfo>() : null;
|
||||
|
||||
if (building != null && building.Repairable && underCursor.Health < building.HP)
|
||||
yield return new Order("Repair", underCursor, null, int2.Zero, null);
|
||||
yield return new Order("Repair", underCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRa.Orders
|
||||
var building = underCursor != null ? underCursor.Info.Traits.Get<BuildingInfo>() : null;
|
||||
|
||||
if (building != null && !building.Unsellable)
|
||||
yield return new Order("Sell", underCursor, null, int2.Zero, null);
|
||||
yield return new Order("Sell", underCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace OpenRa
|
||||
Game.chat.AddLine(Color.White, "Debug", "Requesting package: {0}".F(currentPackage));
|
||||
|
||||
Game.orderManager.IssueOrder(
|
||||
new Order("RequestFile", Game.world.LocalPlayer.PlayerActor, null, int2.Zero, currentPackage) { IsImmediate = true });
|
||||
new Order("RequestFile", Game.world.LocalPlayer.PlayerActor, currentPackage) { IsImmediate = true });
|
||||
|
||||
Fraction = 0f;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace OpenRa
|
||||
public World World { get { return PlayerActor.World; } }
|
||||
|
||||
public Shroud Shroud;
|
||||
public Dictionary<string, SupportPower> SupportPowers;
|
||||
|
||||
public Player( World world, int index, Session.Client client )
|
||||
{
|
||||
@@ -41,10 +40,6 @@ namespace OpenRa
|
||||
this.Palette = client != null ? (PaletteType)client.Palette : (PaletteType)index;
|
||||
this.PlayerName = client != null ? client.Name : "Player {0}".F(index+1);
|
||||
this.Race = client != null ? (Race)client.Race : Race.Allies;
|
||||
|
||||
SupportPowers = Rules.SupportPowerInfo.ToDictionary(
|
||||
spi => spi.Key,
|
||||
spi => new SupportPower(spi.Key, spi.Value, this));
|
||||
}
|
||||
|
||||
void UpdatePower()
|
||||
@@ -134,9 +129,6 @@ namespace OpenRa
|
||||
UpdateOreCapacity();
|
||||
Shroud.Tick( World );
|
||||
|
||||
foreach (var sp in SupportPowers.Values)
|
||||
sp.Tick();
|
||||
|
||||
if (this == World.LocalPlayer)
|
||||
{
|
||||
var totalMoney = Cash + Ore;
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRa.GameRules;
|
||||
using OpenRa.SupportPowers;
|
||||
using OpenRa.Traits;
|
||||
|
||||
namespace OpenRa
|
||||
{
|
||||
// todo: fix this to route Activate through the orders system (otherwise desync in netplay)
|
||||
|
||||
public class SupportPower
|
||||
{
|
||||
public readonly SupportPowerInfo Info;
|
||||
public readonly Player Owner;
|
||||
public readonly ISupportPowerImpl Impl;
|
||||
public readonly string Name;
|
||||
|
||||
static ISupportPowerImpl ConstructPowerImpl(string implName)
|
||||
{
|
||||
var type = typeof(ISupportPowerImpl).Assembly.GetType(
|
||||
typeof(ISupportPowerImpl).Namespace + "." + implName, true, false);
|
||||
var ctor = type.GetConstructor(Type.EmptyTypes);
|
||||
return (ISupportPowerImpl)ctor.Invoke(new object[] { });
|
||||
}
|
||||
|
||||
public SupportPower(string name, SupportPowerInfo info, Player owner)
|
||||
{
|
||||
Name = name;
|
||||
Info = info;
|
||||
Owner = owner;
|
||||
RemainingTime = TotalTime = (int)(info.ChargeTime * 60 * 25);
|
||||
Impl = ConstructPowerImpl(info.Impl);
|
||||
}
|
||||
|
||||
public bool IsUsed;
|
||||
public bool IsAvailable { get; private set; }
|
||||
public bool IsDone { get { return RemainingTime == 0; } }
|
||||
public int RemainingTime { get; private set; }
|
||||
public int TotalTime { get; private set; }
|
||||
bool notifiedReady = false;
|
||||
bool notifiedCharging = false;
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (Info.OneShot && IsUsed)
|
||||
return;
|
||||
|
||||
if (Info.GivenAuto)
|
||||
{
|
||||
var buildings = Rules.TechTree.GatherBuildings(Owner);
|
||||
var effectivePrereq = Info.Prerequisite
|
||||
.Select( a => a.ToLowerInvariant() )
|
||||
.Where( a => Rules.Info[a].Traits.Get<BuildableInfo>().Owner.Contains( Owner.Race ));
|
||||
|
||||
IsAvailable = Info.TechLevel > -1
|
||||
&& effectivePrereq.Any()
|
||||
&& effectivePrereq.All(a => buildings[a].Count > 0);
|
||||
}
|
||||
|
||||
if (IsAvailable && (!Info.Powered || Owner.GetPowerState() == PowerState.Normal))
|
||||
{
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
Impl.IsChargingNotification(this);
|
||||
notifiedCharging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& Impl != null
|
||||
&& !notifiedReady)
|
||||
{
|
||||
Impl.IsReadyNotification(this);
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (Impl != null)
|
||||
Impl.Activate(this);
|
||||
}
|
||||
|
||||
public void FinishActivate()
|
||||
{
|
||||
if (Info.OneShot)
|
||||
{
|
||||
IsUsed = true;
|
||||
IsAvailable = false;
|
||||
}
|
||||
RemainingTime = TotalTime;
|
||||
notifiedReady = false;
|
||||
notifiedCharging = false;
|
||||
}
|
||||
|
||||
public void Give(bool requireCharge) // called by crate/spy/etc code
|
||||
{
|
||||
IsAvailable = true;
|
||||
IsUsed = false;
|
||||
RemainingTime = requireCharge ? TotalTime : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using OpenRa.Orders;
|
||||
using OpenRa.Traits;
|
||||
|
||||
namespace OpenRa.SupportPowers
|
||||
{
|
||||
class ChronospherePower : ISupportPowerImpl
|
||||
{
|
||||
public void IsReadyNotification(SupportPower p) { Sound.Play("chrordy1.aud"); }
|
||||
public void IsChargingNotification(SupportPower p) { Sound.Play("chrochr1.aud"); }
|
||||
|
||||
public void OnFireNotification(Actor target, int2 xy)
|
||||
{
|
||||
p.FinishActivate();
|
||||
Game.controller.CancelInputMode();
|
||||
|
||||
Sound.Play("chrono2.aud");
|
||||
|
||||
// Play chronosphere active anim
|
||||
var chronosphere = target.World.Actors.Where(a => a.Owner == p.Owner && a.traits.Contains<Chronosphere>()).FirstOrDefault();
|
||||
if (chronosphere != null)
|
||||
Game.orderManager.IssueOrder(Order.PlayAnimation(chronosphere, "active"));
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in target.World.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
||||
}
|
||||
SupportPower p;
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
this.p = p;
|
||||
Game.controller.orderGenerator = new ChronosphereSelectOrderGenerator(p);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System.Linq;
|
||||
using OpenRa.Effects;
|
||||
using OpenRa.Traits;
|
||||
|
||||
namespace OpenRa.SupportPowers
|
||||
{
|
||||
class GpsSatellite : ISupportPowerImpl
|
||||
{
|
||||
const int revealDelay = 15 * 25;
|
||||
|
||||
public void OnFireNotification(Actor a, int2 xy) { }
|
||||
public void IsChargingNotification(SupportPower p) { }
|
||||
public void IsReadyNotification(SupportPower p)
|
||||
{
|
||||
var launchSite = p.Owner.World.Actors
|
||||
.FirstOrDefault(a => a.Owner == p.Owner && a.traits.Contains<GpsLaunchSite>());
|
||||
|
||||
if (launchSite == null)
|
||||
return;
|
||||
|
||||
p.Owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
w.Add(new SatelliteLaunch(launchSite));
|
||||
w.Add(new DelayedAction(revealDelay, () => p.Owner.Shroud.HasGPS = true));
|
||||
});
|
||||
|
||||
p.FinishActivate();
|
||||
}
|
||||
|
||||
public void Activate(SupportPower p) {}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.SupportPowers
|
||||
{
|
||||
public interface ISupportPowerImpl
|
||||
{
|
||||
void Activate(SupportPower p);
|
||||
void OnFireNotification(Actor target, int2 xy);
|
||||
void IsChargingNotification(SupportPower p);
|
||||
void IsReadyNotification(SupportPower p);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.Orders;
|
||||
using OpenRa.Traits;
|
||||
|
||||
namespace OpenRa.SupportPowers
|
||||
{
|
||||
class IronCurtainPower : ISupportPowerImpl
|
||||
{
|
||||
public void IsReadyNotification(SupportPower p)
|
||||
{
|
||||
Sound.Play("ironrdy1.aud");
|
||||
}
|
||||
|
||||
public void IsChargingNotification(SupportPower p)
|
||||
{
|
||||
Sound.Play("ironchg1.aud");
|
||||
}
|
||||
|
||||
public void OnFireNotification(Actor target, int2 xy)
|
||||
{
|
||||
p.FinishActivate();
|
||||
Game.controller.CancelInputMode();
|
||||
Sound.Play("ironcur9.aud");
|
||||
|
||||
// Play active anim
|
||||
var ironCurtain = target.World.Actors
|
||||
.Where(a => a.Owner == p.Owner && a.traits.Contains<IronCurtain>())
|
||||
.FirstOrDefault();
|
||||
if (ironCurtain != null)
|
||||
Game.orderManager.IssueOrder(Order.PlayAnimation(ironCurtain, "active"));
|
||||
|
||||
}
|
||||
SupportPower p;
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
this.p = p;
|
||||
// Pick a building to use
|
||||
Game.controller.orderGenerator = new IronCurtainOrderGenerator(p);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.SupportPowers
|
||||
{
|
||||
class NullPower : ISupportPowerImpl
|
||||
{
|
||||
public void OnFireNotification(Actor a, int2 xy) { }
|
||||
public void IsReadyNotification(SupportPower p) { }
|
||||
public void IsChargingNotification(SupportPower p) { }
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
// if this was a real power, i'd do something here!
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace OpenRa.Mods.Aftermath
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right && xy == self.Location && chargeTick <= 0)
|
||||
return new Order("Deploy", self, null, int2.Zero, null);
|
||||
return new Order("Deploy", self);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRa.Mods.Aftermath.Orders
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new Order("ChronoshiftSelf", self, null, xy, null);
|
||||
yield return new Order("ChronoshiftSelf", self, xy);
|
||||
}
|
||||
|
||||
public void Tick( World world ) { }
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace OpenRa.Mods.RA
|
||||
if (underCursor.Owner == self.Owner && !mi.Modifiers.HasModifier(Modifiers.Ctrl)) return null;
|
||||
if (!underCursor.traits.Contains<Building>()) return null;
|
||||
|
||||
return new Order("C4", self, underCursor, int2.Zero, null);
|
||||
return new Order("C4", self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRa.Mods.RA
|
||||
if (underCursor.Owner == null) return null; // don't allow capturing of bridges, etc.
|
||||
|
||||
return new Order(underCursor.Health <= EngineerDamage ? "Capture" : "Infiltrate",
|
||||
self, underCursor, int2.Zero, null);
|
||||
self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRa.Mods.RA
|
||||
return null;
|
||||
|
||||
if (mi.Button == MouseButton.Right && underCursor == self)
|
||||
return new Order("Deploy", self, null, int2.Zero, null);
|
||||
return new Order("Deploy", self);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRa.Mods.RA
|
||||
if (underCursor.Owner == self.Owner &&
|
||||
(underCursor.Info.Name == "spen" || underCursor.Info.Name == "syrd") &&
|
||||
self.Health < self.GetMaxHP())
|
||||
return new Order("Enter", self, underCursor, int2.Zero, null);
|
||||
return new Order("Enter", self, underCursor);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRa.Mods.RA
|
||||
if (underCursor.Owner == self.Owner) return null;
|
||||
if (!underCursor.traits.Contains<IAcceptSpy>()) return null;
|
||||
|
||||
return new Order("Infiltrate", self, underCursor, int2.Zero, null);
|
||||
return new Order("Infiltrate", self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenRa.Mods.RA
|
||||
if (underCursor == null) return null;
|
||||
if (!underCursor.traits.Contains<IAcceptThief>()) return null;
|
||||
|
||||
return new Order("Steal", self, underCursor, int2.Zero, null);
|
||||
return new Order("Steal", self, underCursor);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
Player:
|
||||
ProductionQueue:
|
||||
PlaceBuilding:
|
||||
GpsPower:
|
||||
Image: gpssicon
|
||||
OneShot: yes
|
||||
ChargeTime: 8
|
||||
Description: GPS Satellite
|
||||
LongDesc: Reveals the entire map
|
||||
Prerequisites: ATEK
|
||||
TechLevel: 12
|
||||
RevealDelay: 15
|
||||
ChronoshiftPower:
|
||||
Image: warpicon
|
||||
ChargeTime: 7
|
||||
Description: Chronoshift
|
||||
LongDesc: Temporarily teleports a vehicle across \nthe map.
|
||||
Prerequisites: PDOX
|
||||
TechLevel: 12
|
||||
Duration: 3
|
||||
KillCargo: yes
|
||||
IronCurtainPower:
|
||||
Image: infxicon
|
||||
ChargeTime: 11
|
||||
Description: Invulnerability
|
||||
LongDesc: Makes a single unit invulnerable for a \nshort time.
|
||||
Prerequisites: IRON
|
||||
TechLevel: 12
|
||||
Duration: .75
|
||||
|
||||
World:
|
||||
WaterPaletteRotation:
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
Player:
|
||||
ProductionQueue:
|
||||
PlaceBuilding:
|
||||
GpsPower:
|
||||
Image: gpssicon
|
||||
OneShot: yes
|
||||
ChargeTime: 8
|
||||
Description: GPS Satellite
|
||||
LongDesc: Reveals the entire map
|
||||
Prerequisites: ATEK
|
||||
TechLevel: 12
|
||||
RevealDelay: 15
|
||||
ChronoshiftPower:
|
||||
Image: warpicon
|
||||
ChargeTime: 7
|
||||
Description: Chronoshift
|
||||
LongDesc: Temporarily teleports a vehicle across \nthe map.
|
||||
Prerequisites: PDOX
|
||||
TechLevel: 12
|
||||
Duration: 3
|
||||
KillCargo: yes
|
||||
IronCurtainPower:
|
||||
Image: infxicon
|
||||
ChargeTime: 11
|
||||
Description: Invulnerability
|
||||
LongDesc: Makes a single unit invulnerable for a \nshort time.
|
||||
Prerequisites: IRON
|
||||
TechLevel: 12
|
||||
Duration: .75
|
||||
|
||||
World:
|
||||
WaterPaletteRotation:
|
||||
|
||||
@@ -849,20 +849,6 @@ Move=girlokay
|
||||
Select=einah1,einok1,einyes1
|
||||
Move=einah1,einok1,einyes1
|
||||
|
||||
|
||||
;; todo: where there are different variants of the same power,
|
||||
;; split them here. SonarPulse is the obvious one.
|
||||
|
||||
[SupportPowerTypes]
|
||||
ParadropPower
|
||||
ParabombPower
|
||||
SonarPulsePower
|
||||
ChronoshiftPower
|
||||
SpyPlanePower
|
||||
NukePower
|
||||
GpsSatellitePower
|
||||
InvulnerabilityPower
|
||||
|
||||
[ParadropPower] ; comes free with first AFLD
|
||||
ChargeTime=7
|
||||
Description=Paratroopers
|
||||
@@ -894,15 +880,6 @@ TechLevel=5
|
||||
GivenAuto=no
|
||||
Impl=NullPower
|
||||
|
||||
[ChronoshiftPower] ; free with Chronosphere... sortof the point.
|
||||
ChargeTime=7
|
||||
Description=Chronoshift
|
||||
LongDesc=Temporarily teleports a vehicle across \nthe map.
|
||||
Prerequisite=PDOX
|
||||
Image=warpicon
|
||||
TechLevel=12
|
||||
Impl=ChronospherePower
|
||||
|
||||
[SpyPlanePower] ; free with first AFLD
|
||||
ChargeTime=3
|
||||
TechLevel=5
|
||||
@@ -921,21 +898,3 @@ Image=atomicon
|
||||
TechLevel=12
|
||||
Impl=NullPower
|
||||
|
||||
[GpsSatellitePower] ; free with ATEK
|
||||
ChargeTime=8
|
||||
Description=GPS Satellite
|
||||
LongDesc=Reveals the entire map
|
||||
OneShot=yes
|
||||
Prerequisite=ATEK
|
||||
Image=gpssicon
|
||||
TechLevel=12
|
||||
Impl=GpsSatellite
|
||||
|
||||
[InvulnerabilityPower] ; the point of IRON
|
||||
ChargeTime=11
|
||||
Description=Invulnerability
|
||||
LongDesc=Makes a single unit invulnerable for a \nshort time.
|
||||
Image=infxicon
|
||||
Prerequisite=IRON
|
||||
TechLevel=12
|
||||
Impl=IronCurtainPower
|
||||
|
||||
Reference in New Issue
Block a user