1
AUTHORS
1
AUTHORS
@@ -37,6 +37,7 @@ Also thanks to:
|
||||
* Raymond Martineau (mart0258)
|
||||
* Riderr3
|
||||
* Tim Mylemans (gecko)
|
||||
* Tirili
|
||||
|
||||
Past developers included:
|
||||
* Paul Chote (pchote)
|
||||
|
||||
@@ -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))
|
||||
|
||||
4
OpenRA.FileFormats/Thirdparty/Random.cs
vendored
4
OpenRA.FileFormats/Thirdparty/Random.cs
vendored
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++ )
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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 },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 { }
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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++ )
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; } }
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
44
OpenRA.Mods.RA/FogPalette.cs
Normal file
44
OpenRA.Mods.RA/FogPalette.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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"; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user