Merge pull request #8210 from matija-hustic/ra2_veterancy_icon

Veteran unit production & unlocking through spies.
This commit is contained in:
Matthias Mailänder
2015-07-06 09:38:09 +02:00
23 changed files with 360 additions and 10 deletions

View File

@@ -295,6 +295,7 @@
<Compile Include="Traits\Buildings\TargetableBuilding.cs" /> <Compile Include="Traits\Buildings\TargetableBuilding.cs" />
<Compile Include="Traits\Burns.cs" /> <Compile Include="Traits\Burns.cs" />
<Compile Include="Traits\C4Demolition.cs" /> <Compile Include="Traits\C4Demolition.cs" />
<Compile Include="Traits\VeteranProductionIconOverlay.cs" />
<Compile Include="Traits\Capturable.cs" /> <Compile Include="Traits\Capturable.cs" />
<Compile Include="Traits\CaptureNotification.cs" /> <Compile Include="Traits\CaptureNotification.cs" />
<Compile Include="Traits\Captures.cs" /> <Compile Include="Traits\Captures.cs" />
@@ -473,6 +474,7 @@
<Compile Include="Traits\TransformOnPassenger.cs" /> <Compile Include="Traits\TransformOnPassenger.cs" />
<Compile Include="Traits\Transforms.cs" /> <Compile Include="Traits\Transforms.cs" />
<Compile Include="Traits\Turreted.cs" /> <Compile Include="Traits\Turreted.cs" />
<Compile Include="Traits\ProduceableWithLevel.cs" />
<Compile Include="Traits\Upgrades\DeployToUpgrade.cs" /> <Compile Include="Traits\Upgrades\DeployToUpgrade.cs" />
<Compile Include="Traits\Upgrades\DisableUpgrade.cs" /> <Compile Include="Traits\Upgrades\DisableUpgrade.cs" />
<Compile Include="Traits\Upgrades\GainsStatUpgrades.cs" /> <Compile Include="Traits\Upgrades\GainsStatUpgrades.cs" />

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("This actor's experience increases when it has killed a GivesExperience actor.")] [Desc("This actor's experience increases when it has killed a GivesExperience actor.")]
public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo> public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo>, Requires<UpgradeManagerInfo>
{ {
[FieldLoader.LoadUsing("LoadUpgrades")] [FieldLoader.LoadUsing("LoadUpgrades")]
[Desc("Upgrades to grant at each level", [Desc("Upgrades to grant at each level",
@@ -29,6 +29,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Palette for the level up sprite.")] [Desc("Palette for the level up sprite.")]
public readonly string LevelUpPalette = "effect"; public readonly string LevelUpPalette = "effect";
[Desc("Should the level-up animation be suppressed when actor is created?")]
public readonly bool SuppressLevelupAnimation = true;
public object Create(ActorInitializer init) { return new GainsExperience(init, this); } public object Create(ActorInitializer init) { return new GainsExperience(init, this); }
static object LoadUpgrades(MiniYaml y) static object LoadUpgrades(MiniYaml y)
@@ -56,6 +59,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly Actor self; readonly Actor self;
readonly GainsExperienceInfo info; readonly GainsExperienceInfo info;
readonly UpgradeManager um;
readonly List<Pair<int, string[]>> nextLevel = new List<Pair<int, string[]>>(); readonly List<Pair<int, string[]>> nextLevel = new List<Pair<int, string[]>>();
@@ -77,18 +81,20 @@ namespace OpenRA.Mods.Common.Traits
nextLevel.Add(Pair.New(kv.Key * cost, kv.Value)); nextLevel.Add(Pair.New(kv.Key * cost, kv.Value));
if (init.Contains<ExperienceInit>()) if (init.Contains<ExperienceInit>())
GiveExperience(init.Get<ExperienceInit, int>()); GiveExperience(init.Get<ExperienceInit, int>(), info.SuppressLevelupAnimation);
um = self.Trait<UpgradeManager>();
} }
public bool CanGainLevel { get { return Level < MaxLevel; } } public bool CanGainLevel { get { return Level < MaxLevel; } }
public void GiveLevels(int numLevels) public void GiveLevels(int numLevels, bool silent = false)
{ {
var newLevel = Math.Min(Level + numLevels, MaxLevel); var newLevel = Math.Min(Level + numLevels, MaxLevel);
GiveExperience(nextLevel[newLevel - 1].First - experience); GiveExperience(nextLevel[newLevel - 1].First - experience, silent);
} }
public void GiveExperience(int amount) public void GiveExperience(int amount, bool silent = false)
{ {
experience += amount; experience += amount;
@@ -98,11 +104,12 @@ namespace OpenRA.Mods.Common.Traits
Level++; Level++;
var um = self.TraitOrDefault<UpgradeManager>(); foreach (var u in upgrades)
if (um != null) um.GrantUpgrade(self, u, this);
foreach (var u in upgrades) }
um.GrantUpgrade(self, u, this);
if (!silent)
{
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "LevelUp", self.Owner.Country.Race); 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))); self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", info.LevelUpPalette)));
} }

View File

@@ -0,0 +1,52 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Actors possessing this trait should define the GainsExperience trait. When the prerequisites are fulfilled, ",
"this trait grants a level-up to newly spawned actors. If additionally the actor's owning player defines the ProductionIconOverlay ",
"trait, the production queue icon renders with an overlay defined in that trait.")]
public class ProduceableWithLevelInfo : ITraitInfo, Requires<GainsExperienceInfo>
{
public readonly string[] Prerequisites = { };
[Desc("Number of levels to give to the actor on creation.")]
public readonly int InitialLevels = 1;
[Desc("Should the level-up animation be suppressed when actor is created?")]
public readonly bool SuppressLevelupAnimation = true;
public object Create(ActorInitializer init) { return new ProduceableWithLevel(init, this); }
}
public class ProduceableWithLevel : INotifyCreated
{
readonly ProduceableWithLevelInfo info;
public ProduceableWithLevel(ActorInitializer init, ProduceableWithLevelInfo info)
{
this.info = info;
}
public void Created(Actor self)
{
if (!self.Owner.PlayerActor.Trait<TechTree>().HasPrerequisites(info.Prerequisites))
return;
var ge = self.Trait<GainsExperience>();
if (!ge.CanGainLevel)
return;
ge.GiveLevels(info.InitialLevels, info.SuppressLevelupAnimation);
}
}
}

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
/// Abstract base for enabling and disabling trait using upgrades. /// Abstract base for enabling and disabling trait using upgrades.
/// Requires basing *Info on UpgradableTraitInfo and using base(info) constructor. /// Requires basing *Info on UpgradableTraitInfo and using base(info) constructor.
/// Note that EnabledByUpgrade is not called at creation even if this starts as enabled. /// Note that EnabledByUpgrade is not called at creation even if this starts as enabled.
/// </summary>, /// </summary>
public abstract class UpgradableTrait<InfoType> : IUpgradable, IDisabledTrait, ISync where InfoType : UpgradableTraitInfo public abstract class UpgradableTrait<InfoType> : IUpgradable, IDisabledTrait, ISync where InfoType : UpgradableTraitInfo
{ {
public readonly InfoType Info; public readonly InfoType Info;

View File

@@ -0,0 +1,151 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Common.Traits
{
[Desc("Attach this to the player actor. When attached, enables all actors possessing the LevelupWhenCreated ",
"trait to have their production queue icons render with an overlay defined in this trait. ",
"The icon change occurs when LevelupWhenCreated.Prerequisites are met.")]
public class VeteranProductionIconOverlayInfo : ITraitInfo, Requires<TechTreeInfo>
{
[Desc("Image used for the overlay.")]
public readonly string Image = null;
[Desc("Sequence used for the overlay (cannot be animated).")]
[SequenceReference("Image")] public readonly string Sequence = null;
[Desc("Palette to render the sprite in. Reference the world actor's PaletteFrom* traits.")]
public readonly string Palette = "chrome";
[Desc("Point on the production icon's used as reference for offsetting the overlay. ",
"Possible values are any combination of Top, VCenter, Bottom and Left, HCenter, Right separated by a comma.")]
public readonly ReferencePoints ReferencePoint = ReferencePoints.Top | ReferencePoints.Left;
[Desc("Pixel offset relative to the icon's reference point.")]
public readonly int2 Offset = int2.Zero;
[Desc("Visual scale of the overlay.")]
public readonly float Scale = 1f;
public object Create(ActorInitializer init) { return new VeteranProductionIconOverlay(init, this); }
}
public class VeteranProductionIconOverlay : ITechTreeElement, IProductionIconOverlay
{
// HACK: TechTree doesn't associate Watcher.Key with the registering ITechTreeElement.
// So in a situation where multiple ITechTreeElements register Watchers with the same Key,
// and one removes its Watcher, all other ITechTreeElements' Watchers get removed too.
// This makes sure that the keys are unique with respect to the registering ITechTreeElement.
const string Prefix = "ProductionIconOverlay.";
readonly Actor self;
readonly Sprite sprite;
readonly VeteranProductionIconOverlayInfo info;
Dictionary<ActorInfo, bool> overlayActive = new Dictionary<ActorInfo, bool>();
public VeteranProductionIconOverlay(ActorInitializer init, VeteranProductionIconOverlayInfo info)
{
self = init.Self;
var anim = new Animation(self.World, info.Image);
anim.Play(info.Sequence);
sprite = anim.Image;
this.info = info;
var ttc = self.Trait<TechTree>();
foreach (var a in self.World.Map.Rules.Actors.Values)
{
var uwc = a.Traits.GetOrDefault<ProduceableWithLevelInfo>();
if (uwc != null)
ttc.Add(MakeKey(a.Name), uwc.Prerequisites, 0, this);
}
}
public Sprite Sprite()
{
return sprite;
}
public string Palette()
{
return info.Palette;
}
public float Scale()
{
return info.Scale;
}
public float2 Offset(float2 iconSize)
{
float offsetX = 0, offsetY = 0;
switch (info.ReferencePoint & (ReferencePoints)3)
{
case ReferencePoints.Top:
offsetY = (-iconSize.Y + sprite.Size.Y) / 2;
break;
case ReferencePoints.VCenter:
break;
case ReferencePoints.Bottom:
offsetY = (iconSize.Y - sprite.Size.Y) / 2;
break;
}
switch (info.ReferencePoint & (ReferencePoints)(3 << 2))
{
case ReferencePoints.Left:
offsetX = (-iconSize.X + sprite.Size.X) / 2;
break;
case ReferencePoints.HCenter:
break;
case ReferencePoints.Right:
offsetX = (iconSize.X - sprite.Size.X) / 2;
break;
}
return new float2(offsetX, offsetY) + info.Offset;
}
public bool IsOverlayActive(ActorInfo ai)
{
bool isActive;
overlayActive.TryGetValue(ai, out isActive);
return isActive;
}
static string MakeKey(string name)
{
return Prefix + name;
}
static string GetName(string key)
{
return key.Substring(Prefix.Length);
}
public void PrerequisitesAvailable(string key)
{
var ai = self.World.Map.Rules.Actors[GetName(key)];
overlayActive[ai] = true;
}
public void PrerequisitesUnavailable(string key) { }
public void PrerequisitesItemHidden(string key) { }
public void PrerequisitesItemVisible(string key) { }
}
}

View File

@@ -75,6 +75,15 @@ namespace OpenRA.Mods.Common.Traits
void PrerequisitesItemVisible(string key); void PrerequisitesItemVisible(string key);
} }
public interface IProductionIconOverlay
{
Sprite Sprite();
string Palette();
float Scale();
float2 Offset(float2 iconSize);
bool IsOverlayActive(ActorInfo ai);
}
public interface INotifyTransform { void BeforeTransform(Actor self); void OnTransform(Actor self); void AfterTransform(Actor toActor); } public interface INotifyTransform { void BeforeTransform(Actor self); void OnTransform(Actor self); void AfterTransform(Actor toActor); }
public interface IAcceptResources public interface IAcceptResources

View File

@@ -79,6 +79,11 @@ namespace OpenRA.Mods.Common.Widgets
var location = new float2(RenderBounds.Location) + new float2(queue.i * (IconWidth + IconSpacing), 0); var location = new float2(RenderBounds.Location) + new float2(queue.i * (IconWidth + IconSpacing), 0);
WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f); WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f);
var pio = queue.Trait.Actor.Owner.PlayerActor.TraitsImplementing<IProductionIconOverlay>().FirstOrDefault();
if (pio != null && pio.IsOverlayActive(actor))
WidgetUtils.DrawSHPCentered(pio.Sprite(), location + 0.5f * iconSize + pio.Offset(0.5f * iconSize),
worldRenderer.Palette(pio.Palette()), 0.5f * pio.Scale());
var clock = clocks[queue.Trait]; var clock = clocks[queue.Trait];
clock.PlayFetchIndex("idle", clock.PlayFetchIndex("idle",
() => current.TotalTime == 0 ? 0 : ((current.TotalTime - current.RemainingTime) () => current.TotalTime == 0 ? 0 : ((current.TotalTime - current.RemainingTime)

View File

@@ -351,11 +351,18 @@ namespace OpenRA.Mods.Common.Widgets
var buildableItems = CurrentQueue.BuildableItems(); var buildableItems = CurrentQueue.BuildableItems();
var pio = currentQueue.Actor.Owner.PlayerActor.TraitsImplementing<IProductionIconOverlay>().FirstOrDefault();
var pioOffset = pio != null ? pio.Offset(IconSize) : new float2(0, 0);
// Icons // Icons
foreach (var icon in icons.Values) foreach (var icon in icons.Values)
{ {
WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, icon.Palette); WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, icon.Palette);
// Draw the ProductionIconOverlay's sprite
if (pio != null && pio.IsOverlayActive(icon.Actor))
WidgetUtils.DrawSHPCentered(pio.Sprite(), icon.Pos + iconOffset + pioOffset, worldRenderer.Palette(pio.Palette()), pio.Scale());
// Build progress // Build progress
if (icon.Queued.Count > 0) if (icon.Queued.Count > 0)
{ {

Binary file not shown.

Binary file not shown.

View File

@@ -122,6 +122,8 @@ MIG:
SmokeTrailWhenDamaged: SmokeTrailWhenDamaged:
Offset: -853,0,171 Offset: -853,0,171
Interval: 2 Interval: 2
ProduceableWithLevel:
Prerequisites: aircraft.upgraded
YAK: YAK:
Inherits: ^Plane Inherits: ^Plane
@@ -178,6 +180,8 @@ YAK:
SmokeTrailWhenDamaged: SmokeTrailWhenDamaged:
Offset: -853,0,0 Offset: -853,0,0
Interval: 2 Interval: 2
ProduceableWithLevel:
Prerequisites: aircraft.upgraded
TRAN: TRAN:
Inherits: ^Helicopter Inherits: ^Helicopter
@@ -265,6 +269,8 @@ HELI:
HuskActor: HELI.Husk HuskActor: HELI.Husk
SmokeTrailWhenDamaged: SmokeTrailWhenDamaged:
Offset: -427,0,0 Offset: -427,0,0
ProduceableWithLevel:
Prerequisites: aircraft.upgraded
HIND: HIND:
Inherits: ^Helicopter Inherits: ^Helicopter
@@ -317,6 +323,8 @@ HIND:
HuskActor: HIND.Husk HuskActor: HIND.Husk
SmokeTrailWhenDamaged: SmokeTrailWhenDamaged:
Offset: -427,0,0 Offset: -427,0,0
ProduceableWithLevel:
Prerequisites: aircraft.upgraded
U2: U2:
Inherits: ^Plane Inherits: ^Plane

View File

@@ -67,6 +67,8 @@ E1:
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
E2: E2:
Inherits: ^Soldier Inherits: ^Soldier
@@ -98,6 +100,8 @@ E2:
Explodes: Explodes:
Weapon: UnitExplodeSmall Weapon: UnitExplodeSmall
Chance: 50 Chance: 50
ProduceableWithLevel:
Prerequisites: barracks.upgraded
E3: E3:
Inherits: ^Soldier Inherits: ^Soldier
@@ -125,6 +129,8 @@ E3:
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
E4: E4:
Inherits: ^Soldier Inherits: ^Soldier
@@ -150,6 +156,8 @@ E4:
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
E6: E6:
Inherits: ^Soldier Inherits: ^Soldier
@@ -278,6 +286,8 @@ E7:
AnnounceOnKill: AnnounceOnKill:
Voiced: Voiced:
VoiceSet: TanyaVoice VoiceSet: TanyaVoice
ProduceableWithLevel:
Prerequisites: barracks.upgraded
MEDI: MEDI:
Inherits: ^Soldier Inherits: ^Soldier
@@ -477,6 +487,8 @@ SHOK:
AttackSequence: shoot AttackSequence: shoot
Voiced: Voiced:
VoiceSet: ShokVoice VoiceSet: ShokVoice
ProduceableWithLevel:
Prerequisites: barracks.upgraded
SNIPER: SNIPER:
Inherits: ^Soldier Inherits: ^Soldier
@@ -516,6 +528,8 @@ SNIPER:
DetectCloaked: DetectCloaked:
Range: 6 Range: 6
-MustBeDestroyed: -MustBeDestroyed:
ProduceableWithLevel:
Prerequisites: barracks.upgraded
Zombie: Zombie:
Inherits: ^Soldier Inherits: ^Soldier

View File

@@ -362,6 +362,18 @@ powerproxy.paratroopers:
DisplayBeacon: true DisplayBeacon: true
BeaconPoster: pinficon BeaconPoster: pinficon
barracks.upgraded:
AlwaysVisible:
ProvidesPrerequisite:
vehicles.upgraded:
AlwaysVisible:
ProvidesPrerequisite:
aircraft.upgraded:
AlwaysVisible:
ProvidesPrerequisite:
mpspawn: mpspawn:
AlwaysVisible: AlwaysVisible:
Immobile: Immobile:

View File

@@ -10,6 +10,10 @@
Filename: temperat.pal Filename: temperat.pal
ShadowIndex: 3 ShadowIndex: 3
AllowModifiers: false AllowModifiers: false
PaletteFromFile@cameo-chevron:
Name: cameo-chevron
Filename: cameo-chevron.pal
AllowModifiers: false
PaletteFromFile@effect: PaletteFromFile@effect:
Name: effect Name: effect
Filename: temperat.pal Filename: temperat.pal

View File

@@ -65,4 +65,9 @@ Player:
Prerequisites: techlevel.infonly, techlevel.low, techlevel.medium, techlevel.unrestricted Prerequisites: techlevel.infonly, techlevel.low, techlevel.medium, techlevel.unrestricted
GlobalUpgradeManager: GlobalUpgradeManager:
EnemyWatcher: EnemyWatcher:
VeteranProductionIconOverlay:
Offset: 2, 2
Image: cameo-chevron
Sequence: idle
Palette: cameo-chevron

View File

@@ -855,6 +855,10 @@ WEAP:
Power: Power:
Amount: -30 Amount: -30
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
TargetableBuilding:
TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate
InfiltrateForSupportPower:
Proxy: vehicles.upgraded
FACT: FACT:
Inherits: ^Building Inherits: ^Building
@@ -1080,6 +1084,10 @@ HPAD:
RequiresPrerequisites: structures.germany RequiresPrerequisites: structures.germany
Prerequisite: aircraft.germany Prerequisite: aircraft.germany
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
TargetableBuilding:
TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate
InfiltrateForSupportPower:
Proxy: aircraft.upgraded
AFLD: AFLD:
Inherits: ^Building Inherits: ^Building
@@ -1185,6 +1193,10 @@ AFLD:
Power: Power:
Amount: -20 Amount: -20
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
TargetableBuilding:
TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate
InfiltrateForSupportPower:
Proxy: aircraft.upgraded
POWR: POWR:
Inherits: ^Building Inherits: ^Building
@@ -1352,6 +1364,10 @@ BARR:
Power: Power:
Amount: -20 Amount: -20
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
InfiltrateForSupportPower:
Proxy: barracks.upgraded
TargetableBuilding:
TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate
KENN: KENN:
Inherits: ^Building Inherits: ^Building
@@ -1455,6 +1471,10 @@ TENT:
Power: Power:
Amount: -20 Amount: -20
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
InfiltrateForSupportPower:
Proxy: barracks.upgraded
TargetableBuilding:
TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate
FIX: FIX:
Inherits: ^Building Inherits: ^Building

View File

@@ -29,6 +29,8 @@ V2RL:
WithAttackAnimation: WithAttackAnimation:
AimSequence: aim AimSequence: aim
ReloadPrefix: empty- ReloadPrefix: empty-
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
1TNK: 1TNK:
Inherits: ^Tank Inherits: ^Tank
@@ -67,6 +69,8 @@ V2RL:
EmptyWeapon: UnitExplodeSmall EmptyWeapon: UnitExplodeSmall
LeavesHusk: LeavesHusk:
HuskActor: 1TNK.Husk HuskActor: 1TNK.Husk
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
2TNK: 2TNK:
Inherits: ^Tank Inherits: ^Tank
@@ -107,6 +111,8 @@ V2RL:
HuskActor: 2TNK.Husk HuskActor: 2TNK.Husk
SelectionDecorations: SelectionDecorations:
VisualBounds: 28,28 VisualBounds: 28,28
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
3TNK: 3TNK:
Inherits: ^Tank Inherits: ^Tank
@@ -147,6 +153,8 @@ V2RL:
HuskActor: 3TNK.Husk HuskActor: 3TNK.Husk
SelectionDecorations: SelectionDecorations:
VisualBounds: 28,28 VisualBounds: 28,28
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
4TNK: 4TNK:
Inherits: ^Tank Inherits: ^Tank
@@ -201,6 +209,8 @@ V2RL:
DamageCooldown: 150 DamageCooldown: 150
SelectionDecorations: SelectionDecorations:
VisualBounds: 44,38,0,-4 VisualBounds: 44,38,0,-4
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
ARTY: ARTY:
Inherits: ^Tank Inherits: ^Tank
@@ -232,6 +242,8 @@ ARTY:
Weapon: UnitExplode Weapon: UnitExplode
Chance: 75 Chance: 75
AutoTarget: AutoTarget:
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
HARV: HARV:
Inherits: ^Vehicle Inherits: ^Vehicle
@@ -354,6 +366,8 @@ JEEP:
Types: Infantry Types: Infantry
MaxWeight: 1 MaxWeight: 1
PipCount: 1 PipCount: 1
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
APC: APC:
Inherits: ^Tank Inherits: ^Tank
@@ -386,6 +400,8 @@ APC:
Types: Infantry Types: Infantry
MaxWeight: 5 MaxWeight: 5
PipCount: 5 PipCount: 5
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
MNLY.AP: MNLY.AP:
Inherits: ^Tank Inherits: ^Tank
@@ -569,6 +585,8 @@ TTNK:
SelectionDecorations: SelectionDecorations:
VisualBounds: 30,30 VisualBounds: 30,30
AutoTarget: AutoTarget:
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
FTRK: FTRK:
Inherits: ^Vehicle Inherits: ^Vehicle
@@ -604,6 +622,8 @@ FTRK:
AutoTarget: AutoTarget:
SelectionDecorations: SelectionDecorations:
VisualBounds: 28,28 VisualBounds: 28,28
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
DTRK: DTRK:
Inherits: ^Vehicle Inherits: ^Vehicle
@@ -668,6 +688,8 @@ CTNK:
LocalYaw: -100 LocalYaw: -100
AttackFrontal: AttackFrontal:
PortableChrono: PortableChrono:
ProduceableWithLevel:
Prerequisites: vehicles.upgraded
QTNK: QTNK:
Inherits: ^Tank Inherits: ^Tank
@@ -737,4 +759,6 @@ STNK:
DetectCloaked: DetectCloaked:
Range: 6 Range: 6
-MustBeDestroyed: -MustBeDestroyed:
ProduceableWithLevel:
Prerequisites: vehicles.upgraded

View File

@@ -382,6 +382,11 @@ rank:
rank: rank:
Length: * Length: *
cameo-chevron:
idle:
Length: *
BlendMode: Additive
atomic: atomic:
up: atomicup up: atomicup
Length: * Length: *

View File

@@ -41,6 +41,8 @@ UMAGON:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
CHAMSPY: CHAMSPY:
Inherits: ^Soldier Inherits: ^Soldier
@@ -96,6 +98,8 @@ MUTANT:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
MWMN: MWMN:
Inherits: ^Soldier Inherits: ^Soldier
@@ -119,6 +123,8 @@ MWMN:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
MUTANT3: MUTANT3:
Inherits: ^Soldier Inherits: ^Soldier
@@ -142,6 +148,8 @@ MUTANT3:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
TRATOS: TRATOS:
Inherits: ^Soldier Inherits: ^Soldier

View File

@@ -641,6 +641,9 @@ CAARMR:
HP: 800 HP: 800
RenderBuilding: RenderBuilding:
Palette: player Palette: player
ProvidesPrerequisite:
Prerequisite: barracks.upgraded
Capturable:
CABHUT: CABHUT:
Inherits: ^CivBuilding Inherits: ^CivBuilding

View File

@@ -21,6 +21,8 @@ E2:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: throw AttackSequence: throw
ProduceableWithLevel:
Prerequisites: barracks.upgraded
MEDIC: MEDIC:
Inherits: ^Soldier Inherits: ^Soldier
@@ -81,6 +83,8 @@ JUMPJET:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
-TakeCover: -TakeCover:
ProduceableWithLevel:
Prerequisites: barracks.upgraded
GHOST: GHOST:
Inherits: ^Soldier Inherits: ^Soldier
@@ -117,4 +121,6 @@ GHOST:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded

View File

@@ -22,6 +22,8 @@ E3:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
CYBORG: CYBORG:
Inherits: ^Cyborg Inherits: ^Cyborg
@@ -53,6 +55,8 @@ CYBORG:
Voice: Attack Voice: Attack
SelectionDecorations: SelectionDecorations:
VisualBounds: 16,31,0,-10 VisualBounds: 16,31,0,-10
ProduceableWithLevel:
Prerequisites: barracks.upgraded
CYC2: CYC2:
Inherits: ^Cyborg Inherits: ^Cyborg
@@ -86,6 +90,8 @@ CYC2:
Voice: Attack Voice: Attack
SelectionDecorations: SelectionDecorations:
VisualBounds: 16,32,-1,-12 VisualBounds: 16,32,-1,-12
ProduceableWithLevel:
Prerequisites: barracks.upgraded
MHIJACK: MHIJACK:
Inherits: ^Soldier Inherits: ^Soldier

View File

@@ -26,6 +26,8 @@ E1:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot AttackSequence: shoot
ProduceableWithLevel:
Prerequisites: barracks.upgraded
ENGINEER: ENGINEER:
Inherits: ^Soldier Inherits: ^Soldier