Merge pull request #6556 from pchote/upgrade-all-the-things
Add support for time-limited actor upgrades.
This commit is contained in:
@@ -575,6 +575,76 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
if (engineVersion < 20141001)
|
||||
{
|
||||
// Routed unit upgrades via the UnitUpgradeManager trait
|
||||
if (depth == 0 && node.Value.Nodes.Any(n => n.Key.StartsWith("GainsStatUpgrades")))
|
||||
node.Value.Nodes.Add(new MiniYamlNode("UnitUpgradeManager", new MiniYaml("")));
|
||||
|
||||
// Replaced IronCurtainPower -> GrantUpgradePower
|
||||
if (depth == 1 && node.Key == "IronCurtainPower")
|
||||
{
|
||||
node.Key = "GrantUpgradePower@IRONCURTAIN";
|
||||
node.Value.Nodes.Add(new MiniYamlNode("Upgrades", "invulnerability"));
|
||||
|
||||
var durationNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Duration");
|
||||
if (durationNode != null)
|
||||
durationNode.Value.Value = (int.Parse(durationNode.Value.Value) * 25).ToString();
|
||||
else
|
||||
node.Value.Nodes.Add(new MiniYamlNode("Duration", "600"));
|
||||
|
||||
var soundNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "IronCurtainSound");
|
||||
if (soundNode != null)
|
||||
soundNode.Key = "GrantUpgradeSound";
|
||||
}
|
||||
|
||||
if (depth == 0 && node.Value.Nodes.Any(n => n.Key.StartsWith("IronCurtainable")))
|
||||
{
|
||||
node.Value.Nodes.RemoveAll(n => n.Key.StartsWith("IronCurtainable"));
|
||||
|
||||
var overlayKeys = new List<MiniYamlNode>();
|
||||
overlayKeys.Add(new MiniYamlNode("RequiresUpgrade", "invulnerability"));
|
||||
node.Value.Nodes.Add(new MiniYamlNode("UpgradeOverlay@IRONCURTAIN", new MiniYaml("", overlayKeys)));
|
||||
|
||||
var invulnKeys = new List<MiniYamlNode>();
|
||||
invulnKeys.Add(new MiniYamlNode("RequiresUpgrade", "invulnerability"));
|
||||
node.Value.Nodes.Add(new MiniYamlNode("InvulnerabilityUpgrade@IRONCURTAIN", new MiniYaml("", invulnKeys)));
|
||||
|
||||
var barKeys = new List<MiniYamlNode>();
|
||||
barKeys.Add(new MiniYamlNode("Upgrade", "invulnerability"));
|
||||
node.Value.Nodes.Add(new MiniYamlNode("TimedUpgradeBar", new MiniYaml("", barKeys)));
|
||||
|
||||
if (!node.Value.Nodes.Any(n => n.Key.StartsWith("UnitUpgradeManager")))
|
||||
node.Value.Nodes.Add(new MiniYamlNode("UnitUpgradeManager", new MiniYaml("")));
|
||||
}
|
||||
|
||||
if (depth == 1 && node.Key == "-IronCurtainable")
|
||||
node.Key = "-InvulnerabilityUpgrade@IRONCURTAIN";
|
||||
|
||||
// Replaced RemoveOnConditions with KillsSelf
|
||||
if (depth == 1 && node.Key == "RemoveOnConditions")
|
||||
{
|
||||
node.Key = "KillsSelf";
|
||||
node.Value.Nodes.Add(new MiniYamlNode("RemoveInstead", new MiniYaml("true")));
|
||||
}
|
||||
|
||||
if (depth == 1 && node.Key.StartsWith("UnitUpgradeCrateAction"))
|
||||
{
|
||||
var parts = node.Key.Split('@');
|
||||
node.Key = "GrantUpgradeCrateAction";
|
||||
if (parts.Length > 1)
|
||||
node.Key += "@" + parts[1];
|
||||
}
|
||||
|
||||
if (depth == 1 && node.Key.StartsWith("-UnitUpgradeCrateAction"))
|
||||
{
|
||||
var parts = node.Key.Split('@');
|
||||
node.Key = "-GrantUpgradeCrateAction";
|
||||
if (parts.Length > 1)
|
||||
node.Key += "@" + parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,15 @@ namespace OpenRA.Mods.RA
|
||||
public void UpgradeAvailable(Actor self, string type, bool available)
|
||||
{
|
||||
if (type == Info.RequiresUpgrade)
|
||||
{
|
||||
disabled = !available;
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
Uncloak();
|
||||
remainingTime = Info.InitialDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Uncloak() { Uncloak(Info.CloakDelay); }
|
||||
@@ -86,7 +94,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { if (Info.UncloakOnAttack) Uncloak(); }
|
||||
|
||||
public bool Cloaked { get { return remainingTime <= 0; } }
|
||||
public bool Cloaked { get { return !disabled && remainingTime <= 0; } }
|
||||
|
||||
public void DamageStateChanged(Actor self, AttackInfo e)
|
||||
{
|
||||
@@ -97,20 +105,25 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
||||
{
|
||||
if (remainingTime > 0)
|
||||
if (remainingTime > 0 || disabled)
|
||||
return r;
|
||||
|
||||
if (Cloaked && IsVisible(self, self.World.RenderPlayer))
|
||||
{
|
||||
if (string.IsNullOrEmpty(Info.Palette))
|
||||
return r;
|
||||
else
|
||||
return r.Select(a => a.WithPalette(wr.Palette(Info.Palette)));
|
||||
}
|
||||
else
|
||||
return SpriteRenderable.None;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (disabled)
|
||||
return;
|
||||
|
||||
if (remainingTime > 0 && !disabled && !damageDisabled && --remainingTime <= 0)
|
||||
Sound.Play(Info.CloakSound, self.CenterPosition);
|
||||
|
||||
|
||||
@@ -14,26 +14,29 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.RA.Crates
|
||||
{
|
||||
[Desc("Grants an upgrade to the collector.")]
|
||||
public class UnitUpgradeCrateActionInfo : CrateActionInfo
|
||||
public class GrantUpgradeCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
[Desc("The upgrade to grant.")]
|
||||
[Desc("The upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
[Desc("Duration of the upgrade (in ticks). Set to 0 for a permanent upgrade.")]
|
||||
public readonly int Duration = 0;
|
||||
|
||||
[Desc("The range to search for extra collectors in.", "Extra collectors will also be granted the crate action.")]
|
||||
public readonly WRange Range = new WRange(3);
|
||||
|
||||
[Desc("The maximum number of extra collectors to grant the crate action to.", "-1 = no limit")]
|
||||
public readonly int MaxExtraCollectors = 4;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new UnitUpgradeCrateAction(init.self, this); }
|
||||
public override object Create(ActorInitializer init) { return new GrantUpgradeCrateAction(init.self, this); }
|
||||
}
|
||||
|
||||
public class UnitUpgradeCrateAction : CrateAction
|
||||
public class GrantUpgradeCrateAction : CrateAction
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly UnitUpgradeCrateActionInfo info;
|
||||
readonly GrantUpgradeCrateActionInfo info;
|
||||
|
||||
public UnitUpgradeCrateAction(Actor self, UnitUpgradeCrateActionInfo info)
|
||||
public GrantUpgradeCrateAction(Actor self, GrantUpgradeCrateActionInfo info)
|
||||
: base(self, info)
|
||||
{
|
||||
this.self = self;
|
||||
@@ -42,16 +45,8 @@ namespace OpenRA.Mods.RA.Crates
|
||||
|
||||
bool AcceptsUpgrade(Actor a)
|
||||
{
|
||||
return a.TraitsImplementing<IUpgradable>()
|
||||
.Any(up => info.Upgrades.Any(u => up.AcceptsUpgrade(u)));
|
||||
}
|
||||
|
||||
void GrantActorUpgrades(Actor a)
|
||||
{
|
||||
foreach (var up in a.TraitsImplementing<IUpgradable>())
|
||||
foreach (var u in info.Upgrades)
|
||||
if (up.AcceptsUpgrade(u))
|
||||
up.UpgradeAvailable(a, u, true);
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
return um != null && info.Upgrades.Any(u => um.AcceptsUpgrade(a, u));
|
||||
}
|
||||
|
||||
public override int GetSelectionShares(Actor collector)
|
||||
@@ -61,25 +56,32 @@ namespace OpenRA.Mods.RA.Crates
|
||||
|
||||
public override void Activate(Actor collector)
|
||||
{
|
||||
collector.World.AddFrameEndTask(w => GrantActorUpgrades(collector));
|
||||
|
||||
var actorsInRange = self.World.FindActorsInCircle(self.CenterPosition, info.Range)
|
||||
.Where(a => a != self && a.Owner == collector.Owner && AcceptsUpgrade(a));
|
||||
.Where(a => a != self && a != collector && a.Owner == collector.Owner && AcceptsUpgrade(a));
|
||||
|
||||
if (actorsInRange.Any())
|
||||
if (info.MaxExtraCollectors > -1)
|
||||
actorsInRange = actorsInRange.Take(info.MaxExtraCollectors);
|
||||
|
||||
collector.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (info.MaxExtraCollectors > -1)
|
||||
actorsInRange = actorsInRange.Take(info.MaxExtraCollectors);
|
||||
|
||||
collector.World.AddFrameEndTask(w =>
|
||||
foreach (var a in actorsInRange.Append(collector))
|
||||
{
|
||||
foreach (var a in actorsInRange)
|
||||
if (!a.IsInWorld || a.IsDead())
|
||||
continue;
|
||||
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
foreach (var u in info.Upgrades)
|
||||
{
|
||||
if (!a.IsDead() && a.IsInWorld)
|
||||
GrantActorUpgrades(a);
|
||||
if (!um.AcceptsUpgrade(a, u))
|
||||
continue;
|
||||
|
||||
if (info.Duration > 0)
|
||||
um.GrantTimedUpgrade(a, u, info.Duration);
|
||||
else
|
||||
um.GrantUpgrade(a, u, this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
base.Activate(collector);
|
||||
}
|
||||
48
OpenRA.Mods.RA/DisableUpgrade.cs
Normal file
48
OpenRA.Mods.RA/DisableUpgrade.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class DisableUpgradeInfo : ITraitInfo
|
||||
{
|
||||
public readonly string RequiresUpgrade = "disable";
|
||||
|
||||
public object Create(ActorInitializer init) { return new DisableUpgrade(this); }
|
||||
}
|
||||
|
||||
public class DisableUpgrade : IUpgradable, IDisable
|
||||
{
|
||||
readonly DisableUpgradeInfo info;
|
||||
bool enabled;
|
||||
|
||||
public DisableUpgrade(DisableUpgradeInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public bool AcceptsUpgrade(string type)
|
||||
{
|
||||
return type == info.RequiresUpgrade;
|
||||
}
|
||||
|
||||
public void UpgradeAvailable(Actor self, string type, bool available)
|
||||
{
|
||||
if (type == info.RequiresUpgrade)
|
||||
enabled = available;
|
||||
}
|
||||
|
||||
public bool Disabled { get { return enabled; } }
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class InvulnEffect : IEffect
|
||||
{
|
||||
Actor a;
|
||||
IronCurtainable b;
|
||||
|
||||
public InvulnEffect(Actor a)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = a.Trait<IronCurtainable>();
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
{
|
||||
if (a.IsDead() || b.GetDamageModifier(null, null) > 0)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (a.Destroyed) // Tick will clean up
|
||||
yield break;
|
||||
|
||||
foreach (var r in a.Render(wr))
|
||||
if (!r.IsDecoration)
|
||||
yield return r.WithPalette(wr.Palette("invuln"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,10 +102,10 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
Level++;
|
||||
|
||||
foreach (var up in self.TraitsImplementing<IUpgradable>())
|
||||
var um = self.TraitOrDefault<UpgradeManager>();
|
||||
if (um != null)
|
||||
foreach (var u in upgrades)
|
||||
if (up.AcceptsUpgrade(u))
|
||||
up.UpgradeAvailable(self, u, true);
|
||||
um.GrantUpgrade(self, u, this);
|
||||
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "LevelUp", self.Owner.Country.Race);
|
||||
self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", info.LevelUpPalette)));
|
||||
|
||||
@@ -17,7 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class GlobalUpgradableInfo : ITraitInfo
|
||||
public class GlobalUpgradableInfo : ITraitInfo, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
public readonly string[] Upgrades = { };
|
||||
public readonly string[] Prerequisites = { };
|
||||
@@ -28,34 +28,36 @@ namespace OpenRA.Mods.RA
|
||||
public class GlobalUpgradable : INotifyAddedToWorld, INotifyRemovedFromWorld
|
||||
{
|
||||
readonly GlobalUpgradableInfo info;
|
||||
readonly GlobalUpgradeManager manager;
|
||||
readonly GlobalUpgradeManager globalManager;
|
||||
readonly UpgradeManager manager;
|
||||
|
||||
public GlobalUpgradable(Actor actor, GlobalUpgradableInfo info)
|
||||
public GlobalUpgradable(Actor self, GlobalUpgradableInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
manager = actor.Owner.PlayerActor.Trait<GlobalUpgradeManager>();
|
||||
globalManager = self.Owner.PlayerActor.Trait<GlobalUpgradeManager>();
|
||||
manager = self.Trait<UpgradeManager>();
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
if (info.Prerequisites.Any())
|
||||
manager.Register(self, this, info.Prerequisites);
|
||||
globalManager.Register(self, this, info.Prerequisites);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
if (info.Prerequisites.Any())
|
||||
manager.Unregister(self, this, info.Prerequisites);
|
||||
globalManager.Unregister(self, this, info.Prerequisites);
|
||||
}
|
||||
|
||||
public void PrerequisitesUpdated(Actor self, bool available)
|
||||
{
|
||||
var upgrades = self.TraitsImplementing<IUpgradable>();
|
||||
foreach (var u in upgrades)
|
||||
foreach (var u in info.Upgrades)
|
||||
{
|
||||
foreach (var t in info.Upgrades)
|
||||
if (u.AcceptsUpgrade(t))
|
||||
u.UpgradeAvailable(self, t, available);
|
||||
if (available)
|
||||
manager.GrantUpgrade(self, u, this);
|
||||
else
|
||||
manager.RevokeUpgrade(self, u, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
51
OpenRA.Mods.RA/InvulnerabilityUpgrade.cs
Normal file
51
OpenRA.Mods.RA/InvulnerabilityUpgrade.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class InvulnerabilityUpgradeInfo : ITraitInfo
|
||||
{
|
||||
public readonly string RequiresUpgrade = "invulnerability";
|
||||
|
||||
public object Create(ActorInitializer init) { return new InvulnerabilityUpgrade(this); }
|
||||
}
|
||||
|
||||
public class InvulnerabilityUpgrade : IUpgradable, IDamageModifier
|
||||
{
|
||||
readonly InvulnerabilityUpgradeInfo info;
|
||||
bool enabled;
|
||||
|
||||
public InvulnerabilityUpgrade(InvulnerabilityUpgradeInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public bool AcceptsUpgrade(string type)
|
||||
{
|
||||
return type == info.RequiresUpgrade;
|
||||
}
|
||||
|
||||
public void UpgradeAvailable(Actor self, string type, bool available)
|
||||
{
|
||||
if (type == info.RequiresUpgrade)
|
||||
enabled = available;
|
||||
}
|
||||
|
||||
public int GetDamageModifier(Actor attacker, DamageWarhead warhead)
|
||||
{
|
||||
return enabled ? 0 : 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Drawing;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IronCurtainableInfo : TraitInfo<IronCurtainable> { }
|
||||
|
||||
class IronCurtainable : IDamageModifier, ITick, ISync, ISelectionBar
|
||||
{
|
||||
[Sync] int RemainingTicks = 0;
|
||||
int TotalTicks;
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (RemainingTicks > 0)
|
||||
RemainingTicks--;
|
||||
}
|
||||
|
||||
public int GetDamageModifier(Actor attacker, DamageWarhead warhead)
|
||||
{
|
||||
return RemainingTicks > 0 ? 0 : 100;
|
||||
}
|
||||
|
||||
public void Activate(Actor self, int duration)
|
||||
{
|
||||
if (RemainingTicks == 0)
|
||||
self.World.AddFrameEndTask(w => w.Add(new InvulnEffect(self))); // do not stack the invuln effect
|
||||
|
||||
RemainingTicks = duration;
|
||||
TotalTicks = duration;
|
||||
}
|
||||
|
||||
// Show the remaining time as a bar
|
||||
public float GetValue()
|
||||
{
|
||||
if (RemainingTicks == 0) // otherwise an empty bar is rendered all the time
|
||||
return 0f;
|
||||
|
||||
return (float)RemainingTicks / TotalTicks;
|
||||
}
|
||||
public Color GetColor() { return Color.Red; }
|
||||
}
|
||||
}
|
||||
71
OpenRA.Mods.RA/KillsSelf.cs
Normal file
71
OpenRA.Mods.RA/KillsSelf.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class KillsSelfInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Enable only if this upgrade is enabled.")]
|
||||
public readonly string RequiresUpgrade = null;
|
||||
|
||||
[Desc("Remove the actor from the world (and destroy it) instead of killing it.")]
|
||||
public readonly bool RemoveInstead = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new KillsSelf(init.self, this); }
|
||||
}
|
||||
|
||||
class KillsSelf : INotifyAddedToWorld, IUpgradable
|
||||
{
|
||||
readonly KillsSelfInfo info;
|
||||
readonly Actor self;
|
||||
|
||||
public KillsSelf(Actor self, KillsSelfInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
if (info.RequiresUpgrade == null)
|
||||
Kill();
|
||||
}
|
||||
|
||||
public bool AcceptsUpgrade(string type)
|
||||
{
|
||||
return type == info.RequiresUpgrade;
|
||||
}
|
||||
|
||||
public void UpgradeAvailable(Actor self, string type, bool available)
|
||||
{
|
||||
if (type == info.RequiresUpgrade)
|
||||
Kill();
|
||||
}
|
||||
|
||||
void Kill()
|
||||
{
|
||||
if (self.IsDead())
|
||||
return;
|
||||
|
||||
if (info.RemoveInstead || !self.HasTrait<Health>())
|
||||
self.Destroy();
|
||||
else
|
||||
self.Kill(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
OpenRA.Mods.RA/Modifiers/UpgradeOverlay.cs
Normal file
63
OpenRA.Mods.RA/Modifiers/UpgradeOverlay.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Display a colored overlay when a timed upgrade is active.")]
|
||||
public class UpgradeOverlayInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Upgrade that is required before this overlay is rendered")]
|
||||
public readonly string RequiresUpgrade = null;
|
||||
|
||||
[Desc("Palette to use when rendering the overlay")]
|
||||
public readonly string Palette = "invuln";
|
||||
|
||||
public object Create(ActorInitializer init) { return new UpgradeOverlay(this); }
|
||||
}
|
||||
|
||||
public class UpgradeOverlay : IRenderModifier, IUpgradable
|
||||
{
|
||||
readonly UpgradeOverlayInfo info;
|
||||
bool enabled;
|
||||
|
||||
public UpgradeOverlay(UpgradeOverlayInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
||||
{
|
||||
foreach (var a in r)
|
||||
{
|
||||
yield return a;
|
||||
|
||||
if (enabled && !a.IsDecoration)
|
||||
yield return a.WithPalette(wr.Palette(info.Palette))
|
||||
.WithZOffset(a.ZOffset + 1)
|
||||
.AsDecoration();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AcceptsUpgrade(string type)
|
||||
{
|
||||
return type == info.RequiresUpgrade;
|
||||
}
|
||||
|
||||
public void UpgradeAvailable(Actor self, string type, bool available)
|
||||
{
|
||||
if (type == info.RequiresUpgrade)
|
||||
enabled = available;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,6 @@
|
||||
<Compile Include="Effects\Beacon.cs" />
|
||||
<Compile Include="Player\PlaceBeacon.cs" />
|
||||
<Compile Include="MenuPaletteEffect.cs" />
|
||||
<Compile Include="Crates\UnitUpgradeCrateAction.cs" />
|
||||
<Compile Include="EjectOnDeath.cs" />
|
||||
<Compile Include="Air\FallsToEarth.cs" />
|
||||
<Compile Include="Air\Fly.cs" />
|
||||
@@ -220,7 +219,6 @@
|
||||
<Compile Include="Effects\GpsDot.cs" />
|
||||
<Compile Include="Effects\GpsSatellite.cs" />
|
||||
<Compile Include="Effects\GravityBomb.cs" />
|
||||
<Compile Include="Effects\InvulnEffect.cs" />
|
||||
<Compile Include="Effects\LaserZap.cs" />
|
||||
<Compile Include="Effects\Missile.cs" />
|
||||
<Compile Include="Effects\NukeLaunch.cs" />
|
||||
@@ -245,7 +243,6 @@
|
||||
<Compile Include="Husk.cs" />
|
||||
<Compile Include="Infiltration\InfiltrateForSupportPower.cs" />
|
||||
<Compile Include="Invulnerable.cs" />
|
||||
<Compile Include="IronCurtainable.cs" />
|
||||
<Compile Include="JamsMissiles.cs" />
|
||||
<Compile Include="LeavesHusk.cs" />
|
||||
<Compile Include="Captures.cs" />
|
||||
@@ -297,7 +294,6 @@
|
||||
<Compile Include="Warheads\CreateEffectWarhead.cs" />
|
||||
<Compile Include="Warheads\CreateResourceWarhead.cs" />
|
||||
<Compile Include="Warheads\LeaveSmudgeWarhead.cs" />
|
||||
<Compile Include="RemoveOnConditions.cs" />
|
||||
<Compile Include="Widgets\Logic\TabCompletionLogic.cs" />
|
||||
<Compile Include="World\RadarPings.cs" />
|
||||
<Compile Include="Player\TechTree.cs" />
|
||||
@@ -359,7 +355,6 @@
|
||||
<Compile Include="SupportPowers\AirstrikePower.cs" />
|
||||
<Compile Include="SupportPowers\ChronoshiftPower.cs" />
|
||||
<Compile Include="SupportPowers\GpsPower.cs" />
|
||||
<Compile Include="SupportPowers\IronCurtainPower.cs" />
|
||||
<Compile Include="SupportPowers\NukePower.cs" />
|
||||
<Compile Include="SupportPowers\ParatroopersPower.cs" />
|
||||
<Compile Include="SupportPowers\SupportPower.cs" />
|
||||
@@ -507,7 +502,6 @@
|
||||
<Compile Include="Scripting\Properties\TransportProperties.cs" />
|
||||
<Compile Include="Scripting\Global\CameraGlobal.cs" />
|
||||
<Compile Include="Scripting\Properties\ChronosphereProperties.cs" />
|
||||
<Compile Include="Scripting\ScriptInvulnerable.cs" />
|
||||
<Compile Include="Console\ChatCommands.cs" />
|
||||
<Compile Include="Console\DevCommands.cs" />
|
||||
<Compile Include="Console\HelpCommand.cs" />
|
||||
@@ -564,6 +558,16 @@
|
||||
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\HelicopterProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\PlaneProperties.cs" />
|
||||
<Compile Include="SupportPowers\GrantUpgradePower.cs" />
|
||||
<Compile Include="Modifiers\UpgradeOverlay.cs" />
|
||||
<Compile Include="TimedUpgradeBar.cs" />
|
||||
<Compile Include="InvulnerabilityUpgrade.cs" />
|
||||
<Compile Include="DisableUpgrade.cs" />
|
||||
<Compile Include="UpgradeManager.cs" />
|
||||
<Compile Include="KillsSelf.cs" />
|
||||
<Compile Include="Warheads\GrantUpgradeWarhead.cs" />
|
||||
<Compile Include="Crates\GrantUpgradeCrateAction.cs" />
|
||||
<Compile Include="Scripting\Properties\UpgradeProperties.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Destroys the actor after a specified number of ticks if all conditions are met.")]
|
||||
class RemoveOnConditionsInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Prerequisites required before removal")]
|
||||
public readonly string[] Prerequisites = {};
|
||||
|
||||
[Desc("Delay until it starts checking if you have the prerequisites", "0 = Removal attempted on AddedToWorld")]
|
||||
public readonly int Delay = 0;
|
||||
|
||||
[Desc("Should the trait kill instead of destroy?")]
|
||||
public readonly bool KillInstead = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new RemoveOnConditions(init.self, this); }
|
||||
}
|
||||
|
||||
class RemoveOnConditions : INotifyAddedToWorld, ITechTreeElement
|
||||
{
|
||||
readonly RemoveOnConditionsInfo info;
|
||||
readonly Actor self;
|
||||
|
||||
public RemoveOnConditions(Actor self, RemoveOnConditionsInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
Action act = () =>
|
||||
{
|
||||
if (!info.Prerequisites.Any() || self.Owner.PlayerActor.Trait<TechTree>().HasPrerequisites(info.Prerequisites))
|
||||
Remove();
|
||||
else
|
||||
self.Owner.PlayerActor.Trait<TechTree>().Add("remove_" + string.Join("_", info.Prerequisites.OrderBy(a => a)), info.Prerequisites, 0, this);
|
||||
};
|
||||
|
||||
if (info.Delay <= 0 && (!info.Prerequisites.Any() || self.Owner.PlayerActor.Trait<TechTree>().HasPrerequisites(info.Prerequisites)))
|
||||
Remove();
|
||||
else
|
||||
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(info.Delay, act)));
|
||||
}
|
||||
|
||||
void Remove()
|
||||
{
|
||||
if (!self.IsDead())
|
||||
{
|
||||
if (info.KillInstead && self.HasTrait<Health>())
|
||||
self.Kill(self);
|
||||
else
|
||||
self.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public void PrerequisitesAvailable(string key) { Remove(); }
|
||||
public void PrerequisitesUnavailable(string key) { }
|
||||
public void PrerequisitesItemHidden(string key) { }
|
||||
public void PrerequisitesItemVisible(string key) { }
|
||||
}
|
||||
}
|
||||
@@ -33,22 +33,4 @@ namespace OpenRA.Mods.RA.Scripting
|
||||
[Desc("Maximum health of the actor.")]
|
||||
public int MaxHealth { get { return health.MaxHP; } }
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class InvulnerableProperties : ScriptActorProperties, Requires<ScriptInvulnerableInfo>
|
||||
{
|
||||
ScriptInvulnerable invulnerable;
|
||||
public InvulnerableProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
invulnerable = self.Trait<ScriptInvulnerable>();
|
||||
}
|
||||
|
||||
[Desc("Set or query unit invulnerablility.")]
|
||||
public bool Invulnerable
|
||||
{
|
||||
get { return invulnerable.Invulnerable; }
|
||||
set { invulnerable.Invulnerable = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
50
OpenRA.Mods.RA/Scripting/Properties/UpgradeProperties.cs
Normal file
50
OpenRA.Mods.RA/Scripting/Properties/UpgradeProperties.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class UpgradeProperties : ScriptActorProperties, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
UpgradeManager um;
|
||||
public UpgradeProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
um = self.Trait<UpgradeManager>();
|
||||
}
|
||||
|
||||
[Desc("Grant an upgrade to this actor.")]
|
||||
public void GrantUpgrade(string upgrade)
|
||||
{
|
||||
um.GrantUpgrade(self, upgrade, this);
|
||||
}
|
||||
|
||||
[Desc("Revoke an upgrade that was previously granted using GrantUpgrade.")]
|
||||
public void RevokeUpgrade(string upgrade)
|
||||
{
|
||||
um.RevokeUpgrade(self, upgrade, this);
|
||||
}
|
||||
|
||||
[Desc("Grant a limited-time upgrade to this actor.")]
|
||||
public void GrantTimedUpgrade(string upgrade, int duration)
|
||||
{
|
||||
um.GrantTimedUpgrade(self, upgrade, duration);
|
||||
}
|
||||
|
||||
[Desc("Check whether this actor accepts a specific upgrade.")]
|
||||
public bool AcceptsUpgrade(string upgrade)
|
||||
{
|
||||
return um.AcceptsUpgrade(self, upgrade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Allows map scripts to make this actor invulnerable via actor.Invulnerable = true.")]
|
||||
class ScriptInvulnerableInfo : TraitInfo<ScriptInvulnerable> {}
|
||||
|
||||
class ScriptInvulnerable : IDamageModifier
|
||||
{
|
||||
public bool Invulnerable = false;
|
||||
|
||||
public int GetDamageModifier(Actor attacker, DamageWarhead warhead)
|
||||
{
|
||||
return Invulnerable ? 0 : 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,22 +17,27 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IronCurtainPowerInfo : SupportPowerInfo
|
||||
class GrantUpgradePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[Desc("Seconds")]
|
||||
public readonly int Duration = 10;
|
||||
[Desc("The upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
[Desc("Duration of the upgrade (in ticks). Set to 0 for a permanent upgrade.")]
|
||||
public readonly int Duration = 0;
|
||||
|
||||
[Desc("Cells")]
|
||||
public readonly int Range = 1;
|
||||
public readonly string IronCurtainSound = "ironcur9.aud";
|
||||
public readonly string GrantUpgradeSound = "ironcur9.aud";
|
||||
|
||||
public override object Create(ActorInitializer init) { return new IronCurtainPower(init.self, this); }
|
||||
public override object Create(ActorInitializer init) { return new GrantUpgradePower(init.self, this); }
|
||||
}
|
||||
|
||||
class IronCurtainPower : SupportPower
|
||||
class GrantUpgradePower : SupportPower
|
||||
{
|
||||
IronCurtainPowerInfo info;
|
||||
GrantUpgradePowerInfo info;
|
||||
|
||||
public IronCurtainPower(Actor self, IronCurtainPowerInfo info) : base(self, info)
|
||||
public GrantUpgradePower(Actor self, GrantUpgradePowerInfo info)
|
||||
: base(self, info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
@@ -49,38 +54,59 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
Sound.Play(info.IronCurtainSound, self.World.Map.CenterOfCell(order.TargetLocation));
|
||||
Sound.Play(info.GrantUpgradeSound, self.World.Map.CenterOfCell(order.TargetLocation));
|
||||
|
||||
foreach (var target in UnitsInRange(order.TargetLocation)
|
||||
.Where(a => a.Owner.Stances[self.Owner] == Stance.Ally))
|
||||
target.Trait<IronCurtainable>().Activate(target, ((IronCurtainPowerInfo)Info).Duration * 25);
|
||||
foreach (var a in UnitsInRange(order.TargetLocation))
|
||||
{
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
if (um == null)
|
||||
continue;
|
||||
|
||||
foreach (var u in info.Upgrades)
|
||||
{
|
||||
if (!um.AcceptsUpgrade(a, u))
|
||||
continue;
|
||||
|
||||
if (info.Duration > 0)
|
||||
um.GrantTimedUpgrade(a, u, info.Duration);
|
||||
else
|
||||
um.GrantUpgrade(a, u, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(CPos xy)
|
||||
{
|
||||
var range = ((IronCurtainPowerInfo)Info).Range;
|
||||
var range = info.Range;
|
||||
var tiles = self.World.Map.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(self.World.ActorMap.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<IronCurtainable>());
|
||||
return units.Distinct().Where(a =>
|
||||
{
|
||||
if (!a.Owner.IsAlliedWith(self.Owner))
|
||||
return false;
|
||||
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
return um != null && info.Upgrades.Any(u => um.AcceptsUpgrade(a, u));
|
||||
});
|
||||
}
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
readonly IronCurtainPower power;
|
||||
readonly GrantUpgradePower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(World world, string order, SupportPowerManager manager, IronCurtainPower power)
|
||||
public SelectTarget(World world, string order, SupportPowerManager manager, GrantUpgradePower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = ((IronCurtainPowerInfo)power.Info).Range;
|
||||
this.range = power.info.Range;
|
||||
tile = world.Map.SequenceProvider.GetSequence("overlay", "target-select").GetSprite(0);
|
||||
}
|
||||
|
||||
@@ -101,8 +127,7 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
var targetUnits = power.UnitsInRange(xy).Where(a => a.Owner.Stances[power.self.Owner] == Stance.Ally);
|
||||
foreach (var unit in targetUnits)
|
||||
foreach (var unit in power.UnitsInRange(xy))
|
||||
yield return new SelectionBoxRenderable(unit, Color.Red);
|
||||
}
|
||||
|
||||
@@ -117,7 +142,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public string GetCursor(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
return power.UnitsInRange(xy).Any(a => a.Owner.Stances[power.self.Owner] == Stance.Ally) ? "ability" : "move-blocked";
|
||||
return power.UnitsInRange(xy).Any() ? "ability" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
58
OpenRA.Mods.RA/TimedUpgradeBar.cs
Normal file
58
OpenRA.Mods.RA/TimedUpgradeBar.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Visualizes the remaining time for an upgrade.")]
|
||||
class TimedUpgradeBarInfo : ITraitInfo, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
[Desc("Upgrade that this bar corresponds to")]
|
||||
public readonly string Upgrade = null;
|
||||
|
||||
public readonly Color Color = Color.Red;
|
||||
|
||||
public object Create(ActorInitializer init) { return new TimedUpgradeBar(init.self, this); }
|
||||
}
|
||||
|
||||
class TimedUpgradeBar : ISelectionBar
|
||||
{
|
||||
readonly TimedUpgradeBarInfo info;
|
||||
readonly Actor self;
|
||||
float value;
|
||||
|
||||
public TimedUpgradeBar(Actor self, TimedUpgradeBarInfo info)
|
||||
{
|
||||
this.self = self;
|
||||
this.info = info;
|
||||
|
||||
self.Trait<UpgradeManager>().RegisterWatcher(info.Upgrade, Update);
|
||||
}
|
||||
|
||||
public void Update(int duration, int remaining)
|
||||
{
|
||||
value = remaining * 1f / duration;
|
||||
}
|
||||
|
||||
public float GetValue()
|
||||
{
|
||||
if (!self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||
return 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public Color GetColor() { return info.Color; }
|
||||
}
|
||||
}
|
||||
134
OpenRA.Mods.RA/UpgradeManager.cs
Normal file
134
OpenRA.Mods.RA/UpgradeManager.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class UpgradeManagerInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new UpgradeManager(init); }
|
||||
}
|
||||
|
||||
public class UpgradeManager : ITick
|
||||
{
|
||||
class TimedUpgrade
|
||||
{
|
||||
public readonly string Upgrade;
|
||||
public readonly int Duration;
|
||||
public int Remaining;
|
||||
|
||||
public TimedUpgrade(string upgrade, int duration)
|
||||
{
|
||||
Upgrade = upgrade;
|
||||
Duration = duration;
|
||||
Remaining = duration;
|
||||
}
|
||||
|
||||
public void Tick() { Remaining--; }
|
||||
}
|
||||
|
||||
readonly List<TimedUpgrade> timedUpgrades = new List<TimedUpgrade>();
|
||||
readonly Dictionary<string, List<object>> sources = new Dictionary<string, List<object>>();
|
||||
readonly Dictionary<string, List<Action<int, int>>> watchers = new Dictionary<string, List<Action<int, int>>>();
|
||||
readonly Lazy<IEnumerable<IUpgradable>> upgradable;
|
||||
|
||||
public UpgradeManager(ActorInitializer init)
|
||||
{
|
||||
upgradable = Exts.Lazy(() => init.self.TraitsImplementing<IUpgradable>());
|
||||
}
|
||||
|
||||
public void GrantTimedUpgrade(Actor self, string upgrade, int duration)
|
||||
{
|
||||
var timed = timedUpgrades.FirstOrDefault(u => u.Upgrade == upgrade);
|
||||
if (timed == null)
|
||||
{
|
||||
timed = new TimedUpgrade(upgrade, duration);
|
||||
timedUpgrades.Add(timed);
|
||||
GrantUpgrade(self, upgrade, timed);
|
||||
}
|
||||
else
|
||||
timed.Remaining = Math.Max(duration, timed.Remaining);
|
||||
}
|
||||
|
||||
public void GrantUpgrade(Actor self, string upgrade, object source)
|
||||
{
|
||||
List<object> ss;
|
||||
if (!sources.TryGetValue(upgrade, out ss))
|
||||
{
|
||||
ss = new List<object>();
|
||||
sources.Add(upgrade, ss);
|
||||
|
||||
foreach (var up in upgradable.Value)
|
||||
if (up.AcceptsUpgrade(upgrade))
|
||||
up.UpgradeAvailable(self, upgrade, true);
|
||||
}
|
||||
|
||||
// Track the upgrade source so that the upgrade can be removed without conflicts
|
||||
ss.Add(source);
|
||||
}
|
||||
|
||||
public void RevokeUpgrade(Actor self, string upgrade, object source)
|
||||
{
|
||||
// This upgrade may have been granted by multiple sources
|
||||
// We must be careful to only remove the upgrade after all
|
||||
// sources have been revoked
|
||||
List<object> ss;
|
||||
if (!sources.TryGetValue(upgrade, out ss))
|
||||
return;
|
||||
|
||||
ss.Remove(source);
|
||||
if (!ss.Any())
|
||||
{
|
||||
foreach (var up in upgradable.Value)
|
||||
if (up.AcceptsUpgrade(upgrade))
|
||||
up.UpgradeAvailable(self, upgrade, false);
|
||||
|
||||
sources.Remove(upgrade);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AcceptsUpgrade(Actor self, string upgrade)
|
||||
{
|
||||
return upgradable.Value.Any(up => up.AcceptsUpgrade(upgrade));
|
||||
}
|
||||
|
||||
public void RegisterWatcher(string upgrade, Action<int, int> action)
|
||||
{
|
||||
if (!watchers.ContainsKey(upgrade))
|
||||
watchers.Add(upgrade, new List<Action<int, int>>());
|
||||
|
||||
watchers[upgrade].Add(action);
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
foreach (var u in timedUpgrades)
|
||||
{
|
||||
u.Tick();
|
||||
if (u.Remaining <= 0)
|
||||
RevokeUpgrade(self, u.Upgrade, u);
|
||||
|
||||
List<Action<int, int>> actions;
|
||||
if (watchers.TryGetValue(u.Upgrade, out actions))
|
||||
foreach (var a in actions)
|
||||
a(u.Duration, u.Remaining);
|
||||
}
|
||||
|
||||
timedUpgrades.RemoveAll(u => u.Remaining <= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
OpenRA.Mods.RA/Warheads/GrantUpgradeWarhead.cs
Normal file
54
OpenRA.Mods.RA/Warheads/GrantUpgradeWarhead.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class GrantUpgradeWarhead : Warhead
|
||||
{
|
||||
[Desc("The upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
[Desc("Duration of the upgrade (in ticks). Set to 0 for a permanent upgrade.")]
|
||||
public readonly int Duration = 0;
|
||||
|
||||
public readonly WRange Range = WRange.FromCells(1);
|
||||
|
||||
public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
|
||||
{
|
||||
var actors = target.Type == TargetType.Actor ? new [] { target.Actor } :
|
||||
firedBy.World.FindActorsInCircle(target.CenterPosition, Range);
|
||||
|
||||
foreach (var a in actors)
|
||||
{
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
if (um == null)
|
||||
return;
|
||||
|
||||
foreach (var u in Upgrades)
|
||||
{
|
||||
if (!um.AcceptsUpgrade(a, u))
|
||||
continue;
|
||||
|
||||
if (Duration > 0)
|
||||
um.GrantTimedUpgrade(a, u, Duration);
|
||||
else
|
||||
um.GrantUpgrade(a, u, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,7 +568,7 @@ Rules:
|
||||
-GiveMcvCrateAction:
|
||||
-GiveCashCrateAction:
|
||||
-ExplodeCrateAction@fire:
|
||||
-UnitUpgradeCrateAction@cloak:
|
||||
-GrantUpgradeCrateAction@cloak:
|
||||
ScriptTriggers:
|
||||
|
||||
Sequences:
|
||||
|
||||
@@ -650,7 +650,7 @@ Rules:
|
||||
-GiveMcvCrateAction:
|
||||
-GiveCashCrateAction:
|
||||
-ExplodeCrateAction@fire:
|
||||
-UnitUpgradeCrateAction@cloak:
|
||||
-GrantUpgradeCrateAction@cloak:
|
||||
|
||||
Sequences:
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ Rules:
|
||||
-GiveMcvCrateAction:
|
||||
-RevealMapCrateAction:
|
||||
-HideMapCrateAction:
|
||||
-UnitUpgradeCrateAction@cloak:
|
||||
-GrantUpgradeCrateAction@cloak:
|
||||
-ExplodeCrateAction@nuke:
|
||||
-ExplodeCrateAction@boom:
|
||||
-ExplodeCrateAction@fire:
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
Chronoshiftable:
|
||||
Passenger:
|
||||
CargoType: Vehicle
|
||||
IronCurtainable:
|
||||
HiddenUnderFog:
|
||||
GainsExperience:
|
||||
GivesExperience:
|
||||
@@ -48,6 +47,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Tank:
|
||||
AppearsOnRadar:
|
||||
@@ -70,7 +70,6 @@
|
||||
Chronoshiftable:
|
||||
Passenger:
|
||||
CargoType: Vehicle
|
||||
IronCurtainable:
|
||||
HiddenUnderFog:
|
||||
GainsExperience:
|
||||
GivesExperience:
|
||||
@@ -102,6 +101,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Helicopter:
|
||||
AppearsOnRadar:
|
||||
@@ -140,6 +140,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Infantry:
|
||||
AppearsOnRadar:
|
||||
@@ -220,6 +221,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^CivInfantry:
|
||||
Inherits: ^Infantry
|
||||
@@ -326,6 +328,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Ship:
|
||||
AppearsOnRadar:
|
||||
@@ -359,6 +362,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Building:
|
||||
AppearsOnRadar:
|
||||
|
||||
@@ -14,7 +14,7 @@ CRATE:
|
||||
ExplodeCrateAction@fire:
|
||||
Weapon: Napalm.Crate
|
||||
SelectionShares: 5
|
||||
UnitUpgradeCrateAction@cloak:
|
||||
GrantUpgradeCrateAction@cloak:
|
||||
SelectionShares: 5
|
||||
Effect: cloak
|
||||
Upgrades: cloak
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Tank:
|
||||
AppearsOnRadar:
|
||||
@@ -95,6 +96,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Husk:
|
||||
Health:
|
||||
@@ -221,6 +223,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Plane:
|
||||
AppearsOnRadar:
|
||||
@@ -253,6 +256,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Helicopter:
|
||||
Inherits: ^Plane
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
Name: Concrete
|
||||
Description: Provides a strong foundation that prevents\ndamage from the terrain.
|
||||
RenderSprites:
|
||||
RemoveOnConditions:
|
||||
KillsSelf:
|
||||
RemoveInstead: true
|
||||
|
||||
CONCRETEA:
|
||||
Inherits: ^CONCRETE
|
||||
|
||||
@@ -862,16 +862,17 @@ Rules:
|
||||
Duration: 999999
|
||||
KillCargo: yes
|
||||
Range: 3
|
||||
IronCurtainPower:
|
||||
GrantUpgradePower@IRONCURTAIN:
|
||||
Icon: invuln
|
||||
ChargeTime: 30
|
||||
Description: Invulnerability
|
||||
LongDesc: Makes a unit invulnerable\nfor 3 seconds.
|
||||
Duration: 3
|
||||
Duration: 75
|
||||
SelectTargetSound: slcttgt1.aud
|
||||
BeginChargeSound: ironchg1.aud
|
||||
EndChargeSound: ironrdy1.aud
|
||||
Range: 1
|
||||
Upgrades: invulnerability
|
||||
Power:
|
||||
Amount: 0
|
||||
MINVV:
|
||||
@@ -928,16 +929,17 @@ Rules:
|
||||
Duration: 999999
|
||||
KillCargo: yes
|
||||
Range: 3
|
||||
IronCurtainPower:
|
||||
GrantUpgradePower@IRONCURTAIN:
|
||||
Icon: invuln
|
||||
ChargeTime: 30
|
||||
Description: Invulnerability
|
||||
LongDesc: Makes a unit invulnerable\nfor 3 seconds.
|
||||
Duration: 3
|
||||
Duration: 75
|
||||
SelectTargetSound: slcttgt1.aud
|
||||
BeginChargeSound: ironchg1.aud
|
||||
EndChargeSound: ironrdy1.aud
|
||||
Range: 1
|
||||
Upgrades: invulnerability
|
||||
|
||||
Sequences:
|
||||
miner:
|
||||
|
||||
@@ -109,8 +109,8 @@ end
|
||||
|
||||
SetupAlliedUnits = function()
|
||||
Utils.Do(Map.NamedActors, function(a)
|
||||
if a.Owner == allies and a.HasProperty("Invulnerable") then
|
||||
a.Invulnerable = true
|
||||
if a.Owner == allies and a.HasProperty("AcceptsUpgrade") and a.AcceptsUpgrade("unkillable") then
|
||||
a.GrantUpgrade("unkillable")
|
||||
a.Stance = "Defend"
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -1295,19 +1295,20 @@ Rules:
|
||||
Health:
|
||||
HP: 200
|
||||
^Vehicle:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
GainsExperience:
|
||||
Upgrades:
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
^Tank:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
GainsExperience:
|
||||
Upgrades:
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
^Infantry:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
GainsExperience:
|
||||
@@ -1318,20 +1319,25 @@ Rules:
|
||||
VolumeMultiplier: 0.1
|
||||
DeathSounds@ZAPPED:
|
||||
VolumeMultiplier: 0.1
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
^Ship:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
GainsExperience:
|
||||
Upgrades:
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
^Plane:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
^Building:
|
||||
ScriptInvulnerable:
|
||||
GivesBounty:
|
||||
Percentage: 0
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
|
||||
Sequences:
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ WorldLoaded = function()
|
||||
|
||||
Utils.Do(Snipers, function(a)
|
||||
if a.Owner == soviets then
|
||||
a.Invulnerable = true
|
||||
a.GrantUpgrade("unkillable")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@@ -665,7 +665,8 @@ Rules:
|
||||
HP: 200
|
||||
AutoTarget:
|
||||
InitialStance: Defend
|
||||
ScriptInvulnerable:
|
||||
InvulnerabilityUpgrade@UNKILLABLE:
|
||||
RequiresUpgrade: unkillable
|
||||
SPY:
|
||||
Inherits: ^Infantry
|
||||
Buildable:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
BADR:
|
||||
Inherits: ^Plane
|
||||
ParaDrop:
|
||||
DropRange: 4c0
|
||||
Inherits: ^Plane
|
||||
Health:
|
||||
HP: 300
|
||||
Armor:
|
||||
@@ -12,7 +12,6 @@ BADR:
|
||||
Repulsable: False
|
||||
RenderUnit:
|
||||
WithShadow:
|
||||
IronCurtainable:
|
||||
Cargo:
|
||||
MaxWeight: 10
|
||||
-Selectable:
|
||||
@@ -36,10 +35,10 @@ BADR:
|
||||
RejectsOrders:
|
||||
|
||||
BADR.Bomber:
|
||||
Inherits: ^Plane
|
||||
AttackBomber:
|
||||
Armament:
|
||||
Weapon: ParaBomb
|
||||
Inherits: ^Plane
|
||||
Health:
|
||||
HP: 300
|
||||
Armor:
|
||||
@@ -53,7 +52,6 @@ BADR.Bomber:
|
||||
RenderUnit:
|
||||
Image: badr
|
||||
WithShadow:
|
||||
IronCurtainable:
|
||||
-Selectable:
|
||||
-GainsExperience:
|
||||
Tooltip:
|
||||
@@ -113,7 +111,6 @@ MIG:
|
||||
WithShadow:
|
||||
LimitedAmmo:
|
||||
Ammo: 8
|
||||
IronCurtainable:
|
||||
ReturnOnIdle:
|
||||
Selectable:
|
||||
Bounds: 40,29,0,1
|
||||
@@ -173,7 +170,6 @@ YAK:
|
||||
Ammo: 18
|
||||
PipCount: 6
|
||||
ReloadTicks: 11
|
||||
IronCurtainable:
|
||||
ReturnOnIdle:
|
||||
Selectable:
|
||||
Bounds: 30,28,0,2
|
||||
@@ -224,7 +220,6 @@ TRAN:
|
||||
Types: Infantry
|
||||
MaxWeight: 8
|
||||
PipCount: 8
|
||||
IronCurtainable:
|
||||
LeavesHusk:
|
||||
HuskActor: TRAN.Husk
|
||||
|
||||
@@ -270,7 +265,6 @@ HELI:
|
||||
WithShadow:
|
||||
LimitedAmmo:
|
||||
Ammo: 8
|
||||
IronCurtainable:
|
||||
Selectable:
|
||||
Bounds: 36,28,0,0
|
||||
LeavesHusk:
|
||||
@@ -324,7 +318,6 @@ HIND:
|
||||
Ammo: 24
|
||||
PipCount: 6
|
||||
ReloadTicks: 8
|
||||
IronCurtainable:
|
||||
Selectable:
|
||||
Bounds: 38,32,0,0
|
||||
WithMuzzleFlash:
|
||||
@@ -345,7 +338,6 @@ U2:
|
||||
Repulsable: False
|
||||
RenderUnit:
|
||||
WithShadow:
|
||||
IronCurtainable:
|
||||
AttackBomber:
|
||||
-Selectable:
|
||||
-GainsExperience:
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
Chronoshiftable:
|
||||
Passenger:
|
||||
CargoType: Vehicle
|
||||
IronCurtainable:
|
||||
AttackMove:
|
||||
HiddenUnderFog:
|
||||
GainsExperience:
|
||||
@@ -60,6 +59,13 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
TimedUpgradeBar:
|
||||
Upgrade: invulnerability
|
||||
|
||||
^Tank:
|
||||
AppearsOnRadar:
|
||||
@@ -83,7 +89,6 @@
|
||||
Chronoshiftable:
|
||||
Passenger:
|
||||
CargoType: Vehicle
|
||||
IronCurtainable:
|
||||
AttackMove:
|
||||
HiddenUnderFog:
|
||||
GainsExperience:
|
||||
@@ -123,6 +128,13 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
TimedUpgradeBar:
|
||||
Upgrade: invulnerability
|
||||
|
||||
^Infantry:
|
||||
AppearsOnRadar:
|
||||
@@ -207,6 +219,7 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
|
||||
^Ship:
|
||||
AppearsOnRadar:
|
||||
@@ -247,6 +260,13 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
TimedUpgradeBar:
|
||||
Upgrade: invulnerability
|
||||
|
||||
^Plane:
|
||||
AppearsOnRadar:
|
||||
@@ -290,6 +310,13 @@
|
||||
HealIfBelow: 1
|
||||
DamageCooldown: 125
|
||||
RequiresUpgrade: selfheal
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
TimedUpgradeBar:
|
||||
Upgrade: invulnerability
|
||||
|
||||
^Helicopter:
|
||||
Inherits: ^Plane
|
||||
@@ -345,7 +372,14 @@
|
||||
LuaScriptEvents:
|
||||
Demolishable:
|
||||
ScriptTriggers:
|
||||
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
RequiresUpgrade: invulnerability
|
||||
TimedUpgradeBar:
|
||||
Upgrade: invulnerability
|
||||
|
||||
^Defense:
|
||||
Inherits: ^Building
|
||||
TargetableBuilding:
|
||||
|
||||
@@ -147,6 +147,12 @@ CRATE:
|
||||
Units: e1,e1,e4,e4,e3,e3,e3
|
||||
ValidRaces: soviet
|
||||
TimeDelay: 4500
|
||||
GrantUpgradeCrateAction@invuln:
|
||||
SelectionShares: 5
|
||||
Effect: invuln
|
||||
Notification: ironcur9.aud
|
||||
Upgrades: invulnerability
|
||||
Duration: 600
|
||||
RenderSprites:
|
||||
Palette: effect
|
||||
WithCrateBody:
|
||||
|
||||
@@ -38,7 +38,6 @@ SS:
|
||||
Selectable:
|
||||
Bounds: 38,38
|
||||
Chronoshiftable:
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
AutoTarget:
|
||||
InitialStance: ReturnFire
|
||||
@@ -90,7 +89,6 @@ MSUB:
|
||||
Selectable:
|
||||
Bounds: 44,44
|
||||
Chronoshiftable:
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
AutoTarget:
|
||||
InitialStance: ReturnFire
|
||||
@@ -141,7 +139,6 @@ DD:
|
||||
WithTurret:
|
||||
AutoTarget:
|
||||
Chronoshiftable:
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
DetectCloaked:
|
||||
CloakTypes: Underwater
|
||||
@@ -206,7 +203,6 @@ CA:
|
||||
Turret: secondary
|
||||
AutoTarget:
|
||||
Chronoshiftable:
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
Explodes:
|
||||
Weapon: UnitExplodeShip
|
||||
@@ -238,7 +234,6 @@ LST:
|
||||
Types: Infantry, Vehicle
|
||||
MaxWeight: 5
|
||||
PipCount: 5
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
Explodes:
|
||||
Weapon: UnitExplodeShip
|
||||
@@ -284,7 +279,6 @@ PT:
|
||||
WithTurret:
|
||||
AutoTarget:
|
||||
Chronoshiftable:
|
||||
IronCurtainable:
|
||||
RepairableNear:
|
||||
DetectCloaked:
|
||||
CloakTypes: Underwater
|
||||
|
||||
@@ -19,7 +19,6 @@ MSLO:
|
||||
Type: Wood
|
||||
RevealsShroud:
|
||||
Range: 5c0
|
||||
IronCurtainable:
|
||||
NukePower:
|
||||
Icon: abomb
|
||||
ChargeTime: 540
|
||||
@@ -75,7 +74,6 @@ GAP:
|
||||
HasMinibib: Yes
|
||||
CreatesShroud:
|
||||
Range: 6c0
|
||||
IronCurtainable:
|
||||
RenderShroudCircle:
|
||||
Power:
|
||||
Amount: -60
|
||||
@@ -127,7 +125,6 @@ SPEN:
|
||||
Production:
|
||||
Produces: Ship, Submarine
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
-EmitInfantryOnSell:
|
||||
RepairsUnits:
|
||||
RallyPoint:
|
||||
@@ -181,7 +178,6 @@ SYRD:
|
||||
Production:
|
||||
Produces: Ship, Boat
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
-EmitInfantryOnSell:
|
||||
RepairsUnits:
|
||||
RallyPoint:
|
||||
@@ -217,18 +213,18 @@ IRON:
|
||||
Range: 10c0
|
||||
Bib:
|
||||
HasMinibib: Yes
|
||||
IronCurtainable:
|
||||
IronCurtainPower:
|
||||
GrantUpgradePower@IRONCURTAIN:
|
||||
Icon: invuln
|
||||
ChargeTime: 120
|
||||
Description: Invulnerability
|
||||
LongDesc: Makes a group of units invulnerable\nfor 20 seconds.
|
||||
Duration: 20
|
||||
Duration: 500
|
||||
SelectTargetSound: slcttgt1.aud
|
||||
InsufficientPowerSound: nopowr1.aud
|
||||
BeginChargeSound: ironchg1.aud
|
||||
EndChargeSound: ironrdy1.aud
|
||||
DisplayRadarPing: True
|
||||
Upgrades: invulnerability
|
||||
SupportPowerChargeBar:
|
||||
Power:
|
||||
Amount: -200
|
||||
@@ -260,7 +256,6 @@ PDOX:
|
||||
Range: 10c0
|
||||
Bib:
|
||||
HasMinibib: Yes
|
||||
IronCurtainable:
|
||||
ChronoshiftPower:
|
||||
Icon: chrono
|
||||
ChargeTime: 120
|
||||
@@ -314,7 +309,6 @@ TSLA:
|
||||
MaxCharges: 3
|
||||
ReloadTime: 120
|
||||
AutoTarget:
|
||||
IronCurtainable:
|
||||
-RenderBuilding:
|
||||
RenderRangeCircle:
|
||||
-AcceptsSupplies:
|
||||
@@ -361,7 +355,6 @@ AGUN:
|
||||
AttackTurreted:
|
||||
WithMuzzleFlash:
|
||||
AutoTarget:
|
||||
IronCurtainable:
|
||||
-RenderBuilding:
|
||||
RenderRangeCircle:
|
||||
RangeCircleType: aa
|
||||
@@ -399,7 +392,6 @@ DOME:
|
||||
Range: 10c0
|
||||
Bib:
|
||||
ProvidesRadar:
|
||||
IronCurtainable:
|
||||
InfiltrateForExploration:
|
||||
DetectCloaked:
|
||||
Range: 10
|
||||
@@ -428,7 +420,6 @@ PBOX:
|
||||
Range: 6c0
|
||||
Bib:
|
||||
HasMinibib: Yes
|
||||
IronCurtainable:
|
||||
-AcceptsSupplies:
|
||||
Turreted:
|
||||
ROT: 255
|
||||
@@ -476,7 +467,6 @@ HBOX:
|
||||
Cloak:
|
||||
InitialDelay: 125
|
||||
CloakDelay: 60
|
||||
IronCurtainable:
|
||||
-AcceptsSupplies:
|
||||
Turreted:
|
||||
ROT: 255
|
||||
@@ -534,7 +524,6 @@ GUN:
|
||||
AttackTurreted:
|
||||
WithMuzzleFlash:
|
||||
AutoTarget:
|
||||
IronCurtainable:
|
||||
-RenderBuilding:
|
||||
RenderRangeCircle:
|
||||
-AcceptsSupplies:
|
||||
@@ -575,7 +564,6 @@ FTUR:
|
||||
BodyOrientation:
|
||||
QuantizedFacings: 8
|
||||
AutoTarget:
|
||||
IronCurtainable:
|
||||
RenderRangeCircle:
|
||||
-AcceptsSupplies:
|
||||
DrawLineToTarget:
|
||||
@@ -620,7 +608,6 @@ SAM:
|
||||
AttackTurreted:
|
||||
WithMuzzleFlash:
|
||||
AutoTarget:
|
||||
IronCurtainable:
|
||||
-RenderBuilding:
|
||||
RenderRangeCircle:
|
||||
RangeCircleType: aa
|
||||
@@ -654,7 +641,6 @@ ATEK:
|
||||
RevealsShroud:
|
||||
Range: 10c0
|
||||
Bib:
|
||||
IronCurtainable:
|
||||
GpsPower:
|
||||
Icon: gps
|
||||
OneShot: yes
|
||||
@@ -712,7 +698,6 @@ WEAP:
|
||||
RequiresPrerequisites: structures.soviet
|
||||
Prerequisite: vehicles.soviet
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
Power:
|
||||
Amount: -30
|
||||
@@ -741,7 +726,6 @@ FACT:
|
||||
Bib:
|
||||
Production:
|
||||
Produces: Building,Defense
|
||||
IronCurtainable:
|
||||
Valued:
|
||||
Cost: 2500
|
||||
Tooltip:
|
||||
@@ -793,7 +777,6 @@ PROC:
|
||||
StoresResources:
|
||||
PipCount: 17
|
||||
Capacity: 2000
|
||||
IronCurtainable:
|
||||
DrawLineToTarget:
|
||||
CustomSellValue:
|
||||
Value: 600
|
||||
@@ -837,7 +820,6 @@ SILO:
|
||||
StoresResources:
|
||||
PipCount: 5
|
||||
Capacity: 1500
|
||||
IronCurtainable:
|
||||
-RenderBuilding:
|
||||
-EmitInfantryOnSell:
|
||||
Power:
|
||||
@@ -872,7 +854,6 @@ HPAD:
|
||||
Production:
|
||||
Produces: Aircraft, Helicopter
|
||||
Reservable:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
PrimaryBuilding:
|
||||
Power:
|
||||
@@ -907,7 +888,6 @@ AFLD:
|
||||
Production:
|
||||
Produces: Aircraft, Plane
|
||||
Reservable:
|
||||
IronCurtainable:
|
||||
AirstrikePower:
|
||||
Icon: spyplane
|
||||
ChargeTime: 180
|
||||
@@ -962,7 +942,6 @@ POWR:
|
||||
RevealsShroud:
|
||||
Range: 4c0
|
||||
Bib:
|
||||
IronCurtainable:
|
||||
DeadBuildingState:
|
||||
Power:
|
||||
Amount: 100
|
||||
@@ -996,7 +975,6 @@ APWR:
|
||||
RevealsShroud:
|
||||
Range: 4c0
|
||||
Bib:
|
||||
IronCurtainable:
|
||||
DeadBuildingState:
|
||||
Power:
|
||||
Amount: 200
|
||||
@@ -1030,7 +1008,6 @@ STEK:
|
||||
RevealsShroud:
|
||||
Range: 4c0
|
||||
Bib:
|
||||
IronCurtainable:
|
||||
Power:
|
||||
Amount: -100
|
||||
|
||||
@@ -1065,7 +1042,6 @@ BARR:
|
||||
Production:
|
||||
Produces: Infantry, Soldier
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
ProvidesCustomPrerequisite:
|
||||
Prerequisite: barracks
|
||||
@@ -1101,7 +1077,6 @@ KENN:
|
||||
Production:
|
||||
Produces: Infantry, Dog
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
-EmitInfantryOnSell:
|
||||
Power:
|
||||
@@ -1138,7 +1113,6 @@ TENT:
|
||||
Production:
|
||||
Produces: Infantry, Soldier
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
ProvidesCustomPrerequisite:
|
||||
Prerequisite: barracks
|
||||
@@ -1169,7 +1143,6 @@ FIX:
|
||||
HasMinibib: Yes
|
||||
Reservable:
|
||||
RallyPoint:
|
||||
IronCurtainable:
|
||||
RepairsUnits:
|
||||
Interval: 10
|
||||
WithRepairAnimation:
|
||||
@@ -1200,7 +1173,6 @@ FACF:
|
||||
RenderBuilding:
|
||||
Image: FACT
|
||||
Fake:
|
||||
IronCurtainable:
|
||||
-EmitInfantryOnSell:
|
||||
Power:
|
||||
Amount: -2
|
||||
@@ -1231,7 +1203,6 @@ WEAF:
|
||||
RenderBuildingWarFactory:
|
||||
Image: WEAP
|
||||
Fake:
|
||||
IronCurtainable:
|
||||
-EmitInfantryOnSell:
|
||||
Power:
|
||||
Amount: -2
|
||||
|
||||
@@ -652,7 +652,9 @@ DTRK:
|
||||
Weapon: MiniNuke
|
||||
EmptyWeapon: MiniNuke
|
||||
DemoTruck:
|
||||
-IronCurtainable:
|
||||
-InvulnerabilityUpgrade@IRONCURTAIN:
|
||||
KillsSelf:
|
||||
RequiresUpgrade: invulnerability
|
||||
Chronoshiftable:
|
||||
ExplodeInstead: yes
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
DeathSounds@ZAPPED:
|
||||
DeathSound: Zapped
|
||||
DeathTypes: 6
|
||||
UpgradeManager:
|
||||
|
||||
^CivilianInfantry:
|
||||
Inherits: ^Infantry
|
||||
@@ -243,6 +244,15 @@
|
||||
Explodes:
|
||||
Weapon: UnitExplodeSmall
|
||||
EmptyWeapon: UnitExplodeSmall
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@EMPDISABLE:
|
||||
RequiresUpgrade: empdisable
|
||||
Palette: disabled
|
||||
DisableUpgrade@EMPDISABLE:
|
||||
RequiresUpgrade: empdisable
|
||||
TimedUpgradeBar@EMPDISABLE:
|
||||
Upgrade: empdisable
|
||||
Color: 255,255,255
|
||||
|
||||
^Tank:
|
||||
AppearsOnRadar:
|
||||
@@ -302,6 +312,15 @@
|
||||
Explodes:
|
||||
Weapon: UnitExplodeSmall
|
||||
EmptyWeapon: UnitExplodeSmall
|
||||
UpgradeManager:
|
||||
UpgradeOverlay@EMPDISABLE:
|
||||
RequiresUpgrade: empdisable
|
||||
Palette: disabled
|
||||
DisableUpgrade@EMPDISABLE:
|
||||
RequiresUpgrade: empdisable
|
||||
TimedUpgradeBar@EMPDISABLE:
|
||||
Upgrade: empdisable
|
||||
Color: 255,255,255
|
||||
|
||||
^Helicopter:
|
||||
AppearsOnRadar:
|
||||
@@ -348,6 +367,7 @@
|
||||
ScriptTriggers:
|
||||
Guard:
|
||||
Guardable:
|
||||
UpgradeManager:
|
||||
|
||||
^BlossomTree:
|
||||
Tooltip:
|
||||
|
||||
@@ -113,7 +113,6 @@ GAPILE:
|
||||
Production:
|
||||
Produces: Infantry
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
WithProductionOverlay@LIGHTS:
|
||||
Sequence: production-lights
|
||||
@@ -338,7 +337,6 @@ NAHAND:
|
||||
Production:
|
||||
Produces: Infantry
|
||||
PrimaryBuilding:
|
||||
IronCurtainable:
|
||||
ProductionBar:
|
||||
WithIdleOverlay@LIGHTS:
|
||||
Sequence: idle-lights
|
||||
@@ -1183,6 +1181,46 @@ NAOBEL:
|
||||
Power:
|
||||
Amount: -150
|
||||
|
||||
NAPULS:
|
||||
Inherits: ^Building
|
||||
Valued:
|
||||
Cost: 1000
|
||||
Tooltip:
|
||||
Name: EMP Cannon
|
||||
Description: Disables vehicles. \nRequires power to operate.\n Strong vs all ground units\n Cannot target Aircraft
|
||||
Buildable:
|
||||
Queue: Defense
|
||||
BuildPaletteOrder: 90
|
||||
Prerequisites: radar
|
||||
Owner: nod,gdi
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
RequiresPower:
|
||||
DisabledOverlay:
|
||||
-GivesBuildableArea:
|
||||
Health:
|
||||
HP: 500
|
||||
Armor:
|
||||
Type: Heavy
|
||||
RevealsShroud:
|
||||
Range: 8c0
|
||||
Turreted:
|
||||
ROT: 10
|
||||
InitialFacing: 300
|
||||
AttackTurreted:
|
||||
Armament:
|
||||
Weapon: EMPulseCannon
|
||||
AutoTarget:
|
||||
RenderRangeCircle:
|
||||
RenderDetectionCircle:
|
||||
DetectCloaked:
|
||||
Range: 5
|
||||
WithTurret:
|
||||
Sequence: turret
|
||||
Power:
|
||||
Amount: -150
|
||||
|
||||
ANYPOWER:
|
||||
Tooltip:
|
||||
Name: Power Plant
|
||||
|
||||
@@ -161,7 +161,6 @@ explosion:
|
||||
pulse_explosion: pulsefx2
|
||||
Start: 0
|
||||
Length: *
|
||||
Tick: 160
|
||||
BlendMode: Additive
|
||||
small_watersplash: h2o_exp2
|
||||
Start: 0
|
||||
@@ -279,6 +278,11 @@ canister:
|
||||
Start: 0
|
||||
Length: *
|
||||
|
||||
pulsball:
|
||||
idle:
|
||||
Start: 0
|
||||
Length: *
|
||||
|
||||
dragon:
|
||||
idle:
|
||||
Start: 0
|
||||
|
||||
@@ -698,6 +698,26 @@ nasam:
|
||||
icon: samicon
|
||||
Start: 0
|
||||
|
||||
napuls:
|
||||
idle: ntpuls
|
||||
Start: 0
|
||||
ShadowStart: 3
|
||||
damaged-idle: ntpuls
|
||||
Start: 1
|
||||
ShadowStart: 4
|
||||
critical-idle: ntpuls
|
||||
Start: 2
|
||||
ShadowStart: 5
|
||||
turret: ntpuls_a
|
||||
Start: 0
|
||||
Facings: 32
|
||||
make: ntpulsmk
|
||||
Start: 0
|
||||
Length: 20
|
||||
ShadowStart: 20
|
||||
icon: pulsicon
|
||||
Start: 0
|
||||
|
||||
gavulc:
|
||||
idle: gtctwr
|
||||
Start: 0
|
||||
|
||||
@@ -1114,6 +1114,27 @@ TurretLaser:
|
||||
Warhead@2Smu: LeaveSmudge
|
||||
SmudgeType: Scorch
|
||||
|
||||
EMPulseCannon:
|
||||
ReloadDelay: 100
|
||||
Range: 10c0
|
||||
Report: PLSECAN2.AUD
|
||||
Projectile: Bullet
|
||||
Speed: 425
|
||||
High: yes
|
||||
Shadow: true
|
||||
Angle: 62
|
||||
Image: pulsball
|
||||
Warhead@2Eff: CreateEffect
|
||||
Explosion: pulse_explosion
|
||||
# Dummy warhead to allow targeting
|
||||
Warhead@target: SpreadDamage
|
||||
Spread: 0
|
||||
Damage: 0
|
||||
Warhead@emp: GrantUpgrade
|
||||
Range: 3c0
|
||||
Duration: 250
|
||||
Upgrades: empdisable
|
||||
|
||||
TiberiumExplosion:
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Spread: 9
|
||||
|
||||
Reference in New Issue
Block a user