Merge pull request #5393 from pchote/palettehax

Support per-animation palettes in RenderSprites.
This commit is contained in:
Matthias Mailänder
2014-05-22 14:54:39 +02:00
43 changed files with 352 additions and 168 deletions

View File

@@ -30,40 +30,34 @@ namespace OpenRA.Traits
public class RenderSimple : RenderSprites, IAutoSelectionSize public class RenderSimple : RenderSprites, IAutoSelectionSize
{ {
RenderSimpleInfo Info; public readonly Animation DefaultAnimation;
public RenderSimple(Actor self, Func<int> baseFacing) public RenderSimple(Actor self, Func<int> baseFacing)
: base(self) : base(self)
{ {
anims.Add("", new Animation(self.World, GetImage(self), baseFacing)); DefaultAnimation = new Animation(self.World, GetImage(self), baseFacing);
Info = self.Info.Traits.Get<RenderSimpleInfo>(); Add("", DefaultAnimation);
} }
public RenderSimple(Actor self) public RenderSimple(Actor self)
: this(self, MakeFacingFunc(self)) : this(self, MakeFacingFunc(self))
{ {
anim.PlayRepeating("idle"); DefaultAnimation.PlayRepeating("idle");
self.Trait<IBodyOrientation>().SetAutodetectedFacings(anim.CurrentSequence.Facings); self.Trait<IBodyOrientation>().SetAutodetectedFacings(DefaultAnimation.CurrentSequence.Facings);
} }
public int2 SelectionSize(Actor self) public int2 SelectionSize(Actor self) { return AutoSelectionSize(self); }
{
return anims.Values.Where(b => (b.DisableFunc == null || !b.DisableFunc())
&& b.Animation.CurrentSequence != null)
.Select(a => (a.Animation.Image.size*Info.Scale).ToInt2())
.FirstOrDefault();
}
public string NormalizeSequence(Actor self, string baseSequence) public string NormalizeSequence(Actor self, string baseSequence)
{ {
return NormalizeSequence(anim, self.GetDamageState(), baseSequence); return NormalizeSequence(DefaultAnimation, self.GetDamageState(), baseSequence);
} }
public void PlayCustomAnim(Actor self, string name) public void PlayCustomAnim(Actor self, string name)
{ {
if (anim.HasSequence(name)) if (DefaultAnimation.HasSequence(name))
anim.PlayThen(NormalizeSequence(self, name), DefaultAnimation.PlayThen(NormalizeSequence(self, name),
() => anim.PlayRepeating(NormalizeSequence(self, "idle"))); () => DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle")));
} }
} }
} }

View File

@@ -10,6 +10,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.Primitives; using OpenRA.Primitives;
@@ -33,7 +34,42 @@ namespace OpenRA.Traits
public class RenderSprites : IRender, ITick, INotifyOwnerChanged public class RenderSprites : IRender, ITick, INotifyOwnerChanged
{ {
public Dictionary<string, AnimationWithOffset> anims = new Dictionary<string, AnimationWithOffset>(); class AnimationWrapper
{
public readonly AnimationWithOffset Animation;
public readonly string Palette;
public readonly bool IsPlayerPalette;
public PaletteReference PaletteReference { get; private set; }
public AnimationWrapper(AnimationWithOffset animation, string palette, bool isPlayerPalette)
{
Animation = animation;
Palette = palette;
IsPlayerPalette = isPlayerPalette;
}
public void CachePalette(WorldRenderer wr, Player owner)
{
PaletteReference = wr.Palette(IsPlayerPalette ? Palette + owner.InternalName : Palette);
}
public void OwnerChanged()
{
// Update the palette reference next time we draw
if (IsPlayerPalette)
PaletteReference = null;
}
public bool IsVisible
{
get
{
return Animation.DisableFunc == null || !Animation.DisableFunc();
}
}
}
Dictionary<string, AnimationWrapper> anims = new Dictionary<string, AnimationWrapper>();
public static Func<int> MakeFacingFunc(Actor self) public static Func<int> MakeFacingFunc(Actor self)
{ {
@@ -42,17 +78,8 @@ namespace OpenRA.Traits
return () => facing.Facing; return () => facing.Facing;
} }
public Animation anim
{
get { return anims[""].Animation; }
protected set { anims[""] = new AnimationWithOffset(value,
anims[""].OffsetFunc, anims[""].DisableFunc, anims[""].Paused, anims[""].ZOffset); }
}
RenderSpritesInfo Info; RenderSpritesInfo Info;
string cachedImage = null; string cachedImage = null;
bool initializePalette = true;
protected PaletteReference palette;
public RenderSprites(Actor self) public RenderSprites(Actor self)
{ {
@@ -78,23 +105,25 @@ namespace OpenRA.Traits
return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName; return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName;
} }
protected void UpdatePalette() { initializePalette = true; } protected void UpdatePalette()
{
foreach (var anim in anims.Values)
anim.OwnerChanged();
}
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); } public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); }
public virtual IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr) public virtual IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
{ {
if (initializePalette)
{
palette = wr.Palette(PaletteName(self));
initializePalette = false;
}
foreach (var a in anims.Values) foreach (var a in anims.Values)
{ {
if (a.DisableFunc != null && a.DisableFunc()) if (!a.IsVisible)
continue; continue;
foreach (var r in a.Render(self, wr, palette, Info.Scale)) if (a.PaletteReference == null)
a.CachePalette(wr, self.Owner);
foreach (var r in a.Animation.Render(self, wr, a.PaletteReference, Info.Scale))
yield return r; yield return r;
} }
} }
@@ -102,7 +131,24 @@ namespace OpenRA.Traits
public virtual void Tick(Actor self) public virtual void Tick(Actor self)
{ {
foreach (var a in anims.Values) foreach (var a in anims.Values)
a.Animation.Tick(); a.Animation.Animation.Tick();
}
public void Add(string key, AnimationWithOffset anim, string palette = null, bool isPlayerPalette = false)
{
// Use defaults
if (palette == null)
{
palette = Info.Palette ?? Info.PlayerPalette;
isPlayerPalette = Info.Palette == null;
}
anims.Add(key, new AnimationWrapper(anim, palette, isPlayerPalette));
}
public void Remove(string key)
{
anims.Remove(key);
} }
public static string NormalizeSequence(Animation anim, DamageState state, string baseSequence) public static string NormalizeSequence(Animation anim, DamageState state, string baseSequence)
@@ -121,5 +167,14 @@ namespace OpenRA.Traits
return baseSequence; return baseSequence;
} }
// Required by RenderSimple
protected int2 AutoSelectionSize(Actor self)
{
return anims.Values.Where(b => b.IsVisible
&& b.Animation.Animation.CurrentSequence != null)
.Select(a => (a.Animation.Animation.Image.size*Info.Scale).ToInt2())
.FirstOrDefault();
}
} }
} }

View File

@@ -37,19 +37,19 @@ namespace OpenRA.Mods.RA.Render
left = new Animation(self.World, name, () => turret.turretFacing); left = new Animation(self.World, name, () => turret.turretFacing);
left.Play("left"); left.Play("left");
anims.Add("left", new AnimationWithOffset(left, null, () => facing.Facing > 128, 0)); Add("left", new AnimationWithOffset(left, null, () => facing.Facing > 128, 0));
right = new Animation(self.World, name, () => turret.turretFacing); right = new Animation(self.World, name, () => turret.turretFacing);
right.Play("right"); right.Play("right");
anims.Add("right", new AnimationWithOffset(right, null, () => facing.Facing <= 128, 0)); Add("right", new AnimationWithOffset(right, null, () => facing.Facing <= 128, 0));
var leftWake = new Animation(self.World, name); var leftWake = new Animation(self.World, name);
leftWake.Play("wake-left"); leftWake.Play("wake-left");
anims.Add("wake-left", new AnimationWithOffset(leftWake, null, () => facing.Facing > 128, -87)); Add("wake-left", new AnimationWithOffset(leftWake, null, () => facing.Facing > 128, -87));
var rightWake = new Animation(self.World, name); var rightWake = new Animation(self.World, name);
rightWake.Play("wake-right"); rightWake.Play("wake-right");
anims.Add("wake-right", new AnimationWithOffset(rightWake, null, () => facing.Facing <= 128, -87)); Add("wake-right", new AnimationWithOffset(rightWake, null, () => facing.Facing <= 128, -87));
self.Trait<IBodyOrientation>().SetAutodetectedFacings(2); self.Trait<IBodyOrientation>().SetAutodetectedFacings(2);
} }

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc
var rs = self.Trait<RenderSprites>(); var rs = self.Trait<RenderSprites>();
var roof = new Animation(self.World, rs.GetImage(self)); var roof = new Animation(self.World, rs.GetImage(self));
roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop")); roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop"));
rs.anims.Add("fire", new AnimationWithOffset(roof, null, null, 1024)); rs.Add("fire", new AnimationWithOffset(roof, null, null, 1024));
} }
} }
} }

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc
var rs = self.Trait<RenderSprites>(); var rs = self.Trait<RenderSprites>();
var roof = new Animation(self.World, rs.GetImage(self), () => self.Trait<IFacing>().Facing); var roof = new Animation(self.World, rs.GetImage(self), () => self.Trait<IFacing>().Facing);
roof.Play("roof"); roof.Play("roof");
rs.anims.Add("roof", new AnimationWithOffset(roof, null, null, 1024)); rs.Add("roof", new AnimationWithOffset(roof, null, null, 1024));
} }
} }
} }

View File

@@ -91,6 +91,7 @@
<Compile Include="Render\WithProductionOverlay.cs" /> <Compile Include="Render\WithProductionOverlay.cs" />
<Compile Include="Render\WithDockingOverlay.cs" /> <Compile Include="Render\WithDockingOverlay.cs" />
<Compile Include="Render\WithDeliveryOverlay.cs" /> <Compile Include="Render\WithDeliveryOverlay.cs" />
<Compile Include="PaletteFromScaledPalette.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View File

@@ -0,0 +1,72 @@
#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 OpenRA.FileSystem;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.D2k
{
[Desc("Create a palette by applying a scale and offset to the colors in another palette.")]
class PaletteFromScaledPaletteInfo : ITraitInfo
{
[Desc("Internal palette name")]
public readonly string Name = null;
[Desc("The name of the palette to base off.")]
public readonly string BasePalette = null;
[Desc("Allow palette modifiers to change the palette.")]
public readonly bool AllowModifiers = true;
[Desc("Amount to scale the base palette colors by.")]
public readonly float Scale = 1.0f;
[Desc("Amount to offset the base palette colors by.")]
public readonly int Offset = 0;
public object Create(ActorInitializer init) { return new PaletteFromScaledPalette(this); }
}
class PaletteFromScaledPalette : IPalette
{
readonly PaletteFromScaledPaletteInfo info;
public PaletteFromScaledPalette(PaletteFromScaledPaletteInfo info) { this.info = info; }
public void InitPalette(WorldRenderer wr)
{
var remap = new ScaledPaletteRemap(info.Scale, info.Offset);
wr.AddPalette(info.Name, new Palette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
}
}
class ScaledPaletteRemap : IPaletteRemap
{
readonly float scale;
readonly int offset;
public ScaledPaletteRemap(float scale, int offset)
{
this.scale = scale;
this.offset = offset;
}
public Color GetRemappedColor(Color original, int index)
{
return Color.FromArgb(original.A,
(int)Exts.Clamp((int)(scale * original.R + offset), 0, 255),
(int)Exts.Clamp((int)(scale * original.G + offset), 0, 255),
(int)Exts.Clamp((int)(scale * original.B + offset), 0, 255));
}
}
}

View File

@@ -23,6 +23,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public object Create(ActorInitializer init) { return new WithBuildingPlacedOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithBuildingPlacedOverlay(init.self, this); }
} }
@@ -40,10 +46,11 @@ namespace OpenRA.Mods.RA.Render
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.Play(info.Sequence); overlay.Play(info.Sequence);
rs.anims.Add("crane_overlay_{0}".F(info.Sequence), rs.Add("crane_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete)); () => !buildComplete),
info.Palette, info.IsPlayerPalette);
} }
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)

View File

@@ -19,6 +19,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Sequence name to use")] [Desc("Sequence name to use")]
public readonly string Sequence = "crumble-overlay"; public readonly string Sequence = "crumble-overlay";
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public object Create(ActorInitializer init) { return new WithCrumbleOverlay(init, this); } public object Create(ActorInitializer init) { return new WithCrumbleOverlay(init, this); }
} }
@@ -34,8 +40,9 @@ namespace OpenRA.Mods.RA.Render
{ {
var overlay = new Animation(init.world, rs.GetImage(init.self)); var overlay = new Animation(init.world, rs.GetImage(init.self));
overlay.PlayThen(info.Sequence, () => buildComplete = false); overlay.PlayThen(info.Sequence, () => buildComplete = false);
rs.anims.Add("make_overlay_{0}".F(info.Sequence), rs.Add("make_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, null, () => !buildComplete)); new AnimationWithOffset(overlay, null, () => !buildComplete),
info.Palette, info.IsPlayerPalette);
} }
} }

View File

@@ -24,6 +24,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public object Create(ActorInitializer init) { return new WithDeliveryOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithDeliveryOverlay(init.self, this); }
} }
@@ -44,10 +50,11 @@ namespace OpenRA.Mods.RA.Render
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.Play(info.Sequence); overlay.Play(info.Sequence);
rs.anims.Add("delivery_overlay_{0}".F(info.Sequence), rs.Add("delivery_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete)); () => !buildComplete),
info.Palette, info.IsPlayerPalette);
} }
void PlayDeliveryOverlay() void PlayDeliveryOverlay()

View File

@@ -24,6 +24,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public object Create(ActorInitializer init) { return new WithDockingOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithDockingOverlay(init.self, this); }
} }
@@ -44,10 +50,11 @@ namespace OpenRA.Mods.RA.Render
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.Play(info.Sequence); overlay.Play(info.Sequence);
rs.anims.Add("docking_overlay_{0}".F(info.Sequence), rs.Add("docking_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete)); () => !buildComplete),
info.Palette, info.IsPlayerPalette);
} }
void PlayDockingOverlay() void PlayDockingOverlay()

View File

@@ -26,6 +26,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public object Create(ActorInitializer init) { return new WithProductionOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithProductionOverlay(init.self, this); }
} }
@@ -49,10 +55,11 @@ namespace OpenRA.Mods.RA.Render
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.PlayRepeating(info.Sequence); overlay.PlayRepeating(info.Sequence);
rs.anims.Add("production_overlay_{0}".F(info.Sequence), rs.Add("production_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !IsProducing || !buildComplete)); () => !IsProducing || !buildComplete),
info.Palette, info.IsPlayerPalette);
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Activities
if (started) if (started)
{ {
// Don't break the actor if someone has overriden the animation prematurely // Don't break the actor if someone has overriden the animation prematurely
if (rb.anim.CurrentSequence.Name != "make") if (rb.DefaultAnimation.CurrentSequence.Name != "make")
{ {
complete = true; complete = true;
OnComplete(); OnComplete();

View File

@@ -24,29 +24,26 @@ namespace OpenRA.Mods.RA.Buildings
public object Create(ActorInitializer init) { return new Bib(init.self, this); } public object Create(ActorInitializer init) { return new Bib(init.self, this); }
} }
public class Bib : IRender, INotifyAddedToWorld public class Bib : INotifyAddedToWorld, INotifyRemovedFromWorld
{ {
readonly BibInfo info; readonly BibInfo info;
List<AnimationWithOffset> tiles; readonly RenderSprites rs;
readonly BuildingInfo bi;
public Bib(Actor self, BibInfo info) public Bib(Actor self, BibInfo info)
{ {
this.info = info; this.info = info;
rs = self.Trait<RenderSprites>();
bi = self.Info.Traits.Get<BuildingInfo>();
} }
public void AddedToWorld(Actor self) public void AddedToWorld(Actor self)
{ {
var rs = self.Trait<RenderSprites>(); var width = bi.Dimensions.X;
var building = self.Info.Traits.Get<BuildingInfo>(); var bibOffset = bi.Dimensions.Y - 1;
var width = building.Dimensions.X; var centerOffset = FootprintUtils.CenterOffset(bi);
var bibOffset = building.Dimensions.Y - 1;
var centerOffset = FootprintUtils.CenterOffset(building);
var location = self.Location; var location = self.Location;
tiles = new List<AnimationWithOffset>(); var rows = info.HasMinibib ? 1 : 2;
int rows = 2;
if (info.HasMinibib)
rows = 1;
for (var i = 0; i < rows * width; i++) for (var i = 0; i < rows * width; i++)
{ {
@@ -63,21 +60,18 @@ namespace OpenRA.Mods.RA.Buildings
// Z-order is one set to the top of the footprint // Z-order is one set to the top of the footprint
var offset = cellOffset.ToWVec() - centerOffset; var offset = cellOffset.ToWVec() - centerOffset;
tiles.Add(new AnimationWithOffset(anim, () => offset, null, -(offset.Y + centerOffset.Y + 512))); var awo = new AnimationWithOffset(anim, () => offset, null, -(offset.Y + centerOffset.Y + 512));
rs.Add("bib_{0}".F(i), awo, info.Palette);
} }
} }
bool paletteInitialized; public void RemovedFromWorld(Actor self)
PaletteReference palette;
public virtual IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
{ {
if (!paletteInitialized) var width = bi.Dimensions.X;
{ var rows = info.HasMinibib ? 1 : 2;
palette = wr.Palette(info.Palette);
paletteInitialized = true;
}
return tiles.SelectMany(t => t.Render(self, wr, palette, 1f)); for (var i = 0; i < rows * width; i++)
rs.Remove("bib_{0}".F(i));
} }
} }
} }

View File

@@ -13,7 +13,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Cnc namespace OpenRA.Mods.Cnc
{ {
class DeadBuildingStateInfo : ITraitInfo, Requires<HealthInfo>, Requires<RenderSpritesInfo> class DeadBuildingStateInfo : ITraitInfo, Requires<HealthInfo>, Requires<RenderSimpleInfo>
{ {
public readonly int LingerTime = 20; public readonly int LingerTime = 20;
@@ -23,23 +23,23 @@ namespace OpenRA.Mods.Cnc
class DeadBuildingState : INotifyKilled class DeadBuildingState : INotifyKilled
{ {
DeadBuildingStateInfo info; DeadBuildingStateInfo info;
RenderSprites rs; RenderSimple rs;
public DeadBuildingState(Actor self, DeadBuildingStateInfo info) public DeadBuildingState(Actor self, DeadBuildingStateInfo info)
{ {
this.info = info; this.info = info;
rs = self.Trait<RenderSprites>(); rs = self.Trait<RenderSimple>();
self.Trait<Health>().RemoveOnDeath = !rs.anim.HasSequence("dead"); self.Trait<Health>().RemoveOnDeath = !rs.DefaultAnimation.HasSequence("dead");
} }
public void Killed(Actor self, AttackInfo e) public void Killed(Actor self, AttackInfo e)
{ {
if (!rs.anim.HasSequence("dead")) return; if (!rs.DefaultAnimation.HasSequence("dead")) return;
if (rs.anim.GetSequence("dead").Length > 1) if (rs.DefaultAnimation.GetSequence("dead").Length > 1)
rs.anim.Play("dead"); rs.DefaultAnimation.Play("dead");
else else
rs.anim.PlayRepeating("dead"); rs.DefaultAnimation.PlayRepeating("dead");
self.World.AddFrameEndTask( self.World.AddFrameEndTask(
w => w.Add( w => w.Add(

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation(self.World, "fire", () => 0); var anim = new Animation(self.World, "fire", () => 0);
anim.IsDecoration = true; anim.IsDecoration = true;
anim.PlayRepeating(Info.Anim); anim.PlayRepeating(Info.Anim);
self.Trait<RenderSprites>().anims.Add("fire", anim); self.Trait<RenderSprites>().Add("fire", anim);
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -49,8 +49,8 @@ namespace OpenRA.Mods.RA.Render
this.info = info; this.info = info;
// Work around a bogus crash // Work around a bogus crash
anim.PlayRepeating(NormalizeSequence(self, "idle")); DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle"));
self.Trait<IBodyOrientation>().SetAutodetectedFacings(anim.CurrentSequence.Facings); self.Trait<IBodyOrientation>().SetAutodetectedFacings(DefaultAnimation.CurrentSequence.Facings);
// Can't call Complete() directly from ctor because other traits haven't been inited yet // Can't call Complete() directly from ctor because other traits haven't been inited yet
if (self.Info.Traits.Get<RenderBuildingInfo>().HasMakeAnimation && !init.Contains<SkipMakeAnimsInit>()) if (self.Info.Traits.Get<RenderBuildingInfo>().HasMakeAnimation && !init.Contains<SkipMakeAnimsInit>())
@@ -61,45 +61,45 @@ namespace OpenRA.Mods.RA.Render
void Complete(Actor self) void Complete(Actor self)
{ {
anim.PlayRepeating(NormalizeSequence(self, "idle")); DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle"));
foreach (var x in self.TraitsImplementing<INotifyBuildComplete>()) foreach (var x in self.TraitsImplementing<INotifyBuildComplete>())
x.BuildingComplete(self); x.BuildingComplete(self);
if (info.PauseOnLowPower) if (info.PauseOnLowPower)
{ {
var disabled = self.TraitsImplementing<IDisable>(); var disabled = self.TraitsImplementing<IDisable>();
anim.Paused = () => disabled.Any(d => d.Disabled) DefaultAnimation.Paused = () => disabled.Any(d => d.Disabled)
&& anim.CurrentSequence.Name == NormalizeSequence(self, "idle"); && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, "idle");
} }
} }
public void PlayCustomAnimThen(Actor self, string name, Action a) public void PlayCustomAnimThen(Actor self, string name, Action a)
{ {
anim.PlayThen(NormalizeSequence(self, name), DefaultAnimation.PlayThen(NormalizeSequence(self, name),
() => { anim.PlayRepeating(NormalizeSequence(self, "idle")); a(); }); () => { DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle")); a(); });
} }
public void PlayCustomAnimRepeating(Actor self, string name) public void PlayCustomAnimRepeating(Actor self, string name)
{ {
anim.PlayThen(NormalizeSequence(self, name), DefaultAnimation.PlayThen(NormalizeSequence(self, name),
() => PlayCustomAnimRepeating(self, name)); () => PlayCustomAnimRepeating(self, name));
} }
public void PlayCustomAnimBackwards(Actor self, string name, Action a) public void PlayCustomAnimBackwards(Actor self, string name, Action a)
{ {
anim.PlayBackwardsThen(NormalizeSequence(self, name), DefaultAnimation.PlayBackwardsThen(NormalizeSequence(self, name),
() => { anim.PlayRepeating(NormalizeSequence(self, "idle")); a(); }); () => { DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle")); a(); });
} }
public void CancelCustomAnim(Actor self) public void CancelCustomAnim(Actor self)
{ {
anim.PlayRepeating(NormalizeSequence(self, "idle")); DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle"));
} }
public virtual void DamageStateChanged(Actor self, AttackInfo e) public virtual void DamageStateChanged(Actor self, AttackInfo e)
{ {
if (anim.CurrentSequence != null) if (DefaultAnimation.CurrentSequence != null)
anim.ReplaceAnim(NormalizeSequence(self, "idle")); DefaultAnimation.ReplaceAnim(NormalizeSequence(self, "idle"));
} }
} }
} }

View File

@@ -35,8 +35,8 @@ namespace OpenRA.Mods.RA.Render
public void PlayCharge(Actor self) public void PlayCharge(Actor self)
{ {
Sound.Play(info.ChargeAudio, self.CenterPosition); Sound.Play(info.ChargeAudio, self.CenterPosition);
anim.PlayThen(NormalizeSequence(self, info.ChargeSequence), DefaultAnimation.PlayThen(NormalizeSequence(self, info.ChargeSequence),
() => anim.PlayRepeating(NormalizeSequence(self, "idle"))); () => DefaultAnimation.PlayRepeating(NormalizeSequence(self, "idle")));
} }
} }
} }

View File

@@ -30,9 +30,9 @@ namespace OpenRA.Mods.RA.Render
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)
{ {
var animation = (self.GetDamageState() >= DamageState.Heavy) ? "damaged-idle" : "idle"; var animation = (self.GetDamageState() >= DamageState.Heavy) ? "damaged-idle" : "idle";
anim.PlayFetchIndex(animation, DefaultAnimation.PlayFetchIndex(animation,
() => playerResources.OreCapacity != 0 () => playerResources.OreCapacity != 0
? ((10 * anim.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity) ? ((10 * DefaultAnimation.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0); : 0);
} }

View File

@@ -34,13 +34,13 @@ namespace OpenRA.Mods.RA.Render
: base(init, info, MakeTurretFacingFunc(init.self)) : base(init, info, MakeTurretFacingFunc(init.self))
{ {
t = init.self.TraitsImplementing<Turreted>().FirstOrDefault(); t = init.self.TraitsImplementing<Turreted>().FirstOrDefault();
t.QuantizedFacings = anim.CurrentSequence.Facings; t.QuantizedFacings = DefaultAnimation.CurrentSequence.Facings;
} }
public override void DamageStateChanged(Actor self, AttackInfo e) public override void DamageStateChanged(Actor self, AttackInfo e)
{ {
base.DamageStateChanged(self, e); base.DamageStateChanged(self, e);
t.QuantizedFacings = anim.CurrentSequence.Facings; t.QuantizedFacings = DefaultAnimation.CurrentSequence.Facings;
} }
} }
} }

View File

@@ -35,12 +35,12 @@ namespace OpenRA.Mods.RA.Render
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)
{ {
anim.PlayFetchIndex(info.Sequence, () => adjacent); DefaultAnimation.PlayFetchIndex(info.Sequence, () => adjacent);
} }
public override void DamageStateChanged(Actor self, AttackInfo e) public override void DamageStateChanged(Actor self, AttackInfo e)
{ {
anim.PlayFetchIndex(NormalizeSequence(anim, e.DamageState, info.Sequence), () => adjacent); DefaultAnimation.PlayFetchIndex(NormalizeSequence(DefaultAnimation, e.DamageState, info.Sequence), () => adjacent);
} }
public override void Tick(Actor self) public override void Tick(Actor self)

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Render
// Additional 512 units move from center -> top of cell // Additional 512 units move from center -> top of cell
var offset = FootprintUtils.CenterOffset(bi).Y + 512; var offset = FootprintUtils.CenterOffset(bi).Y + 512;
anims.Add("roof", new AnimationWithOffset(roof, null, Add("roof", new AnimationWithOffset(roof, null,
() => !buildComplete, offset)); () => !buildComplete, offset));
} }
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.RA.Render
roof.PlayThen(NormalizeSequence(self, "build-top"), () => { isOpen = true; openExit = exit; }); roof.PlayThen(NormalizeSequence(self, "build-top"), () => { isOpen = true; openExit = exit; });
} }
public void Selling(Actor self) { anims.Remove("roof"); } public void Selling(Actor self) { Remove("roof"); }
public void Sold(Actor self) { } public void Sold(Actor self) { }
} }
} }

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Render
if (disguise.AsSprite != intendedSprite) if (disguise.AsSprite != intendedSprite)
{ {
intendedSprite = disguise.AsSprite; intendedSprite = disguise.AsSprite;
anim.ChangeImage(intendedSprite ?? GetImage(self), info.StandAnimations.Random(Game.CosmeticRandom)); DefaultAnimation.ChangeImage(intendedSprite ?? GetImage(self), info.StandAnimations.Random(Game.CosmeticRandom));
UpdatePalette(); UpdatePalette();
} }

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA.Render
public RenderFlare(Actor self) public RenderFlare(Actor self)
: base(self, () => 0) : base(self, () => 0)
{ {
anim.PlayThen("open", () => anim.PlayRepeating("idle")); DefaultAnimation.PlayThen("open", () => DefaultAnimation.PlayRepeating("idle"));
} }
} }
} }

View File

@@ -40,15 +40,15 @@ namespace OpenRA.Mods.RA.Render
var desiredState = harv.Fullness * (info.ImagesByFullness.Length - 1) / 100; var desiredState = harv.Fullness * (info.ImagesByFullness.Length - 1) / 100;
var desiredImage = info.ImagesByFullness[desiredState]; var desiredImage = info.ImagesByFullness[desiredState];
if (anim.Name != desiredImage) if (DefaultAnimation.Name != desiredImage)
anim.ChangeImage(desiredImage, "idle"); DefaultAnimation.ChangeImage(desiredImage, "idle");
base.Tick(self); base.Tick(self);
} }
public void Harvested(Actor self, ResourceType resource) public void Harvested(Actor self, ResourceType resource)
{ {
if (anim.CurrentSequence.Name != "harvest") if (DefaultAnimation.CurrentSequence.Name != "harvest")
PlayCustomAnim(self, "harvest"); PlayCustomAnim(self, "harvest");
} }
} }

View File

@@ -59,20 +59,20 @@ namespace OpenRA.Mods.RA.Render
: base(self, MakeFacingFunc(self)) : base(self, MakeFacingFunc(self))
{ {
this.info = info; this.info = info;
anim.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0); DefaultAnimation.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0);
State = AnimationState.Waiting; State = AnimationState.Waiting;
move = self.Trait<IMove>(); move = self.Trait<IMove>();
self.Trait<IBodyOrientation>().SetAutodetectedFacings(anim.CurrentSequence.Facings); self.Trait<IBodyOrientation>().SetAutodetectedFacings(DefaultAnimation.CurrentSequence.Facings);
} }
public void Attacking(Actor self, Target target) public void Attacking(Actor self, Target target)
{ {
State = AnimationState.Attacking; State = AnimationState.Attacking;
if (anim.HasSequence(NormalizeInfantrySequence(self, "shoot"))) if (DefaultAnimation.HasSequence(NormalizeInfantrySequence(self, "shoot")))
anim.PlayThen(NormalizeInfantrySequence(self, "shoot"), () => State = AnimationState.Idle); DefaultAnimation.PlayThen(NormalizeInfantrySequence(self, "shoot"), () => State = AnimationState.Idle);
else if (anim.HasSequence(NormalizeInfantrySequence(self, "heal"))) else if (DefaultAnimation.HasSequence(NormalizeInfantrySequence(self, "heal")))
anim.PlayThen(NormalizeInfantrySequence(self, "heal"), () => State = AnimationState.Idle); DefaultAnimation.PlayThen(NormalizeInfantrySequence(self, "heal"), () => State = AnimationState.Idle);
} }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
@@ -87,12 +87,12 @@ namespace OpenRA.Mods.RA.Render
if ((State == AnimationState.Moving || dirty) && !move.IsMoving) if ((State == AnimationState.Moving || dirty) && !move.IsMoving)
{ {
State = AnimationState.Waiting; State = AnimationState.Waiting;
anim.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0); DefaultAnimation.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0);
} }
else if ((State != AnimationState.Moving || dirty) && move.IsMoving) else if ((State != AnimationState.Moving || dirty) && move.IsMoving)
{ {
State = AnimationState.Moving; State = AnimationState.Moving;
anim.PlayRepeating(NormalizeInfantrySequence(self, "run")); DefaultAnimation.PlayRepeating(NormalizeInfantrySequence(self, "run"));
} }
dirty = false; dirty = false;
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.RA.Render
{ {
if (State != AnimationState.Idle && State != AnimationState.IdleAnimating) if (State != AnimationState.Idle && State != AnimationState.IdleAnimating)
{ {
anim.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0); DefaultAnimation.PlayFetchIndex(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)), () => 0);
State = AnimationState.Idle; State = AnimationState.Idle;
if (info.IdleAnimations.Length > 0) if (info.IdleAnimations.Length > 0)
@@ -113,12 +113,12 @@ namespace OpenRA.Mods.RA.Render
} }
else if (AllowIdleAnimation(self) && idleDelay > 0 && --idleDelay == 0) else if (AllowIdleAnimation(self) && idleDelay > 0 && --idleDelay == 0)
{ {
if (anim.HasSequence(idleSequence)) if (DefaultAnimation.HasSequence(idleSequence))
{ {
State = AnimationState.IdleAnimating; State = AnimationState.IdleAnimating;
anim.PlayThen(idleSequence, () => DefaultAnimation.PlayThen(idleSequence, () =>
{ {
anim.PlayRepeating(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom))); DefaultAnimation.PlayRepeating(NormalizeInfantrySequence(self, info.StandAnimations.Random(Game.CosmeticRandom)));
State = AnimationState.Waiting; State = AnimationState.Waiting;
}); });
} }

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.RA.Render
{ {
var prefix = sc != null && sc.Panicking ? "panic-" : ""; var prefix = sc != null && sc.Panicking ? "panic-" : "";
if (anim.HasSequence(prefix + baseSequence)) if (DefaultAnimation.HasSequence(prefix + baseSequence))
return prefix + baseSequence; return prefix + baseSequence;
else else
return baseSequence; return baseSequence;

View File

@@ -51,20 +51,20 @@ namespace OpenRA.Mods.RA.Render
void Open() void Open()
{ {
if (open || !anim.HasSequence(info.OpenAnim)) if (open || !DefaultAnimation.HasSequence(info.OpenAnim))
return; return;
open = true; open = true;
PlayCustomAnimation(self, info.OpenAnim, () => PlayCustomAnimation(self, info.OpenAnim, () =>
{ {
if (anim.HasSequence(info.UnloadAnim)) if (DefaultAnimation.HasSequence(info.UnloadAnim))
PlayCustomAnimRepeating(self, info.UnloadAnim); PlayCustomAnimRepeating(self, info.UnloadAnim);
}); });
} }
void Close() void Close()
{ {
if (!open || !anim.HasSequence(info.OpenAnim)) if (!open || !DefaultAnimation.HasSequence(info.OpenAnim))
return; return;
open = false; open = false;

View File

@@ -25,19 +25,19 @@ namespace OpenRA.Mods.RA.Render
public void PlayCustomAnimation(Actor self, string newAnim, Action after) public void PlayCustomAnimation(Actor self, string newAnim, Action after)
{ {
anim.PlayThen(newAnim, () => { anim.Play("idle"); if (after != null) after(); }); DefaultAnimation.PlayThen(newAnim, () => { DefaultAnimation.Play("idle"); if (after != null) after(); });
} }
public void PlayCustomAnimRepeating(Actor self, string name) public void PlayCustomAnimRepeating(Actor self, string name)
{ {
anim.PlayThen(name, DefaultAnimation.PlayThen(name,
() => { PlayCustomAnimRepeating(self, name); }); () => { PlayCustomAnimRepeating(self, name); });
} }
public void PlayCustomAnimBackwards(Actor self, string name, Action after) public void PlayCustomAnimBackwards(Actor self, string name, Action after)
{ {
anim.PlayBackwardsThen(name, DefaultAnimation.PlayBackwardsThen(name,
() => { anim.PlayRepeating("idle"); if (after != null) after(); }); () => { DefaultAnimation.PlayRepeating("idle"); if (after != null) after(); });
} }
} }
} }

View File

@@ -38,8 +38,8 @@ namespace OpenRA.Mods.RA.Render
public override void Tick(Actor self) public override void Tick(Actor self)
{ {
var sequence = (armament.IsReloading ? "empty-" : "") + (attack.IsAttacking ? "aim" : "idle"); var sequence = (armament.IsReloading ? "empty-" : "") + (attack.IsAttacking ? "aim" : "idle");
if (sequence != anim.CurrentSequence.Name) if (sequence != DefaultAnimation.CurrentSequence.Name)
anim.ReplaceAnim(sequence); DefaultAnimation.ReplaceAnim(sequence);
base.Tick(self); base.Tick(self);
} }

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Render
var images = info.XmasImages.Any() && DateTime.Today.Month == 12 ? info.XmasImages : info.Images; var images = info.XmasImages.Any() && DateTime.Today.Month == 12 ? info.XmasImages : info.Images;
anim = new Animation(self.World, images.Random(Game.CosmeticRandom)); anim = new Animation(self.World, images.Random(Game.CosmeticRandom));
anim.Play("idle"); anim.Play("idle");
rs.anims.Add("", anim); rs.Add("", anim);
} }
public void OnLanded() public void OnLanded()

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Render
anim = new Animation(self.World, rs.GetImage(self), RenderSimple.MakeFacingFunc(self)); anim = new Animation(self.World, rs.GetImage(self), RenderSimple.MakeFacingFunc(self));
anim.Play(info.Sequence); anim.Play(info.Sequence);
rs.anims.Add("harvest_{0}".F(info.Sequence), new AnimationWithOffset(anim, rs.Add("harvest_{0}".F(info.Sequence), new AnimationWithOffset(anim,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !visible, () => !visible,
() => false, () => false,

View File

@@ -24,6 +24,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public readonly bool PauseOnLowPower = false; public readonly bool PauseOnLowPower = false;
public object Create(ActorInitializer init) { return new WithIdleOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithIdleOverlay(init.self, this); }
@@ -43,12 +49,13 @@ namespace OpenRA.Mods.RA.Render
buildComplete = !self.HasTrait<Building>(); // always render instantly for units buildComplete = !self.HasTrait<Building>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.PlayRepeating(info.Sequence); overlay.PlayRepeating(info.Sequence);
rs.anims.Add("idle_overlay_{0}".F(info.Sequence), rs.Add("idle_overlay_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete, () => !buildComplete,
() => info.PauseOnLowPower && disabled.Any(d => d.Disabled), () => info.PauseOnLowPower && disabled.Any(d => d.Disabled),
p => WithTurret.ZOffsetFromCenter(self, p, 1))); p => WithTurret.ZOffsetFromCenter(self, p, 1)),
info.Palette, info.IsPlayerPalette);
} }
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)

View File

@@ -25,6 +25,12 @@ namespace OpenRA.Mods.RA.Render
[Desc("Position relative to body")] [Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Custom palette name")]
public readonly string Palette = null;
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public readonly bool PauseOnLowPower = false; public readonly bool PauseOnLowPower = false;
public object Create(ActorInitializer init) { return new WithRepairOverlay(init.self, this); } public object Create(ActorInitializer init) { return new WithRepairOverlay(init.self, this); }
@@ -44,12 +50,13 @@ namespace OpenRA.Mods.RA.Render
buildComplete = !self.HasTrait<Building>(); // always render instantly for units buildComplete = !self.HasTrait<Building>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self)); overlay = new Animation(self.World, rs.GetImage(self));
overlay.Play(info.Sequence); overlay.Play(info.Sequence);
rs.anims.Add("repair_{0}".F(info.Sequence), rs.Add("repair_{0}".F(info.Sequence),
new AnimationWithOffset(overlay, new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete, () => !buildComplete,
() => info.PauseOnLowPower && disabled.Any(d => d.Disabled), () => info.PauseOnLowPower && disabled.Any(d => d.Disabled),
p => WithTurret.ZOffsetFromCenter(self, p, 1))); p => WithTurret.ZOffsetFromCenter(self, p, 1)),
info.Palette, info.IsPlayerPalette);
} }
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)

View File

@@ -42,7 +42,7 @@ namespace OpenRA.Mods.RA.Render
? ((10 * anim.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity) ? ((10 * anim.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0); : 0);
rs.anims.Add("resources_{0}".F(info.Sequence), new AnimationWithOffset( rs.Add("resources_{0}".F(info.Sequence), new AnimationWithOffset(
anim, null, () => !buildComplete, 1024)); anim, null, () => !buildComplete, 1024));
} }
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.RA.Render
playerResources = newOwner.PlayerActor.Trait<PlayerResources>(); playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
} }
public void Selling(Actor self) { rs.anims.Remove("resources_{0}".F(info.Sequence)); } public void Selling(Actor self) { rs.Remove("resources_{0}".F(info.Sequence)); }
public void Sold(Actor self) { } public void Sold(Actor self) { }
} }
} }

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Mods.RA.Render
rotorAnim = new Animation(self.World, rs.GetImage(self)); rotorAnim = new Animation(self.World, rs.GetImage(self));
rotorAnim.PlayRepeating(info.Sequence); rotorAnim.PlayRepeating(info.Sequence);
rs.anims.Add(info.Id, new AnimationWithOffset(rotorAnim, rs.Add(info.Id, new AnimationWithOffset(rotorAnim,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
null, () => false, p => WithTurret.ZOffsetFromCenter(self, p, 1))); null, () => false, p => WithTurret.ZOffsetFromCenter(self, p, 1)));
} }

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Render
var rs = self.Trait<RenderSprites>(); var rs = self.Trait<RenderSprites>();
anim = new Animation(self.World, "smoke_m"); anim = new Animation(self.World, "smoke_m");
rs.anims.Add("smoke", new AnimationWithOffset(anim, null, () => !isSmoking)); rs.Add("smoke", new AnimationWithOffset(anim, null, () => !isSmoking));
} }
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)

View File

@@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Render
anim = new Animation(self.World, rs.GetImage(self), () => t.turretFacing); anim = new Animation(self.World, rs.GetImage(self), () => t.turretFacing);
anim.Play(info.Sequence); anim.Play(info.Sequence);
rs.anims.Add("turret_{0}".F(info.Turret), new AnimationWithOffset( rs.Add("turret_{0}".F(info.Turret), new AnimationWithOffset(
anim, () => TurretOffset(self), null, () => false, p => ZOffsetFromCenter(self, p, 1))); anim, () => TurretOffset(self), null, () => false, p => ZOffsetFromCenter(self, p, 1)));
// Restrict turret facings to match the sprite // Restrict turret facings to match the sprite
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA.Render
return; return;
var sequence = ab.IsAttacking ? info.AimSequence : info.Sequence; var sequence = ab.IsAttacking ? info.AimSequence : info.Sequence;
rs.anims["turret_{0}".F(info.Turret)].Animation.ReplaceAnim(sequence); anim.ReplaceAnim(sequence);
} }
static public int ZOffsetFromCenter(Actor self, WPos pos, int offset) static public int ZOffsetFromCenter(Actor self, WPos pos, int offset)

View File

@@ -87,7 +87,7 @@ namespace OpenRA.Mods.RA
{ {
var prefix = tc != null && tc.IsProne ? "prone-" : ""; var prefix = tc != null && tc.IsProne ? "prone-" : "";
if (anim.HasSequence(prefix + baseSequence)) if (DefaultAnimation.HasSequence(prefix + baseSequence))
return prefix + baseSequence; return prefix + baseSequence;
else else
return baseSequence; return baseSequence;

View File

@@ -79,7 +79,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation(init.world, rs.GetImage(self), () => (int)facing); var anim = new Animation(init.world, rs.GetImage(self), () => (int)facing);
anim.PlayRepeating(info.Anim); anim.PlayRepeating(info.Anim);
rs.anims.Add(info.Anim, new AnimationWithOffset(anim, () => pos, null)); rs.Add(info.Anim, new AnimationWithOffset(anim, () => pos, null));
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -74,6 +74,7 @@ CONCRETEB:
ProvidesCustomPrerequisite: ProvidesCustomPrerequisite:
Prerequisite: Conyard Prerequisite: Conyard
WithBuildingPlacedOverlay: WithBuildingPlacedOverlay:
Palette: d2k
^POWER: ^POWER:
Inherits: ^Building Inherits: ^Building
@@ -380,6 +381,7 @@ CONCRETEB:
Produces: Starport Produces: Starport
ActorType: frigate ActorType: frigate
WithDeliveryOverlay: WithDeliveryOverlay:
Palette: starportlights
ProductionBar: ProductionBar:
PrimaryBuilding: PrimaryBuilding:
RequiresPower: RequiresPower:
@@ -579,6 +581,7 @@ WALL:
ProvidesCustomPrerequisite: ProvidesCustomPrerequisite:
Prerequisite: Repair Prerequisite: Repair
WithRepairOverlay: WithRepairOverlay:
Palette: repairlights
^HIGHTECH: ^HIGHTECH:
Inherits: ^Building Inherits: ^Building

View File

@@ -66,6 +66,16 @@ World:
G: 0 G: 0
B: 0 B: 0
A: 180 A: 180
PaletteFromScaledPalette@starportlights:
Name: starportlights
BasePalette: d2k
AllowModifiers: false
Offset: -64
PaletteFromScaledPalette@repairlights:
Name: repairlights
BasePalette: d2k
AllowModifiers: false
Offset: -128
PaletteFromR8@shroud: PaletteFromR8@shroud:
Name: shroud Name: shroud
Filename: DATA.R8 Filename: DATA.R8

View File

@@ -219,21 +219,23 @@ repaira:
Start: 2571 Start: 2571
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA
Start: 2572
Offset: -48,48
ZOffset: -1c511
active: DATA active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
BlendMode: Additive
damaged-active: DATA damaged-active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Tick: 60 Tick: 60
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA BlendMode: Additive
Start: 2572
Offset: -48,48
ZOffset: -1c511
icon: DATA icon: DATA
Start: 4096 Start: 4096
Offset: -30,-24 Offset: -30,-24
@@ -252,21 +254,23 @@ repairh:
Start: 2731 Start: 2731
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA
Start: 2732
Offset: -48,48
ZOffset: -1c511
active: DATA active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
BlendMode: Additive
damaged-active: DATA damaged-active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Tick: 60 Tick: 60
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA BlendMode: Additive
Start: 2732
Offset: -48,48
ZOffset: -1c511
icon: DATA icon: DATA
Start: 4097 Start: 4097
Offset: -30,-24 Offset: -30,-24
@@ -285,21 +289,23 @@ repairo:
Start: 2891 Start: 2891
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA
Start: 2892
Offset: -48,48
ZOffset: -1c511
active: DATA active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
BlendMode: Additive
damaged-active: DATA damaged-active: DATA
Start: 4746 Start: 4746
Length: 14 Length: 14
Tick: 60 Tick: 60
Offset: -48,48 Offset: -48,48
ZOffset: -1c511 ZOffset: -1c511
damaged-idle: DATA BlendMode: Additive
Start: 2892
Offset: -48,48
ZOffset: -1c511
icon: DATA icon: DATA
Start: 4098 Start: 4098
Offset: -30,-24 Offset: -30,-24
@@ -318,14 +324,14 @@ starporta:
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
damaged-active: DATA damaged-active: DATA
Start: 4723 Start: 4723
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
make: DATA make: DATA
Start: 4347 Start: 4347
@@ -820,14 +826,14 @@ starporth:
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
damaged-active: DATA damaged-active: DATA
Start: 4723 Start: 4723
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
make: DATA make: DATA
Start: 4347 Start: 4347
@@ -1231,14 +1237,14 @@ starporto:
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
damaged-active: DATA damaged-active: DATA
Start: 4723 Start: 4723
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
make: DATA make: DATA
Start: 4347 Start: 4347
@@ -1624,14 +1630,14 @@ starportc: # TODO: unused
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
damaged-active: DATA damaged-active: DATA
Start: 4723 Start: 4723
Length: 23 Length: 23
ZOffset: -1c511 ZOffset: -1c511
Offset: -48,64 Offset: -48,64
BlendMode: Alpha BlendMode: Additive
Tick: 200 Tick: 200
make: DATA make: DATA
Start: 4347 Start: 4347