Replace repair indicator effect with a Decoration subclass.
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2018 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
class RepairIndicator : IEffect, IEffectAboveShroud
|
||||
{
|
||||
readonly Actor building;
|
||||
readonly Animation anim;
|
||||
readonly RepairableBuilding rb;
|
||||
|
||||
int shownPlayer = 0;
|
||||
|
||||
public RepairIndicator(Actor building)
|
||||
{
|
||||
this.building = building;
|
||||
|
||||
rb = building.Trait<RepairableBuilding>();
|
||||
anim = new Animation(building.World, rb.Info.IndicatorImage, () => !rb.RepairActive || rb.IsTraitDisabled);
|
||||
|
||||
CycleRepairer();
|
||||
}
|
||||
|
||||
void IEffect.Tick(World world)
|
||||
{
|
||||
if (!building.IsInWorld || building.IsDead || !rb.Repairers.Any())
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
anim.Tick();
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffect.Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
|
||||
IEnumerable<IRenderable> IEffectAboveShroud.RenderAboveShroud(WorldRenderer wr)
|
||||
{
|
||||
if (building.Disposed || rb.Repairers.Count == 0 || wr.World.FogObscures(building))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
PaletteReference palette;
|
||||
if (!string.IsNullOrEmpty(rb.Info.IndicatorPalette))
|
||||
palette = wr.Palette(rb.Info.IndicatorPalette);
|
||||
else
|
||||
palette = wr.Palette(rb.Info.IndicatorPalettePrefix + rb.Repairers[shownPlayer % rb.Repairers.Count].InternalName);
|
||||
|
||||
// Size shouldn't scale with pixel doubling
|
||||
// TODO: Remove this RepairIndicator entirely in favor of using WithDecoration
|
||||
var zoom = 1f / wr.Viewport.Zoom;
|
||||
return anim.Render(building.CenterPosition, WVec.Zero, 0, palette, zoom);
|
||||
}
|
||||
|
||||
void CycleRepairer()
|
||||
{
|
||||
anim.PlayThen(rb.Info.IndicatorSequence, CycleRepairer);
|
||||
|
||||
if (++shownPlayer == rb.Repairers.Count)
|
||||
shownPlayer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,6 @@
|
||||
<Compile Include="Effects\FloatingText.cs" />
|
||||
<Compile Include="Effects\MapNotificationEffect.cs" />
|
||||
<Compile Include="Effects\RallyPointIndicator.cs" />
|
||||
<Compile Include="Effects\RepairIndicator.cs" />
|
||||
<Compile Include="Effects\SpriteEffect.cs" />
|
||||
<Compile Include="Graphics\RailgunRenderable.cs" />
|
||||
<Compile Include="Projectiles\AreaBeam.cs" />
|
||||
@@ -882,6 +881,8 @@
|
||||
<Compile Include="UpdateRules\Rules\DefineLocomotors.cs" />
|
||||
<Compile Include="UpdateRules\Rules\DefineOwnerLostAction.cs" />
|
||||
<Compile Include="UpdateRules\Rules\RenameEmitInfantryOnSell.cs" />
|
||||
<Compile Include="Traits\Render\WithBuildingRepairDecoration.cs" />
|
||||
<Compile Include="UpdateRules\Rules\SplitRepairDecoration.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="AfterBuild">
|
||||
|
||||
@@ -36,23 +36,40 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Cancel the repair state when the trait is disabled.")]
|
||||
public readonly bool CancelWhenDisabled = false;
|
||||
|
||||
public readonly string IndicatorImage = "allyrepair";
|
||||
[SequenceReference("IndicatorImage")] public readonly string IndicatorSequence = "repair";
|
||||
|
||||
[Desc("Overrides the IndicatorPalettePrefix.")]
|
||||
[PaletteReference] public readonly string IndicatorPalette = "";
|
||||
|
||||
[Desc("Suffixed by the internal repairing player name.")]
|
||||
public readonly string IndicatorPalettePrefix = "player";
|
||||
|
||||
[Desc("Experience gained by a player for repairing structures of allied players.")]
|
||||
public readonly int PlayerExperience = 0;
|
||||
|
||||
[GrantedConditionReference]
|
||||
[Desc("The condition to grant to self while being repaired.")]
|
||||
public readonly string RepairCondition = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new RepairableBuilding(init.Self, this); }
|
||||
}
|
||||
|
||||
public class RepairableBuilding : ConditionalTrait<RepairableBuildingInfo>, ITick
|
||||
{
|
||||
readonly Health health;
|
||||
readonly Predicate<Player> isNotActiveAlly;
|
||||
readonly Stack<int> repairTokens = new Stack<int>();
|
||||
ConditionManager conditionManager;
|
||||
int remainingTicks;
|
||||
|
||||
public readonly List<Player> Repairers = new List<Player>();
|
||||
public bool RepairActive { get; private set; }
|
||||
|
||||
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
|
||||
: base(info)
|
||||
{
|
||||
health = self.Trait<Health>();
|
||||
isNotActiveAlly = player => player.WinState != WinState.Undefined || player.Stances[self.Owner] != Stance.Ally;
|
||||
}
|
||||
|
||||
protected override void Created(Actor self)
|
||||
{
|
||||
base.Created(self);
|
||||
conditionManager = self.TraitOrDefault<ConditionManager>();
|
||||
}
|
||||
|
||||
[Sync]
|
||||
public int RepairersHash
|
||||
{
|
||||
@@ -65,40 +82,39 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public readonly List<Player> Repairers = new List<Player>();
|
||||
|
||||
readonly Health health;
|
||||
public bool RepairActive = false;
|
||||
|
||||
readonly Predicate<Player> isNotActiveAlly;
|
||||
|
||||
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
|
||||
: base(info)
|
||||
void UpdateCondition(Actor self)
|
||||
{
|
||||
health = self.Trait<Health>();
|
||||
isNotActiveAlly = player => player.WinState != WinState.Undefined || player.Stances[self.Owner] != Stance.Ally;
|
||||
if (conditionManager == null || string.IsNullOrEmpty(Info.RepairCondition))
|
||||
return;
|
||||
|
||||
var currentRepairers = Repairers.Count;
|
||||
while (Repairers.Count > repairTokens.Count)
|
||||
repairTokens.Push(conditionManager.GrantCondition(self, Info.RepairCondition));
|
||||
|
||||
while (Repairers.Count < repairTokens.Count && repairTokens.Count > 0)
|
||||
conditionManager.RevokeCondition(self, repairTokens.Pop());
|
||||
}
|
||||
|
||||
public void RepairBuilding(Actor self, Player player)
|
||||
{
|
||||
if (!IsTraitDisabled && self.AppearsFriendlyTo(player.PlayerActor))
|
||||
if (IsTraitDisabled || !self.AppearsFriendlyTo(player.PlayerActor))
|
||||
return;
|
||||
|
||||
// Remove the player if they are already repairing
|
||||
if (Repairers.Remove(player))
|
||||
{
|
||||
// If the player won't affect the repair, we won't add him
|
||||
if (!Repairers.Remove(player) && Repairers.Count < Info.RepairBonuses.Length)
|
||||
{
|
||||
Repairers.Add(player);
|
||||
Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", "Repairing", player.Faction.InternalName);
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (!self.IsDead)
|
||||
w.Add(new RepairIndicator(self));
|
||||
});
|
||||
}
|
||||
UpdateCondition(self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't add new players if the limit has already been reached
|
||||
if (Repairers.Count >= Info.RepairBonuses.Length - 1)
|
||||
return;
|
||||
|
||||
int remainingTicks;
|
||||
Repairers.Add(player);
|
||||
Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", "Repairing", player.Faction.InternalName);
|
||||
UpdateCondition(self);
|
||||
}
|
||||
|
||||
void ITick.Tick(Actor self)
|
||||
{
|
||||
@@ -107,7 +123,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (RepairActive && Info.CancelWhenDisabled)
|
||||
{
|
||||
Repairers.Clear();
|
||||
RepairActive = false;
|
||||
UpdateCondition(self);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -115,11 +131,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
if (remainingTicks == 0)
|
||||
{
|
||||
Repairers.RemoveAll(isNotActiveAlly);
|
||||
|
||||
// If after the previous operation there's no repairers left, stop
|
||||
Repairers.RemoveAll(isNotActiveAlly);
|
||||
UpdateCondition(self);
|
||||
|
||||
// If after the previous operation there's no repairers left, stop
|
||||
if (Repairers.Count == 0)
|
||||
{
|
||||
RepairActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var buildingValue = self.GetSellValue();
|
||||
|
||||
@@ -160,6 +180,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
Repairers.Clear();
|
||||
RepairActive = false;
|
||||
UpdateCondition(self);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (order.OrderString == "RepairBuilding" && order.Target.Type == TargetType.Actor)
|
||||
{
|
||||
var building = order.Target.Actor;
|
||||
if (building.Info.HasTraitInfo<RepairableBuildingInfo>())
|
||||
if (building.AppearsFriendlyTo(self))
|
||||
building.Trait<RepairableBuilding>().RepairBuilding(building, self.Owner);
|
||||
if (!building.AppearsFriendlyTo(self))
|
||||
return;
|
||||
|
||||
var rb = building.TraitOrDefault<RepairableBuilding>();
|
||||
if (rb != null)
|
||||
rb.RepairBuilding(building, self.Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2018 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Support;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
[Desc("Displays a custom UI overlay relative to the actor's mouseover bounds.")]
|
||||
public class WithBuildingRepairDecorationInfo : WithDecorationInfo, Requires<RepairableBuildingInfo>
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new WithBuildingRepairDecoration(init.Self, this); }
|
||||
}
|
||||
|
||||
public class WithBuildingRepairDecoration : WithDecoration
|
||||
{
|
||||
readonly RepairableBuilding rb;
|
||||
readonly WithBuildingRepairDecorationInfo info;
|
||||
int shownPlayer = 0;
|
||||
|
||||
public WithBuildingRepairDecoration(Actor self, WithBuildingRepairDecorationInfo info)
|
||||
: base(self, info)
|
||||
{
|
||||
this.info = info;
|
||||
rb = self.Trait<RepairableBuilding>();
|
||||
anim = new Animation(self.World, info.Image,
|
||||
() => !rb.RepairActive || rb.IsTraitDisabled || !ShouldRender(self));
|
||||
anim.PlayThen(info.Sequence, CycleRepairer);
|
||||
CycleRepairer();
|
||||
}
|
||||
|
||||
protected override bool ShouldRender(Actor self)
|
||||
{
|
||||
if (!rb.Repairers.Any())
|
||||
return false;
|
||||
|
||||
return base.ShouldRender(self);
|
||||
}
|
||||
|
||||
protected override PaletteReference GetPalette(Actor self, WorldRenderer wr)
|
||||
{
|
||||
if (!info.IsPlayerPalette)
|
||||
return wr.Palette(info.Palette);
|
||||
|
||||
return wr.Palette(info.Palette + rb.Repairers[shownPlayer % rb.Repairers.Count].InternalName);
|
||||
}
|
||||
|
||||
void CycleRepairer()
|
||||
{
|
||||
anim.PlayThen(info.Sequence, CycleRepairer);
|
||||
|
||||
if (++shownPlayer == rb.Repairers.Count)
|
||||
shownPlayer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
|
||||
public class WithDecoration : ConditionalTrait<WithDecorationInfo>, ITick, IRenderAboveShroud, IRenderAboveShroudWhenSelected
|
||||
{
|
||||
protected readonly Animation Anim;
|
||||
protected Animation anim;
|
||||
readonly IDecorationBounds[] decorationBounds;
|
||||
readonly string image;
|
||||
|
||||
@@ -68,8 +68,8 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
: base(info)
|
||||
{
|
||||
image = info.Image ?? self.Info.Name;
|
||||
Anim = new Animation(self.World, image, () => self.World.Paused);
|
||||
Anim.PlayRepeating(info.Sequence);
|
||||
anim = new Animation(self.World, image, () => self.World.Paused);
|
||||
anim.PlayRepeating(info.Sequence);
|
||||
decorationBounds = self.TraitsImplementing<IDecorationBounds>().ToArray();
|
||||
}
|
||||
|
||||
@@ -85,6 +85,11 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual PaletteReference GetPalette(Actor self, WorldRenderer wr)
|
||||
{
|
||||
return wr.Palette(Info.Palette + (Info.IsPlayerPalette ? self.Owner.InternalName : ""));
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr)
|
||||
{
|
||||
return !Info.RequiresSelection ? RenderInner(self, wr) : SpriteRenderable.None;
|
||||
@@ -100,14 +105,14 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
|
||||
IEnumerable<IRenderable> RenderInner(Actor self, WorldRenderer wr)
|
||||
{
|
||||
if (IsTraitDisabled || self.IsDead || !self.IsInWorld || Anim == null)
|
||||
if (IsTraitDisabled || self.IsDead || !self.IsInWorld || anim == null)
|
||||
return Enumerable.Empty<IRenderable>();
|
||||
|
||||
if (!ShouldRender(self) || self.World.FogObscures(self))
|
||||
return Enumerable.Empty<IRenderable>();
|
||||
|
||||
var bounds = decorationBounds.FirstNonEmptyBounds(self, wr);
|
||||
var halfSize = (0.5f * Anim.Image.Size.XY).ToInt2();
|
||||
var halfSize = (0.5f * anim.Image.Size.XY).ToInt2();
|
||||
|
||||
var boundsOffset = new int2(bounds.Left + bounds.Right, bounds.Top + bounds.Bottom) / 2;
|
||||
var sizeOffset = -halfSize;
|
||||
@@ -136,10 +141,10 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
var pxPos = wr.Viewport.WorldToViewPx(boundsOffset) + sizeOffset;
|
||||
return new IRenderable[]
|
||||
{
|
||||
new UISpriteRenderable(Anim.Image, self.CenterPosition, pxPos, Info.ZOffset, wr.Palette(Info.Palette + (Info.IsPlayerPalette ? self.Owner.InternalName : "")), 1f)
|
||||
new UISpriteRenderable(anim.Image, self.CenterPosition, pxPos, Info.ZOffset, GetPalette(self, wr), 1f)
|
||||
};
|
||||
}
|
||||
|
||||
void ITick.Tick(Actor self) { Anim.Tick(); }
|
||||
void ITick.Tick(Actor self) { anim.Tick(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2018 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
{
|
||||
public class SplitRepairDecoration : UpdateRule
|
||||
{
|
||||
public override string Name { get { return "WithBuildingRepairDecoration trait split from RepairableBuilding"; } }
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Rendering for the building repair indicator has been moved to a new\n" +
|
||||
"WithBuildingRepairDecoration trait. The indicator definitions are automatically\n" +
|
||||
"migrated from RepairableBuilding to WithBuildingRepairDecoration.";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
|
||||
{
|
||||
// RepairableBuilding is hardcoded to only support one instance per actor
|
||||
var rb = actorNode.LastChildMatching("RepairableBuilding");
|
||||
if (rb != null)
|
||||
{
|
||||
var imageNode = rb.LastChildMatching("IndicatorImage");
|
||||
var sequenceNode = rb.LastChildMatching("IndicatorSequence");
|
||||
var paletteNode = rb.LastChildMatching("IndicatorPalette");
|
||||
var palettePrefixNode = rb.LastChildMatching("IndicatorPalettePrefix");
|
||||
|
||||
var decoration = new MiniYamlNode("WithBuildingRepairDecoration", "");
|
||||
decoration.AddNode("Image", imageNode != null ? imageNode.Value.Value : "allyrepair");
|
||||
decoration.AddNode("Sequence", sequenceNode != null ? sequenceNode.Value.Value : "repair");
|
||||
decoration.AddNode("ReferencePoint", "Center");
|
||||
|
||||
if (paletteNode != null)
|
||||
{
|
||||
decoration.AddNode("Palette", paletteNode.Value.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
decoration.AddNode("Palette", palettePrefixNode != null ? palettePrefixNode.Value.Value : "player");
|
||||
decoration.AddNode("IsPlayerPalette", true);
|
||||
}
|
||||
|
||||
actorNode.AddNode(decoration);
|
||||
|
||||
rb.RemoveNode(imageNode);
|
||||
rb.RemoveNode(sequenceNode);
|
||||
rb.RemoveNode(paletteNode);
|
||||
rb.RemoveNode(palettePrefixNode);
|
||||
}
|
||||
|
||||
if (actorNode.LastChildMatching("-RepairableBuilding") != null)
|
||||
actorNode.AddNode("-WithBuildingRepairDecoration", "");
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,8 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
new RemovePaletteFromCurrentTileset(),
|
||||
new DefineLocomotors(),
|
||||
new DefineOwnerLostAction(),
|
||||
new RenameEmitInfantryOnSell()
|
||||
new RenameEmitInfantryOnSell(),
|
||||
new SplitRepairDecoration(),
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -697,6 +697,12 @@
|
||||
Capturable:
|
||||
CaptureThreshold: 55
|
||||
WithMakeAnimation:
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
ReferencePoint: Center
|
||||
Palette: player
|
||||
IsPlayerPalette: True
|
||||
|
||||
^CivBuilding:
|
||||
Inherits: ^Building
|
||||
@@ -744,6 +750,12 @@
|
||||
ShowOwnerRow: True
|
||||
EditorTilesetFilter:
|
||||
Categories: Tech building
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
ReferencePoint: Center
|
||||
Palette: player
|
||||
IsPlayerPalette: True
|
||||
|
||||
^CivField:
|
||||
Inherits: ^CivBuilding
|
||||
|
||||
@@ -147,3 +147,4 @@ sietch:
|
||||
ProvidesPrerequisite@buildingname:
|
||||
-WithMakeAnimation:
|
||||
-WithCrumbleOverlay:
|
||||
-WithBuildingRepairDecoration:
|
||||
|
||||
@@ -430,6 +430,12 @@
|
||||
EditorTilesetFilter:
|
||||
Categories: Building
|
||||
CommandBarBlacklist:
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
ReferencePoint: Center
|
||||
Palette: player
|
||||
IsPlayerPalette: True
|
||||
|
||||
^Defense:
|
||||
Inherits: ^Building
|
||||
|
||||
@@ -90,6 +90,7 @@ AFLD:
|
||||
|
||||
GUN:
|
||||
-RepairableBuilding:
|
||||
-WithBuildingRepairDecoration:
|
||||
|
||||
HARV:
|
||||
Harvester:
|
||||
|
||||
@@ -622,6 +622,12 @@
|
||||
String: Structure
|
||||
Sellable:
|
||||
SellSounds: cashturn.aud
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
ReferencePoint: Center
|
||||
Palette: player
|
||||
IsPlayerPalette: True
|
||||
|
||||
^ScienceBuilding:
|
||||
Inherits: ^Building
|
||||
|
||||
@@ -344,7 +344,6 @@
|
||||
Capturable:
|
||||
RepairableBuilding:
|
||||
RepairStep: 700
|
||||
IndicatorPalette: mouse
|
||||
PlayerExperience: 25
|
||||
WithDeathAnimation:
|
||||
DeathSequence: dead
|
||||
@@ -365,6 +364,11 @@
|
||||
Pieces: 3, 5
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 3
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
ReferencePoint: Center
|
||||
Palette: mouse
|
||||
|
||||
^CivBuilding:
|
||||
Inherits: ^BasicBuilding
|
||||
|
||||
Reference in New Issue
Block a user