Merge pull request #1 from OpenRA/bleed

Bleed
This commit is contained in:
Okunev Yu Dmitry
2013-03-02 00:19:25 -08:00
162 changed files with 1236 additions and 966 deletions

View File

@@ -37,6 +37,7 @@ Also thanks to:
* Raymond Martineau (mart0258)
* Riderr3
* Tim Mylemans (gecko)
* Tirili
Past developers included:
* Paul Chote (pchote)

View File

@@ -39,6 +39,12 @@ namespace OpenRA.FileFormats
get { return colors; }
}
public void ApplyRemap(IPaletteRemap r)
{
for(int i = 0; i < 256; i++)
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]),i).ToArgb();
}
public Palette(Stream s, int[] remapShadow)
{
colors = new uint[256];
@@ -61,9 +67,8 @@ namespace OpenRA.FileFormats
public Palette(Palette p, IPaletteRemap r)
{
colors = new uint[256];
for(int i = 0; i < 256; i++)
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)p.colors[i]),i).ToArgb();
colors = (uint[])p.colors.Clone();
ApplyRemap(r);
}
public Palette(Palette p)
@@ -71,6 +76,13 @@ namespace OpenRA.FileFormats
colors = (uint[])p.colors.Clone();
}
public Palette(uint[] data)
{
if (data.Length != 256)
throw new InvalidDataException("Attempting to create palette with incorrect array size");
colors = (uint[])data.Clone();
}
public ColorPalette AsSystemPalette()
{
ColorPalette pal;
@@ -88,6 +100,21 @@ namespace OpenRA.FileFormats
return pal;
}
public Bitmap AsBitmap()
{
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
uint* c = (uint*)data.Scan0;
for (var x = 0; x < 256; x++)
*(c + x) = colors[x];
}
b.UnlockBits(data);
return b;
}
public static Palette Load(string filename, int[] remap)
{
using(var s = File.OpenRead(filename))

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Thirdparty
int index = 0;
public int Last;
public int TotalCount = 0;
public Random() : this(Environment.TickCount) { }
@@ -41,13 +42,14 @@ namespace OpenRA.Thirdparty
y ^= y >> 18;
index = (index + 1) % 624;
TotalCount++;
Last = (int)(y % int.MaxValue);
return Last;
}
public int Next(int low, int high) { return low + Next() % (high - low); }
public int Next(int high) { return Next() % high; }
public double NextDouble() { return Math.Abs(Next() / (double)0x7fffffff); }
public float NextFloat() { return Math.Abs(Next() / (float)0x7fffffff); }
void Generate()
{

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA
@@ -73,7 +74,7 @@ namespace OpenRA
AddTrait(trait.Create(init));
}
Move = Lazy.New( () => TraitOrDefault<IMove>() );
Move = Lazy.New(() => TraitOrDefault<IMove>());
Size = Lazy.New(() =>
{
@@ -81,27 +82,23 @@ namespace OpenRA
if (si != null && si.Bounds != null)
return new int2(si.Bounds[0], si.Bounds[1]);
// auto size from render
var firstSprite = TraitsImplementing<IRender>().SelectMany(ApplyIRender).FirstOrDefault();
if (firstSprite.Sprite == null) return int2.Zero;
return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2();
return TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
});
if(this.HasTrait<RevealsShroud>())
if (this.HasTrait<RevealsShroud>())
{
Sight = new Shroud.ActorVisibility
{
range = this.Trait<RevealsShroud>().RevealRange,
vis = Shroud.GetVisOrigins(this).ToArray()
};
}
ApplyIRender = x => x.Render(this);
ApplyRenderModifier = (m, p) => p.ModifyRender(this, m);
Bounds = Cached.New( () => CalculateBounds(false) );
ExtendedBounds = Cached.New( () => CalculateBounds(true) );
ApplyIRender = (x, wr) => x.Render(this, wr);
ApplyRenderModifier = (m, p, wr) => p.ModifyRender(this, wr, m);
Bounds = Cached.New(() => CalculateBounds(false));
ExtendedBounds = Cached.New(() => CalculateBounds(true));
}
public void Tick()
@@ -109,7 +106,7 @@ namespace OpenRA
Bounds.Invalidate();
ExtendedBounds.Invalidate();
currentActivity = Util.RunActivity( this, currentActivity );
currentActivity = Traits.Util.RunActivity( this, currentActivity );
}
public void UpdateSight()
@@ -125,13 +122,13 @@ namespace OpenRA
OpenRA.FileFormats.Lazy<int2> Size;
// note: these delegates are cached to avoid massive allocation.
Func<IRender, IEnumerable<Renderable>> ApplyIRender;
Func<IEnumerable<Renderable>, IRenderModifier, IEnumerable<Renderable>> ApplyRenderModifier;
public IEnumerable<Renderable> Render()
Func<IRender, WorldRenderer, IEnumerable<Renderable>> ApplyIRender;
Func<IEnumerable<Renderable>, IRenderModifier, WorldRenderer, IEnumerable<Renderable>> ApplyRenderModifier;
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
var mods = TraitsImplementing<IRenderModifier>();
var sprites = TraitsImplementing<IRender>().SelectMany(ApplyIRender);
return mods.Aggregate(sprites, ApplyRenderModifier);
var sprites = TraitsImplementing<IRender>().SelectMany(x => ApplyIRender(x, wr));
return mods.Aggregate(sprites, (m,p) => ApplyRenderModifier(m,p,wr));
}
// When useAltitude = true, the bounding box is extended
@@ -146,22 +143,14 @@ namespace OpenRA
var si = Info.Traits.GetOrDefault<SelectableInfo>();
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
{
#if true
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
#else
loc.X += si.Bounds[2];
loc.Y += si.Bounds[3];
#endif
}
var move = Move.Value;
if (move != null)
{
#if true
loc -= new PVecInt(0, move.Altitude);
#else
loc.Y -= move.Altitude;
#endif
if (useAltitude)
size = new PVecInt(size.X, size.Y + move.Altitude);
}
@@ -257,10 +246,15 @@ namespace OpenRA
{
World.AddFrameEndTask(w =>
{
var oldOwner = Owner;
// momentarily remove from world so the ownership queries don't get confused
w.Remove(this);
Owner = newOwner;
w.Add(this);
foreach (var t in this.TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
});
}
}

View File

@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
@@ -25,12 +26,12 @@ namespace OpenRA.Effects
this.delay = delay;
}
public void Tick( World world )
public void Tick(World world)
{
if (--delay <= 0)
world.AddFrameEndTask(w => { w.Remove(this); a(); });
}
public IEnumerable<Renderable> Render() { yield break; }
public IEnumerable<Renderable> Render(WorldRenderer wr) { yield break; }
}
}

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
@@ -32,14 +33,14 @@ namespace OpenRA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (!target.IsInWorld)
yield break;
if (remainingTicks % 2 == 0)
foreach (var r in target.Render())
yield return r.WithPalette("highlight");
foreach (var r in target.Render(wr))
yield return r.WithPalette(wr.Palette("highlight"));
}
}
}

View File

@@ -9,13 +9,14 @@
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
{
public interface IEffect
{
void Tick( World world );
IEnumerable<Renderable> Render();
void Tick(World world);
IEnumerable<Renderable> Render(WorldRenderer r);
}
}

View File

@@ -58,7 +58,7 @@ namespace OpenRA
static string ChooseReplayFilename()
{
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ.rep");
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ");
}
static void JoinInner(OrderManager om)

View File

@@ -120,6 +120,26 @@ namespace OpenRA.GameRules
public string ConnectTo = "";
}
public class KeySettings
{
public string PauseKey = "f3";
public string CycleBaseKey = "backspace";
public string GotoLastEventKey = "space";
public string SellKey = "v";
public string PowerDownKey = "b";
public string RepairKey = "n";
public string AttackMoveKey = "a";
public string StopKey = "s";
public string ScatterKey = "x";
public string StanceCycleKey = "z";
public string DeployKey = "f";
public string CycleTabsKey = "tab";
}
public class Settings
{
string SettingsFile;
@@ -130,6 +150,7 @@ namespace OpenRA.GameRules
public GraphicSettings Graphics = new GraphicSettings();
public ServerSettings Server = new ServerSettings();
public DebugSettings Debug = new DebugSettings();
public KeySettings Keys = new KeySettings();
public Dictionary<string, object> Sections;
@@ -144,6 +165,7 @@ namespace OpenRA.GameRules
{"Graphics", Graphics},
{"Server", Server},
{"Debug", Debug},
{"Keys", Keys},
};
// Override fieldloader to ignore invalid entries

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Graphics
this.DisableFunc = d;
}
public Renderable Image(Actor self, string pal)
public Renderable Image(Actor self, PaletteReference pal)
{
var p = self.CenterLocation;
var loc = p.ToFloat2() - 0.5f * Animation.Image.size

View File

@@ -19,6 +19,7 @@ namespace OpenRA.Graphics
{
public static class CursorProvider
{
public static Dictionary<string, Palette> Palettes { get; private set; }
static Dictionary<string, CursorSequence> cursors;
public static void Initialize(string[] sequenceFiles)
@@ -28,13 +29,14 @@ namespace OpenRA.Graphics
int[] ShadowIndex = { };
if (sequences.NodesDict.ContainsKey("ShadowIndex"))
{
Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1);
ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value);
}
{
Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1);
ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value);
}
Palettes = new Dictionary<string, Palette>();
foreach (var s in sequences.NodesDict["Palettes"].Nodes)
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
Palettes.Add(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
LoadSequencesForCursor(s.Key, s.Value);

View File

@@ -25,11 +25,13 @@ namespace OpenRA.Graphics
ITexture texture;
Dictionary<string, Palette> palettes;
Dictionary<string, int> indices;
Dictionary<string, bool> allowsMods;
public HardwarePalette()
{
palettes = new Dictionary<string, Palette>();
indices = new Dictionary<string, int>();
allowsMods = new Dictionary<string, bool>();
texture = Game.Renderer.Device.CreateTexture();
}
@@ -49,22 +51,24 @@ namespace OpenRA.Graphics
return ret;
}
public void AddPalette(string name, Palette p)
public void AddPalette(string name, Palette p, bool allowModifiers)
{
if (palettes.ContainsKey(name))
throw new InvalidOperationException("Palette {0} has already been defined".F(name));
palettes.Add(name, p);
indices.Add(name, allocated++);
allowsMods.Add(name, allowModifiers);
}
uint[,] data = new uint[MaxPalettes, 256];
public void Update(IEnumerable<IPaletteModifier> paletteMods)
{
var copy = palettes.ToDictionary(p => p.Key, p => new Palette(p.Value));
var modifiable = copy.Where(p => allowsMods[p.Key]).ToDictionary(p => p.Key, p => p.Value);
foreach (var mod in paletteMods)
mod.AdjustPalette(copy);
mod.AdjustPalette(modifiable);
foreach (var pal in copy)
{

View File

@@ -50,20 +50,20 @@ namespace OpenRA.Graphics
TempBufferCount = Game.Settings.Graphics.NumTempBuffers;
SheetSize = Game.Settings.Graphics.SheetSize;
WorldSpriteShader = device.CreateShader("world-shp");
WorldLineShader = device.CreateShader("world-line");
LineShader = device.CreateShader("chrome-line");
RgbaSpriteShader = device.CreateShader("chrome-rgba");
SpriteShader = device.CreateShader("chrome-shp");
WorldSpriteShader = device.CreateShader("shp");
WorldLineShader = device.CreateShader("line");
LineShader = device.CreateShader("line");
RgbaSpriteShader = device.CreateShader("rgba");
SpriteShader = device.CreateShader("shp");
WorldSpriteRenderer = new SpriteRenderer( this, WorldSpriteShader );
WorldSpriteRenderer = new SpriteRenderer(this, WorldSpriteShader);
WorldLineRenderer = new LineRenderer(this, WorldLineShader);
LineRenderer = new LineRenderer(this, LineShader);
RgbaSpriteRenderer = new SpriteRenderer( this, RgbaSpriteShader );
SpriteRenderer = new SpriteRenderer( this, SpriteShader );
RgbaSpriteRenderer = new SpriteRenderer(this, RgbaSpriteShader);
SpriteRenderer = new SpriteRenderer(this, SpriteShader);
for( int i = 0 ; i < TempBufferCount ; i++ )
tempBuffers.Enqueue( device.CreateVertexBuffer( TempBufferSize ) );
for (int i = 0; i < TempBufferCount; i++)
tempBuffers.Enqueue(device.CreateVertexBuffer(TempBufferSize));
}
public void InitializeFonts(Manifest m)
@@ -80,22 +80,22 @@ namespace OpenRA.Graphics
float2 r2 = new float2(-1, 1);
var zr1 = zoom*r1;
SetShaderParams( WorldSpriteShader, zr1, r2, scroll );
SetShaderParams( WorldLineShader, zr1, r2, scroll );
SetShaderParams( LineShader, r1, r2, scroll );
SetShaderParams( RgbaSpriteShader, r1, r2, scroll );
SetShaderParams( SpriteShader, r1, r2, scroll );
SetShaderParams(WorldSpriteShader, zr1, r2, scroll);
SetShaderParams(WorldLineShader, zr1, r2, scroll);
SetShaderParams(LineShader, r1, r2, float2.Zero);
SetShaderParams(RgbaSpriteShader, r1, r2, float2.Zero);
SetShaderParams(SpriteShader, r1, r2, float2.Zero);
}
void SetShaderParams( IShader s, float2 r1, float2 r2, float2 scroll )
void SetShaderParams(IShader s, float2 r1, float2 r2, float2 scroll)
{
s.SetValue( "Palette", PaletteTexture );
s.SetValue( "Scroll", (int) scroll.X, (int) scroll.Y );
s.SetValue( "r1", r1.X, r1.Y );
s.SetValue( "r2", r2.X, r2.Y );
s.SetValue("Palette", PaletteTexture);
s.SetValue("Scroll", (int)scroll.X, (int)scroll.Y);
s.SetValue("r1", r1.X, r1.Y);
s.SetValue("r2", r2.X, r2.Y);
}
public void EndFrame( IInputHandler inputHandler )
public void EndFrame(IInputHandler inputHandler)
{
Flush();
device.PumpInput(inputHandler);
@@ -129,17 +129,17 @@ namespace OpenRA.Graphics
// which makes the window non-interactive in Windowed/Pseudofullscreen mode.
static Screen FixOSX() { return Screen.PrimaryScreen; }
internal static void Initialize( WindowMode windowMode )
internal static void Initialize(WindowMode windowMode)
{
if (Platform.CurrentPlatform == PlatformType.OSX)
FixOSX();
var resolution = GetResolution( windowMode );
var resolution = GetResolution(windowMode);
string renderer = Game.Settings.Server.Dedicated?"Null":Game.Settings.Graphics.Renderer;
var rendererPath = Path.GetFullPath( "OpenRA.Renderer.{0}.dll".F(renderer) );
string renderer = Game.Settings.Server.Dedicated ? "Null" : Game.Settings.Graphics.Renderer;
var rendererPath = Path.GetFullPath("OpenRA.Renderer.{0}.dll".F(renderer));
device = CreateDevice( Assembly.LoadFile( rendererPath ), resolution.Width, resolution.Height, windowMode );
device = CreateDevice(Assembly.LoadFile(rendererPath), resolution.Width, resolution.Height, windowMode);
}
static Size GetResolution(WindowMode windowmode)
@@ -150,12 +150,12 @@ namespace OpenRA.Graphics
return new Size(size.X, size.Y);
}
static IGraphicsDevice CreateDevice( Assembly rendererDll, int width, int height, WindowMode window )
static IGraphicsDevice CreateDevice(Assembly rendererDll, int width, int height, WindowMode window)
{
foreach( RendererAttribute r in rendererDll.GetCustomAttributes( typeof( RendererAttribute ), false ) )
foreach (RendererAttribute r in rendererDll.GetCustomAttributes(typeof(RendererAttribute), false))
{
var factory = (IDeviceFactory) r.Type.GetConstructor( Type.EmptyTypes ).Invoke( null );
return factory.Create( new Size( width, height ), window );
var factory = (IDeviceFactory)r.Type.GetConstructor(Type.EmptyTypes).Invoke(null);
return factory.Create(new Size(width, height), window);
}
throw new InvalidOperationException("Renderer DLL is missing RendererAttribute to tell us what type to use!");
@@ -164,7 +164,7 @@ namespace OpenRA.Graphics
internal IVertexBuffer<Vertex> GetTempVertexBuffer()
{
var ret = tempBuffers.Dequeue();
tempBuffers.Enqueue( ret );
tempBuffers.Enqueue(ret);
return ret;
}
@@ -176,8 +176,8 @@ namespace OpenRA.Graphics
get { return currentBatchRenderer; }
set
{
if( currentBatchRenderer == value ) return;
if( currentBatchRenderer != null )
if (currentBatchRenderer == value) return;
if (currentBatchRenderer != null)
currentBatchRenderer.Flush();
currentBatchRenderer = value;
}
@@ -186,7 +186,7 @@ namespace OpenRA.Graphics
public void EnableScissor(int left, int top, int width, int height)
{
Flush();
Device.EnableScissor( left, top, width, height );
Device.EnableScissor(left, top, width, height);
}
public void DisableScissor()

View File

@@ -18,12 +18,13 @@ namespace OpenRA.Graphics
public class Sequence
{
readonly Sprite[] sprites;
readonly int start, length, facings, tick;
readonly int start, length, stride, facings, tick;
public readonly string Name;
public int Start { get { return start; } }
public int End { get { return start + length; } }
public int Length { get { return length; } }
public int Stride { get { return stride; } }
public int Facings { get { return facings; } }
public int Tick { get { return tick; } }
@@ -43,6 +44,10 @@ namespace OpenRA.Graphics
else
length = int.Parse(d["Length"].Value);
if (d.ContainsKey("Stride"))
stride = int.Parse(d["Stride"].Value);
else
stride = length;
if(d.ContainsKey("Facings"))
facings = int.Parse(d["Facings"].Value);
@@ -54,10 +59,15 @@ namespace OpenRA.Graphics
else
tick = 40;
if (start < 0 || start + facings * length > sprites.Length)
if (length > stride)
throw new InvalidOperationException(
"{0}: Sequence {1}.{2}: Length must be <= stride"
.F(info.Nodes[0].Location, unit, name));
if (start < 0 || start + facings * stride > sprites.Length)
throw new InvalidOperationException(
"{6}: Sequence {0}.{1} uses frames [{2}..{3}] of SHP `{4}`, but only 0..{5} actually exist"
.F(unit, name, start, start + facings * length - 1, srcOverride ?? unit, sprites.Length - 1,
.F(unit, name, start, start + facings * stride - 1, srcOverride ?? unit, sprites.Length - 1,
info.Nodes[0].Location));
}
@@ -69,7 +79,7 @@ namespace OpenRA.Graphics
public Sprite GetSprite(int frame, int facing)
{
var f = Traits.Util.QuantizeFacing( facing, facings );
return sprites[ (f * length) + ( frame % length ) + start ];
return sprites[ (f * stride) + ( frame % length ) + start ];
}
}
}

View File

@@ -105,8 +105,17 @@ namespace OpenRA.Graphics
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
}
internal void Draw( WorldRenderer wr )
bool initializePalettes = true;
PaletteReference fogPalette, shroudPalette;
internal void Draw(WorldRenderer wr)
{
if (initializePalettes)
{
fogPalette = wr.Palette("fog");
shroudPalette = wr.Palette("shroud");
initializePalettes = false;
}
if (shroud != null && shroud.dirty)
{
shroud.dirty = false;
@@ -120,14 +129,12 @@ namespace OpenRA.Graphics
}
var clipRect = Game.viewport.WorldBounds(wr.world);
DrawShroud( wr, clipRect, fogSprites, "fog" );
DrawShroud( wr, clipRect, sprites, "shroud" );
DrawShroud(wr, clipRect, fogSprites, fogPalette);
DrawShroud(wr, clipRect, sprites, shroudPalette);
}
void DrawShroud( WorldRenderer wr, Rectangle clip, Sprite[,] s, string pal )
void DrawShroud(WorldRenderer wr, Rectangle clip, Sprite[,] s, PaletteReference pal)
{
var shroudPalette = wr.GetPaletteIndex(pal);
for (var j = clip.Top; j < clip.Bottom; j++)
{
var starti = clip.Left;
@@ -142,14 +149,14 @@ namespace OpenRA.Graphics
{
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
pal.Index,
new float2(Game.CellSize * (i - starti), Game.CellSize));
starti = i + 1;
}
s[i, j].DrawAt(
Game.CellSize * new float2(i, j),
shroudPalette);
pal.Index);
starti = i + 1;
last = s[i, j];
}
@@ -157,7 +164,7 @@ namespace OpenRA.Graphics
if (starti < clip.Right)
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
pal.Index,
new float2(Game.CellSize * (clip.Right - starti), Game.CellSize));
}
}

View File

@@ -49,12 +49,12 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette)
{
DrawSprite(s, location, wr.GetPaletteIndex(palette), s.size);
DrawSprite(s, location, wr.Palette(palette).Index, s.size);
}
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette, float2 size)
{
DrawSprite(s, location, wr.GetPaletteIndex(palette), size);
DrawSprite(s, location, wr.Palette(palette).Index, size);
}
public void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size)

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Graphics
int nv = 0;
var terrainPalette = Game.modData.Palette.GetPaletteIndex("terrain");
var terrainPalette = wr.Palette("terrain").Index;
for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ )
for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ )

View File

@@ -133,7 +133,7 @@ namespace OpenRA.Graphics
renderer.SpriteRenderer.DrawSprite(cursorSprite,
Viewport.LastMousePos - cursorSequence.Hotspot,
Game.modData.Palette.GetPaletteIndex(cursorSequence.Palette),
wr.Palette(cursorSequence.Palette).Index,
cursorSprite.size);
}

View File

@@ -17,27 +17,56 @@ using OpenRA.Traits;
namespace OpenRA.Graphics
{
public class PaletteReference
{
public readonly string Name;
public readonly int Index;
public readonly Palette Palette;
public PaletteReference(string name, int index, Palette palette)
{
Name = name;
Index = index;
Palette = palette;
}
}
public class WorldRenderer
{
public readonly World world;
internal readonly TerrainRenderer terrainRenderer;
internal readonly ShroudRenderer shroudRenderer;
internal readonly HardwarePalette palette;
internal Cache<string, PaletteReference> palettes;
internal WorldRenderer(World world)
{
this.world = world;
this.palette = Game.modData.Palette;
foreach( var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>( world ) )
palette = new HardwarePalette();
foreach (var p in CursorProvider.Palettes)
palette.AddPalette(p.Key, p.Value, false);
palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
foreach (var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>(world))
pal.Trait.InitPalette( this );
// Generate initial palette texture
palette.Update(new IPaletteModifier[] {});
terrainRenderer = new TerrainRenderer(world, this);
shroudRenderer = new ShroudRenderer(world);
}
public int GetPaletteIndex(string name) { return palette.GetPaletteIndex(name); }
public Palette GetPalette(string name) { return palette.GetPalette(name); }
public void AddPalette(string name, Palette pal) { palette.AddPalette(name, pal); }
PaletteReference CreatePaletteReference(string name)
{
var pal = palette.GetPalette(name);
if (pal == null)
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
}
public PaletteReference Palette(string name) { return palettes[name]; }
public void AddPalette(string name, Palette pal, bool allowModifiers) { palette.AddPalette(name, pal, allowModifiers); }
class SpriteComparer : IComparer<Renderable>
{
@@ -57,10 +86,10 @@ namespace OpenRA.Graphics
bounds.BottomRightAsCPos().ToPPos()
);
var renderables = actors.SelectMany(a => a.Render())
var renderables = actors.SelectMany(a => a.Render(this))
.OrderBy(r => r, comparer);
var effects = world.Effects.SelectMany(e => e.Render());
var effects = world.Effects.SelectMany(e => e.Render(this));
return renderables.Concat(effects);
}
@@ -77,8 +106,8 @@ namespace OpenRA.Graphics
terrainRenderer.Draw(this, Game.viewport);
foreach (var a in world.traitDict.ActorsWithTraitMultiple<IRenderAsTerrain>(world))
foreach (var r in a.Trait.RenderAsTerrain(a.Actor))
r.Sprite.DrawAt(r.Pos, this.GetPaletteIndex(r.Palette), r.Scale);
foreach (var r in a.Trait.RenderAsTerrain(this, a.Actor))
r.Sprite.DrawAt(r.Pos, r.Palette.Index, r.Scale);
foreach (var a in world.Selection.Actors)
if (!a.Destroyed)
@@ -91,7 +120,7 @@ namespace OpenRA.Graphics
world.OrderGenerator.RenderBeforeWorld(this, world);
foreach (var image in SpritesToRender())
image.Sprite.DrawAt(image.Pos, this.GetPaletteIndex(image.Palette), image.Scale);
image.Sprite.DrawAt(image.Pos, image.Palette.Index, image.Scale);
// added for contrails
foreach (var a in world.ActorsWithTrait<IPostRender>())

View File

@@ -28,7 +28,6 @@ namespace OpenRA
public ILoadScreen LoadScreen = null;
public SheetBuilder SheetBuilder;
public SpriteLoader SpriteLoader;
public HardwarePalette Palette { get; private set; }
public ModData( params string[] mods )
{
@@ -51,13 +50,11 @@ namespace OpenRA
AvailableMaps = FindMaps(Manifest.Mods);
Palette = new HardwarePalette();
ChromeMetrics.Initialize(Manifest.ChromeMetrics);
ChromeProvider.Initialize(Manifest.Chrome);
SheetBuilder = new SheetBuilder(TextureChannel.Red);
SpriteLoader = new SpriteLoader(new string[] { ".shp" }, SheetBuilder);
CursorProvider.Initialize(Manifest.Cursors);
Palette.Update(new IPaletteModifier[] { });
}
public Map PrepareMap(string uid)

View File

@@ -34,12 +34,23 @@ namespace OpenRA.Network
void StartSavingReplay(byte[] initialContent)
{
var filename = chooseFilename();
var replayPath = Path.Combine(Platform.SupportDir, "Replays");
var replaysDirectory = Path.Combine(Platform.SupportDir, "Replays");
if (!Directory.Exists(replayPath))
Directory.CreateDirectory(replayPath);
if (!Directory.Exists(replaysDirectory))
Directory.CreateDirectory(replaysDirectory);
var file = File.Create(Path.Combine(replayPath, filename));
string fullFilename;
var id = -1;
do
{
fullFilename = Path.Combine(replaysDirectory, id < 0
? "{0}.rep".F(filename)
: "{0}-{1}.rep".F(filename, id));
id++;
}
while (File.Exists(fullFilename));
var file = File.Create(fullFilename);
file.Write(initialContent);
this.writer = new BinaryWriter(file);
}

View File

@@ -42,7 +42,9 @@ namespace OpenRA.Network
public class Client
{
public int Index;
public ColorRamp ColorRamp;
public ColorRamp PreferredColorRamp; // Color that the client normally uses from settings.yaml.
public ColorRamp ColorRamp; // Actual color that the client is using.
// Usually the same as PreferredColorRamp but can be different on maps with locked colors.
public string Country;
public int SpawnPoint;
public string Name;
@@ -79,6 +81,7 @@ namespace OpenRA.Network
public bool AllowCheats = false;
public bool Dedicated;
public string Difficulty;
public bool Crates = true;
}
public Session(string[] mods)

View File

@@ -36,6 +36,7 @@ namespace OpenRA.Network
{
report.Frame = orderManager.NetFrameNumber;
report.SyncedRandom = orderManager.world.SharedRandom.Last;
report.TotalCount = orderManager.world.SharedRandom.TotalCount;
report.Traits.Clear();
foreach (var a in orderManager.world.ActorsWithTrait<ISync>())
{
@@ -58,7 +59,7 @@ namespace OpenRA.Network
if (r.Frame == frame)
{
Log.Write("sync", "Sync for net frame {0} -------------", r.Frame);
Log.Write("sync", "SharedRandom: "+r.SyncedRandom);
Log.Write("sync", "SharedRandom: {0} (#{1})", r.SyncedRandom, r.TotalCount);
Log.Write("sync", "Synced Traits:");
foreach (var a in r.Traits)
Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F(
@@ -77,6 +78,7 @@ namespace OpenRA.Network
{
public int Frame;
public int SyncedRandom;
public int TotalCount;
public List<TraitReport> Traits = new List<TraitReport>();
}

View File

@@ -119,6 +119,7 @@ namespace OpenRA.Network
var info = new Session.Client()
{
Name = Game.Settings.Player.Name,
PreferredColorRamp = Game.Settings.Player.ColorRamp,
ColorRamp = Game.Settings.Player.ColorRamp,
Country = "random",
SpawnPoint = 0,

View File

@@ -374,6 +374,8 @@ namespace OpenRA.Server
return;
if (pr.LockColor)
c.ColorRamp = pr.ColorRamp;
else
c.ColorRamp = c.PreferredColorRamp;
if (pr.LockRace)
c.Country = pr.Race;
if (pr.LockSpawn)

View File

@@ -76,8 +76,7 @@ namespace OpenRA.Traits
case "DevShroud":
{
DisableShroud ^= true;
if (self.World.LocalPlayer == self.Owner)
self.World.RenderedShroud.Disabled = DisableShroud;
self.Owner.Shroud.Disabled = DisableShroud;
break;
}
case "DevPathDebug":
@@ -87,8 +86,7 @@ namespace OpenRA.Traits
}
case "DevGiveExploration":
{
if (self.World.LocalPlayer == self.Owner)
self.World.LocalPlayer.Shroud.ExploreAll(self.World);
self.Owner.Shroud.ExploreAll(self.World);
break;
}
case "DevUnlimitedPower":

View File

@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
namespace OpenRA.Traits
@@ -23,16 +24,16 @@ namespace OpenRA.Traits
public virtual object Create(ActorInitializer init) { return new RenderSimple(init.self); }
public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, Player owner)
public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, PaletteReference pr)
{
var anim = new Animation(RenderSimple.GetImage(building), () => 0);
anim.PlayRepeating("idle");
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale),
Palette ?? (owner != null ? PlayerPalette + owner.InternalName : null), 0, Scale);
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale), pr, 0, Scale);
}
}
public class RenderSimple : IRender, ITick
public class RenderSimple : IRender, IAutoSelectionSize, ITick, INotifyOwnerChanged
{
public Dictionary<string, AnimationWithOffset> anims = new Dictionary<string, AnimationWithOffset>();
@@ -55,7 +56,6 @@ namespace OpenRA.Traits
return Info.Image ?? actor.Name;
}
string cachedImage = null;
public string GetImage(Actor self)
{
if (cachedImage != null)
@@ -65,6 +65,9 @@ namespace OpenRA.Traits
}
RenderSimpleInfo Info;
string cachedImage = null;
bool initializePalette = true;
protected PaletteReference palette;
public RenderSimple(Actor self, Func<int> baseFacing)
{
@@ -77,20 +80,40 @@ namespace OpenRA.Traits
anim.PlayRepeating("idle");
}
public string Palette(Player p) { return Info.Palette ?? Info.PlayerPalette + p.InternalName; }
public virtual IEnumerable<Renderable> Render(Actor self)
protected virtual string PaletteName(Actor self)
{
return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName;
}
protected void UpdatePalette() { initializePalette = true; }
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); }
public virtual IEnumerable<Renderable> Render(Actor self, WorldRenderer wr)
{
if (initializePalette)
{
palette = wr.Palette(PaletteName(self));
initializePalette = false;
}
foreach (var a in anims.Values)
if (a.DisableFunc == null || !a.DisableFunc())
{
Renderable ret = a.Image(self, Palette(self.Owner));
Renderable ret = a.Image(self, palette);
if (Info.Scale != 1f)
ret = ret.WithScale(Info.Scale).WithPos(ret.Pos + 0.5f * ret.Sprite.size * (1 - Info.Scale));
yield return ret;
}
}
public int2 SelectionSize(Actor 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 virtual void Tick(Actor self)
{
foreach (var a in anims.Values)

View File

@@ -34,7 +34,8 @@ namespace OpenRA.Traits
}
public interface ITick { void Tick(Actor self); }
public interface IRender { IEnumerable<Renderable> Render(Actor self); }
public interface IRender { IEnumerable<Renderable> Render(Actor self, WorldRenderer wr); }
public interface IAutoSelectionSize { int2 SelectionSize(Actor self); }
public interface IIssueOrder
{
@@ -62,6 +63,7 @@ namespace OpenRA.Traits
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, CPos exit); }
public interface INotifyOwnerChanged { void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner); }
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
@@ -113,7 +115,7 @@ namespace OpenRA.Traits
}
public interface INotifyAttack { void Attacking(Actor self, Target target); }
public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r); }
public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r); }
public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); }
public interface ISpeedModifier { decimal GetSpeedModifier(); }
public interface IFirepowerModifier { float GetFirepowerModifier(); }
@@ -154,12 +156,12 @@ namespace OpenRA.Traits
{
public readonly Sprite Sprite;
public readonly float2 Pos;
public readonly string Palette;
public readonly PaletteReference Palette;
public readonly int Z;
public readonly int ZOffset;
public float Scale;
public Renderable(Sprite sprite, float2 pos, string palette, int z, int zOffset, float scale)
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z, int zOffset, float scale)
{
Sprite = sprite;
Pos = pos;
@@ -169,14 +171,14 @@ namespace OpenRA.Traits
Scale = scale; /* default */
}
public Renderable(Sprite sprite, float2 pos, string palette, int z)
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z)
: this(sprite, pos, palette, z, 0, 1f) { }
public Renderable(Sprite sprite, float2 pos, string palette, int z, float scale)
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z, float scale)
: this(sprite, pos, palette, z, 0, scale) { }
public Renderable WithScale(float newScale) { return new Renderable(Sprite, Pos, Palette, Z, ZOffset, newScale); }
public Renderable WithPalette(string newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
public Renderable WithPalette(PaletteReference newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
public Renderable WithZOffset(int newOffset) { return new Renderable(Sprite, Pos, Palette, Z, newOffset, Scale); }
public Renderable WithPos(float2 newPos) { return new Renderable(Sprite, newPos, Palette, Z, ZOffset, Scale); }
}
@@ -208,7 +210,7 @@ namespace OpenRA.Traits
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr); }
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(Actor self); }
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(WorldRenderer wr, Actor self); }
public interface ITargetable
{

View File

@@ -18,6 +18,7 @@ namespace OpenRA.Traits
public readonly string BasePalette = null;
public readonly string BaseName = "player";
public readonly int[] RemapIndex = {};
public readonly bool AllowModifiers = true;
public object Create( ActorInitializer init ) { return new PlayerColorPalette( init.self.Owner, this ); }
}
@@ -36,9 +37,9 @@ namespace OpenRA.Traits
public void InitPalette( WorldRenderer wr )
{
var paletteName = "{0}{1}".F( info.BaseName, owner.InternalName );
var newpal = new Palette(wr.GetPalette(info.BasePalette),
var newpal = new Palette(wr.Palette(info.BasePalette).Palette,
new PlayerColorRemap(info.RemapIndex, owner.ColorRamp));
wr.AddPalette(paletteName, newpal);
wr.AddPalette(paletteName, newpal, info.AllowModifiers);
}
}
}

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Traits
{
hasSetupPalettes = true;
foreach (var rt in world.WorldActor.TraitsImplementing<ResourceType>())
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
rt.info.PaletteRef = wr.Palette(rt.info.Palette);
}
var clip = Game.viewport.WorldBounds(world);
@@ -47,7 +47,7 @@ namespace OpenRA.Traits
if (c.image != null)
c.image[c.density].DrawAt(
new CPos(x, y).ToPPos().ToFloat2(),
c.type.info.PaletteIndex);
c.type.info.PaletteRef.Index);
}
}

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Traits
public readonly bool AllowUnderActors = false;
public Sprite[][] Sprites;
public int PaletteIndex;
public PaletteReference PaletteRef;
public PipType PipColor = PipType.Yellow;

View File

@@ -137,6 +137,9 @@ namespace OpenRA.Traits
if (a.Owner.World.LocalPlayer == null
|| a.Owner.Stances[a.Owner.World.LocalPlayer] == Stance.Ally) return;
if (v == null)
return;
foreach (var p in v.vis)
foreach (var q in FindVisibleTiles(a.World, p, range))
foggedCells[q.X, q.Y] = exploredCells[q.X, q.Y];

View File

@@ -101,7 +101,7 @@ namespace OpenRA.Widgets
var xAxisSize = GetXAxisSize();
var yAxisSize = GetYAxisSize();
var maxValue = GetSeries().Select(p => p.Points).SelectMany(d => d).Max();
var maxValue = GetSeries().Select(p => p.Points).SelectMany(d => d).Concat(new[] { 0f }).Max();
var scale = 200 / Math.Max(5000, (float)Math.Ceiling(maxValue / 1000) * 1000);
var xStep = width / xAxisSize;

View File

@@ -127,7 +127,7 @@ namespace OpenRA
public static float Gauss1D(this Thirdparty.Random r, int samples)
{
return Exts.MakeArray(samples, _ => (float)r.NextDouble() * 2 - 1f)
return Exts.MakeArray(samples, _ => r.NextFloat() * 2 - 1f)
.Sum() / samples;
}

View File

@@ -61,8 +61,6 @@ namespace OpenRA.Mods.Cnc
}
}
static Set<string> excludePalettes = new Set<string>("cursor", "chrome", "colorpicker", "shroud", "fog");
public void AdjustPalette(Dictionary<string,Palette> palettes)
{
if (to == EffectType.None && remainingFrames == 0)
@@ -70,9 +68,6 @@ namespace OpenRA.Mods.Cnc
foreach (var pal in palettes)
{
if (excludePalettes.Contains(pal.Key))
continue;
for (var x = 0; x < 256; x++)
{
var orig = pal.Value.GetColor(x);

View File

@@ -32,11 +32,11 @@ namespace OpenRA.Mods.Cnc.Effects
public void Tick(World world) { anim.Tick(); }
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image,
target.CenterLocation.ToFloat2() - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
"effect", (int)target.CenterLocation.Y);
wr.Palette("effect"), (int)target.CenterLocation.Y);
}
void Finish( World world )

View File

@@ -11,6 +11,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Cnc
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Cnc
Info = info;
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
foreach (var c in cargo.Passengers)
{
@@ -55,7 +56,7 @@ namespace OpenRA.Mods.Cnc
Info.PassengerTypes.Contains(p.Trait<Passenger>().info.CargoType))
: cargo.Passengers;
return r.Concat(visiblePassengers.SelectMany(a => a.Render())
return r.Concat(visiblePassengers.SelectMany(a => a.Render(wr))
.Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude))
.WithZOffset(a.ZOffset + Info.RelativeAltitude)));
}

View File

@@ -10,6 +10,7 @@
using System;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
@@ -20,7 +21,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
Widget menu;
[ObjectCreator.UseCtor]
public CncIngameMenuLogic(Widget widget, World world, Action onExit)
public CncIngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer)
{
var resumeDisabled = false;
menu = widget.Get("INGAME_MENU");
@@ -72,6 +73,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
{
{ "world", world },
{ "worldRenderer", worldRenderer },
{ "onExit", () => hideButtons = false },
});
};

View File

@@ -85,9 +85,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
settingsMenu.Get<ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
{
Menu = MenuType.None;
Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
{
{ "world", world },
{ "onExit", () => Menu = MenuType.Settings },
});
};

View File

@@ -6,6 +6,7 @@
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
@@ -17,6 +18,7 @@ using OpenRA.GameRules;
using OpenRA.Mods.RA;
using OpenRA.Mods.RA.Widgets.Logic;
using OpenRA.Widgets;
using OpenRA.Mods.RA.Widgets;
namespace OpenRA.Mods.Cnc.Widgets.Logic
{
@@ -25,7 +27,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
enum PanelType { General, Input }
PanelType Settings = PanelType.General;
ColorPickerPaletteModifier playerPalettePreview;
ColorPreviewManagerWidget colorPreview;
World world;
[ObjectCreator.UseCtor]
@@ -52,8 +54,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
var nameTextfield = generalPane.Get<TextFieldWidget>("NAME_TEXTFIELD");
nameTextfield.Text = playerSettings.Name;
playerPalettePreview = world.WorldActor.Trait<ColorPickerPaletteModifier>();
playerPalettePreview.Ramp = playerSettings.ColorRamp;
colorPreview = panel.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
colorPreview.Ramp = playerSettings.ColorRamp;
var colorDropdown = generalPane.Get<DropDownButtonWidget>("COLOR");
colorDropdown.OnMouseDown = _ => ShowColorPicker(colorDropdown, playerSettings);
@@ -153,8 +155,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
bool ShowColorPicker(DropDownButtonWidget color, PlayerSettings s)
{
Action<ColorRamp> onSelect = c => { s.ColorRamp = c; color.RemovePanel(); };
Action<ColorRamp> onChange = c => { playerPalettePreview.Ramp = c; };
Action<ColorRamp> onSelect = c => {s.ColorRamp = c; color.RemovePanel();};
Action<ColorRamp> onChange = c => {colorPreview.Ramp = c;};
var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
{

View File

@@ -266,7 +266,7 @@ namespace OpenRA.Mods.Cnc.Widgets
public override bool HandleKeyPress(KeyInput e)
{
if (e.Event != KeyInputEvent.Down) return false;
if (e.KeyName == "tab")
if (e.KeyName == Game.Settings.Keys.CycleTabsKey)
{
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift));

View File

@@ -35,10 +35,8 @@ namespace OpenRA.Mods.RA
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10
&& self.Owner.WinState != WinState.Lost)
{
self.World.AddFrameEndTask(w => w.Add(
new Parachute(pilot.Owner,
Util.CenterOfCell(self.CenterLocation.ToCPos()),
aircraft.Altitude, pilot)));
self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot,
Util.CenterOfCell(self.CenterLocation.ToCPos()), aircraft.Altitude)));
Sound.Play(info.ChuteSound, self.CenterLocation);
}

View File

@@ -38,13 +38,12 @@ namespace OpenRA.Mods.RA.Air
}
var attack = self.Trait<AttackHeli>();
var range = attack.GetMaximumRange() * 0.625f;
var dist = target.CenterLocation - self.CenterLocation;
var desiredFacing = Util.GetFacing(dist, aircraft.Facing);
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
if( !float2.WithinEpsilon( float2.Zero, dist.ToFloat2(), range * Game.CellSize ) )
if (!Combat.IsInRange(self.CenterLocation, attack.GetMaximumRange(), target))
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, desiredFacing);
attack.DoAttack( self, target );

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA.Air
}
var dist = Dest - aircraft.PxPosition;
if (float2.WithinEpsilon(float2.Zero, dist.ToFloat2(), 2))
if (Math.Abs(dist.X) < 2 && Math.Abs(dist.Y) < 2)
{
aircraft.SubPxPosition = Dest.ToPSubPos();
return NextActivity;

View File

@@ -56,17 +56,17 @@ namespace OpenRA.Mods.RA.Air
var altitude = aircraft.Altitude;
if (altitude == 0) altitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
var approachStart = landPos.ToFloat2() - new float2(altitude * speed, 0);
var approachStart = landPos.ToInt2() - new float2(altitude * speed, 0);
var turnRadius = (128f / self.Info.Traits.Get<AircraftInfo>().ROT) * speed / (float)Math.PI;
/* work out the center points */
var fwd = -float2.FromAngle(aircraft.Facing / 128f * (float)Math.PI);
var side = new float2(-fwd.Y, fwd.X); /* rotate */
var sideTowardBase = new[] { side, -side }
.OrderBy(a => float2.Dot(a, self.CenterLocation.ToFloat2() - approachStart))
.OrderBy(a => float2.Dot(a, self.CenterLocation.ToInt2() - approachStart))
.First();
var c1 = self.CenterLocation.ToFloat2() + turnRadius * sideTowardBase;
var c1 = self.CenterLocation.ToInt2() + turnRadius * sideTowardBase;
var c2 = approachStart + new float2(0, turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point
/* work out tangent points */

View File

@@ -107,7 +107,7 @@ namespace OpenRA.Mods.RA
{
var info = self.Info.Traits.Get<AttackBaseInfo>();
nextScanTime = (int)(25 * (info.ScanTimeAverage +
(self.World.SharedRandom.NextDouble() * 2 - 1) * info.ScanTimeSpread));
(self.World.SharedRandom.NextFloat() * 2 - 1) * info.ScanTimeSpread));
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, (int)(Game.CellSize * range));

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
@@ -18,7 +19,7 @@ namespace OpenRA.Mods.RA
class BelowUnits : IRenderModifier
{
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
return r.Select(a => a.WithZOffset((int) -a.Sprite.size.Y));
}

View File

@@ -135,10 +135,18 @@ namespace OpenRA.Mods.RA
return bridges.GetBridge(self.Location + new CVec(offset[0], offset[1]));
}
public IEnumerable<Renderable> RenderAsTerrain(Actor self)
bool initializePalettes = true;
PaletteReference terrainPalette;
public IEnumerable<Renderable> RenderAsTerrain(WorldRenderer wr, Actor self)
{
if (initializePalettes)
{
terrainPalette = wr.Palette("terrain");
initializePalettes = false;
}
foreach (var t in TileSprites[currentTemplate])
yield return new Renderable(t.Value, t.Key.ToPPos().ToFloat2(), "terrain", Game.CellSize * t.Key.Y);
yield return new Renderable(t.Value, t.Key.ToPPos().ToFloat2(), terrainPalette, Game.CellSize * t.Key.Y);
}
bool IsIntact(Bridge b)

View File

@@ -19,6 +19,7 @@ namespace OpenRA.Mods.RA.Buildings
public readonly int RepairPercent = 20;
public readonly int RepairInterval = 24;
public readonly int RepairStep = 7;
public readonly string IndicatorPalettePrefix = "player";
public object Create(ActorInitializer init) { return new RepairableBuilding(init.self, this); }
}
@@ -51,7 +52,7 @@ namespace OpenRA.Mods.RA.Buildings
Sound.PlayNotification(Repairer, "Speech", "Repairing", self.Owner.Country.Race);
self.World.AddFrameEndTask(
w => w.Add(new RepairIndicator(self, p)));
w => w.Add(new RepairIndicator(self, Info.IndicatorPalettePrefix, p)));
}
}
}

View File

@@ -10,8 +10,8 @@
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Effects;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Orders;
using OpenRA.Traits;
@@ -35,12 +35,12 @@ namespace OpenRA.Mods.RA
public IEnumerable<IOrderTargeter> Orders
{
get { yield return new UnitTraitOrderTargeter<Building>( "C4", 6, "c4", true, false ); }
get { yield return new UnitTraitOrderTargeter<C4Demolishable>("C4", 6, "c4", true, false); }
}
public Order IssueOrder( Actor self, IOrderTargeter order, Target target, bool queued )
{
if( order.OrderID == "C4" )
if (order.OrderID == "C4")
return new Order("C4", self, queued) { TargetActor = target.Actor };
return null;
@@ -65,4 +65,7 @@ namespace OpenRA.Mods.RA
return (order.OrderString == "C4") ? "Attack" : null;
}
}
class C4DemolishableInfo : TraitInfo<C4Demolishable> { }
class C4Demolishable { }
}

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
@@ -8,6 +8,7 @@
*/
#endregion
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Traits;
@@ -56,7 +57,7 @@ namespace OpenRA.Mods.RA
self.World.Add(args.weapon.Projectile.Create(args));
if (args.weapon.Report != null)
if (args.weapon.Report != null && args.weapon.Report.Any())
Sound.Play(args.weapon.Report.Random(self.World.SharedRandom) + ".aud", self.CenterLocation);
}
}

View File

@@ -32,8 +32,6 @@ namespace OpenRA.Mods.RA
if (remainingFrames > 0)
remainingFrames--;
}
static List<string> excludePalettes = new List<string>{"cursor", "chrome", "colorpicker", "shroud", "fog"};
public void AdjustPalette(Dictionary<string,Palette> palettes)
{
@@ -44,9 +42,6 @@ namespace OpenRA.Mods.RA
foreach (var pal in palettes)
{
if (excludePalettes.Contains(pal.Key))
continue;
for (var x = 0; x < 256; x++)
{
var orig = pal.Value.GetColor(x);

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
@@ -67,13 +68,13 @@ namespace OpenRA.Mods.RA
static readonly Renderable[] Nothing = { };
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> rs)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
if (remainingTime > 0)
return rs;
return r;
if (Cloaked && IsVisible(self))
return rs.Select(a => a.WithPalette(info.Palette));
return r.Select(a => a.WithPalette(wr.Palette(info.Palette)));
else
return Nothing;
}

View File

@@ -1,47 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class ColorPickerPaletteModifierInfo : ITraitInfo
{
public string PlayerPalette = "player";
public object Create( ActorInitializer init ) { return new ColorPickerPaletteModifier( this ); }
}
public class ColorPickerPaletteModifier : IPalette, IPaletteModifier
{
ColorPickerPaletteModifierInfo Info;
int[] index;
public ColorRamp Ramp;
public ColorPickerPaletteModifier(ColorPickerPaletteModifierInfo info) { Info = info; }
public void InitPalette( WorldRenderer wr )
{
var info = Rules.Info["player"].Traits.WithInterface<PlayerColorPaletteInfo>()
.First(p => p.BaseName == Info.PlayerPalette);
index = info.RemapIndex;
wr.AddPalette("colorpicker", wr.GetPalette(info.BasePalette));
}
public void AdjustPalette(Dictionary<string, Palette> palettes)
{
palettes["colorpicker"] = new Palette(palettes["colorpicker"],
new PlayerColorRemap(index, Ramp));
}
}
}

View File

@@ -153,7 +153,7 @@ namespace OpenRA.Mods.RA
facing = 0
};
if (args.weapon.Report != null)
if (args.weapon.Report != null && args.weapon.Report.Any())
Sound.Play(args.weapon.Report.Random(attacker.World.SharedRandom) + ".aud", pos);
DoImpacts(args);
@@ -208,18 +208,18 @@ namespace OpenRA.Mods.RA
return false;
}
static float2 GetRecoil(Actor self, float recoil)
static PVecFloat GetRecoil(Actor self, float recoil)
{
if (!self.HasTrait<RenderUnitTurreted>())
return float2.Zero;
return PVecFloat.Zero;
var facing = self.Trait<Turreted>().turretFacing;
var localRecoil = new float2(0, recoil); // vector in turret-space.
return Util.RotateVectorByFacing(localRecoil, facing, .7f);
return (PVecFloat)Util.RotateVectorByFacing(localRecoil, facing, .7f);
}
public static PVecInt GetTurretPosition(Actor self, IFacing facing, Turret turret)
public static PVecFloat GetTurretPosition(Actor self, IFacing facing, Turret turret)
{
if (facing == null) return turret.ScreenSpacePosition; /* things that don't have a rotating base don't need the turrets repositioned */
@@ -228,23 +228,23 @@ namespace OpenRA.Mods.RA
var bodyFacing = facing.Facing;
var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs);
return (PVecInt) ((PVecFloat)(Util.RotateVectorByFacing(turret.UnitSpacePosition.ToFloat2(), quantizedFacing, .7f)
+ GetRecoil(self, turret.Recoil))
+ turret.ScreenSpacePosition);
return (PVecFloat)Util.RotateVectorByFacing(turret.UnitSpacePosition.ToFloat2(), quantizedFacing, .7f)
+ GetRecoil(self, turret.Recoil)
+ (PVecFloat)turret.ScreenSpacePosition.ToFloat2();
}
static PVecInt GetUnitspaceBarrelOffset(Actor self, IFacing facing, Turret turret, Barrel barrel)
static PVecFloat GetUnitspaceBarrelOffset(Actor self, IFacing facing, Turret turret, Barrel barrel)
{
var turreted = self.TraitOrDefault<Turreted>();
if (turreted == null && facing == null)
return PVecInt.Zero;
return PVecFloat.Zero;
var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing;
return (PVecInt)(PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f);
return (PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f);
}
// gets the screen-space position of a barrel.
public static PVecInt GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel)
public static PVecFloat GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel)
{
return GetTurretPosition(self, facing, turret) + barrel.ScreenSpaceOffset
+ GetUnitspaceBarrelOffset(self, facing, turret, barrel);

View File

@@ -40,6 +40,8 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self)
{
if (!self.World.LobbyInfo.GlobalSettings.Crates) return;
if (--ticks <= 0)
{
ticks = Info.SpawnInterval * 25; // todo: randomize
@@ -76,7 +78,7 @@ namespace OpenRA.Mods.RA
void SpawnCrate(Actor self)
{
var inWater = self.World.SharedRandom.NextDouble() < Info.WaterChance;
var inWater = self.World.SharedRandom.NextFloat() < Info.WaterChance;
var pp = ChooseDropCell(self, inWater, 100);
if (pp == null) return;

View File

@@ -34,6 +34,8 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self)
{
if (!self.World.LobbyInfo.GlobalSettings.Crates) return;
if (--ticks <= 0)
{
var info = self.Info.Traits.Get<CrateSpawnerInfo>();
@@ -52,7 +54,7 @@ namespace OpenRA.Mods.RA
void SpawnCrate(Actor self, CrateSpawnerInfo info)
{
var threshold = 100;
var inWater = self.World.SharedRandom.NextDouble() < info.WaterChance;
var inWater = self.World.SharedRandom.NextFloat() < info.WaterChance;
for (var n = 0; n < threshold; n++ )
{

View File

@@ -13,10 +13,11 @@ using System.Linq;
using OpenRA.Traits;
using OpenRA.Mods.RA.Effects;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render;
namespace OpenRA.Mods.RA
{
class CrushableInfantryInfo : ITraitInfo, Requires<MobileInfo>
class CrushableInfantryInfo : ITraitInfo, Requires<MobileInfo>, Requires<RenderInfantryInfo>
{
public readonly string CrushSound = "squish2.aud";
public readonly string CorpseSequence = "die-crushed";
@@ -29,11 +30,13 @@ namespace OpenRA.Mods.RA
{
readonly Actor self;
readonly CrushableInfantryInfo Info;
readonly RenderInfantry ri;
public CrushableInfantry(Actor self, CrushableInfantryInfo info)
{
this.self = self;
this.Info = info;
ri = self.Trait<RenderInfantry>();
}
public void WarnCrush(Actor crusher)
@@ -45,12 +48,7 @@ namespace OpenRA.Mods.RA
public void OnCrush(Actor crusher)
{
Sound.Play(Info.CrushSound, crusher.CenterLocation);
self.World.AddFrameEndTask(w =>
{
if (!self.Destroyed)
w.Add(new Corpse(self, Info.CorpseSequence));
});
ri.SpawnCorpse(self, Info.CorpseSequence);
self.Kill(crusher);
}

View File

@@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Effects
if (info.Inaccuracy > 0)
{
var factor = ((Args.dest - Args.src).Length / (float)Game.CellSize) / args.weapon.Range;
var factor = ((Args.dest - Args.src).Length / Game.CellSize) / (float)args.weapon.Range;
Args.dest += (PVecInt) (info.Inaccuracy * factor * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
}
@@ -144,7 +144,7 @@ namespace OpenRA.Mods.RA.Effects
const float height = .1f;
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (anim != null)
{
@@ -158,15 +158,15 @@ namespace OpenRA.Mods.RA.Effects
if (Info.High || Info.Angle > 0)
{
if (Info.Shadow)
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "shadow", (int)pos.Y);
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, wr.Palette("shadow"), (int)pos.Y);
var highPos = pos - new float2(0, GetAltitude());
yield return new Renderable(anim.Image, highPos - .5f * anim.Image.size, "effect", (int)pos.Y);
yield return new Renderable(anim.Image, highPos - .5f * anim.Image.size, wr.Palette("effect"), (int)pos.Y);
}
else
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size,
Args.weapon.Underwater ? "shadow" : "effect", (int)pos.Y);
wr.Palette(Args.weapon.Underwater ? "shadow" : "effect"), (int)pos.Y);
}
}

View File

@@ -49,7 +49,7 @@ namespace OpenRA.Mods.RA.Effects
pos -= new PVecInt(0, velocity);
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
font.DrawTextWithContrast(s, Game.viewport.Zoom*(pos.ToFloat2() - Game.viewport.Location) - offset, color, Color.Black,1);
yield break;

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self)
{
history.Tick(self.CenterLocation - new PVecInt(0, move.Altitude) - Combat.GetTurretPosition(self, facing, contrailTurret));
history.Tick(self.CenterLocation - new PVecInt(0, move.Altitude) - (PVecInt)Combat.GetTurretPosition(self, facing, contrailTurret).ToInt2());
}
public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(self); }

View File

@@ -19,24 +19,21 @@ namespace OpenRA.Mods.RA.Effects
{
readonly Animation anim;
readonly float2 pos;
readonly string palette;
readonly string paletteName;
public Corpse(Actor fromActor, string sequence)
public Corpse(World world, float2 pos, string image, string sequence, string paletteName)
{
var rs = fromActor.Trait<RenderSimple>();
palette = rs.Palette(fromActor.Owner);
anim = new Animation(rs.GetImage(fromActor));
anim.PlayThen(sequence,
() => fromActor.World.AddFrameEndTask(w => w.Remove(this)));
pos = fromActor.CenterLocation.ToFloat2();
this.pos = pos;
this.paletteName = paletteName;
anim = new Animation(image);
anim.PlayThen(sequence, () => world.AddFrameEndTask(w => w.Remove(this)));
}
public void Tick( World world ) { anim.Tick(); }
public void Tick(World world) { anim.Tick(); }
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, palette, (int)pos.Y);
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, wr.Palette(paletteName), (int)pos.Y);
}
}
}

View File

@@ -39,11 +39,12 @@ namespace OpenRA.Mods.RA.Effects
anim.Tick();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (a.IsInWorld)
yield return new Renderable(anim.Image,
a.CenterLocation.ToFloat2() - .5f * anim.Image.size + offset, "effect", (int)a.CenterLocation.Y);
a.CenterLocation.ToFloat2() - .5f * anim.Image.size + offset,
wr.Palette("effect"), (int)a.CenterLocation.Y);
}
}
}

View File

@@ -32,11 +32,11 @@ namespace OpenRA.Mods.RA.Effects
public void Tick( World world ) { anim.Tick(); }
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image,
pos.ToFloat2() - .5f * anim.Image.size - new int2(0,altitude),
"effect", (int)pos.Y - altitude);
wr.Palette("effect"), (int)pos.Y - altitude);
}
public Player Owner { get { return null; } }

View File

@@ -15,65 +15,76 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Effects
{
class GpsDotInfo : ITraitInfo, Requires<RenderSimpleInfo>
class GpsDotInfo : ITraitInfo
{
public readonly string String = "Infantry";
public readonly string IndicatorPalettePrefix = "player";
public object Create(ActorInitializer init)
{
return new GpsDot(init, String);
return new GpsDot(init.self, this);
}
}
class GpsDot : IEffect
{
Actor self;
GpsWatcher watcher;
RenderSimple rs;
bool show = false;
GpsDotInfo info;
Animation anim;
public GpsDot(ActorInitializer init, string s)
{
anim = new Animation("gpsdot");
anim.PlayRepeating(s);
GpsWatcher watcher;
HiddenUnderFog huf;
Spy spy;
bool show = false;
public GpsDot(Actor self, GpsDotInfo info)
{
this.self = self;
this.info = info;
anim = new Animation("gpsdot");
anim.PlayRepeating(info.String);
self = init.self;
rs = self.Trait<RenderSimple>();
self.World.AddFrameEndTask(w => w.Add(this));
if(self.World.LocalPlayer != null)
if (self.World.LocalPlayer != null)
watcher = self.World.LocalPlayer.PlayerActor.Trait<GpsWatcher>();
}
bool firstTick = true;
public void Tick(World world)
{
show = false;
if (self.Destroyed)
world.AddFrameEndTask(w => w.Remove(this));
if (world.LocalPlayer == null)
if (world.LocalPlayer == null || !self.IsInWorld || self.Destroyed)
return;
if (
self.IsInWorld
&& (watcher.Granted || watcher.GrantedAllies)
&& !self.Trait<HiddenUnderFog>().IsVisible(self.World.RenderedShroud, self) // WRONG
&& (!self.HasTrait<Cloak>() || !self.Trait<Cloak>().Cloaked)
&& (!self.HasTrait<Spy>() || !self.Trait<Spy>().Disguised)
)
// Can be granted at runtime via a crate, so can't cache
var cloak = self.TraitOrDefault<Cloak>();
if (firstTick)
{
show = true;
huf = self.TraitOrDefault<HiddenUnderFog>();
spy = self.TraitOrDefault<Spy>();
firstTick = false;
}
var hasGps = (watcher != null && (watcher.Granted || watcher.GrantedAllies));
var hasDot = (huf != null && !huf.IsVisible(self.World.RenderedShroud, self)); // WRONG (why?)
var dotHidden = (cloak != null && cloak.Cloaked) || (spy != null && spy.Disguised);
show = hasGps && hasDot && !dotHidden;
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (show && !self.Destroyed)
{
var p = self.CenterLocation;
yield return new Renderable(anim.Image, p.ToFloat2() - 0.5f * anim.Image.size, rs.Palette(self.Owner), p.Y)
.WithScale(1.5f);
}
if (!show || self.Destroyed)
yield break;
var p = self.CenterLocation;
var palette = wr.Palette(info.IndicatorPalettePrefix+self.Owner.InternalName);
yield return new Renderable(anim.Image, p.ToFloat2() - 0.5f * anim.Image.size, palette, p.Y)
.WithScale(1.5f);
}
}
}

View File

@@ -36,9 +36,9 @@ namespace OpenRA.Mods.RA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image,offset, "effect", (int)offset.Y);
yield return new Renderable(anim.Image,offset, wr.Palette("effect"), (int)offset.Y);
}
}
}

View File

@@ -51,10 +51,10 @@ namespace OpenRA.Mods.RA.Effects
anim.Tick();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image,
Args.dest.ToInt2() - new int2(0, altitude) - .5f * anim.Image.size, "effect", Args.dest.Y);
var pos = Args.dest.ToInt2() - new int2(0, altitude) - .5f * anim.Image.size;
yield return new Renderable(anim.Image, pos, wr.Palette("effect"), Args.dest.Y);
}
}
}

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using OpenRA.Effects;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Effects
@@ -31,13 +32,13 @@ namespace OpenRA.Mods.RA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (a.Destroyed) // Tick will clean up
yield break;
foreach (var r in a.Render())
yield return r.WithPalette("invuln");
foreach (var r in a.Render(wr))
yield return r.WithPalette(wr.Palette("invuln"));
}
}
}

View File

@@ -74,11 +74,11 @@ namespace OpenRA.Mods.RA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (explosion != null)
yield return new Renderable(explosion.Image,
args.dest.ToFloat2() - .5f * explosion.Image.size, "effect", (int)args.dest.Y);
yield return new Renderable(explosion.Image, args.dest.ToFloat2() - .5f * explosion.Image.size,
wr.Palette("effect"), (int)args.dest.Y);
if (ticks >= info.BeamDuration)
yield break;

View File

@@ -152,11 +152,11 @@ namespace OpenRA.Mods.RA.Effects
Combat.DoImpacts(Args);
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (Args.firedBy.World.RenderedShroud.IsVisible(PxPosition.ToCPos()))
yield return new Renderable(anim.Image, PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude),
Args.weapon.Underwater ? "shadow" : "effect", PxPosition.Y);
wr.Palette(Args.weapon.Underwater ? "shadow" : "effect"), PxPosition.Y);
if (Trail != null)
Trail.Render(Args.firedBy);

View File

@@ -77,10 +77,10 @@ namespace OpenRA.Mods.RA.Effects
a.Trait.Enable();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image, pos.ToFloat2() - 0.5f * anim.Image.size - new float2(0, altitude),
"effect", (int)pos.Y);
wr.Palette("effect"), (int)pos.Y);
}
}
}

View File

@@ -9,6 +9,7 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Effects;
using OpenRA.Graphics;
using OpenRA.Traits;
@@ -17,8 +18,6 @@ namespace OpenRA.Mods.RA.Effects
{
public class Parachute : IEffect
{
readonly Animation anim;
readonly string palette;
readonly Animation paraAnim;
readonly PPos location;
@@ -28,29 +27,19 @@ namespace OpenRA.Mods.RA.Effects
float altitude;
const float fallRate = .3f;
public Parachute(Player owner, PPos location, int altitude, Actor cargo)
public Parachute(Actor cargo, PPos location, int altitude)
{
this.location = location;
this.altitude = altitude;
this.cargo = cargo;
var rs = cargo.Trait<RenderSimple>();
var image = rs.anim.Name;
palette = rs.Palette(owner);
anim = new Animation(image);
if (anim.HasSequence("idle"))
anim.PlayFetchIndex("idle", () => 0);
else
anim.PlayFetchIndex("stand", () => 0);
anim.Tick();
var pai = cargo.Info.Traits.GetOrDefault<ParachuteAttachmentInfo>();
paraAnim = new Animation(pai != null ? pai.ParachuteSprite : "parach");
paraAnim.PlayThen("open", () => paraAnim.PlayRepeating("idle"));
if (pai != null) offset = pai.Offset;
cargo.Trait<ITeleportable>().SetPxPosition(cargo, location);
}
public void Tick(World world)
@@ -73,12 +62,23 @@ namespace OpenRA.Mods.RA.Effects
});
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
var rc = cargo.Render(wr).Select(a => a.WithPos(a.Pos - new float2(0, altitude))
.WithZOffset(a.ZOffset + (int)altitude));
// Don't render anything if the cargo is invisible (e.g. under fog)
if (!rc.Any())
yield break;
foreach (var c in rc)
{
yield return c.WithPos(location.ToFloat2() - .5f * c.Sprite.size).WithPalette(wr.Palette("shadow")).WithZOffset(0);
yield return c.WithZOffset(2);
}
var pos = location.ToFloat2() - new float2(0, altitude);
yield return new Renderable(anim.Image, location.ToFloat2() - .5f * anim.Image.size, "shadow", 0);
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, palette, 2);
yield return new Renderable(paraAnim.Image, pos - .5f * paraAnim.Image.size + offset, palette, 3);
yield return new Renderable(paraAnim.Image, pos - .5f * paraAnim.Image.size + offset, rc.First().Palette, 3);
}
}
}

View File

@@ -34,11 +34,11 @@ namespace OpenRA.Mods.RA.Effects
anim.Tick();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (!a.Destroyed && (a.World.LocalPlayer == null || a.Owner.Stances[a.Owner.World.LocalPlayer] == Stance.Ally))
yield return new Renderable(anim.Image,
a.CenterLocation.ToFloat2() - .5f * anim.Image.size, "chrome", (int)a.CenterLocation.Y);
yield return new Renderable(anim.Image, a.CenterLocation.ToFloat2() - .5f * anim.Image.size,
wr.Palette("chrome"), (int)a.CenterLocation.Y);
}
}
}

View File

@@ -20,13 +20,15 @@ namespace OpenRA.Mods.RA.Effects
{
readonly Actor building;
readonly RA.RallyPoint rp;
readonly string palettePrefix;
public Animation flag = new Animation("rallypoint");
public Animation circles = new Animation("rallypoint");
public RallyPoint(Actor building)
public RallyPoint(Actor building, string palettePrefix)
{
this.building = building;
rp = building.Trait<RA.RallyPoint>();
this.palettePrefix = palettePrefix;
flag.PlayRepeating("flag");
circles.Play("circles");
}
@@ -46,13 +48,13 @@ namespace OpenRA.Mods.RA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (building.IsInWorld && building.Owner == building.World.LocalPlayer
&& building.World.Selection.Actors.Contains(building))
{
var pos = Traits.Util.CenterOfCell(rp.rallyPoint);
var palette = building.Trait<RenderSimple>().Palette(building.Owner);
var palette = wr.Palette(palettePrefix+building.Owner.InternalName);
yield return new Renderable(circles.Image,
pos.ToFloat2() - .5f * circles.Image.size,

View File

@@ -20,34 +20,35 @@ namespace OpenRA.Mods.RA.Effects
{
Actor building;
Player player;
string palettePrefix;
Animation anim = new Animation("allyrepair");
RepairableBuilding rb;
public RepairIndicator(Actor building, Player player)
public RepairIndicator(Actor building, string palettePrefix, Player player)
{
this.building = building;
this.player = player;
this.palettePrefix = palettePrefix;
rb = building.Trait<RepairableBuilding>();
anim.PlayRepeating("repair");
}
public void Tick(World world)
{
if (!building.IsInWorld ||
building.IsDead() ||
building.Trait<RepairableBuilding>().Repairer == null ||
building.Trait<RepairableBuilding>().Repairer != player)
if (!building.IsInWorld || building.IsDead() ||
rb.Repairer == null || rb.Repairer != player)
world.AddFrameEndTask(w => w.Remove(this));
anim.Tick();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (!building.Destroyed)
{
var palette = building.Trait<RenderSimple>().Palette(player);
yield return new Renderable(anim.Image,
building.CenterLocation.ToFloat2() - .5f * anim.Image.size, palette, (int)building.CenterLocation.Y);
building.CenterLocation.ToFloat2() - .5f * anim.Image.size,
wr.Palette(palettePrefix+player.InternalName), (int)building.CenterLocation.Y);
}
}
}

View File

@@ -40,9 +40,9 @@ namespace OpenRA.Mods.RA.Effects
}
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(doors.Image, pos, "effect", (int)doorOffset.Y);
yield return new Renderable(doors.Image, pos, wr.Palette("effect"), (int)doorOffset.Y);
}
}
}

View File

@@ -33,9 +33,10 @@ namespace OpenRA.Mods.RA.Effects
anim.Tick();
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
yield return new Renderable(anim.Image, pos.ToFloat2() - .5f * anim.Image.size, "effect", (int)pos.Y);
yield return new Renderable(anim.Image, pos.ToFloat2() - .5f * anim.Image.size,
wr.Palette("effect"), (int)pos.Y);
}
}
}

View File

@@ -29,27 +29,35 @@ namespace OpenRA.Mods.RA.Effects
class TeslaZap : IEffect
{
readonly ProjectileArgs Args;
readonly TeslaZapInfo Info;
IEnumerable<Renderable> renderables;
int timeUntilRemove = 2; // # of frames
bool doneDamage = false;
readonly List<Renderable> renderables = new List<Renderable>();
bool initialized = false;
public TeslaZap(TeslaZapInfo info, ProjectileArgs args)
{
Args = args;
var bright = SequenceProvider.GetSequence(info.Image, "bright");
var dim = SequenceProvider.GetSequence(info.Image, "dim");
for( var n = 0; n < info.DimZaps; n++ )
renderables.AddRange(DrawZapWandering(args.src, args.dest, dim));
for( var n = 0; n < info.BrightZaps; n++ )
renderables.AddRange(DrawZapWandering(args.src, args.dest, bright));
Info = info;
}
public void Tick( World world )
public IEnumerable<Renderable> GenerateRenderables(WorldRenderer wr)
{
if( timeUntilRemove <= 0 )
world.AddFrameEndTask( w => w.Remove( this ) );
var bright = SequenceProvider.GetSequence(Info.Image, "bright");
var dim = SequenceProvider.GetSequence(Info.Image, "dim");
for (var n = 0; n < Info.DimZaps; n++)
foreach (var z in DrawZapWandering(wr, Args.src, Args.dest, dim))
yield return z;
for (var n = 0; n < Info.BrightZaps; n++)
foreach (var z in DrawZapWandering(wr, Args.src, Args.dest, bright))
yield return z;
}
public void Tick(World world)
{
if (timeUntilRemove <= 0)
world.AddFrameEndTask(w => w.Remove(this));
--timeUntilRemove;
if (!doneDamage)
@@ -62,9 +70,18 @@ namespace OpenRA.Mods.RA.Effects
}
}
public IEnumerable<Renderable> Render() { return renderables; }
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (!initialized)
{
renderables = GenerateRenderables(wr);
initialized = true;
}
static IEnumerable<Renderable> DrawZapWandering(PPos from, PPos to, Sequence s)
return renderables;
}
static IEnumerable<Renderable> DrawZapWandering(WorldRenderer wr, PPos from, PPos to, Sequence s)
{
var z = float2.Zero; /* hack */
var dist = to - from;
@@ -76,22 +93,22 @@ namespace OpenRA.Mods.RA.Effects
var p1 = from.ToFloat2() + (1 / 3f) * dist.ToFloat2() + Game.CosmeticRandom.Gauss1D(1) * .2f * dist.Length * norm;
var p2 = from.ToFloat2() + (2 / 3f) * dist.ToFloat2() + Game.CosmeticRandom.Gauss1D(1) * .2f * dist.Length * norm;
renderables.AddRange(DrawZap(from.ToFloat2(), p1, s, out p1));
renderables.AddRange(DrawZap(p1, p2, s, out p2));
renderables.AddRange(DrawZap(p2, to.ToFloat2(), s, out z));
renderables.AddRange(DrawZap(wr, from.ToFloat2(), p1, s, out p1));
renderables.AddRange(DrawZap(wr, p1, p2, s, out p2));
renderables.AddRange(DrawZap(wr, p2, to.ToFloat2(), s, out z));
}
else
{
var p1 = from.ToFloat2() + (1 / 2f) * dist.ToFloat2() + Game.CosmeticRandom.Gauss1D(1) * .2f * dist.Length * norm;
renderables.AddRange(DrawZap(from.ToFloat2(), p1, s, out p1));
renderables.AddRange(DrawZap(p1, to.ToFloat2(), s, out z));
renderables.AddRange(DrawZap(wr, from.ToFloat2(), p1, s, out p1));
renderables.AddRange(DrawZap(wr, p1, to.ToFloat2(), s, out z));
}
return renderables;
}
static IEnumerable<Renderable> DrawZap(float2 from, float2 to, Sequence s, out float2 p)
static IEnumerable<Renderable> DrawZap(WorldRenderer wr, float2 from, float2 to, Sequence s, out float2 p)
{
var dist = to - from;
var q = new float2(-dist.Y, dist.X);
@@ -104,7 +121,8 @@ namespace OpenRA.Mods.RA.Effects
var step = steps.Where(t => (to - (z + new float2(t[0],t[1]))).LengthSquared < (to - z).LengthSquared )
.OrderBy(t => Math.Abs(float2.Dot(z + new float2(t[0], t[1]), q) + c)).First();
rs.Add(new Renderable(s.GetSprite(step[4]), z + new float2(step[2], step[3]), "effect", (int)from.Y));
rs.Add(new Renderable(s.GetSprite(step[4]), z + new float2(step[2], step[3]),
wr.Palette("effect"), (int)from.Y));
z += new float2(step[0], step[1]);
if( rs.Count >= 1000 )
break;

View File

@@ -0,0 +1,44 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class FogPaletteInfo : ITraitInfo
{
public readonly string Name = "fog";
public object Create(ActorInitializer init) { return new FogPalette(this); }
}
class FogPalette : IPalette
{
readonly FogPaletteInfo info;
public FogPalette(FogPaletteInfo info) { this.info = info; }
public void InitPalette(WorldRenderer wr)
{
var c = new[] {
Color.Transparent, Color.Green,
Color.Blue, Color.Yellow,
Color.FromArgb(128,0,0,0),
Color.FromArgb(128,0,0,0),
Color.FromArgb(128,0,0,0),
Color.FromArgb(64,0,0,0)
};
wr.AddPalette(info.Name, new Palette(Exts.MakeArray(256, i => (uint)c[i % 8].ToArgb())), false);
}
}
}

View File

@@ -21,20 +21,22 @@ namespace OpenRA.Mods.RA
public readonly int2 SpawnOffset = int2.Zero;
public readonly int Facing = 0;
public object Create( ActorInitializer init ) { return new FreeActor(init.self, this); }
public object Create( ActorInitializer init ) { return new FreeActor(init, this); }
}
public class FreeActor
{
public FreeActor(Actor self, FreeActorInfo info)
public FreeActor(ActorInitializer init, FreeActorInfo info)
{
self.World.AddFrameEndTask(
if (init.Contains<FreeActorInit>() && !init.Get<FreeActorInit>().value) return;
init.self.World.AddFrameEndTask(
w =>
{
var a = w.CreateActor(info.Actor, new TypeDictionary
{
new LocationInit( self.Location + (CVec)info.SpawnOffset ),
new OwnerInit( self.Owner ),
new LocationInit( init.self.Location + (CVec)info.SpawnOffset ),
new OwnerInit( init.self.Owner ),
new FacingInit( info.Facing ),
});
@@ -43,4 +45,13 @@ namespace OpenRA.Mods.RA
});
}
}
public class FreeActorInit : IActorInit<bool>
{
[FieldFromYamlKey]
public readonly bool value = true;
public FreeActorInit() { }
public FreeActorInit(bool init) { value = init; }
public bool Value(World world) { return value; }
}
}

View File

@@ -97,23 +97,23 @@ namespace OpenRA.Mods.RA
return Level > 0 ? Info.SpeedModifier[Level - 1] : 1m;
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> rs)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
if (self.Owner == self.World.LocalPlayer && Level > 0)
return InnerModifyRender(self, rs);
return InnerModifyRender(self, wr, r);
else
return rs;
return r;
}
IEnumerable<Renderable> InnerModifyRender(Actor self, IEnumerable<Renderable> rs)
IEnumerable<Renderable> InnerModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
foreach (var r in rs)
yield return r;
foreach (var rs in r)
yield return rs;
RankAnim.Tick(); // HACK
var bounds = self.Bounds.Value;
yield return new Renderable(RankAnim.Image,
new float2(bounds.Right - 6, bounds.Bottom - 8), "effect", self.CenterLocation.Y);
yield return new Renderable(RankAnim.Image, new float2(bounds.Right - 6, bounds.Bottom - 8),
wr.Palette("effect"), self.CenterLocation.Y);
}
}

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
@@ -32,7 +33,7 @@ namespace OpenRA.Mods.RA
static readonly Renderable[] Nothing = { };
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
return IsVisible(self.Owner.Shroud, self) ? r : Nothing;
}

View File

@@ -24,15 +24,10 @@ namespace OpenRA.Mods.RA
t += .5f;
}
static readonly string[] ExcludePalettes = { "cursor", "chrome", "colorpicker", "terrain" };
public void AdjustPalette(Dictionary<string,Palette> palettes)
{
foreach (var pal in palettes)
{
if (ExcludePalettes.Contains(pal.Key))
continue;
var rotate = (int)t % 18;
if (rotate > 9)
rotate = 18 - rotate;

View File

@@ -81,7 +81,7 @@ namespace OpenRA.Mods.RA
var p = end - start;
var q = new float2(p.Y, -p.X);
q = (start != end) ? (1 / q.Length) * q : new float2(1, 0);
var c = -float2.Dot(q, start.ToFloat2());
var c = -float2.Dot(q, start.ToInt2());
/* return all points such that |ax + by + c| < depth */

View File

@@ -57,6 +57,7 @@ namespace OpenRA.Mods.RA.Missions
Actor sam2;
Actor sam3;
Actor sam4;
Actor[] sams;
Actor tanya;
Actor einstein;
Actor engineer;
@@ -74,8 +75,6 @@ namespace OpenRA.Mods.RA.Missions
Actor parabombPoint1;
Actor parabombPoint2;
Actor sovietRallyPoint;
Actor flamersEntryPoint;
Actor tanksEntryPoint;
Actor townPoint;
Actor sovietTownAttackPoint1;
Actor sovietTownAttackPoint2;
@@ -103,7 +102,7 @@ namespace OpenRA.Mods.RA.Missions
static readonly string[] SovietVehicles1 = { "3tnk" };
static readonly string[] SovietVehicles2 = { "3tnk", "v2rl" };
const int SovietVehiclesUpgradeTicks = 1500 * 4;
const int SovietGroupSize = 20;
const int SovietGroupSize = 5;
const int ReinforcementsTicks = 1500 * 12;
static readonly string[] Reinforcements =
@@ -120,18 +119,11 @@ namespace OpenRA.Mods.RA.Missions
const int ParabombTicks = 750;
const int FlamersTicks = 1500 * 2;
static readonly string[] Flamers = { "e4", "e4", "e4", "e4", "e4" };
const string ApcName = "apc";
const int ParatroopersTicks = 1500 * 5;
static readonly string[] Badger1Passengers = { "e1", "e1", "e1", "e2", "3tnk" };
static readonly string[] Badger2Passengers = { "e1", "e1", "e1", "e2", "e2" };
static readonly string[] Badger3Passengers = { "e1", "e1", "e1", "e2", "e2" };
const int TanksTicks = 1500 * 11;
static readonly string[] Tanks = { "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk" };
const string SignalFlareName = "flare";
const string YakName = "yak";
@@ -180,12 +172,6 @@ namespace OpenRA.Mods.RA.Missions
if (allies1 != allies2)
{
if (world.FrameNumber == TanksTicks)
RushSovietUnits();
if (world.FrameNumber == FlamersTicks)
RushSovietFlamers();
if (yak == null || (yak != null && !yak.IsDead() && (yak.GetCurrentActivity() is FlyCircle || yak.IsIdle)))
{
var alliedUnitsNearYakPoint = world.FindAliveCombatantActorsInCircle(yakAttackPoint.CenterLocation, 10)
@@ -218,22 +204,19 @@ namespace OpenRA.Mods.RA.Missions
}
if (objectives[DestroySamSitesID].Status == ObjectiveStatus.InProgress)
{
if ((sam1.Destroyed || sam1.Owner != soviets)
&& (sam2.Destroyed || sam2.Owner != soviets)
&& (sam3.Destroyed || sam3.Owner != soviets)
&& (sam4.Destroyed || sam4.Owner != soviets))
if (sams.All(s => s.IsDead() || s.Owner != soviets))
{
objectives[DestroySamSitesID].Status = ObjectiveStatus.Completed;
objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
SpawnSignalFlare();
world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZ.Location) });
Sound.Play("flaren1.aud");
ExtractEinsteinAtLZ();
}
}
if (objectives[ExtractEinsteinID].Status == ObjectiveStatus.InProgress && einsteinChinook != null)
{
if (einsteinChinook.Destroyed)
if (einsteinChinook.IsDead())
{
objectives[ExtractEinsteinID].Status = ObjectiveStatus.Failed;
objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed;
@@ -253,22 +236,19 @@ namespace OpenRA.Mods.RA.Missions
}
}
if (tanya.Destroyed)
if (tanya.IsDead())
MissionFailed("Tanya was killed.");
else if (einstein.Destroyed)
else if (einstein.IsDead())
MissionFailed("Einstein was killed.");
world.AddFrameEndTask(w =>
else if (!world.Actors.Any(a => (a.Owner == allies || a.Owner == allies2) && !a.IsDead()
&& (a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>()))
{
if (!world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20)
.Any(a => a.HasTrait<Building>() && !a.HasTrait<Wall>() && (a.Owner == allies || a.Owner == allies2)))
{
objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Allied reinforcements have been defeated.");
}
});
objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Allied reinforcements have been defeated.");
}
}
void UpdateDeaths()
@@ -308,10 +288,10 @@ namespace OpenRA.Mods.RA.Missions
void BuildSovietUnits()
{
if (!sovietBarracks.Destroyed)
if (!sovietBarracks.IsDead())
BuildSovietUnit(InfantryQueueName, SovietInfantry.Random(world.SharedRandom));
if (!sovietWarFactory.Destroyed)
if (!sovietWarFactory.IsDead())
{
var vehicles = world.FrameNumber >= SovietVehiclesUpgradeTicks ? SovietVehicles2 : SovietVehicles1;
BuildSovietUnit(VehicleQueueName, vehicles.Random(world.SharedRandom));
@@ -320,44 +300,39 @@ namespace OpenRA.Mods.RA.Missions
void ManageSovietUnits()
{
var idleSovietUnitsAtRP = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterLocation, 3)
.Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait<IMove>());
if (idleSovietUnitsAtRP.Count() >= SovietGroupSize)
var units = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterLocation, 10)
.Where(u => u.IsIdle && u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values);
if (units.Count() >= SovietGroupSize)
{
var firstUnit = idleSovietUnitsAtRP.FirstOrDefault();
if (firstUnit != null)
foreach (var unit in units)
MissionUtils.AttackNearestLandActor(true, unit, allies2);
}
var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.IsIdle
&& u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values)
.Except(units);
foreach (var unit in scatteredUnits)
MissionUtils.AttackNearestLandActor(true, unit, allies2);
}
void SetupAlliedBase()
{
foreach (var actor in world.Actors.Where(a => a.Owner == allies && a != allies.PlayerActor))
{
actor.ChangeOwner(allies2);
if (actor.Info.Name == "pbox")
{
var closestAlliedBuilding = ClosestAlliedBuilding(firstUnit, 40);
if (closestAlliedBuilding != null)
foreach (var unit in idleSovietUnitsAtRP)
{
unit.Trait<Mobile>().Nudge(unit, unit, true);
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3)));
}
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s, world.CreateActor(false, "e1", allies2, null, null))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
}
if (actor.Info.Name == "proc")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
foreach (var c in actor.TraitsImplementing<INotifyCapture>())
c.OnCapture(actor, actor, allies, allies2);
}
var idleSovietUnits = world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20)
.Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait<IMove>());
foreach (var unit in idleSovietUnits)
{
var closestAlliedBuilding = ClosestAlliedBuilding(unit, 40);
if (closestAlliedBuilding != null)
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3)));
}
}
Actor ClosestAlliedBuilding(Actor actor, int range)
{
return MissionUtils.ClosestPlayerBuilding(world, allies2, actor.CenterLocation, range);
}
IEnumerable<Actor> ClosestAlliedBuildings(Actor actor, int range)
{
return MissionUtils.ClosestPlayerBuildings(world, allies2, actor.CenterLocation, range);
}
void InitializeSovietFactories()
@@ -365,7 +340,7 @@ namespace OpenRA.Mods.RA.Missions
var sbrp = sovietBarracks.Trait<RallyPoint>();
var swrp = sovietWarFactory.Trait<RallyPoint>();
sbrp.rallyPoint = swrp.rallyPoint = sovietRallyPoint.Location;
sbrp.nearEnough = swrp.nearEnough = 3;
sbrp.nearEnough = swrp.nearEnough = 6;
sovietBarracks.Trait<PrimaryBuilding>().SetPrimaryProducer(sovietBarracks, true);
sovietWarFactory.Trait<PrimaryBuilding>().SetPrimaryProducer(sovietWarFactory, true);
}
@@ -378,11 +353,6 @@ namespace OpenRA.Mods.RA.Missions
queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, unit, 1));
}
void SpawnSignalFlare()
{
world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZ.Location) });
}
void StartReinforcementsTimer()
{
Sound.Play("timergo1.aud");
@@ -409,38 +379,6 @@ namespace OpenRA.Mods.RA.Missions
.QueueActivity(new Move.Move(allies2BasePoint.Location));
}
void RushSovietUnits()
{
var closestAlliedBuildings = ClosestAlliedBuildings(badgerDropPoint1, 40);
if (!closestAlliedBuildings.Any()) return;
foreach (var tank in Tanks)
{
var unit = world.CreateActor(tank, new TypeDictionary
{
new OwnerInit(soviets),
new LocationInit(tanksEntryPoint.Location)
});
foreach (var building in closestAlliedBuildings)
unit.QueueActivity(new Attack(Target.FromActor(building), 3));
}
}
void RushSovietFlamers()
{
var closestAlliedBuilding = ClosestAlliedBuilding(badgerDropPoint1, 40);
if (closestAlliedBuilding == null) return;
var apc = world.CreateActor(ApcName, new TypeDictionary { new OwnerInit(soviets), new LocationInit(flamersEntryPoint.Location) });
foreach (var flamer in Flamers)
{
var unit = world.CreateActor(false, flamer, new TypeDictionary { new OwnerInit(soviets) });
apc.Trait<Cargo>().Load(apc, unit);
}
apc.QueueActivity(new MoveAdjacentTo(Target.FromActor(closestAlliedBuilding)));
apc.QueueActivity(new UnloadCargo(true));
}
void ExtractEinsteinAtLZ()
{
einsteinChinook = MissionUtils.ExtractUnitWithChinook(
@@ -461,7 +399,7 @@ namespace OpenRA.Mods.RA.Missions
void TransferTownUnitsToAllies()
{
foreach (var unit in world.FindAliveNonCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange)
.Where(a => a.HasTrait<IMove>()))
.Where(a => a.HasTrait<Mobile>()))
unit.ChangeOwner(allies1);
}
@@ -492,11 +430,14 @@ namespace OpenRA.Mods.RA.Missions
allies = w.Players.Single(p => p.InternalName == "Allies");
soviets = w.Players.Single(p => p.InternalName == "Soviets");
soviets.PlayerActor.Trait<PlayerResources>().Cash = 1000;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
sam1 = actors["SAM1"];
sam2 = actors["SAM2"];
sam3 = actors["SAM3"];
sam4 = actors["SAM4"];
sams = new[] { sam1, sam2, sam3, sam4 };
tanya = actors["Tanya"];
einstein = actors["Einstein"];
engineer = actors["Engineer"];
@@ -515,17 +456,15 @@ namespace OpenRA.Mods.RA.Missions
sovietBarracks = actors["SovietBarracks"];
sovietWarFactory = actors["SovietWarFactory"];
sovietRallyPoint = actors["SovietRallyPoint"];
flamersEntryPoint = actors["FlamersEntryPoint"];
tanksEntryPoint = actors["TanksEntryPoint"];
townPoint = actors["TownPoint"];
sovietTownAttackPoint1 = actors["SovietTownAttackPoint1"];
sovietTownAttackPoint2 = actors["SovietTownAttackPoint2"];
yakEntryPoint = actors["YakEntryPoint"];
yakAttackPoint = actors["YakAttackPoint"];
SetupAlliedBase(actors);
SetupAlliedBase();
var shroud = w.WorldActor.Trait<Shroud>();
var shroud = allies1.Shroud;
shroud.Explore(w, sam1.Location, 2);
shroud.Explore(w, sam2.Location, 2);
shroud.Explore(w, sam3.Location, 2);
@@ -539,20 +478,5 @@ namespace OpenRA.Mods.RA.Missions
MissionUtils.PlayMissionMusic();
}
void SetupAlliedBase(Dictionary<string, Actor> actors)
{
world.AddFrameEndTask(w =>
{
foreach (var actor in actors.Where(a => a.Value.Owner == allies))
actor.Value.ChangeOwner(allies2);
world.CreateActor("proc", new TypeDictionary
{
new LocationInit(actors["Allies2ProcPoint"].Location),
new OwnerInit(allies2)
});
});
}
}
}

View File

@@ -10,12 +10,14 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
@@ -488,19 +490,21 @@ namespace OpenRA.Mods.RA.Missions
public override object Create(ActorInitializer init) { return new Allies04RenderHijacked(init.self, this); }
}
class Allies04RenderHijacked : RenderUnit, IRenderModifier
class Allies04RenderHijacked : RenderUnit
{
Allies04Hijackable hijackable;
Allies04RenderHijackedInfo info;
public Allies04RenderHijacked(Actor self, Allies04RenderHijackedInfo info)
: base(self)
{
this.info = info;
hijackable = self.Trait<Allies04Hijackable>();
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
protected override string PaletteName(Actor self)
{
return r.Select(a => a.WithPalette(Palette(hijackable.OldOwner)));
return info.Palette ?? info.PlayerPalette + hijackable.OldOwner.InternalName;
}
}
@@ -533,4 +537,27 @@ namespace OpenRA.Mods.RA.Missions
}
class Allies04TransformOnLabInfiltrate { }
class Allies04HazyPaletteEffectInfo : TraitInfo<Allies04HazyPaletteEffect> { }
class Allies04HazyPaletteEffect : IPaletteModifier
{
static readonly string[] ExcludePalettes = { "cursor", "chrome", "colorpicker", "fog", "shroud" };
public void AdjustPalette(Dictionary<string, Palette> palettes)
{
foreach (var pal in palettes)
{
if (ExcludePalettes.Contains(pal.Key))
continue;
for (var x = 0; x < 256; x++)
{
var from = pal.Value.GetColor(x);
var to = Color.FromArgb(from.A, Color.FromKnownColor(KnownColor.DarkOrange));
pal.Value.SetColor(x, Exts.ColorLerp(0.15f, from, to));
}
}
}
}
}

View File

@@ -109,30 +109,6 @@ namespace OpenRA.Mods.RA.Missions
return units.Any() && units.All(a => a.Owner == player);
}
public static Actor ClosestPlayerUnit(World world, Player player, PPos location, int range)
{
return ClosestPlayerUnits(world, player, location, range).FirstOrDefault();
}
public static IEnumerable<Actor> ClosestPlayerUnits(World world, Player player, PPos location, int range)
{
return world.FindAliveCombatantActorsInCircle(location, range)
.Where(a => a.Owner == player && a.HasTrait<IMove>())
.OrderBy(a => (location - a.CenterLocation).LengthSquared);
}
public static Actor ClosestPlayerBuilding(World world, Player player, PPos location, int range)
{
return ClosestPlayerBuildings(world, player, location, range).FirstOrDefault();
}
public static IEnumerable<Actor> ClosestPlayerBuildings(World world, Player player, PPos location, int range)
{
return world.FindAliveCombatantActorsInCircle(location, range)
.Where(a => a.Owner == player && a.HasTrait<Building>() && !a.HasTrait<Wall>())
.OrderBy(a => (location - a.CenterLocation).LengthSquared);
}
public static IEnumerable<ProductionQueue> FindQueues(World world, Player player, string category)
{
return world.ActorsWithTrait<ProductionQueue>()
@@ -231,7 +207,7 @@ namespace OpenRA.Mods.RA.Missions
public static void AttackNearestLandActor(bool queued, Actor self, Player enemyPlayer)
{
var enemies = self.World.Actors.Where(u => u.AppearsHostileTo(self) && u.Owner == enemyPlayer
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()) && u.IsInWorld && !u.IsDead());
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || (u.HasTrait<Mobile>() && !u.HasTrait<Aircraft>())) && u.IsInWorld && !u.IsDead());
var enemy = enemies.OrderBy(u => (self.CenterLocation - u.CenterLocation).LengthSquared).FirstOrDefault();
if (enemy != null)

View File

@@ -8,13 +8,13 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using System;
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.Mods.RA.Missions
{
@@ -137,11 +137,10 @@ namespace OpenRA.Mods.RA.Missions
if (baseTransferredTick == -1)
{
var actorsInBase = world.FindUnits(alliedBaseTopLeft.CenterLocation, alliedBaseBottomRight.CenterLocation).Where(a => !a.IsDead() && a.IsInWorld);
var actorsInBase = world.FindUnits(alliedBaseTopLeft.CenterLocation, alliedBaseBottomRight.CenterLocation).Where(a => a != a.Owner.PlayerActor);
if (actorsInBase.Any(a => a.Owner == greece))
{
foreach (var actor in actorsInBase)
TransferActorToAllies(actor);
SetupAlliedBase(actorsInBase);
baseTransferredTick = world.FrameNumber;
objectives[FindOutpostID].Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
@@ -234,20 +233,22 @@ namespace OpenRA.Mods.RA.Missions
}
}
void TransferActorToAllies(Actor actor)
void SetupAlliedBase(IEnumerable<Actor> actors)
{
// hack hack hack
actor.ChangeOwner(greece);
if (actor.Info.Name == "pbox")
foreach (var actor in actors)
{
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s, world.CreateActor(false, "e1", greece, null, null))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
// hack hack hack
actor.ChangeOwner(greece);
if (actor.Info.Name == "pbox")
{
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s, world.CreateActor(false, "e1", greece, null, null))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
}
else if (actor.Info.Name == "proc")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
foreach (var c in actor.TraitsImplementing<INotifyCapture>())
c.OnCapture(actor, actor, neutral, greece);
}
else if (actor.Info.Name == "proc.nofreeactor")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
var building = actor.TraitOrDefault<Building>();
if (building != null)
building.OnCapture(actor, actor, neutral, greece);
}
void EvacuateCivilians()

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.RA
}
Renderable[] cache = { };
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
if (IsVisible(self.World.RenderedShroud, self))
cache = r.ToArray();

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.RA
}
static Renderable[] Nothing = { };
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
return IsVisible(self.World.RenderedShroud, self) ? r : Nothing;
}

View File

@@ -32,8 +32,6 @@ namespace OpenRA.Mods.RA
if (remainingFrames > 0)
remainingFrames--;
}
static List<string> excludePalettes = new List<string>{ "cursor", "chrome", "colorpicker", "shroud", "fog" };
public void AdjustPalette(Dictionary<string,Palette> palettes)
{
@@ -44,9 +42,6 @@ namespace OpenRA.Mods.RA
foreach (var pal in palettes)
{
if (excludePalettes.Contains(pal.Key))
continue;
for (var x = 0; x < 256; x++)
{
var orig = pal.Value.GetColor(x);

View File

@@ -169,7 +169,6 @@
<Compile Include="ChronoshiftPaletteEffect.cs" />
<Compile Include="Chronoshiftable.cs" />
<Compile Include="Cloak.cs" />
<Compile Include="ColorPickerPaletteModifier.cs" />
<Compile Include="Combat.cs" />
<Compile Include="ConquestVictoryConditions.cs" />
<Compile Include="ContainsCrate.cs" />
@@ -408,6 +407,8 @@
<Compile Include="RenderShroudCircle.cs" />
<Compile Include="Widgets\Logic\CheatsLogic.cs" />
<Compile Include="CloakPaletteEffect.cs" />
<Compile Include="Widgets\ColorPreviewManagerWidget.cs" />
<Compile Include="FogPalette.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -21,9 +21,10 @@ namespace OpenRA.Mods.RA.Orders
{
readonly Actor Producer;
readonly string Building;
readonly IEnumerable<Renderable> Preview;
readonly BuildingInfo BuildingInfo;
IEnumerable<Renderable> preview;
Sprite buildOk, buildBlocked;
bool initialized = false;
public PlaceBuildingOrderGenerator(Actor producer, string name)
{
@@ -31,9 +32,6 @@ namespace OpenRA.Mods.RA.Orders
Building = name;
BuildingInfo = Rules.Info[Building].Traits.Get<BuildingInfo>();
Preview = Rules.Info[Building].Traits.Get<RenderBuildingInfo>()
.RenderPreview(Rules.Info[Building], producer.Owner);
buildOk = SequenceProvider.GetSequence("overlay", "build-valid").GetSprite(0);
buildBlocked = SequenceProvider.GetSequence("overlay", "build-invalid").GetSprite(0);
}
@@ -43,7 +41,7 @@ namespace OpenRA.Mods.RA.Orders
if (mi.Button == MouseButton.Right)
world.CancelInputMode();
var ret = InnerOrder( world, xy, mi ).ToList();
var ret = InnerOrder(world, xy, mi).ToList();
if (ret.Count > 0)
world.CancelInputMode();
@@ -54,26 +52,26 @@ namespace OpenRA.Mods.RA.Orders
{
if (mi.Button == MouseButton.Left)
{
var topLeft = xy - FootprintUtils.AdjustForBuildingSize( BuildingInfo );
if (!world.CanPlaceBuilding( Building, BuildingInfo, topLeft, null)
var topLeft = xy - FootprintUtils.AdjustForBuildingSize(BuildingInfo);
if (!world.CanPlaceBuilding(Building, BuildingInfo, topLeft, null)
|| !BuildingInfo.IsCloseEnoughToBase(world, Producer.Owner, Building, topLeft))
{
Sound.PlayNotification(Producer.Owner, "Speech", "BuildingCannotPlaceAudio", Producer.Owner.Country.Race);
yield break;
}
var isLineBuild = Rules.Info[ Building ].Traits.Contains<LineBuildInfo>();
var isLineBuild = Rules.Info[Building].Traits.Contains<LineBuildInfo>();
yield return new Order(isLineBuild ? "LineBuild" : "PlaceBuilding",
Producer.Owner.PlayerActor, false) { TargetLocation = topLeft, TargetString = Building };
}
}
public void Tick( World world ) {}
public void RenderAfterWorld( WorldRenderer wr, World world ) {}
public void RenderBeforeWorld( WorldRenderer wr, World world )
public void Tick(World world) {}
public void RenderAfterWorld(WorldRenderer wr, World world) {}
public void RenderBeforeWorld(WorldRenderer wr, World world)
{
var position = Game.viewport.ViewToWorld(Viewport.LastMousePos);
var topLeft = position - FootprintUtils.AdjustForBuildingSize( BuildingInfo );
var topLeft = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo);
var actorInfo = Rules.Info[Building];
foreach (var dec in actorInfo.Traits.WithInterface<IPlaceBuildingDecoration>())
@@ -84,24 +82,34 @@ namespace OpenRA.Mods.RA.Orders
// Assumes a 1x1 footprint; weird things will happen for other footprints
if (Rules.Info[Building].Traits.Contains<LineBuildInfo>())
{
foreach( var t in BuildingUtils.GetLineBuildCells( world, topLeft, Building, BuildingInfo ) )
cells.Add( t, BuildingInfo.IsCloseEnoughToBase( world, world.LocalPlayer, Building, t ) );
foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, Building, BuildingInfo))
cells.Add(t, BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, t));
}
else
{
foreach (var r in Preview)
if (!initialized)
{
var rbi = Rules.Info[Building].Traits.Get<RenderBuildingInfo>();
var palette = rbi.Palette ?? (Producer.Owner != null ?
rbi.PlayerPalette + Producer.Owner.InternalName : null);
preview = rbi.RenderPreview(Rules.Info[Building], wr.Palette(palette));
initialized = true;
}
foreach (var r in preview)
r.Sprite.DrawAt(topLeft.ToPPos().ToFloat2() + r.Pos,
wr.GetPaletteIndex(r.Palette),
r.Palette.Index,
r.Scale*r.Sprite.size);
var res = world.WorldActor.Trait<ResourceLayer>();
var isCloseEnough = BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, topLeft);
foreach (var t in FootprintUtils.Tiles(Building, BuildingInfo, topLeft))
cells.Add( t, isCloseEnough && world.IsCellBuildable(t, BuildingInfo) && res.GetResource(t) == null );
cells.Add(t, isCloseEnough && world.IsCellBuildable(t, BuildingInfo) && res.GetResource(t) == null);
}
foreach( var c in cells )
( c.Value ? buildOk : buildBlocked ).DrawAt(wr, c.Key.ToPPos().ToFloat2(), "terrain" );
foreach (var c in cells)
(c.Value ? buildOk : buildBlocked).DrawAt(wr, c.Key.ToPPos().ToFloat2(), "terrain");
}
public string GetCursor(World world, CPos xy, MouseInput mi) { return "default"; }

View File

@@ -17,6 +17,7 @@ namespace OpenRA.Mods.RA
{
public readonly string Name = null;
public readonly int[] ShadowIndex = { };
public readonly bool AllowModifiers = true;
public object Create(ActorInitializer init) { return new PaletteFromCurrentTileset(init.world, this); }
}
@@ -32,9 +33,9 @@ namespace OpenRA.Mods.RA
this.info = info;
}
public void InitPalette( OpenRA.Graphics.WorldRenderer wr )
public void InitPalette(OpenRA.Graphics.WorldRenderer wr)
{
wr.AddPalette( info.Name, new Palette( FileSystem.Open( world.TileSet.Palette ), info.ShadowIndex ) );
wr.AddPalette(info.Name, new Palette(FileSystem.Open(world.TileSet.Palette), info.ShadowIndex), info.AllowModifiers);
}
}
}

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA
public readonly string Tileset = null;
public readonly string Filename = null;
public readonly int[] ShadowIndex = { };
public readonly bool AllowModifiers = true;
public object Create(ActorInitializer init) { return new PaletteFromFile(init.world, this); }
}
@@ -34,10 +35,10 @@ namespace OpenRA.Mods.RA
this.info = info;
}
public void InitPalette( WorldRenderer wr )
public void InitPalette(WorldRenderer wr)
{
if( info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant() )
wr.AddPalette( info.Name, new Palette( FileSystem.Open( info.Filename ), info.ShadowIndex ) );
if (info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant())
wr.AddPalette(info.Name, new Palette(FileSystem.Open(info.Filename), info.ShadowIndex), info.AllowModifiers);
}
}
}

View File

@@ -23,6 +23,7 @@ namespace OpenRA.Mods.RA
public readonly int G = 0;
public readonly int B = 0;
public readonly int A = 255;
public readonly bool AllowModifiers = true;
public object Create(ActorInitializer init) { return new PaletteFromRGBA(init.world, this); }
}
@@ -37,28 +38,14 @@ namespace OpenRA.Mods.RA
this.info = info;
}
public void InitPalette( WorldRenderer wr )
public void InitPalette(WorldRenderer wr)
{
if (info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant())
{
// TODO: This shouldn't rely on a base palette
var pal = wr.GetPalette("terrain");
wr.AddPalette(info.Name, new Palette(pal, new SingleColorRemap(Color.FromArgb(info.A, info.R, info.G, info.B))));
}
}
}
// Enable palette only for a specific tileset
if (info.Tileset != null && info.Tileset.ToLowerInvariant() != world.Map.Tileset.ToLowerInvariant())
return;
class SingleColorRemap : IPaletteRemap
{
Color c;
public SingleColorRemap(Color c)
{
this.c = c;
}
public Color GetRemappedColor(Color original, int index)
{
return original.A > 0 ? c : original;
var c = (uint)((info.A << 24) | (info.R << 16) | (info.G << 8) | info.B);
wr.AddPalette(info.Name, new Palette(Exts.MakeArray(256, i => (i == 0) ? 0 : c)), info.AllowModifiers);
}
}
}

View File

@@ -55,11 +55,9 @@ namespace OpenRA.Mods.RA
var aircraft = self.Trait<IMove>();
self.World.AddFrameEndTask(w => w.Add(
new Parachute(
self.Owner,
new Parachute(a,
Util.CenterOfCell(self.CenterLocation.ToCPos()),
aircraft.Altitude, a
)
aircraft.Altitude)
));
Sound.Play(info.ChuteSound, self.CenterLocation);

View File

@@ -17,6 +17,7 @@ namespace OpenRA.Mods.RA
{
public readonly string Name = null;
public readonly int[] ShadowIndex = { };
public readonly bool AllowModifiers = true;
public object Create(ActorInitializer init) { return new PlayerPaletteFromCurrentTileset(init.world, this); }
}
@@ -35,7 +36,7 @@ namespace OpenRA.Mods.RA
public void InitPalette (OpenRA.Graphics.WorldRenderer wr)
{
string Filename = world.TileSet.PlayerPalette == null ? world.TileSet.Palette : world.TileSet.PlayerPalette;
wr.AddPalette(info.Name, new Palette(FileSystem.Open(Filename), info.ShadowIndex));
wr.AddPalette(info.Name, new Palette(FileSystem.Open(Filename), info.ShadowIndex), info.AllowModifiers);
}
}
}

View File

@@ -14,11 +14,12 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class RallyPointInfo : ITraitInfo, Requires<RenderSimpleInfo>
public class RallyPointInfo : ITraitInfo
{
public readonly int[] RallyPoint = { 1, 3 };
public readonly string IndicatorPalettePrefix = "player";
public object Create(ActorInitializer init) { return new RallyPoint(init.self); }
public object Create(ActorInitializer init) { return new RallyPoint(init.self, this); }
}
public class RallyPoint : IIssueOrder, IResolveOrder, ISync
@@ -26,11 +27,10 @@ namespace OpenRA.Mods.RA
[Sync] public CPos rallyPoint;
public int nearEnough = 1;
public RallyPoint(Actor self)
public RallyPoint(Actor self, RallyPointInfo info)
{
var info = self.Info.Traits.Get<RallyPointInfo>();
rallyPoint = self.Location + new CVec(info.RallyPoint[0], info.RallyPoint[1]);
self.World.AddFrameEndTask(w => w.Add(new Effects.RallyPoint(self)));
self.World.AddFrameEndTask(w => w.Add(new Effects.RallyPoint(self, info.IndicatorPalettePrefix)));
}
public IEnumerable<IOrderTargeter> Orders

View File

@@ -25,9 +25,9 @@ namespace OpenRA.Mods.RA.Render
public readonly float2 Origin = float2.Zero;
public override object Create(ActorInitializer init) { return new RenderBuilding(init, this);}
public override IEnumerable<Renderable> RenderPreview(ActorInfo building, Player owner)
public override IEnumerable<Renderable> RenderPreview(ActorInfo building, PaletteReference pr)
{
return base.RenderPreview(building, owner)
return base.RenderPreview(building, pr)
.Select(a => a.WithPos(a.Pos + building.Traits.Get<RenderBuildingInfo>().Origin));
}
}
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA.Render
self.QueueActivity(new CallFunc(() => Complete(self)));
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
{
var disabled = self.IsDisabled();
foreach (var a in r)
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.RA.Render
var ret = a.WithPos(a.Pos - Info.Origin);
yield return ret;
if (disabled)
yield return ret.WithPalette("disabled").WithZOffset(1);
yield return ret.WithPalette(wr.Palette("disabled")).WithZOffset(1);
}
}

Some files were not shown because too many files have changed in this diff Show More