Compare commits

...

60 Commits

Author SHA1 Message Date
Chris Forbes
a3c0448e15 fix broken mac packaging script 2010-09-27 21:44:23 +13:00
Bob
699b4b1154 add IHasLocation 2010-09-26 18:17:23 +12:00
Bob
911db3feb1 remove setters on Mobile.{from,to}Cell. use SetLocation instead 2010-09-26 16:46:22 +12:00
Paul Chote
c790db8e84 Fix and bulletproof osx packaging script; cleanup some obsolete .gitignore entries 2010-09-26 10:18:22 +13:00
Bob
d6dd392028 use Invariant culture for float parsing (workaround a mono bug) 2010-09-26 09:11:26 +12:00
Bob
636b2a8ea7 fix Direct Connect window 2010-09-25 19:26:02 +12:00
Chris Forbes
959d3f8bd7 fix crash in giving a harv DeliverOre order after its proc has died, but it hasnt noticed yet 2010-09-25 07:34:51 +12:00
Matthew
193cb929f1 Fixing error with Windows package script launching 2010-09-24 22:12:26 +12:00
Chris Forbes
f93e270fe4 reduce v2 range and damage slightly 2010-09-24 21:49:26 +12:00
Chris Forbes
f19953c39a nerf ftrk heavily vs most ground, and reduce hp from 300 to 120 2010-09-24 21:44:57 +12:00
Matthew
59d5ce1bc8 +x permissions for checkout-and-build.sh 2010-09-24 20:42:29 +12:00
Matthew
43cf7cd074 Yet another packaging script. 2010-09-24 20:42:26 +12:00
Chris Forbes
aba76f4b50 don't look up resource type every cell for ore, too 2010-09-24 20:40:56 +12:00
Bob
8021fc3b20 Deduplicate shroud rendering code 2010-09-24 18:11:11 +12:00
Bob
7bf4cb85fa fix perf in ShroudRenderer 2010-09-24 18:11:08 +12:00
Bob
6dd03bb339 bugfix in ResourceLayer 2010-09-24 18:11:06 +12:00
Bob
14e517cab5 Autoflush renderer. Sprite.DrawAt convenience function. 2010-09-24 18:11:03 +12:00
Bob
cdcfeb6276 render perf improvement: BufferSubData, and don't use the same buffer back-to-back 2010-09-24 18:11:00 +12:00
Matthew
c77c63a380 Fix #130.
Windows installer now checks version of OpenAL32.dll and downloads and updates if necessary.
2010-09-24 16:40:55 +12:00
Matthew
9921fe8fad Linux package parallelisation. 2010-09-24 16:40:55 +12:00
Matthew
f848c5d7d4 Parallel building of packages. 2010-09-24 16:40:55 +12:00
Matthew
62c47e3b12 Reordered packaging platforms due to popular demand. 2010-09-24 16:40:55 +12:00
Matthew
094986d066 Tag prefixes change upload location for packages. 2010-09-24 16:40:55 +12:00
Chris Forbes
d87e02ab41 more tweaks, make DD a detector again (wtf?) 2010-09-23 22:23:39 +12:00
Chris Forbes
3f415a8fdf tweak torps more 2010-09-23 22:09:56 +12:00
Chris Forbes
846371cf3e homing torps, bubble trail 2010-09-23 22:09:56 +12:00
Chris Forbes
45c77e64ee fix various desyncs when using cheats 2010-09-23 22:09:55 +12:00
Bob
66493031c8 fix crash with idle units and pathdebug 2010-09-23 21:06:44 +12:00
Bob
384b26db60 fix fieldloader bug caused by foreach language-bug 2010-09-23 17:24:06 +12:00
Bob
d66dbeb312 removing unused stuff from TraitsInterfaces 2010-09-23 15:43:34 +12:00
Chris Forbes
ba9611f544 un-FP Building.cs power stuff 2010-09-22 21:43:04 +12:00
Chris Forbes
b6e56560d4 fix a crash in RepairIndicator with a dead building 2010-09-22 20:48:45 +12:00
Chris Forbes
1f047d439f back out editor icon hack -- it breaks the packaged editor on windows 2010-09-22 19:26:09 +12:00
Chris Forbes
5233ae4770 remove spam from Util.GetFacing 2010-09-22 19:21:22 +12:00
Chris Forbes
562e07264a remove lots of debug spam 2010-09-22 19:19:18 +12:00
Chris Forbes
4dab4ed73f reenable crates 2010-09-22 19:15:45 +12:00
Chris Forbes
a97ddffa53 fix cnc movement (argh) 2010-09-22 19:00:07 +12:00
Bob
8e589e3c16 fix infantry anims 2010-09-22 13:32:58 +12:00
Bob
96f72ce842 new map in ra_perf 2010-09-22 13:08:02 +12:00
Bob
d8de477edb fix IdleAnimation. add IsAttacking to AttackBase 2010-09-22 12:21:49 +12:00
Bob
694fb6831a fix target line on Move that has not yet calculated path 2010-09-22 12:03:45 +12:00
Bob
c16a515224 make more activities cancelable. remove many uses of CurrentActivity is T 2010-09-22 11:53:58 +12:00
Bob
e2eae7973b removing warning 2010-09-22 11:18:47 +12:00
Bob
9e3c938706 removing cancelable from Move. remove unnecessary qualified names from Production 2010-09-22 10:46:54 +12:00
Bob
ef665df2e9 refactor activity queueing 2010-09-22 10:13:13 +12:00
Bob
271a3eea8d fix harv 2010-09-22 08:49:56 +12:00
Bob
2f6315b816 make the pathfinder use integers 2010-09-22 08:04:52 +12:00
Bob
ac8d408ba7 allow queuing non-buildings while the queue is ready 2010-09-22 08:02:20 +12:00
Bob
0fdd49c96a MovePart becomes an Activity 2010-09-22 08:02:17 +12:00
Bob
e390cf8ab0 fix real-ra map importer when map isn't in game root 2010-09-22 08:02:15 +12:00
Bob
64d700cd70 make c&c work too 2010-09-22 08:02:12 +12:00
Bob
d3db9d3710 yes, i do want += 2010-09-22 08:02:09 +12:00
Bob
9eb05a43f9 show perf widget 2010-09-22 08:02:06 +12:00
Bob
3165ec5359 create widgets on demand 2010-09-22 08:02:03 +12:00
Bob
f4699132d6 made OpenWindow and CloseWindow static 2010-09-22 08:02:00 +12:00
Bob
086bdfb4bd new object creation logic 2010-09-22 08:01:57 +12:00
Chris Forbes
61fd12c7da oops; prev didnt run 2010-09-22 07:19:18 +12:00
Chris Forbes
9979209c34 more useful debug, less debug 2010-09-21 22:42:31 +12:00
Chris Forbes
b0c06d4cd9 force consistent conversion to float in a few places 2010-09-21 22:08:40 +12:00
Chris Forbes
3a617f8934 sync the last path generated, to try and catch this MUCH earlier 2010-09-21 21:43:16 +12:00
163 changed files with 2962 additions and 2803 deletions

11
.gitignore vendored
View File

@@ -12,20 +12,11 @@ mods/*/*.dll
# Red Alert binary files
mods/*/packages/*.[mM][iI][xX]
# Crap generated by OpenRa
sheet-*.png
log.txt
*.rep
#binary stuff
/*.dll
*.pdb
*.mdb
*.exe
OpenRA
OpenRA.app
*.vqa
# backup files by various editors
*~
@@ -33,10 +24,8 @@ OpenRA.app
# dependency DLLs (different for every platform!)
cg.dll
cgGL.dll
glfw.dll
/OpenRa.Gl.dll
settings.ini
#monodevelop
*.pidb

View File

@@ -36,9 +36,6 @@ namespace OpenRA.Editor
Rules.LoadRules(Game.modData.Manifest, new Map());
surface1.AfterChange += MakeDirty;
string path = Directory.GetCurrentDirectory();
Icon = new Icon(path + Path.DirectorySeparatorChar + "OpenRA.Editor" + Path.DirectorySeparatorChar + "OpenRA.Editor.Icon.ico");
}
void MakeDirty() { dirty = true; }
@@ -349,9 +346,11 @@ namespace OpenRA.Editor
void ImportLegacyMapClicked(object sender, EventArgs e)
{
var currentDirectory = Directory.GetCurrentDirectory();
using (var ofd = new OpenFileDialog { Filter = "Legacy maps (*.ini;*.mpr)|*.ini;*.mpr" })
if (DialogResult.OK == ofd.ShowDialog())
{
Directory.SetCurrentDirectory( currentDirectory );
/* massive hack: we should be able to call NewMap() with the imported Map object,
* but something's not right internally in it, unless loaded via the real maploader */

View File

@@ -17,6 +17,7 @@ using OpenRA;
using OpenRA.FileFormats;
using OpenRA.Traits;
using System.Drawing;
using System.Globalization;
namespace OpenRA.Editor
{
@@ -401,7 +402,7 @@ namespace OpenRA.Editor
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new OwnerInit(parts[0]),
new HealthInit(float.Parse(parts[2])/256),
new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)/256),
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
new ActorStanceInit(stance),
};

View File

@@ -73,5 +73,17 @@ namespace OpenRA
{
return mi.GetCustomAttributes(typeof(T), true).Length != 0;
}
public static T[] GetCustomAttributes<T>( this MemberInfo mi, bool inherit )
where T : class
{
return (T[])mi.GetCustomAttributes( typeof( T ), inherit );
}
public static T[] GetCustomAttributes<T>( this ParameterInfo mi )
where T : class
{
return (T[])mi.GetCustomAttributes( typeof( T ), true );
}
}
}

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Globalization;
namespace OpenRA.FileFormats
{
@@ -99,7 +100,7 @@ namespace OpenRA.FileFormats
else if (fieldType == typeof(float))
{
float res;
if (float.TryParse(x.Replace("%",""), out res))
if (float.TryParse(x.Replace("%",""), System.Globalization.NumberStyles.Any, NumberFormatInfo.InvariantInfo, out res))
return res * (x.Contains( '%' ) ? 0.01f : 1f);
return InvalidValueAction(x,fieldType, field);
}
@@ -177,11 +178,12 @@ namespace OpenRA.FileFormats
{
var ret = new Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>();
foreach( var field in type.GetFields() )
foreach( var ff in type.GetFields() )
{
var load = (LoadAttribute[])field.GetCustomAttributes( typeof( LoadAttribute ), false );
var loadUsing = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false );
var fromYamlKey = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false );
var field = ff;
var load = field.GetCustomAttributes<LoadAttribute>( false );
var loadUsing = field.GetCustomAttributes<LoadUsingAttribute>( false );
var fromYamlKey = field.GetCustomAttributes<FieldFromYamlKeyAttribute>( false );
if( loadUsing.Length != 0 )
ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml );
else if( fromYamlKey.Length != 0 )

View File

@@ -52,13 +52,13 @@ namespace OpenRA.FileFormats.Graphics
public interface IVertexBuffer<T>
{
void Bind();
void SetData( T[] vertices );
void SetData( T[] vertices, int length );
}
public interface IIndexBuffer
{
void Bind();
void SetData( ushort[] indices );
void SetData( ushort[] indices, int length );
}
public interface IShader

View File

@@ -25,6 +25,7 @@ namespace OpenRA
public static int2 operator -(int2 a, int2 b) { return new int2(a.X - b.X, a.Y - b.Y); }
public static int2 operator *(int a, int2 b) { return new int2(a * b.X, a * b.Y); }
public static int2 operator *(int2 b, int a) { return new int2(a * b.X, a * b.Y); }
public static int2 operator /(int2 a, int b) { return new int2(a.X / b, a.Y / b); }
public static bool operator ==(int2 me, int2 other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(int2 me, int2 other) { return !(me == other); }
@@ -59,5 +60,15 @@ namespace OpenRA
{
return (uint)((orig & 0xff000000) >> 24) | ((orig & 0x00ff0000) >> 8) | ((orig & 0x0000ff00) << 8) | ((orig & 0x000000ff) << 24);
}
public static int Lerp( int a, int b, int mul, int div )
{
return a + ( b - a ) * mul / div;
}
public static int2 Lerp( int2 a, int2 b, int mul, int div )
{
return a + ( b - a ) * mul / div;
}
}
}

View File

@@ -26,7 +26,8 @@ namespace OpenRA
public readonly World World;
public readonly uint ActorID;
public int2 Location { get { return Trait<IOccupySpace>().TopLeft; } }
public int2 Location { get { return Trait<IOccupySpace>().TopLeft; } }
public float2 CenterLocation { get { return Trait<IHasLocation>().PxPosition; } }
[Sync]
public Player Owner;
@@ -52,9 +53,6 @@ namespace OpenRA
AddTrait(trait.Create(init));
}
if( CenterLocation == float2.Zero && HasTrait<IOccupySpace>() )
CenterLocation = Traits.Util.CenterOfCell(Location);
Size = Lazy.New(() =>
{
var si = Info.Traits.GetOrDefault<SelectableInfo>();
@@ -99,8 +97,6 @@ namespace OpenRA
get { return currentActivity == null || currentActivity is Idle; }
}
public float2 CenterLocation;
OpenRA.FileFormats.Lazy<float2> Size;
public IEnumerable<Renderable> Render()
@@ -151,16 +147,9 @@ namespace OpenRA
public void QueueActivity( IActivity nextActivity )
{
if( currentActivity == null )
{
currentActivity = nextActivity;
return;
}
var act = currentActivity;
while( act.NextActivity != null )
{
act = act.NextActivity;
}
act.NextActivity = nextActivity;
else
currentActivity.Queue( nextActivity );
}
public void CancelActivity()

View File

@@ -22,7 +22,7 @@ namespace OpenRA
public void Draw(int frame, float2 pos)
{
Game.Renderer.SpriteRenderer.DrawSprite(sequence.GetSprite(frame), pos - sequence.Hotspot, sequence.Palette);
sequence.GetSprite(frame).DrawAt(pos - sequence.Hotspot, sequence.Palette);
}
}
}

View File

@@ -279,6 +279,36 @@ namespace OpenRA
JoinLocal();
StartGame(modData.Manifest.ShellmapUid);
Game.BeforeGameStart += () => Widget.OpenWindow("INGAME_ROOT");
Game.ConnectionStateChanged += () =>
{
Widget.CloseWindow();
switch( Game.orderManager.Connection.ConnectionState )
{
case ConnectionState.PreConnecting:
Widget.OpenWindow("MAINMENU_BG");
break;
case ConnectionState.Connecting:
Widget.OpenWindow("CONNECTING_BG");
break;
case ConnectionState.NotConnected:
Widget.OpenWindow("CONNECTION_FAILED_BG");
break;
case ConnectionState.Connected:
var lobby = Widget.OpenWindow("SERVER_LOBBY");
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
//r.GetWidget("INGAME_ROOT").GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
break;
}
};
modData.WidgetLoader.LoadWidget( Widget.RootWidget, "PERF_BG" );
Widget.OpenWindow("MAINMENU_BG");
ResetTimer();
}
@@ -310,8 +340,8 @@ namespace OpenRA
LobbyInfo.GlobalSettings.Mods = Settings.Game.Mods;
JoinLocal();
StartGame(shellmap);
Widget.RootWidget.CloseWindow();
Widget.CloseWindow();
Widget.OpenWindow("MAINMENU_BG");
}

View File

@@ -8,13 +8,13 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using System;
namespace OpenRA.GameRules
{

View File

@@ -13,45 +13,46 @@ using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics
{
public class LineRenderer
public class LineRenderer : Renderer.IBatchRenderer
{
Renderer renderer;
IVertexBuffer<Vertex> vertexBuffer;
IIndexBuffer indexBuffer; /* kindof a waste of space, but the GPU likes indexing, oh well */
const int linesPerBatch = 1024;
Vertex[] vertices = new Vertex[ 2 * linesPerBatch ];
ushort[] indices = new ushort[ 2 * linesPerBatch ];
int lines = 0;
Vertex[] vertices = new Vertex[ Renderer.TempBufferSize ];
ushort[] indices = new ushort[ Renderer.TempBufferSize ];
int nv = 0, ni = 0;
public LineRenderer( Renderer renderer )
{
this.renderer = renderer;
vertexBuffer = renderer.Device.CreateVertexBuffer(vertices.Length );
indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length );
}
public void Flush()
{
if( lines > 0 )
if( ni > 0 )
{
renderer.LineShader.Render( () =>
{
vertexBuffer.SetData( vertices );
indexBuffer.SetData( indices );
renderer.DrawBatch( vertexBuffer, indexBuffer,
var vb = renderer.GetTempVertexBuffer();
var ib = renderer.GetTempIndexBuffer();
vb.SetData( vertices, nv );
ib.SetData( indices, ni );
renderer.DrawBatch( vb, ib,
nv, ni / 2, PrimitiveType.LineList );
} );
nv = 0; ni = 0;
lines = 0;
}
}
public void DrawLine( float2 start, float2 end, Color startColor, Color endColor )
{
Renderer.CurrentBatchRenderer = this;
if( ni + 2 > Renderer.TempBufferSize )
Flush();
if( nv + 2 > Renderer.TempBufferSize )
Flush();
indices[ ni++ ] = (ushort)nv;
vertices[ nv++ ] = new Vertex( start,
@@ -63,9 +64,6 @@ namespace OpenRA.Graphics
vertices[ nv++ ] = new Vertex( end,
new float2( endColor.R / 255.0f, endColor.G / 255.0f ),
new float2( endColor.B / 255.0f, endColor.A / 255.0f ) );
if( ++lines >= linesPerBatch )
Flush();
}
public void FillRect( RectangleF r, Color color )

View File

@@ -16,6 +16,7 @@ using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using OpenRA.Support;
using System.Windows.Forms;
using System.Collections.Generic;
namespace OpenRA.Graphics
{
@@ -23,10 +24,10 @@ namespace OpenRA.Graphics
{
internal static int SheetSize;
public IShader SpriteShader { get; private set; } /* note: shared shader params */
public IShader LineShader { get; private set; }
public IShader RgbaSpriteShader { get; private set; }
public IShader WorldSpriteShader { get; private set; }
internal IShader SpriteShader { get; private set; } /* note: shared shader params */
internal IShader LineShader { get; private set; }
internal IShader RgbaSpriteShader { get; private set; }
internal IShader WorldSpriteShader { get; private set; }
public SpriteRenderer SpriteRenderer { get; private set; }
public SpriteRenderer RgbaSpriteRenderer { get; private set; }
@@ -37,6 +38,12 @@ namespace OpenRA.Graphics
public readonly SpriteFont RegularFont, BoldFont, TitleFont;
internal const int TempBufferSize = 8192;
const int TempBufferCount = 8;
Queue<IVertexBuffer<Vertex>> tempBuffersV = new Queue<IVertexBuffer<Vertex>>();
Queue<IIndexBuffer> tempBuffersI = new Queue<IIndexBuffer>();
public Renderer()
{
SpriteShader = device.CreateShader(FileSystem.Open("shaders/world-shp.fx"));
@@ -52,9 +59,15 @@ namespace OpenRA.Graphics
RegularFont = new SpriteFont("FreeSans.ttf", 14);
BoldFont = new SpriteFont("FreeSansBold.ttf", 14);
TitleFont = new SpriteFont("titles.ttf", 48);
for( int i = 0 ; i < TempBufferCount ; i++ )
{
tempBuffersV.Enqueue( device.CreateVertexBuffer( TempBufferSize ) );
tempBuffersI.Enqueue( device.CreateIndexBuffer( TempBufferSize ) );
}
}
public IGraphicsDevice Device { get { return device; } }
internal IGraphicsDevice Device { get { return device; } }
public void BeginFrame(float2 scroll)
{
@@ -81,6 +94,7 @@ namespace OpenRA.Graphics
public void EndFrame()
{
Flush();
device.End();
device.Present();
}
@@ -111,15 +125,9 @@ namespace OpenRA.Graphics
public void Flush()
{
WorldSpriteRenderer.Flush();
RgbaSpriteRenderer.Flush();
LineRenderer.Flush();
CurrentBatchRenderer = null;
}
static IGraphicsDevice device;
public static Size Resolution { get { return device.WindowSize; } }
@@ -154,5 +162,49 @@ namespace OpenRA.Graphics
}
throw new NotImplementedException();
}
internal IVertexBuffer<Vertex> GetTempVertexBuffer()
{
var ret = tempBuffersV.Dequeue();
tempBuffersV.Enqueue( ret );
return ret;
}
internal IIndexBuffer GetTempIndexBuffer()
{
var ret = tempBuffersI.Dequeue();
tempBuffersI.Enqueue( ret );
return ret;
}
public interface IBatchRenderer
{
void Flush();
}
static IBatchRenderer currentBatchRenderer;
public static IBatchRenderer CurrentBatchRenderer
{
get { return currentBatchRenderer; }
set
{
if( currentBatchRenderer == value ) return;
if( currentBatchRenderer != null )
currentBatchRenderer.Flush();
currentBatchRenderer = value;
}
}
public void EnableScissor(int left, int top, int width, int height)
{
Flush();
Device.EnableScissor( left, top, width, height );
}
public void DisableScissor()
{
Flush();
Device.DisableScissor();
}
}
}

View File

@@ -49,6 +49,26 @@ namespace OpenRA.Graphics
{
return uvhax[ k ];
}
public void DrawAt( float2 location, string palette )
{
Game.Renderer.SpriteRenderer.DrawSprite( this, location, palette, this.size );
}
public void DrawAt( float2 location, int paletteIndex )
{
Game.Renderer.SpriteRenderer.DrawSprite( this, location, paletteIndex, this.size );
}
public void DrawAt(float2 location, string palette, float2 size)
{
Game.Renderer.SpriteRenderer.DrawSprite( this, location, palette, size );
}
public void DrawAt( float2 location, int paletteIndex, float2 size )
{
Game.Renderer.SpriteRenderer.DrawSprite( this, location, paletteIndex, size );
}
}
public enum TextureChannel

View File

@@ -12,28 +12,20 @@ using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics
{
public class SpriteRenderer
public class SpriteRenderer : Renderer.IBatchRenderer
{
IVertexBuffer<Vertex> vertexBuffer;
IIndexBuffer indexBuffer;
Renderer renderer;
IShader shader;
const int spritesPerBatch = 1024;
Vertex[] vertices = new Vertex[4 * spritesPerBatch];
ushort[] indices = new ushort[6 * spritesPerBatch];
Vertex[] vertices = new Vertex[Renderer.TempBufferSize];
ushort[] indices = new ushort[Renderer.TempBufferSize];
Sheet currentSheet = null;
int sprites = 0;
int nv = 0, ni = 0;
public SpriteRenderer(Renderer renderer, IShader shader)
{
this.renderer = renderer;
this.shader = shader;
vertexBuffer = renderer.Device.CreateVertexBuffer( vertices.Length );
indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length );
}
public SpriteRenderer(Renderer renderer)
@@ -41,14 +33,16 @@ namespace OpenRA.Graphics
public void Flush()
{
if (sprites > 0)
if (ni > 0)
{
shader.SetValue( "DiffuseTexture", currentSheet.Texture );
shader.Render(() =>
{
vertexBuffer.SetData(vertices);
indexBuffer.SetData(indices);
renderer.DrawBatch(vertexBuffer, indexBuffer,
var vb = renderer.GetTempVertexBuffer();
var ib = renderer.GetTempIndexBuffer();
vb.SetData(vertices, nv);
ib.SetData(indices, ni);
renderer.DrawBatch(vb, ib,
new Range<int>(0, nv),
new Range<int>(0, ni),
PrimitiveType.TriangleList,
@@ -57,7 +51,6 @@ namespace OpenRA.Graphics
nv = 0; ni = 0;
currentSheet = null;
sprites = 0;
}
}
@@ -73,14 +66,19 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size)
{
Renderer.CurrentBatchRenderer = this;
if (s.sheet != currentSheet)
Flush();
if( nv + 4 > Renderer.TempBufferSize )
Flush();
if( ni + 6 > Renderer.TempBufferSize )
Flush();
currentSheet = s.sheet;
Util.FastCreateQuad(vertices, indices, location.ToInt2(), s, paletteIndex, nv, ni, size);
nv += 4; ni += 6;
if (++sprites >= spritesPerBatch)
Flush();
}

View File

@@ -56,10 +56,10 @@ namespace OpenRA.Graphics
}
vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length );
vertexBuffer.SetData( vertices );
vertexBuffer.SetData( vertices, nv );
indexBuffer = Game.Renderer.Device.CreateIndexBuffer( indices.Length );
indexBuffer.SetData( indices );
indexBuffer.SetData( indices, ni );
}
public void Draw( Viewport viewport )

View File

@@ -107,10 +107,6 @@ namespace OpenRA.Graphics
var c = new Cursor(cursorName);
c.Draw((int)cursorFrame, Viewport.LastMousePos + Location);
renderer.RgbaSpriteRenderer.Flush();
renderer.SpriteRenderer.Flush();
renderer.WorldSpriteRenderer.Flush();
renderer.EndFrame();
}

View File

@@ -90,20 +90,16 @@ namespace OpenRA.Graphics
public void Draw()
{
var bounds = GetBoundsRect();
Game.Renderer.Device.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
Game.Renderer.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
terrainRenderer.Draw(Game.viewport);
if (world.OrderGenerator != null)
world.OrderGenerator.RenderBeforeWorld(world);
Game.Renderer.SpriteRenderer.Flush();
Game.Renderer.LineRenderer.Flush();
foreach (var image in worldSprites)
Game.Renderer.SpriteRenderer.DrawSprite(image.Sprite, image.Pos, image.Palette);
image.Sprite.DrawAt(image.Pos, image.Palette);
uiOverlay.Draw(world);
Game.Renderer.SpriteRenderer.Flush();
if (world.OrderGenerator != null)
world.OrderGenerator.RenderAfterWorld(world);
@@ -111,11 +107,7 @@ namespace OpenRA.Graphics
if (world.LocalPlayer != null)
world.LocalPlayer.Shroud.Draw();
Game.Renderer.SpriteRenderer.Flush();
Game.Renderer.Device.DisableScissor();
Game.Renderer.LineRenderer.Flush();
Game.Renderer.DisableScissor();
}
void DrawBox(RectangleF r, Color color)

View File

@@ -24,6 +24,7 @@ namespace OpenRA
public readonly SheetBuilder SheetBuilder;
public readonly CursorSheetBuilder CursorSheetBuilder;
public readonly Dictionary<string, MapStub> AvailableMaps;
public readonly WidgetLoader WidgetLoader;
public ILoadScreen LoadScreen = null;
public ModData( params string[] mods )
@@ -39,6 +40,7 @@ namespace OpenRA
SheetBuilder = new SheetBuilder( TextureChannel.Red );
CursorSheetBuilder = new CursorSheetBuilder( this );
AvailableMaps = FindMaps( mods );
WidgetLoader = new WidgetLoader( this );
}
// TODO: Do this nicer

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using OpenRA.FileFormats;
using System.Collections.Generic;
namespace OpenRA
{
@@ -30,19 +31,61 @@ namespace OpenRA
public static Action<string> MissingTypeAction =
s => { throw new InvalidOperationException("Cannot locate type: {0}".F(s)); };
public T CreateObject<T>(string classname)
public T CreateObject<T>(string className)
{
foreach (var mod in ModAssemblies)
{
var fullTypeName = mod.Second + "." + classname;
var obj = mod.First.CreateInstance(fullTypeName);
if (obj != null)
return (T)obj;
}
return CreateObject<T>( className, new Dictionary<string, object>() );
}
MissingTypeAction(classname);
public T CreateObject<T>( string className, Dictionary<string, object> args )
{
foreach( var mod in ModAssemblies )
{
var type = mod.First.GetType( mod.Second + "." + className, false );
if( type == null ) continue;
var ctors = type.GetConstructors().Where( x => x.HasAttribute<UseCtorAttribute>() ).ToList();
if( ctors.Count == 0 )
return (T)CreateBasic( type );
else if( ctors.Count == 1 )
return (T)CreateUsingArgs( ctors[ 0 ], args );
else
throw new InvalidOperationException( "ObjectCreator: UseCtor on multiple constructors; invalid." );
}
MissingTypeAction(className);
return default(T);
}
public object CreateBasic( Type type )
{
return type.GetConstructor( new Type[ 0 ] ).Invoke( new object[ 0 ] );
}
public object CreateUsingArgs( ConstructorInfo ctor, Dictionary<string, object> args )
{
var p = ctor.GetParameters();
var a = new object[ p.Length ];
for( int i = 0 ; i < p.Length ; i++ )
{
var attrs = p[ i ].GetCustomAttributes<ParamAttribute>();
if( attrs.Length != 1 ) throw new InvalidOperationException( "ObjectCreator: argument in [UseCtor] doesn't have [Param]" );
a[ i ] = args[ attrs[ 0 ].ParamName ];
}
return ctor.Invoke( a );
}
[AttributeUsage( AttributeTargets.Parameter )]
public class ParamAttribute : Attribute
{
public string ParamName { get; private set; }
public ParamAttribute( string paramName )
{
ParamName = paramName;
}
}
[AttributeUsage( AttributeTargets.Constructor )]
public class UseCtorAttribute : Attribute
{
}
}
}

View File

@@ -207,11 +207,11 @@ namespace OpenRA
public struct CellInfo
{
public float MinCost;
public int MinCost;
public int2 Path;
public bool Seen;
public CellInfo( float minCost, int2 path, bool seen )
public CellInfo( int minCost, int2 path, bool seen )
{
MinCost = minCost;
Path = path;
@@ -221,10 +221,10 @@ namespace OpenRA
public struct PathDistance : IComparable<PathDistance>
{
public float EstTotal;
public int EstTotal;
public int2 Location;
public PathDistance(float estTotal, int2 location)
public PathDistance(int estTotal, int2 location)
{
EstTotal = estTotal;
Location = location;

View File

@@ -20,7 +20,7 @@ namespace OpenRA
World world;
public CellInfo[ , ] cellInfo;
public PriorityQueue<PathDistance> queue;
public Func<int2, float> heuristic;
public Func<int2, int> heuristic;
Func<int2, bool> customBlock;
public bool checkForBlocked;
public Actor ignoreBuilding;
@@ -58,7 +58,7 @@ namespace OpenRA
return this;
}
public PathSearch WithHeuristic(Func<int2, float> h)
public PathSearch WithHeuristic(Func<int2, int> h)
{
heuristic = h;
return this;
@@ -66,7 +66,7 @@ namespace OpenRA
public PathSearch WithoutLaneBias()
{
LaneBias = 0f;
LaneBias = 0;
return this;
}
@@ -76,7 +76,7 @@ namespace OpenRA
return this;
}
float LaneBias = .5f;
int LaneBias = 1;
public int2 Expand( World world )
{
@@ -91,7 +91,7 @@ namespace OpenRA
var thisCost = Mobile.MovementCostForCell(mobileInfo, world, p.Location);
if (thisCost == float.PositiveInfinity)
if (thisCost == int.MaxValue)
return p.Location;
foreach( int2 d in directions )
@@ -104,7 +104,7 @@ namespace OpenRA
var costHere = Mobile.MovementCostForCell(mobileInfo, world, newHere);
if (costHere == float.PositiveInfinity)
if (costHere == int.MaxValue)
continue;
if (!Mobile.CanEnterCell(mobileInfo, world, uim, bim, newHere, ignoreBuilding, checkForBlocked))
@@ -114,10 +114,11 @@ namespace OpenRA
continue;
var est = heuristic( newHere );
if( est == float.PositiveInfinity )
if( est == int.MaxValue )
continue;
float cellCost = ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * costHere;
int cellCost = costHere;
if( d.X * d.Y != 0 ) cellCost = ( cellCost * 34 ) / 24;
// directional bonuses for smoother flow!
var ux = (newHere.X + (inReverse ? 1 : 0) & 1);
@@ -128,7 +129,7 @@ namespace OpenRA
if (uy == 0 && d.X < 0) cellCost += LaneBias;
else if (uy == 1 && d.X > 0) cellCost += LaneBias;
float newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;
int newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
continue;
@@ -199,18 +200,18 @@ namespace OpenRA
var cellInfo = new CellInfo[ world.Map.MapSize.X, world.Map.MapSize.Y ];
for( int x = 0 ; x < world.Map.MapSize.X ; x++ )
for( int y = 0 ; y < world.Map.MapSize.Y ; y++ )
cellInfo[ x, y ] = new CellInfo( float.PositiveInfinity, new int2( x, y ), false );
cellInfo[ x, y ] = new CellInfo( int.MaxValue, new int2( x, y ), false );
return cellInfo;
}
public static Func<int2, float> DefaultEstimator( int2 destination )
public static Func<int2, int> DefaultEstimator( int2 destination )
{
return here =>
{
int2 d = ( here - destination ).Abs();
int diag = Math.Min( d.X, d.Y );
int straight = Math.Abs( d.X - d.Y );
return 1.5f * diag + straight;
return (3400 * diag / 24) + (100 * straight);
};
}
}

View File

@@ -151,65 +151,39 @@ namespace OpenRA
var minx = clipRect.Left;
var maxx = clipRect.Right;
var shroudPalette = "fog";
DrawShroud( minx, miny, maxx, maxy, fogSprites, "fog" );
DrawShroud( minx, miny, maxx, maxy, sprites, "shroud" );
}
void DrawShroud( int minx, int miny, int maxx, int maxy, Sprite[,] s, string pal )
{
var shroudPalette = Game.world.WorldRenderer.GetPaletteIndex(pal);
for (var j = miny; j < maxy; j++)
{
var starti = minx;
for (var i = minx; i < maxx; i++)
{
if (fogSprites[i, j] == shadowBits[0x0f])
if (s[i, j] == shadowBits[0x0f])
continue;
if (starti != i)
{
Game.Renderer.SpriteRenderer.DrawSprite(fogSprites[starti, j],
Game.CellSize * new float2(starti, j),
shroudPalette,
new float2(Game.CellSize * (i - starti), Game.CellSize));
starti = i+1;
}
Game.Renderer.SpriteRenderer.DrawSprite(fogSprites[i, j],
Game.CellSize * new float2(i, j),
shroudPalette);
starti = i+1;
}
if (starti < maxx)
Game.Renderer.SpriteRenderer.DrawSprite(fogSprites[starti, j],
Game.CellSize * new float2(starti, j),
shroudPalette,
new float2(Game.CellSize * (maxx - starti), Game.CellSize));
}
shroudPalette = "shroud";
for (var j = miny; j < maxy; j++)
{
var starti = minx;
for (var i = minx; i < maxx; i++)
{
if (sprites[i, j] == shadowBits[0x0f])
continue;
if (starti != i)
{
Game.Renderer.SpriteRenderer.DrawSprite(sprites[starti, j],
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
new float2(Game.CellSize * (i - starti), Game.CellSize));
starti = i + 1;
}
Game.Renderer.SpriteRenderer.DrawSprite(sprites[i, j],
s[i, j].DrawAt(
Game.CellSize * new float2(i, j),
shroudPalette);
starti = i + 1;
}
if (starti < maxx)
Game.Renderer.SpriteRenderer.DrawSprite(sprites[starti, j],
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
new float2(Game.CellSize * (maxx - starti), Game.CellSize));

View File

@@ -8,19 +8,19 @@
*/
#endregion
using OpenRA.Traits;
using System.Collections.Generic;
namespace OpenRA.Traits.Activities
{
public class Drag : IActivity
{
public IActivity NextActivity { get; set; }
IActivity NextActivity { get; set; }
float2 endLocation;
float2 startLocation;
int2 endLocation;
int2 startLocation;
int length;
public Drag(float2 start, float2 end, int length)
public Drag(int2 start, int2 end, int length)
{
startLocation = start;
endLocation = end;
@@ -29,16 +29,32 @@ namespace OpenRA.Traits.Activities
int ticks = 0;
public IActivity Tick( Actor self )
{
self.CenterLocation = float2.Lerp(startLocation, endLocation, (float)ticks/(length-1));
Log.Write("debug", "drag #{0} {1} {2}", self.ActorID, ticks, self.CenterLocation);
{
var mobile = self.Trait<Mobile>();
mobile.PxPosition = int2.Lerp( startLocation, endLocation, ticks, length - 1 );
if (++ticks >= length)
return NextActivity;
{
mobile.IsMoving = false;
return NextActivity;
}
mobile.IsMoving = true;
return this;
}
public void Cancel(Actor self) { }
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public IEnumerable<float2> GetCurrentPath()
{
yield return endLocation;
}
}
}

View File

@@ -10,11 +10,8 @@
namespace OpenRA.Traits.Activities
{
class Idle : IActivity
class Idle : CancelableActivity
{
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self) { return NextActivity; }
public void Cancel(Actor self) {}
public override IActivity Tick(Actor self) { return NextActivity; }
}
}

View File

@@ -15,18 +15,14 @@ using System.Linq;
namespace OpenRA.Traits.Activities
{
public class Move : IActivity
public class Move : CancelableActivity
{
public IActivity NextActivity { get; set; }
int2? destination;
int nearEnough;
public List<int2> path;
Func<Actor, Mobile, List<int2>> getPath;
public Actor ignoreBuilding;
bool cancellable = true;
MovePart move;
int ticksBeforePathing;
const int avgTicksBeforePathing = 5;
@@ -49,7 +45,6 @@ namespace OpenRA.Traits.Activities
.WithoutLaneBias());
this.destination = destination;
this.nearEnough = 0;
this.cancellable = false;
}
public Move( int2 destination, int nearEnough )
@@ -102,26 +97,29 @@ namespace OpenRA.Traits.Activities
this.nearEnough = 0;
}
static int HashList<T>(List<T> xs)
{
int hash = 0;
int n = 0;
foreach (var x in xs)
hash += n++ * x.GetHashCode();
return hash;
}
List<int2> EvalPath( Actor self, Mobile mobile )
{
var path = getPath(self, mobile).TakeWhile(a => a != mobile.toCell).ToList();
Log.Write("debug", "EvalPath #{0} {1}",
self.ActorID, string.Join(" ", path.Select(a => a.ToString()).ToArray()));
mobile.PathHash = HashList(path);
Log.Write("debug", "EvalPathHash #{0} {1}",
self.ActorID, mobile.PathHash);
return path;
}
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
var mobile = self.Trait<Mobile>();
if( move != null )
{
move.TickMove( self, mobile, this );
return this;
}
if (destination == mobile.toCell)
return NextActivity;
@@ -154,24 +152,20 @@ namespace OpenRA.Traits.Activities
if( firstFacing != mobile.Facing )
{
path.Add( nextCell.Value );
Log.Write("debug", "Turn: #{0} from {1} to {2}",
self.ActorID, mobile.Facing, firstFacing);
return new Turn( firstFacing ) { NextActivity = this };
return Util.SequenceActivities( new Turn( firstFacing ), this ).Tick( self );
}
else
{
mobile.toCell = nextCell.Value;
move = new MoveFirstHalf(
mobile.SetLocation( mobile.fromCell, nextCell.Value );
var move = new MoveFirstHalf(
this,
Util.CenterOfCell( mobile.fromCell ),
Util.BetweenCells( mobile.fromCell, mobile.toCell ),
mobile.Facing,
mobile.Facing,
0 );
move.TickMove( self, mobile, this );
return this;
return move.Tick( self );
}
}
@@ -245,64 +239,98 @@ namespace OpenRA.Traits.Activities
return nextCell;
}
public void Cancel( Actor self )
protected override bool OnCancel()
{
if (!cancellable) return;
path = new List<int2>();
NextActivity = null;
return true;
}
abstract class MovePart
public override IEnumerable<float2> GetCurrentPath()
{
public readonly float2 from, to;
if( path != null )
return Enumerable.Reverse(path).Select( c => (float2)Util.CenterOfCell(c) );
if( destination != null )
return new float2[] { destination.Value };
return new float2[ 0 ];
}
abstract class MovePart : IActivity
{
public readonly Move move;
public readonly int2 from, to;
public readonly int fromFacing, toFacing;
public int moveFraction;
public readonly int moveFractionTotal;
public MovePart( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
public MovePart( Move move, int2 from, int2 to, int fromFacing, int toFacing, int startingFraction )
{
this.move = move;
this.from = from;
this.to = to;
this.fromFacing = fromFacing;
this.toFacing = toFacing;
this.moveFraction = startingFraction;
this.moveFractionTotal = (int)(( to - from ).Length*3);
this.moveFractionTotal = (int)( ( to - from ) * 3 ).Length;
}
public void TickMove( Actor self, Mobile mobile, Move parent )
public void Cancel( Actor self )
{
moveFraction += (int)mobile.MovementSpeedForCell(self, mobile.toCell);
if( moveFraction >= moveFractionTotal )
move.Cancel( self );
}
public void Queue( IActivity activity )
{
move.Queue( activity );
}
public IActivity Tick( Actor self )
{
var mobile = self.Trait<Mobile>();
var ret = InnerTick( self, mobile );
mobile.IsMoving = ( ret is MovePart );
if( moveFraction > moveFractionTotal )
moveFraction = moveFractionTotal;
UpdateCenterLocation( self, mobile );
if( moveFraction >= moveFractionTotal )
{
parent.move = OnComplete( self, mobile, parent );
if( parent.move == null )
UpdateCenterLocation( self, mobile );
}
return ret;
}
IActivity InnerTick( Actor self, Mobile mobile )
{
moveFraction += (int)mobile.MovementSpeedForCell(self, mobile.toCell);
if( moveFraction <= moveFractionTotal )
return this;
var next = OnComplete( self, mobile, move );
if( next != null )
return next;
return move;
}
void UpdateCenterLocation( Actor self, Mobile mobile )
{
var frac = (float)moveFraction / moveFractionTotal;
self.CenterLocation = float2.Lerp( from, to, frac );
mobile.PxPosition = int2.Lerp( from, to, moveFraction, moveFractionTotal );
if( moveFraction >= moveFractionTotal )
mobile.Facing = toFacing & 0xFF;
else
mobile.Facing = ( fromFacing + ( toFacing - fromFacing ) * moveFraction / moveFractionTotal ) & 0xFF;
mobile.Facing = int2.Lerp( fromFacing, toFacing, moveFraction, moveFractionTotal ) & 0xFF;
}
protected abstract MovePart OnComplete( Actor self, Mobile mobile, Move parent );
public IEnumerable<float2> GetCurrentPath()
{
return move.GetCurrentPath();
}
}
class MoveFirstHalf : MovePart
{
public MoveFirstHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
: base( from, to, fromFacing, toFacing, startingFraction )
public MoveFirstHalf( Move move, int2 from, int2 to, int fromFacing, int toFacing, int startingFraction )
: base( move, from, to, fromFacing, toFacing, startingFraction )
{
}
@@ -314,40 +342,41 @@ namespace OpenRA.Traits.Activities
if( ( nextCell - mobile.toCell ) != ( mobile.toCell - mobile.fromCell ) )
{
var ret = new MoveFirstHalf(
move,
Util.BetweenCells( mobile.fromCell, mobile.toCell ),
Util.BetweenCells( mobile.toCell, nextCell.Value ),
mobile.Facing,
Util.GetNearestFacing( mobile.Facing, Util.GetFacing( nextCell.Value - mobile.toCell, mobile.Facing ) ),
moveFraction - moveFractionTotal );
mobile.fromCell = mobile.toCell;
mobile.toCell = nextCell.Value;
mobile.SetLocation( mobile.toCell, nextCell.Value );
return ret;
}
else
parent.path.Add( nextCell.Value );
}
var ret2 = new MoveSecondHalf(
move,
Util.BetweenCells( mobile.fromCell, mobile.toCell ),
Util.CenterOfCell( mobile.toCell ),
mobile.Facing,
mobile.Facing,
moveFraction - moveFractionTotal );
mobile.fromCell = mobile.toCell;
mobile.SetLocation( mobile.toCell, mobile.toCell );
return ret2;
}
}
class MoveSecondHalf : MovePart
{
public MoveSecondHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
: base( from, to, fromFacing, toFacing, startingFraction )
public MoveSecondHalf( Move move, int2 from, int2 to, int fromFacing, int toFacing, int startingFraction )
: base( move, from, to, fromFacing, toFacing, startingFraction )
{
}
protected override MovePart OnComplete( Actor self, Mobile mobile, Move parent )
{
self.CenterLocation = Util.CenterOfCell( mobile.toCell );
mobile.fromCell = mobile.toCell;
mobile.PxPosition = Util.CenterOfCell( mobile.toCell );
mobile.SetLocation( mobile.toCell, mobile.toCell );
mobile.FinishedMoving(self);
return null;
}

View File

@@ -10,18 +10,13 @@
namespace OpenRA.Traits.Activities
{
public class RemoveSelf : IActivity
public class RemoveSelf : CancelableActivity
{
bool isCanceled;
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
self.Destroy();
return null;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -8,11 +8,13 @@
*/
#endregion
using System.Collections.Generic;
namespace OpenRA.Traits.Activities
{
class Sell : IActivity
{
public IActivity NextActivity { get; set; }
IActivity NextActivity { get; set; }
bool started;
@@ -55,5 +57,18 @@ namespace OpenRA.Traits.Activities
}
public void Cancel(Actor self) { /* never gonna give you up.. */ }
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public IEnumerable<float2> GetCurrentPath()
{
yield break;
}
}
}

View File

@@ -12,9 +12,8 @@ using System.Linq;
namespace OpenRA.Traits.Activities
{
public class Turn : IActivity
public class Turn : CancelableActivity
{
public IActivity NextActivity { get; set; }
int desiredFacing;
public Turn( int desiredFacing )
@@ -22,8 +21,9 @@ namespace OpenRA.Traits.Activities
this.desiredFacing = desiredFacing;
}
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
if (IsCanceled) return NextActivity;
var facing = self.Trait<IFacing>();
if( desiredFacing == facing.Facing )
@@ -32,11 +32,5 @@ namespace OpenRA.Traits.Activities
return this;
}
public void Cancel( Actor self )
{
desiredFacing = self.Trait<IFacing>().Facing;
NextActivity = null;
}
}
}

View File

@@ -47,13 +47,13 @@ namespace OpenRA.Traits
readonly PowerManager PlayerPower;
public int2 PxPosition { get { return ( 2 * topLeft + Info.Dimensions ) * Game.CellSize / 2; } }
public Building(ActorInitializer init)
{
this.self = init.self;
this.topLeft = init.Get<LocationInit,int2>();
Info = self.Info.Traits.Get<BuildingInfo>();
self.CenterLocation = Game.CellSize
* ((float2)topLeft + .5f * (float2)Info.Dimensions);
PlayerPower = init.self.Owner.PlayerActor.Trait<PowerManager>();
}
@@ -64,19 +64,14 @@ namespace OpenRA.Traits
return Info.Power;
var health = self.TraitOrDefault<Health>();
var healthFraction = (health == null) ? 1f : health.HPFraction;
return (int)(healthFraction * Info.Power);
return health != null ? (Info.Power * health.HP / health.MaxHP) : Info.Power;
}
public void Damaged(Actor self, AttackInfo e)
{
// Power plants lose power with damage
if (Info.Power > 0)
{
var health = self.TraitOrDefault<Health>();
var healthFraction = (health == null) ? 1f : health.HPFraction;
PlayerPower.UpdateActor(self, (int)(healthFraction * Info.Power));
}
PlayerPower.UpdateActor(self, GetPowerUsage());
if (e.DamageState == DamageState.Dead)
{

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Traits
foreach (var t in y.NodesDict["TerrainSpeeds"].Nodes)
{
var speed = (float)FieldLoader.GetValue("speed", typeof(float),t.Value.Value);
var cost = t.Value.NodesDict.ContainsKey("PathingCost") ? (float)FieldLoader.GetValue("cost", typeof(float), t.Value.NodesDict["PathingCost"].Value) : 1f/speed;
var cost = t.Value.NodesDict.ContainsKey("PathingCost") ? (int)FieldLoader.GetValue("cost", typeof(int), t.Value.NodesDict["PathingCost"].Value) : (int)(10000/speed);
ret.Add(t.Key, new TerrainInfo{Speed = speed, Cost = cost});
}
@@ -48,7 +48,7 @@ namespace OpenRA.Traits
public class TerrainInfo
{
public float Cost = float.PositiveInfinity;
public int Cost = int.MaxValue;
public float Speed = 0;
}
}
@@ -57,6 +57,7 @@ namespace OpenRA.Traits
{
public readonly Actor self;
public readonly MobileInfo Info;
public bool IsMoving { get; internal set; }
int __facing;
int2 __fromCell, __toCell;
@@ -66,48 +67,35 @@ namespace OpenRA.Traits
public int Facing
{
get { return __facing; }
set
{
__facing = value;
Log.Write("debug", "#{0} set Facing={1}", self.ActorID, value);
Log.Write("debug", "{0}", new StackTrace());
}
set { __facing = value; }
}
[Sync]
public int Altitude
{
get { return __altitude; }
set { __altitude = value; Log.Write("debug", "#{0} set Altitude={1}", self.ActorID, value); }
set { __altitude = value; }
}
public int ROT { get { return Info.ROT; } }
public int InitialFacing { get { return Info.InitialFacing; } }
[Sync]
public int2 fromCell
{
get { return __fromCell; }
set { SetLocation( value, __toCell ); }
}
public int2 PxPosition { get; set; }
[Sync]
public int2 toCell
{
get { return __toCell; }
set { SetLocation( __fromCell, value ); }
}
public int2 fromCell { get { return __fromCell; } }
[Sync]
public int2 toCell { get { return __toCell; } }
[Sync]
public int PathHash; // written by Move.EvalPath, to temporarily debug this crap.
void SetLocation(int2 from, int2 to)
public void SetLocation(int2 from, int2 to)
{
if (fromCell == from && toCell == to) return;
RemoveInfluence();
__fromCell = from;
__toCell = to;
AddInfluence();
Log.Write("debug", "#{0} set location = {1} {2}", self.ActorID, from, to);
Log.Write("debug", "{0}", new StackTrace());
}
UnitInfluence uim;
@@ -122,6 +110,7 @@ namespace OpenRA.Traits
if (init.Contains<LocationInit>())
{
this.__fromCell = this.__toCell = init.Get<LocationInit,int2>();
this.PxPosition = Util.CenterOfCell( fromCell );
AddInfluence();
}
@@ -132,7 +121,14 @@ namespace OpenRA.Traits
public void SetPosition(Actor self, int2 cell)
{
SetLocation( cell, cell );
self.CenterLocation = Util.CenterOfCell(fromCell);
PxPosition = Util.CenterOfCell(fromCell);
}
public void SetPxPosition( Actor self, int2 px )
{
var cell = Util.CellContaining( px );
SetLocation( cell, cell );
PxPosition = px;
}
public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor)
@@ -244,7 +240,7 @@ namespace OpenRA.Traits
public static bool CanEnterCell( MobileInfo mobileInfo, World world, UnitInfluence uim, BuildingInfluence bim, int2 cell, Actor ignoreActor, bool checkTransientActors )
{
if (MovementCostForCell(mobileInfo, world, cell) == float.PositiveInfinity)
if (MovementCostForCell(mobileInfo, world, cell) == int.MaxValue)
return false;
// Check for buildings
@@ -289,19 +285,14 @@ namespace OpenRA.Traits
}
}
public float MovementCostForCell( Actor self, int2 cell )
{
return MovementCostForCell( Info, self.World, cell );
}
public static float MovementCostForCell(MobileInfo info, World world, int2 cell)
public static int MovementCostForCell(MobileInfo info, World world, int2 cell)
{
if (!world.Map.IsInMap(cell.X,cell.Y))
return float.PositiveInfinity;
return int.MaxValue;
var type = world.GetTerrainType(cell);
if (!info.TerrainSpeeds.ContainsKey(type))
return float.PositiveInfinity;
return int.MaxValue;
return info.TerrainSpeeds[type].Cost;
}
@@ -317,15 +308,7 @@ namespace OpenRA.Traits
.TraitsImplementing<ISpeedModifier>()
.Select(t => t.GetSpeedModifier())
.Product();
return Info.Speed * Info.TerrainSpeeds[type].Speed * modifier;
}
public IEnumerable<float2> GetCurrentPath(Actor self)
{
var move = self.GetCurrentActivity() as Move;
if (move == null || move.path == null) return new float2[] { };
return Enumerable.Reverse(move.path).Select( c => Util.CenterOfCell(c) );
return Info.Speed * Info.TerrainSpeeds[type].Speed * modifier / 100f;
}
public void AddInfluence()

View File

@@ -67,18 +67,15 @@ namespace OpenRA.Traits
break;
}
case "DevShroud":
{
{
DisableShroud ^= true;
if (self.World.LocalPlayer == self.Owner)
{
DisableShroud ^= true;
Game.world.LocalPlayer.Shroud.Disabled = DisableShroud;
}
break;
}
case "DevPathDebug":
{
if (self.World.LocalPlayer == self.Owner)
PathDebug ^= true;
PathDebug ^= true;
break;
}
case "DevUnitDebug":

View File

@@ -96,7 +96,7 @@ namespace OpenRA.Traits
var pipImages = new Animation("pips");
pipImages.PlayFetchIndex("groups", () => (int)group);
pipImages.Tick();
Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, basePosition + new float2(-8, 1), "chrome");
pipImages.Image.DrawAt(basePosition + new float2(-8, 1), "chrome");
}
void DrawPips(Actor self, float2 basePosition)
@@ -122,7 +122,7 @@ namespace OpenRA.Traits
}
var pipImages = new Animation("pips");
pipImages.PlayRepeating(pipStrings[(int)pip]);
Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, pipxyBase + pipxyOffset, "chrome");
pipImages.Image.DrawAt(pipxyBase + pipxyOffset, "chrome");
pipxyOffset += new float2(4, 0);
}
// Increment row
@@ -148,7 +148,7 @@ namespace OpenRA.Traits
var tagImages = new Animation("pips");
tagImages.PlayRepeating(tagStrings[(int)tag]);
Game.Renderer.SpriteRenderer.DrawSprite(tagImages.Image, tagxyBase + tagxyOffset, "chrome");
tagImages.Image.DrawAt(tagxyBase + tagxyOffset, "chrome");
// Increment row
tagxyOffset.Y += 8;
@@ -159,12 +159,13 @@ namespace OpenRA.Traits
void DrawUnitPath(Actor self)
{
if (!Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().PathDebug) return;
var activity = self.GetCurrentActivity();
var mobile = self.TraitOrDefault<IMove>();
if (mobile != null)
if (activity != null && mobile != null)
{
var alt = new float2(0, -mobile.Altitude);
var path = mobile.GetCurrentPath(self);
var path = activity.GetCurrentPath();
var start = self.CenterLocation + alt;
var c = Color.Green;

View File

@@ -49,7 +49,6 @@ namespace OpenRA.Traits
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); }
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
public interface INotifyEnterCell { void OnEnterCell(Actor self, int2 cell); }
public interface IStoreOre { int Capacity { get; }}
public interface IDisable { bool Disabled { get; } }
@@ -64,18 +63,18 @@ namespace OpenRA.Traits
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IOccupySpace
public interface IHasLocation
{
int2 PxPosition { get; }
}
public interface IOccupySpace : IHasLocation
{
int2 TopLeft { get; }
IEnumerable<int2> OccupiedCells();
}
public interface IOccupyAir
{
int2 TopLeft { get; }
IEnumerable<int2> OccupiedAirCells();
}
public static class IOccupySpaceExts
{
public static int2 NearestCellTo( this IOccupySpace ios, int2 other )
@@ -104,17 +103,15 @@ namespace OpenRA.Traits
public interface IPips { IEnumerable<PipType> GetPips(Actor self); }
public interface ITags { IEnumerable<TagType> GetTags(); }
public interface ITeleportable /* crap name! */
public interface ITeleportable : IHasLocation /* crap name! */
{
bool CanEnterCell(int2 location);
void SetPosition(Actor self, int2 cell);
void SetPxPosition(Actor self, int2 px);
}
public interface IMove : ITeleportable
{
float MovementCostForCell(Actor self, int2 cell);
float MovementSpeedForCell(Actor self, int2 cell);
IEnumerable<float2> GetCurrentPath(Actor self);
int Altitude { get; set; }
}
@@ -171,9 +168,41 @@ namespace OpenRA.Traits
public interface IActivity
{
IActivity NextActivity { get; set; }
IActivity Tick(Actor self);
void Cancel(Actor self);
void Queue(IActivity activity);
IEnumerable<float2> GetCurrentPath();
}
public abstract class CancelableActivity : IActivity
{
protected IActivity NextActivity { get; private set; }
protected bool IsCanceled { get; private set; }
public abstract IActivity Tick( Actor self );
protected virtual bool OnCancel() { return true; }
public void Cancel( Actor self )
{
IsCanceled = OnCancel();
if( IsCanceled )
NextActivity = null;
else
NextActivity.Cancel( self );
}
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public virtual IEnumerable<float2> GetCurrentPath()
{
yield break;
}
}
public interface IRenderOverlay { void Render(); }
@@ -203,6 +232,7 @@ namespace OpenRA.Traits
public static readonly Target None = new Target();
public bool IsValid { get { return valid && (actor == null || actor.IsInWorld); } }
public int2 PxPosition { get { return actor != null ? actor.Trait<IHasLocation>().PxPosition : pos.ToInt2(); } }
public float2 CenterLocation { get { return actor != null ? actor.CenterLocation : pos.ToInt2(); } }
public Actor Actor { get { return actor; } }

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Traits
static float2[] fvecs = Graphics.Util.MakeArray<float2>( 32,
i => -float2.FromAngle( i / 16.0f * (float)Math.PI ) * new float2( 1f, 1.3f ) );
public static int _GetFacing( float2 d, int currentFacing )
public static int GetFacing( float2 d, int currentFacing )
{
if (float2.WithinEpsilon(d, float2.Zero, 0.001f))
return currentFacing;
@@ -53,13 +53,6 @@ namespace OpenRA.Traits
return highest * 8;
}
public static int GetFacing(float2 d, int currentFacing)
{
var result = _GetFacing(d, currentFacing);
Log.Write("debug", "GetFacing {0} {1} => {2}", d, currentFacing, result);
return result;
}
public static int GetNearestFacing( int facing, int desiredFacing )
{
var turn = desiredFacing - facing;
@@ -89,14 +82,14 @@ namespace OpenRA.Traits
ecc * (cosAngle * v.Y - sinAngle * v.X));
}
public static float2 CenterOfCell(int2 loc)
public static int2 CenterOfCell(int2 loc)
{
return new float2(12, 12) + Game.CellSize * (float2)loc;
return new int2(Game.CellSize/2, Game.CellSize/2) + Game.CellSize * loc;
}
public static float2 BetweenCells(int2 from, int2 to)
public static int2 BetweenCells(int2 from, int2 to)
{
return 0.5f * (CenterOfCell(from) + CenterOfCell(to));
return int2.Lerp( CenterOfCell( from ), CenterOfCell( to ), 1, 2 );
}
public static int2 AsInt2(this int[] xs) { return new int2(xs[0], xs[1]); }
@@ -113,7 +106,7 @@ namespace OpenRA.Traits
public static IActivity SequenceActivities(params IActivity[] acts)
{
return acts.Reverse().Aggregate(
(next, a) => { a.NextActivity = next; return a; });
(next, a) => { a.Queue( next ); return a; });
}
public static Color ArrayToColor(int[] x) { return Color.FromArgb(x[0], x[1], x[2]); }

View File

@@ -84,7 +84,7 @@ namespace OpenRA.Traits
if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(kv.Key))
continue;
Game.Renderer.SpriteRenderer.DrawSprite(bibSprites[kv.Value.type - 1][kv.Value.image],
bibSprites[kv.Value.type - 1][kv.Value.image].DrawAt(
Game.CellSize * kv.Key, "terrain");
}
}

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Traits
public class ResourceLayerInfo : TraitInfo<ResourceLayer> { }
public class ResourceLayer: IRenderOverlay, IWorldLoaded
{
{
World world;
public ResourceType[] resourceTypes;
@@ -37,6 +37,9 @@ namespace OpenRA.Traits
var miny = cliprect.Top;
var maxy = cliprect.Bottom;
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
rt.info.PaletteIndex = world.WorldRenderer.GetPaletteIndex(rt.info.Palette);
for (int x = minx; x < maxx; x++)
for (int y = miny; y < maxy; y++)
{
@@ -46,9 +49,9 @@ namespace OpenRA.Traits
var c = content[x, y];
if (c.image != null)
Game.Renderer.SpriteRenderer.DrawSprite(c.image[c.density],
c.image[c.density].DrawAt(
Game.CellSize * new int2(x, y),
c.type.info.Palette);
c.type.info.PaletteIndex);
}
}
@@ -146,6 +149,7 @@ namespace OpenRA.Traits
content[p.X, p.Y].type = null;
content[p.X, p.Y].image = null;
content[p.X, p.Y].density = 0;
world.Map.CustomTerrain[p.X, p.Y] = null;
}
public ResourceType GetResource(int2 p) { return content[p.X, p.Y].type; }

View File

@@ -23,6 +23,7 @@ namespace OpenRA.Traits
public readonly string TerrainType = "Ore";
public Sprite[][] Sprites;
public int PaletteIndex;
public object Create(ActorInitializer init) { return new ResourceType(this); }
}

View File

@@ -45,9 +45,9 @@ namespace OpenRA.Traits
for (var i = 0; i <= bins.GetUpperBound(0); i++)
bins[i, j].Clear();
foreach (var a in self.World.Actors)
foreach (var a in self.World.Queries.WithTrait<IHasLocation>())
{
var bounds = a.GetBounds(true);
var bounds = a.Actor.GetBounds(true);
if (bounds.Right <= Game.CellSize * self.World.Map.XOffset) continue;
if (bounds.Bottom <= Game.CellSize * self.World.Map.YOffset) continue;
@@ -61,7 +61,7 @@ namespace OpenRA.Traits
for (var j = j1; j <= j2; j++)
for (var i = i1; i <= i2; i++)
bins[i, j].Add(a);
bins[i, j].Add(a.Actor);
}
}

View File

@@ -49,7 +49,7 @@ namespace OpenRA
for (var i = world.Map.Bounds.Left; i < world.Map.Bounds.Right; i++)
for (var j = world.Map.Bounds.Top; j < world.Map.Bounds.Bottom; j++)
if (uim.GetUnitsAt(new int2(i, j)).Any())
Game.Renderer.SpriteRenderer.DrawSprite(unitDebug, Game.CellSize * new float2(i, j), "terrain");
unitDebug.DrawAt(Game.CellSize * new float2(i, j), "terrain");
}
}
@@ -63,19 +63,17 @@ namespace OpenRA
if (Rules.Info[name].Traits.Contains<LineBuildInfo>())
{
foreach (var t in LineBuildUtils.GetLineBuildCells(world, topLeft, name, bi))
Game.Renderer.SpriteRenderer.DrawSprite(world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, t)
? buildOk : buildBlocked, Game.CellSize * t, "terrain");
(world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, t) ? buildOk : buildBlocked)
.DrawAt(Game.CellSize * t, "terrain");
}
else
{
var res = world.WorldActor.Trait<ResourceLayer>();
var isCloseEnough = world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, topLeft);
foreach (var t in Footprint.Tiles(name, bi, topLeft))
Game.Renderer.SpriteRenderer.DrawSprite((isCloseEnough && world.IsCellBuildable(t, bi.WaterBound) && res.GetResource(t) == null)
? buildOk : buildBlocked, Game.CellSize * t, "terrain");
((isCloseEnough && world.IsCellBuildable(t, bi.WaterBound) && res.GetResource(t) == null) ? buildOk : buildBlocked)
.DrawAt(Game.CellSize * t, "terrain");
}
Game.Renderer.SpriteRenderer.Flush();
}
}

View File

@@ -41,8 +41,7 @@ namespace OpenRA.Widgets
if (DrawBackground)
WidgetUtils.DrawPanel("dialog3", chatLogArea);
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.Device.EnableScissor(chatLogArea.Left, chatLogArea.Top, chatLogArea.Width, chatLogArea.Height);
Game.Renderer.EnableScissor(chatLogArea.Left, chatLogArea.Top, chatLogArea.Width, chatLogArea.Height);
foreach (var line in recentLines.AsEnumerable().Reverse())
{
chatpos.Y -= 20;
@@ -52,8 +51,7 @@ namespace OpenRA.Widgets
Game.Renderer.RegularFont.DrawText(line.Text, chatpos + new int2(inset, 0), Color.White);
}
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.Device.DisableScissor();
Game.Renderer.DisableScissor();
}
public void AddLine(Color c, string from, string text)

View File

@@ -33,8 +33,6 @@ namespace OpenRA.Widgets
Game.Renderer.BoldFont.DrawText(text, RenderOrigin + new float2(3, 7), Color.White);
Game.Renderer.RegularFont.DrawText(content, RenderOrigin + new float2(3 + w, 7), Color.White);
Game.Renderer.RgbaSpriteRenderer.Flush();
}
}

View File

@@ -37,7 +37,6 @@ namespace OpenRA.Widgets
public override void DrawInner(World world)
{
WidgetUtils.FillRectWithColor(RenderBounds, GetColor());
Game.Renderer.LineRenderer.Flush();
}
}
}

View File

@@ -14,56 +14,37 @@ namespace OpenRA.Widgets.Delegates
{
public class ConnectionDialogsDelegate : IWidgetDelegate
{
public ConnectionDialogsDelegate()
[ObjectCreator.UseCtor]
public ConnectionDialogsDelegate( [ObjectCreator.Param( "widget" )] Widget widget )
{
var r = Widget.RootWidget;
r.GetWidget("CONNECTION_BUTTON_ABORT").OnMouseUp = mi => {
r.GetWidget("CONNECTION_BUTTON_ABORT").Parent.Visible = false;
widget.GetWidget("CONNECTION_BUTTON_ABORT").OnMouseUp = mi => {
widget.GetWidget("CONNECTION_BUTTON_ABORT").Parent.Visible = false;
Game.Disconnect();
return true;
};
r.GetWidget("CONNECTION_BUTTON_CANCEL").OnMouseUp = mi => {
r.GetWidget("CONNECTION_BUTTON_CANCEL").Parent.Visible = false;
widget.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Connecting to {0}:{1}...".F(Game.CurrentHost, Game.CurrentPort);
}
}
public class ConnectionFailedDelegate : IWidgetDelegate
{
[ObjectCreator.UseCtor]
public ConnectionFailedDelegate( [ObjectCreator.Param( "widget" )] Widget widget )
{
widget.GetWidget("CONNECTION_BUTTON_CANCEL").OnMouseUp = mi => {
widget.GetWidget("CONNECTION_BUTTON_CANCEL").Parent.Visible = false;
Game.Disconnect();
return true;
};
r.GetWidget("CONNECTION_BUTTON_RETRY").OnMouseUp = mi => {
widget.GetWidget("CONNECTION_BUTTON_RETRY").OnMouseUp = mi => {
Game.JoinServer(Game.CurrentHost, Game.CurrentPort);
return true;
};
r.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Connecting to {0}:{1}...".F(Game.CurrentHost, Game.CurrentPort);
r.GetWidget<LabelWidget>("CONNECTION_FAILED_DESC").GetText = () =>
widget.GetWidget<LabelWidget>("CONNECTION_FAILED_DESC").GetText = () =>
"Could not connect to {0}:{1}".F(Game.CurrentHost, Game.CurrentPort);
Game.ConnectionStateChanged += () =>
{
r.CloseWindow();
switch( Game.orderManager.Connection.ConnectionState )
{
case ConnectionState.PreConnecting:
r.OpenWindow("MAINMENU_BG");
break;
case ConnectionState.Connecting:
r.OpenWindow("CONNECTING_BG");
break;
case ConnectionState.NotConnected:
r.OpenWindow("CONNECTION_FAILED_BG");
break;
case ConnectionState.Connected:
r.OpenWindow("SERVER_LOBBY");
var lobby = r.GetWidget("SERVER_LOBBY");
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
r.GetWidget("INGAME_ROOT").GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
break;
}
};
}
}
}

View File

@@ -14,26 +14,18 @@ using System.Net;
namespace OpenRA.Widgets.Delegates
{
public class CreateServerMenuDelegate : IWidgetDelegate
{
public CreateServerMenuDelegate()
{
[ObjectCreator.UseCtor]
public CreateServerMenuDelegate( [ObjectCreator.Param( "widget" )] Widget cs )
{
var settings = Game.Settings;
var r = Widget.RootWidget;
var cs = r.GetWidget("CREATESERVER_BG");
r.GetWidget("MAINMENU_BUTTON_CREATE").OnMouseUp = mi => {
r.OpenWindow("CREATESERVER_BG");
return true;
};
cs.GetWidget("BUTTON_CANCEL").OnMouseUp = mi => {
r.CloseWindow();
Widget.CloseWindow();
return true;
};
cs.GetWidget("BUTTON_START").OnMouseUp = mi => {
r.OpenWindow("SERVER_LOBBY");
var map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Key;
settings.Server.Name = cs.GetWidget<TextFieldWidget>("GAME_TITLE").Text;

View File

@@ -27,7 +27,8 @@ namespace OpenRA.Widgets.Delegates
public static Color CurrentColorPreview1;
public static Color CurrentColorPreview2;
public LobbyDelegate()
[ObjectCreator.UseCtor]
public LobbyDelegate( [ObjectCreator.Param( "widget" )] Widget lobby )
{
Game.LobbyInfoChanged += UpdateCurrentMap;
UpdateCurrentMap();
@@ -35,9 +36,7 @@ namespace OpenRA.Widgets.Delegates
CurrentColorPreview1 = Game.Settings.Player.Color1;
CurrentColorPreview2 = Game.Settings.Player.Color2;
var r = Widget.RootWidget;
var lobby = r.GetWidget("SERVER_LOBBY");
Players = Widget.RootWidget.GetWidget("SERVER_LOBBY").GetWidget("PLAYERS");
Players = lobby.GetWidget("PLAYERS");
LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE");
EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
@@ -74,8 +73,7 @@ namespace OpenRA.Widgets.Delegates
var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON");
mapButton.OnMouseUp = mi =>
{
r.GetWidget("MAP_CHOOSER").SpecialOneArg(MapUid);
r.OpenWindow("MAP_CHOOSER");
Widget.OpenWindow("MAP_CHOOSER").SpecialOneArg(MapUid); // WTF
return true;
};

View File

@@ -14,13 +14,17 @@ namespace OpenRA.Widgets.Delegates
{
public class MainMenuButtonsDelegate : IWidgetDelegate
{
public MainMenuButtonsDelegate()
[ObjectCreator.UseCtor]
public MainMenuButtonsDelegate( [ObjectCreator.Param( "widget" )] Widget widget )
{
// Main menu is the default window
Widget.WindowList.Push("MAINMENU_BG");
Widget.RootWidget.GetWidget("MAINMENU_BUTTON_QUIT").OnMouseUp = mi => { Game.Exit(); return true; };
widget.GetWidget( "MAINMENU_BUTTON_JOIN" ).OnMouseUp = mi => { Widget.OpenWindow( "JOINSERVER_BG" ); return true; };
widget.GetWidget( "MAINMENU_BUTTON_CREATE" ).OnMouseUp = mi => { Widget.OpenWindow( "CREATESERVER_BG" ); return true; };
widget.GetWidget( "MAINMENU_BUTTON_SETTINGS" ).OnMouseUp = mi => { Widget.OpenWindow( "SETTINGS_MENU" ); return true; };
widget.GetWidget( "MAINMENU_BUTTON_MUSIC" ).OnMouseUp = mi => { Widget.OpenWindow( "MUSIC_MENU" ); return true; };
widget.GetWidget( "MAINMENU_BUTTON_QUIT" ).OnMouseUp = mi => { Game.Exit(); return true; };
var version = Widget.RootWidget.GetWidget("MAINMENU_BG").GetWidget<LabelWidget>("VERSION_STRING");
var version = widget.GetWidget<LabelWidget>("VERSION_STRING");
if (FileSystem.Exists("VERSION"))
{

View File

@@ -17,10 +17,10 @@ namespace OpenRA.Widgets.Delegates
public class MapChooserDelegate : IWidgetDelegate
{
MapStub Map = null;
public MapChooserDelegate()
[ObjectCreator.UseCtor]
public MapChooserDelegate( [ObjectCreator.Param( "widget" )] Widget bg )
{
var r = Widget.RootWidget;
var bg = r.GetWidget("MAP_CHOOSER");
bg.SpecialOneArg = (map) => RefreshMapList(map);
var ml = bg.GetWidget<ListBoxWidget>("MAP_LIST");
@@ -33,13 +33,13 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("BUTTON_OK").OnMouseUp = mi =>
{
Game.IssueOrder(Order.Command("map " + Map.Uid));
r.CloseWindow();
Widget.CloseWindow();
return true;
};
bg.GetWidget("BUTTON_CANCEL").OnMouseUp = mi =>
{
r.CloseWindow();
Widget.CloseWindow();
return true;
};

View File

@@ -24,15 +24,10 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("BUTTON_CLOSE").OnMouseUp = mi => {
Game.Settings.Save();
Widget.RootWidget.CloseWindow();
Widget.CloseWindow();
return true;
};
Widget.RootWidget.GetWidget("MAINMENU_BUTTON_MUSIC").OnMouseUp = mi => {
Widget.RootWidget.OpenWindow("MUSIC_MENU");
return true;
};
bg.GetWidget("BUTTON_PLAY").OnMouseUp = mi =>
{
if (CurrentSong == null)

View File

@@ -23,28 +23,20 @@ namespace OpenRA.Widgets.Delegates
GameServer currentServer = null;
Widget ServerTemplate;
public ServerBrowserDelegate()
[ObjectCreator.UseCtor]
public ServerBrowserDelegate( [ObjectCreator.Param( "widget" )] Widget widget )
{
var r = Widget.RootWidget;
var bg = r.GetWidget("JOINSERVER_BG");
var dc = r.GetWidget("DIRECTCONNECT_BG");
var bg = widget.GetWidget("JOINSERVER_BG");
MasterServerQuery.OnComplete += games => RefreshServerList(games);
r.GetWidget("MAINMENU_BUTTON_JOIN").OnMouseUp = mi =>
{
r.OpenWindow("JOINSERVER_BG");
bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
bg.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
r.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
bg.Children.RemoveAll(a => GameButtons.Contains(a));
GameButtons.Clear();
bg.Children.RemoveAll(a => GameButtons.Contains(a));
GameButtons.Clear();
MasterServerQuery.Refresh(Game.Settings.Server.MasterServer);
return true;
};
MasterServerQuery.Refresh(Game.Settings.Server.MasterServer);
bg.GetWidget("SERVER_INFO").IsVisible = () => currentServer != null;
var preview = bg.GetWidget<MapPreviewWidget>("MAP_PREVIEW");
@@ -70,8 +62,8 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("REFRESH_BUTTON").OnMouseUp = mi =>
{
r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
r.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
bg.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
bg.Children.RemoveAll(a => GameButtons.Contains(a));
GameButtons.Clear();
@@ -83,16 +75,14 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("CANCEL_BUTTON").OnMouseUp = mi =>
{
r.CloseWindow();
Widget.CloseWindow();
return true;
};
bg.GetWidget("DIRECTCONNECT_BUTTON").OnMouseUp = mi =>
{
r.CloseWindow();
dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
r.OpenWindow("DIRECTCONNECT_BG");
Widget.CloseWindow();
Widget.OpenWindow("DIRECTCONNECT_BG");
return true;
};
@@ -119,33 +109,10 @@ namespace OpenRA.Widgets.Delegates
return false;
}
r.CloseWindow();
Widget.CloseWindow();
Game.JoinServer(currentServer.Address.Split(':')[0], int.Parse(currentServer.Address.Split(':')[1]));
return true;
};
// Direct Connect
dc.GetWidget("JOIN_BUTTON").OnMouseUp = mi =>
{
var address = dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text;
var cpts = address.Split(':').ToArray();
if (cpts.Length != 2)
return true;
Game.Settings.Player.LastServer = address;
Game.Settings.Save();
r.CloseWindow();
Game.JoinServer(cpts[0], int.Parse(cpts[1]));
return true;
};
dc.GetWidget("CANCEL_BUTTON").OnMouseUp = mi =>
{
r.CloseWindow();
return r.GetWidget("MAINMENU_BUTTON_JOIN").OnMouseUp(mi);
};
}
MapStub CurrentMap()
@@ -205,4 +172,37 @@ namespace OpenRA.Widgets.Delegates
}
}
}
public class DirectConnectDelegate : IWidgetDelegate
{
[ObjectCreator.UseCtor]
public DirectConnectDelegate( [ObjectCreator.Param( "widget" )] Widget widget )
{
var dc = widget.GetWidget("DIRECTCONNECT_BG");
dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
dc.GetWidget("JOIN_BUTTON").OnMouseUp = mi =>
{
var address = dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text;
var cpts = address.Split(':').ToArray();
if (cpts.Length != 2)
return true;
Game.Settings.Player.LastServer = address;
Game.Settings.Save();
Widget.CloseWindow();
Game.JoinServer(cpts[0], int.Parse(cpts[1]));
return true;
};
dc.GetWidget("CANCEL_BUTTON").OnMouseUp = mi =>
{
Widget.CloseWindow();
Widget.OpenWindow("MAINMENU_BG");
return true;
};
}
}
}

View File

@@ -150,17 +150,9 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("BUTTON_CLOSE").OnMouseUp = mi => {
Game.Settings.Save();
Widget.RootWidget.CloseWindow();
Widget.CloseWindow();
return true;
};
// Menu Buttons
Widget.RootWidget.GetWidget("MAINMENU_BUTTON_SETTINGS").OnMouseUp = mi => {
Widget.RootWidget.OpenWindow("SETTINGS_MENU");
return true;
};
}
string open = null;

View File

@@ -44,13 +44,13 @@ namespace OpenRA.Widgets.Delegates
bg.GetWidget("BUTTON_CLOSE").OnMouseUp = mi => {
player.Stop();
Widget.RootWidget.CloseWindow();
Widget.CloseWindow();
return true;
};
// Menu Buttons
Widget.RootWidget.GetWidget("MAINMENU_BUTTON_VIDEOPLAYER").OnMouseUp = mi => {
Widget.RootWidget.OpenWindow("VIDEOPLAYER_MENU");
Widget.OpenWindow("VIDEOPLAYER_MENU");
return true;
};

View File

@@ -71,15 +71,12 @@ namespace OpenRA.Widgets
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", "down_arrow"),
new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset));
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.Device.EnableScissor(backgroundRect.X, backgroundRect.Y + HeaderHeight, backgroundRect.Width, backgroundRect.Height - HeaderHeight);
Game.Renderer.EnableScissor(backgroundRect.X, backgroundRect.Y + HeaderHeight, backgroundRect.Width, backgroundRect.Height - HeaderHeight);
foreach (var child in Children)
child.Draw(world);
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.Device.DisableScissor();
Game.Renderer.DisableScissor();
}
public override int2 ChildOrigin { get { return RenderOrigin + new int2(0, (int)ListOffset); } }

View File

@@ -105,8 +105,6 @@ namespace OpenRA.Widgets
new float2(MapRect.Location),
new float2( MapRect.Size ) );
Game.Renderer.RgbaSpriteRenderer.Flush();
// Overlay spawnpoints
var colors = SpawnColors();
foreach (var p in map.SpawnPoints)
@@ -120,12 +118,9 @@ namespace OpenRA.Widgets
sprite = OwnedSpawn;
offset = new int2(-OwnedSpawn.bounds.Width/2, -OwnedSpawn.bounds.Height/2);
WidgetUtils.FillRectWithColor(new Rectangle(pos.X + offset.X + 2, pos.Y + offset.Y + 2, 12, 12), colors[p]);
Game.Renderer.LineRenderer.Flush();
}
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos + offset);
}
Game.Renderer.Flush();
}
}
}

View File

@@ -40,8 +40,6 @@ namespace OpenRA.Widgets
return b;
});
}
Game.Renderer.LineRenderer.Flush();
}
}
}

View File

@@ -127,16 +127,13 @@ namespace OpenRA.Widgets
if (Focused)
textPos += new int2(Bounds.Width - 2 * margin - textSize.X, 0);
Game.Renderer.Device.EnableScissor(pos.X + margin, pos.Y, Bounds.Width - 2 * margin, Bounds.Bottom);
Game.Renderer.EnableScissor(pos.X + margin, pos.Y, Bounds.Width - 2 * margin, Bounds.Bottom);
}
font.DrawText(Text + cursor, textPos, Color.White);
if (textSize.X > Bounds.Width - 2 * margin)
{
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.Device.DisableScissor();
}
Game.Renderer.DisableScissor();
}
public override Widget Clone() { return new TextFieldWidget(this); }

View File

@@ -26,6 +26,7 @@ namespace OpenRA.Widgets
public string Width = "0";
public string Height = "0";
public string Delegate = null;
public string EventHandler = null;
public bool ClickThrough = true;
public bool Visible = true;
public readonly List<Widget> Children = new List<Widget>();
@@ -35,7 +36,7 @@ namespace OpenRA.Widgets
public Widget Parent = null;
static List<string> Delegates = new List<string>();
public static Stack<string> WindowList = new Stack<string>();
public static Stack<Widget> WindowList = new Stack<Widget>();
// Common Funcs that most widgets will want
public Action<object> SpecialOneArg = (arg) => {};
@@ -47,24 +48,13 @@ namespace OpenRA.Widgets
public Func<bool> IsVisible;
public Widget() { IsVisible = () => Visible; }
public static Widget RootWidget {
get
{
if (rootWidget == null)
{
rootWidget = new ContainerWidget();
foreach( var file in Game.modData.Manifest.ChromeLayout.Select( a => MiniYaml.FromFile( a ) ) )
foreach( var w in file )
rootWidget.AddChild( WidgetLoader.LoadWidget( w ) );
rootWidget.Initialize();
rootWidget.InitDelegates();
}
return rootWidget;
}
public static Widget RootWidget
{
get { return rootWidget; }
set { rootWidget = value; }
}
private static Widget rootWidget = null;
private static Widget rootWidget = new ContainerWidget();
public Widget(Widget widget)
{
@@ -132,14 +122,15 @@ namespace OpenRA.Widgets
Evaluator.Evaluate(Y, substitutions),
width,
height);
}
// Non-static func definitions
if (Delegate != null && !Delegates.Contains(Delegate))
Delegates.Add(Delegate);
foreach (var child in Children)
child.Initialize();
public void PostInit()
{
if( Delegate != null )
{
var createDict = new Dictionary<string, object> { { "widget", this } };
Game.modData.ObjectCreator.CreateObject<IWidgetDelegate>( Delegate, createDict );
}
}
public void InitDelegates()
@@ -322,20 +313,19 @@ namespace OpenRA.Widgets
return (widget != null)? (T) widget : null;
}
public void CloseWindow()
public static void CloseWindow()
{
RootWidget.GetWidget(WindowList.Pop()).Visible = false;
if (WindowList.Count > 0)
RootWidget.GetWidget(WindowList.Peek()).Visible = true;
RootWidget.Children.Remove( WindowList.Pop() );
if( WindowList.Count > 0 )
rootWidget.Children.Add( WindowList.Peek() );
}
public Widget OpenWindow(string id)
public static Widget OpenWindow(string id)
{
if (WindowList.Count > 0)
RootWidget.GetWidget(WindowList.Peek()).Visible = false;
WindowList.Push(id);
var window = RootWidget.GetWidget(id);
window.Visible = true;
var window = Game.modData.WidgetLoader.LoadWidget( rootWidget, id );
if( WindowList.Count > 0 )
rootWidget.Children.Remove( WindowList.Peek() );
WindowList.Push( window );
return window;
}

View File

@@ -8,29 +8,57 @@
*/
#endregion
using System.Linq;
using System.Collections.Generic;
using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA
{
class WidgetLoader
public class WidgetLoader
{
public static Widget LoadWidget(MiniYamlNode node)
// foreach( var file in Game.modData.Manifest.ChromeLayout.Select( a => MiniYaml.FromFile( a ) ) )
// foreach( var w in file )
// rootWidget.AddChild( WidgetLoader.LoadWidget( w ) );
// rootWidget.Initialize();
// rootWidget.InitDelegates();
Dictionary<string, MiniYamlNode> widgets = new Dictionary<string, MiniYamlNode>();
public WidgetLoader( ModData modData )
{
foreach( var file in modData.Manifest.ChromeLayout.Select( a => MiniYaml.FromFile( a ) ) )
foreach( var w in file )
widgets.Add( w.Key.Substring( w.Key.IndexOf( '@' ) + 1 ), w );
}
public Widget LoadWidget( Widget parent, string w )
{
return LoadWidget( parent, widgets[ w ] );
}
public Widget LoadWidget( Widget parent, MiniYamlNode node)
{
var widget = NewWidget(node.Key);
parent.AddChild( widget );
foreach (var child in node.Value.Nodes)
if (child.Key != "Children")
FieldLoader.LoadField(widget, child.Key, child.Value.Value);
widget.Initialize();
foreach (var child in node.Value.Nodes)
{
if (child.Key == "Children")
foreach (var c in child.Value.Nodes)
widget.AddChild(LoadWidget(c));
else
FieldLoader.LoadField(widget, child.Key, child.Value.Value);
}
LoadWidget( widget, c);
widget.PostInit();
return widget;
}
static Widget NewWidget(string widgetType)
Widget NewWidget(string widgetType)
{
widgetType = widgetType.Split('@')[0];
return Game.CreateObject<Widget>(widgetType + "Widget");

View File

@@ -127,8 +127,6 @@ namespace OpenRA.Widgets
DrawRGBA(ss[6], new float2(Bounds.Left, Bounds.Bottom - ss[6].size.Y));
if (ps.HasFlags(PanelSides.Right | PanelSides.Bottom))
DrawRGBA(ss[7], new float2(Bounds.Right - ss[7].size.X, Bounds.Bottom - ss[7].size.Y));
Game.Renderer.RgbaSpriteRenderer.Flush();
}
}

View File

@@ -39,8 +39,6 @@ namespace OpenRA.Widgets
foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second))
world.WorldRenderer.DrawSelectionBox(u, Color.Yellow);
Game.Renderer.LineRenderer.Flush();
}
float2 dragStart, dragEnd;

View File

@@ -85,7 +85,6 @@ namespace OpenRA.Widgets
ChromeProvider.GetImage("flags", actor.Owner.Country.Race),
new float2(Viewport.LastMousePos.X + 30, Viewport.LastMousePos.Y + 50));
}
Game.Renderer.RgbaSpriteRenderer.Flush();
}
}
}

View File

@@ -22,13 +22,21 @@ namespace OpenRA.GlRenderer
{
Gl.glGenBuffers(1, out buffer);
GraphicsDevice.CheckGlError();
}
public void SetData(ushort[] data)
{
Bind();
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER,
new IntPtr(2 * data.Length), data, Gl.GL_DYNAMIC_DRAW);
new IntPtr(2 * size),
new ushort[ size ],
Gl.GL_DYNAMIC_DRAW);
GraphicsDevice.CheckGlError();
}
public void SetData(ushort[] data, int length)
{
Bind();
Gl.glBufferSubData(Gl.GL_ELEMENT_ARRAY_BUFFER,
IntPtr.Zero,
new IntPtr(2 * length),
data);
GraphicsDevice.CheckGlError();
}

View File

@@ -24,13 +24,21 @@ namespace OpenRA.GlRenderer
{
Gl.glGenBuffers(1, out buffer);
GraphicsDevice.CheckGlError();
}
public void SetData(T[] data)
{
Bind();
Gl.glBufferData(Gl.GL_ARRAY_BUFFER,
new IntPtr(Marshal.SizeOf(typeof(T)) * data.Length), data, Gl.GL_DYNAMIC_DRAW);
new IntPtr(Marshal.SizeOf(typeof(T)) * size),
new T[ size ],
Gl.GL_DYNAMIC_DRAW);
GraphicsDevice.CheckGlError();
}
public void SetData(T[] data, int length)
{
Bind();
Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER,
IntPtr.Zero,
new IntPtr(Marshal.SizeOf(typeof(T)) * length),
data);
GraphicsDevice.CheckGlError();
}

View File

@@ -65,7 +65,6 @@ namespace OpenRA.Mods.Cnc
WidgetUtils.FillRectWithSprite(StripeRect, Stripe);
r.RgbaSpriteRenderer.DrawSprite(Logo, LogoPos);
Font.DrawText(text, new float2(Renderer.Resolution.Width - textSize.X - 20, Renderer.Resolution.Height - textSize.Y - 20), Color.White);
r.RgbaSpriteRenderer.Flush();
r.EndFrame();
}
}

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA
public static void PlayFullscreenFMVThen(World w, string movie, Action then)
{
var playerRoot = Widget.RootWidget.OpenWindow("FMVPLAYER");
var playerRoot = Widget.OpenWindow("FMVPLAYER");
var player = playerRoot.GetWidget<VqaPlayerWidget>("PLAYER");
w.DisableTick = true;
player.Load(movie);
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.RA
if (music)
Sound.PlayMusic();
Widget.RootWidget.CloseWindow();
Widget.CloseWindow();
w.DisableTick = false;
then();
});

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Cnc
new AltitudeInit( Rules.Info["c17"].Traits.Get<PlaneInfo>().CruiseAltitude ),
});
a.QueueActivity(new Fly(self.Location + new int2(6,0)));
a.QueueActivity(Fly.ToCell(self.Location + new int2(6,0)));
a.QueueActivity(new Land(Target.FromActor(self)));
a.QueueActivity(new CallFunc(() =>
{
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Cnc
rb.PlayCustomAnimRepeating(self, "idle");
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit));
}));
a.QueueActivity(new Fly(endPos));
a.QueueActivity(Fly.ToCell(endPos));
a.QueueActivity(new RemoveSelf());
});

View File

@@ -31,9 +31,9 @@ namespace OpenRA.Mods.Cnc
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
{
foreach (var c in cargo.Passengers)
c.CenterLocation = self.CenterLocation;
{
foreach( var c in cargo.Passengers )
c.Trait<ITeleportable>().SetPxPosition( c, self.Trait<IHasLocation>().PxPosition );
return r.Concat(cargo.Passengers.SelectMany(a => a.Render()));
}

View File

@@ -25,8 +25,8 @@ namespace OpenRA.Mods.Cnc
bool preventDock = false;
public void OnDock(Actor self, Actor harv, DeliverResources dockOrder)
{
float2 startDock = harv.CenterLocation;
float2 endDock = self.CenterLocation + new float2(-15,8);
int2 startDock = harv.Trait<IHasLocation>().PxPosition;
int2 endDock = self.Trait<IHasLocation>().PxPosition + new int2(-15,8);
var harvester = harv.Trait<Harvester>();
harv.QueueActivity( new Turn(112) );

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits.Activities;
namespace OpenRA.Mods.RA.Activities
{
/* non-turreted attack */
public class Attack : IActivity
public class Attack : CancelableActivity
{
Target Target;
int Range;
@@ -26,10 +26,17 @@ namespace OpenRA.Mods.RA.Activities
Range = range;
}
public IActivity NextActivity { get; set; }
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
var attack = self.Trait<AttackBase>();
var ret = InnerTick( self, attack );
attack.IsAttacking = ( ret == this );
return ret;
}
IActivity InnerTick( Actor self, AttackBase attack )
{
if (IsCanceled) return NextActivity;
var facing = self.Trait<IFacing>();
if (!Target.IsValid)
return NextActivity;
@@ -37,7 +44,7 @@ namespace OpenRA.Mods.RA.Activities
var targetCell = Util.CellContaining(Target.CenterLocation);
if ((targetCell - self.Location).LengthSquared >= Range * Range)
return new Move( Target, Range ) { NextActivity = this };
return Util.SequenceActivities( new Move( Target, Range ), this );
var desiredFacing = Util.GetFacing((targetCell - self.Location).ToFloat2(), 0);
var renderUnit = self.TraitOrDefault<RenderUnit>();
@@ -47,15 +54,12 @@ namespace OpenRA.Mods.RA.Activities
if (Util.QuantizeFacing(facing.Facing, numDirs)
!= Util.QuantizeFacing(desiredFacing, numDirs))
{
return new Turn( desiredFacing ) { NextActivity = this };
return Util.SequenceActivities( new Turn( desiredFacing ), this );
}
var attack = self.Trait<AttackBase>();
attack.target = Target;
attack.DoAttack(self);
return this;
}
public void Cancel(Actor self) { Target = Target.None; }
}
}

View File

@@ -9,6 +9,7 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities
Action a;
bool interruptable;
public IActivity NextActivity { get; set; }
IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
{
@@ -40,5 +41,18 @@ namespace OpenRA.Mods.RA.Activities
a = null;
NextActivity = null;
}
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public IEnumerable<float2> GetCurrentPath()
{
yield break;
}
}
}

View File

@@ -12,16 +12,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class CaptureBuilding : IActivity
class CaptureBuilding : CancelableActivity
{
Target target;
public CaptureBuilding(Actor target) { this.target = Target.FromActor(target); }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
if (!target.IsValid) return NextActivity;
if ((target.Actor.Location - self.Location).Length > 1)
return NextActivity;
@@ -41,7 +40,5 @@ namespace OpenRA.Mods.RA.Activities
});
return NextActivity;
}
public void Cancel(Actor self) { target = Target.None; NextActivity = null; }
}
}

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System.Collections.Generic;
using OpenRA.Traits;
using OpenRA.Traits.Activities;
@@ -15,7 +16,7 @@ namespace OpenRA.Mods.RA.Activities
{
public class DeliverResources : IActivity
{
public IActivity NextActivity { get; set; }
IActivity NextActivity { get; set; }
bool isDocking;
@@ -32,25 +33,38 @@ namespace OpenRA.Mods.RA.Activities
harv.ChooseNewProc(self, null);
if (harv.LinkedProc == null) // no procs exist; check again in 1s.
return new Wait(25) { NextActivity = this };
return Util.SequenceActivities( new Wait(25), this );
var proc = harv.LinkedProc;
if( self.Location != proc.Location + proc.Trait<IAcceptOre>().DeliverOffset )
{
return new Move(proc.Location + proc.Trait<IAcceptOre>().DeliverOffset, 0) { NextActivity = this };
return Util.SequenceActivities( new Move(proc.Location + proc.Trait<IAcceptOre>().DeliverOffset, 0), this );
}
else if (!isDocking)
{
isDocking = true;
proc.Trait<IAcceptOre>().OnDock(self, this);
}
return new Wait(10) { NextActivity = this };
return Util.SequenceActivities( new Wait(10), this );
}
public void Cancel(Actor self)
{
// TODO: allow canceling of deliver orders?
}
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public IEnumerable<float2> GetCurrentPath()
{
yield break;
}
}
}

View File

@@ -13,15 +13,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class Demolish : IActivity
class Demolish : CancelableActivity
{
Target target;
public IActivity NextActivity { get; set; }
public Demolish( Actor target ) { this.target = Target.FromActor(target); }
public IActivity Tick(Actor self)
{
public override IActivity Tick(Actor self)
{
if( IsCanceled ) return NextActivity;
if (!target.IsValid) return NextActivity;
if ((target.Actor.Location - self.Location).Length > 1)
return NextActivity;
@@ -31,7 +31,5 @@ namespace OpenRA.Mods.RA.Activities
() => { if (target.IsValid) target.Actor.Kill(self); })));
return NextActivity;
}
public void Cancel(Actor self) { target = Target.None; NextActivity = null; }
}
}

View File

@@ -12,10 +12,8 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class EnterTransport : IActivity
class EnterTransport : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
public Actor transport;
public EnterTransport(Actor self, Actor transport)
@@ -23,9 +21,9 @@ namespace OpenRA.Mods.RA.Activities
this.transport = transport;
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
if (transport == null || !transport.IsInWorld) return NextActivity;
var cargo = transport.Trait<Cargo>();
@@ -43,7 +41,5 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -9,26 +9,28 @@
#endregion
using System;
using System.Linq;
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Fly : IActivity
public class Fly : CancelableActivity
{
public readonly float2 Pos;
bool isCanceled;
public Fly(float2 pos) { Pos = pos; }
public Fly(int2 pos) { Pos = Util.CenterOfCell(pos); }
private Fly( float2 pos )
{
this.Pos = pos;
}
public static Fly ToPx( float2 px ) { return new Fly( px ); }
public static Fly ToCell( int2 pos ) { return new Fly( Util.CenterOfCell( pos ) ); }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
var cruiseAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
var d = Pos - self.CenterLocation;
if (d.LengthSquared < 50) /* close enough */
@@ -47,7 +49,10 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
public override IEnumerable<float2> GetCurrentPath()
{
yield return Pos;
}
}
public static class FlyUtil
@@ -57,7 +62,7 @@ namespace OpenRA.Mods.RA.Activities
var aircraft = self.Trait<Aircraft>();
var speed = .2f * aircraft.MovementSpeedForCell(self, self.Location);
var angle = aircraft.Facing / 128f * Math.PI;
self.CenterLocation += speed * -float2.FromAngle((float)angle);
aircraft.center += speed * -float2.FromAngle((float)angle);
aircraft.Location = Util.CellContaining(self.CenterLocation);
aircraft.Altitude += Math.Sign(desiredAltitude - aircraft.Altitude);
}

View File

@@ -12,15 +12,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class FlyAttack : IActivity
public class FlyAttack : CancelableActivity
{
public IActivity NextActivity { get; set; }
Target Target;
public FlyAttack(Target target) { Target = target; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
if (!Target.IsValid)
return NextActivity;
@@ -29,33 +29,26 @@ namespace OpenRA.Mods.RA.Activities
return NextActivity;
return Util.SequenceActivities(
new Fly(Target.CenterLocation),
Fly.ToPx(Target.CenterLocation),
new FlyTimed(50),
this);
}
public void Cancel(Actor self) { Target = Target.None; NextActivity = null; }
}
public class FlyCircle : IActivity
public class FlyCircle : CancelableActivity
{
public IActivity NextActivity { get; set; }
int2 Target;
bool isCanceled;
public FlyCircle(int2 target) { Target = target; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled)
return NextActivity;
if( IsCanceled ) return NextActivity;
return Util.SequenceActivities(
new Fly(Util.CenterOfCell(Target)),
Fly.ToPx(Util.CenterOfCell(Target)),
new FlyTimed(50),
this);
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -12,46 +12,37 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class FlyTimed : IActivity
public class FlyTimed : CancelableActivity
{
public IActivity NextActivity { get; set; }
int remainingTicks;
public FlyTimed(int ticks) { remainingTicks = ticks; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if( IsCanceled ) return NextActivity;
var targetAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
if (remainingTicks-- == 0) return NextActivity;
FlyUtil.Fly(self, targetAltitude);
return this;
}
public void Cancel(Actor self) { remainingTicks = 0; NextActivity = null; }
}
public class FlyOffMap : IActivity
public class FlyOffMap : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
public bool Interruptible = true;
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
var targetAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
if (isCanceled || !self.World.Map.IsInMap(self.Location)) return NextActivity;
if (IsCanceled || !self.World.Map.IsInMap(self.Location)) return NextActivity;
FlyUtil.Fly(self, targetAltitude);
return this;
}
public void Cancel(Actor self)
protected override bool OnCancel()
{
if (Interruptible)
{
isCanceled = true;
NextActivity = null;
}
return Interruptible;
}
}
}

View File

@@ -13,7 +13,7 @@ using OpenRA.Traits.Activities;
namespace OpenRA.Mods.RA.Activities
{
public class Follow : IActivity
public class Follow : CancelableActivity
{
Target Target;
int Range;
@@ -24,24 +24,18 @@ namespace OpenRA.Mods.RA.Activities
Range = range;
}
public IActivity NextActivity { get; set; }
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
if (!Target.IsValid)
return NextActivity;
if (IsCanceled) return NextActivity;
if (!Target.IsValid) return NextActivity;
var inRange = ( Util.CellContaining( Target.CenterLocation ) - self.Location ).LengthSquared < Range * Range;
if( !inRange )
return new Move( Target, Range ) { NextActivity = this };
if( inRange ) return this;
return this;
}
public void Cancel(Actor self)
{
Target = Target.None;
var ret = new Move( Target, Range );
ret.Queue( this );
return ret;
}
}
}

View File

@@ -15,21 +15,21 @@ using OpenRA.Traits.Activities;
namespace OpenRA.Mods.RA.Activities
{
public class Harvest : IActivity
public class Harvest : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isHarvesting = false;
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
if( isHarvesting ) return this;
if( IsCanceled ) return NextActivity;
if( NextActivity != null ) return NextActivity;
var harv = self.Trait<Harvester>();
harv.LastHarvestedCell = self.Location;
if( harv.IsFull )
return new DeliverResources { NextActivity = NextActivity };
return Util.SequenceActivities( new DeliverResources(), NextActivity );
if (HarvestThisTile(self))
return this;
@@ -72,7 +72,5 @@ namespace OpenRA.Mods.RA.Activities
}));
self.QueueActivity(new Harvest());
}
public void Cancel(Actor self) { }
}
}

View File

@@ -14,17 +14,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class HeliAttack : IActivity
public class HeliAttack : CancelableActivity
{
Target target;
public HeliAttack( Target target ) { this.target = target; }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (!target.IsValid)
return NextActivity;
if (IsCanceled) return NextActivity;
if (!target.IsValid) return NextActivity;
var limitedAmmo = self.TraitOrDefault<LimitedAmmo>();
if (limitedAmmo != null && !limitedAmmo.HasAmmo())
@@ -49,11 +47,9 @@ namespace OpenRA.Mods.RA.Activities
var rawSpeed = .2f * aircraft.MovementSpeedForCell(self, self.Location);
if (!float2.WithinEpsilon(float2.Zero, dist, range * Game.CellSize))
self.CenterLocation += (rawSpeed / dist.Length) * dist;
aircraft.center += (rawSpeed / dist.Length) * dist;
return this;
}
public void Cancel(Actor self) { target = Target.None; NextActivity = null; }
}
}

View File

@@ -9,12 +9,12 @@
#endregion
using System;
using System.Linq;
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class HeliFly : IActivity
class HeliFly : CancelableActivity
{
public readonly float2 Dest;
public HeliFly(float2 dest)
@@ -22,13 +22,9 @@ namespace OpenRA.Mods.RA.Activities
Dest = dest;
}
public IActivity NextActivity { get; set; }
bool isCanceled;
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled)
return NextActivity;
if (IsCanceled) return NextActivity;
var info = self.Info.Traits.Get<HelicopterInfo>();
var aircraft = self.Trait<Aircraft>();
@@ -42,7 +38,7 @@ namespace OpenRA.Mods.RA.Activities
var dist = Dest - self.CenterLocation;
if (float2.WithinEpsilon(float2.Zero, dist, 2))
{
self.CenterLocation = Dest;
aircraft.center = Dest;
aircraft.Location = Util.CellContaining(self.CenterLocation);
return NextActivity;
}
@@ -52,12 +48,15 @@ namespace OpenRA.Mods.RA.Activities
aircraft.ROT);
var rawSpeed = .2f * aircraft.MovementSpeedForCell(self, self.Location);
self.CenterLocation += (rawSpeed / dist.Length) * dist;
aircraft.center += (rawSpeed / dist.Length) * dist;
aircraft.Location = Util.CellContaining(self.CenterLocation);
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
public override IEnumerable<float2> GetCurrentPath()
{
yield return Dest;
}
}
}

View File

@@ -12,17 +12,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class HeliLand : IActivity
class HeliLand : CancelableActivity
{
public HeliLand(bool requireSpace) { this.requireSpace = requireSpace; }
bool requireSpace;
bool isCanceled;
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
var aircraft = self.Trait<Aircraft>();
if (aircraft.Altitude == 0)
return NextActivity;
@@ -33,7 +31,5 @@ namespace OpenRA.Mods.RA.Activities
--aircraft.Altitude;
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -14,11 +14,8 @@ using OpenRA.Traits.Activities;
namespace OpenRA.Mods.RA.Activities
{
public class HeliReturn : IActivity
public class HeliReturn : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
static Actor ChooseHelipad(Actor self)
{
var rearmBuildings = self.Info.Traits.Get<HelicopterInfo>().RearmBuildings;
@@ -27,9 +24,9 @@ namespace OpenRA.Mods.RA.Activities
!Reservable.IsReserved(a));
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
var dest = ChooseHelipad(self);
var initialFacing = self.Info.Traits.Get<AircraftInfo>().InitialFacing;
@@ -54,7 +51,5 @@ namespace OpenRA.Mods.RA.Activities
new Rearm(),
NextActivity);
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -6,11 +6,11 @@
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
using System;
#endregion
using System.Collections.Generic;
using OpenRA.Mods.RA.Render;
using OpenRA.Traits;
using OpenRA.Mods.RA.Render;
namespace OpenRA.Mods.RA.Activities
{
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities
this.delay = delay;
}
public IActivity NextActivity { get; set; }
IActivity NextActivity { get; set; }
bool active = true;
public IActivity Tick(Actor self)
@@ -43,5 +43,18 @@ namespace OpenRA.Mods.RA.Activities
active = false;
NextActivity = null;
}
public void Queue( IActivity activity )
{
if( NextActivity != null )
NextActivity.Queue( activity );
else
NextActivity = activity;
}
public IEnumerable<float2> GetCurrentPath()
{
yield break;
}
}
}

View File

@@ -12,14 +12,14 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class Infiltrate : IActivity
class Infiltrate : CancelableActivity
{
Actor target;
public Infiltrate(Actor target) { this.target = target; }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
if (target == null || target.IsDead()) return NextActivity;
if (target.Owner == self.Owner) return NextActivity;
@@ -30,7 +30,5 @@ namespace OpenRA.Mods.RA.Activities
return NextActivity;
}
public void Cancel(Actor self) { target = null; NextActivity = null; }
}
}

View File

@@ -14,21 +14,18 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Land : IActivity
public class Land : CancelableActivity
{
bool isCanceled;
Target Target;
public Land(Target t) { Target = t; }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (!Target.IsValid)
Cancel(self);
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
var d = Target.CenterLocation - self.CenterLocation;
if (d.LengthSquared < 50) /* close enough */
@@ -44,12 +41,10 @@ namespace OpenRA.Mods.RA.Activities
var speed = .2f * aircraft.MovementSpeedForCell(self, self.Location);
var angle = aircraft.Facing / 128f * Math.PI;
self.CenterLocation += speed * -float2.FromAngle((float)angle);
aircraft.center += speed * -float2.FromAngle((float)angle);
aircraft.Location = Util.CellContaining(self.CenterLocation);
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -17,14 +17,11 @@ namespace OpenRA.Mods.RA.Activities
{
// assumes you have Minelayer on that unit
class LayMines : IActivity
class LayMines : CancelableActivity
{
bool canceled = false;
public IActivity NextActivity { get; set; }
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
if (canceled) return NextActivity;
if (IsCanceled) return NextActivity;
var limitedAmmo = self.TraitOrDefault<LimitedAmmo>();
if (!limitedAmmo.HasAmmo())
@@ -37,8 +34,11 @@ namespace OpenRA.Mods.RA.Activities
if (rearmTarget == null)
return new Wait(20);
return new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget)
{ NextActivity = new Rearm() { NextActivity = new Repair(rearmTarget) { NextActivity = this } } };
return Util.SequenceActivities(
new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget),
new Rearm(),
new Repair(rearmTarget),
this );
}
var ml = self.Trait<Minelayer>();
@@ -46,14 +46,14 @@ namespace OpenRA.Mods.RA.Activities
ShouldLayMine(self, self.Location))
{
LayMine(self);
return new Wait(20) { NextActivity = this }; // a little wait after placing each mine, for show
return Util.SequenceActivities( new Wait(20), this ); // a little wait after placing each mine, for show
}
for (var n = 0; n < 20; n++) // dont get stuck forever here
{
var p = ml.minefield.Random(self.World.SharedRandom);
if (ShouldLayMine(self, p))
return new Move(p, 0) { NextActivity = this };
return Util.SequenceActivities( new Move(p, 0), this );
}
// todo: return somewhere likely to be safe (near fix) so we're not sitting out in the minefield.
@@ -80,7 +80,5 @@ namespace OpenRA.Mods.RA.Activities
new OwnerInit( self.Owner ),
}));
}
public void Cancel( Actor self ) { canceled = true; NextActivity = null; }
}
}

View File

@@ -14,47 +14,46 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class Leap : IActivity
class Leap : CancelableActivity
{
Target target;
float2 initialLocation;
float t;
int2 initialLocation;
const int delay = 6;
int moveFraction;
public Leap(Actor self, Target target)
{
this.target = target;
initialLocation = self.CenterLocation;
initialLocation = self.Trait<Mobile>().PxPosition;
self.Trait<RenderInfantry>().Attacking(self);
Sound.Play("dogg5p.aud", self.CenterLocation);
}
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (!target.IsValid)
return NextActivity;
if( moveFraction == 0 && IsCanceled ) return NextActivity;
if (!target.IsValid) return NextActivity;
t += (1f / delay);
self.Trait<AttackLeap>().IsLeaping = true;
var mobile = self.Trait<Mobile>();
++moveFraction;
self.CenterLocation = float2.Lerp(initialLocation, target.CenterLocation, t);
mobile.PxPosition = int2.Lerp(initialLocation, target.PxPosition, moveFraction, delay);
if (t >= 1f)
if (moveFraction >= delay)
{
self.TraitsImplementing<IMove>().FirstOrDefault()
.SetPosition(self, Util.CellContaining(target.CenterLocation));
if (target.IsActor)
target.Actor.Kill(self);
self.Trait<AttackLeap>().IsLeaping = false;
return NextActivity;
}
return this;
}
public void Cancel(Actor self) { target = new Target(); NextActivity = null; }
}
}

View File

@@ -14,17 +14,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Rearm : IActivity
public class Rearm : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
int remainingTicks = ticksPerPip;
const int ticksPerPip = 25 * 2;
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
var limitedAmmo = self.TraitOrDefault<LimitedAmmo>();
if (limitedAmmo == null) return NextActivity;
@@ -43,7 +41,5 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -14,18 +14,16 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Repair : IActivity
public class Repair : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
int remainingTicks;
Actor host;
public Repair(Actor host) { this.host = host; }
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
if (host != null && !host.IsInWorld) return NextActivity;
if (remainingTicks == 0)
{
@@ -58,7 +56,5 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -12,16 +12,15 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class RepairBuilding : IActivity
class RepairBuilding : CancelableActivity
{
Target target;
public RepairBuilding(Actor target) { this.target = Target.FromActor(target); }
public IActivity NextActivity { get; set; }
public IActivity Tick(Actor self)
{
public override IActivity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
if (!target.IsValid) return NextActivity;
if ((target.Actor.Location - self.Location).Length > 1)
return NextActivity;
@@ -34,8 +33,6 @@ namespace OpenRA.Mods.RA.Activities
self.Destroy();
return NextActivity;
}
public void Cancel(Actor self) { target = Target.None; NextActivity = null; }
}
}
}

View File

@@ -14,11 +14,8 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class ReturnToBase : IActivity
public class ReturnToBase : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
bool isCalculated;
Actor dest;
@@ -88,20 +85,18 @@ namespace OpenRA.Mods.RA.Activities
this.dest = dest;
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
if (!isCalculated)
Calculate(self);
return Util.SequenceActivities(
new Fly(w1),
new Fly(w2),
new Fly(w3),
Fly.ToPx(w1),
Fly.ToPx(w2),
Fly.ToPx(w3),
new Land(Target.FromActor(dest)),
NextActivity);
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -13,10 +13,8 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Teleport : IActivity
public class Teleport : CancelableActivity
{
public IActivity NextActivity { get; set; }
int2 destination;
public Teleport(int2 destination)
@@ -24,12 +22,10 @@ namespace OpenRA.Mods.RA.Activities
this.destination = destination;
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
self.TraitsImplementing<IMove>().FirstOrDefault().SetPosition(self, destination);
return NextActivity;
}
public void Cancel(Actor self) { }
}
}

View File

@@ -17,12 +17,11 @@ using OpenRA.FileFormats;
namespace OpenRA.Mods.RA.Activities
{
class Transform : IActivity
class Transform : CancelableActivity
{
string actor = null;
int2 offset;
string[] sounds = null;
bool isCanceled;
int facing;
RenderBuilding rb;
@@ -34,10 +33,7 @@ namespace OpenRA.Mods.RA.Activities
this.facing = facing;
rb = self.TraitOrDefault<RenderBuilding>();
}
public IActivity NextActivity { get; set; }
void DoTransform(Actor self)
{
// Hack: repeat the first frame of the make anim instead
@@ -70,9 +66,9 @@ namespace OpenRA.Mods.RA.Activities
}
bool started = false;
public IActivity Tick( Actor self )
public override IActivity Tick( Actor self )
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
if (started) return this;
if (rb == null)
@@ -88,7 +84,5 @@ namespace OpenRA.Mods.RA.Activities
}
return this;
}
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
}

View File

@@ -16,11 +16,8 @@ using System.Drawing;
namespace OpenRA.Mods.RA.Activities
{
public class UnloadCargo : IActivity
public class UnloadCargo : CancelableActivity
{
public IActivity NextActivity { get; set; }
bool isCanceled;
int2? ChooseExitTile(Actor self, Actor cargo)
{
// is anyone still hogging this tile?
@@ -38,16 +35,16 @@ namespace OpenRA.Mods.RA.Activities
return null;
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (isCanceled) return NextActivity;
if (IsCanceled) return NextActivity;
// if we're a thing that can turn, turn to the
// right facing for the unload animation
var facing = self.TraitOrDefault<IFacing>();
var unloadFacing = self.Info.Traits.Get<CargoInfo>().UnloadFacing;
if (facing != null && facing.Facing != unloadFacing)
return new Turn(unloadFacing) { NextActivity = this };
return Util.SequenceActivities( new Turn(unloadFacing), this );
// todo: handle the BS of open/close sequences, which are inconsistent,
// for reasons that probably make good sense to the westwood guys.
@@ -82,7 +79,5 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
public void Cancel(Actor self) { NextActivity = null; isCanceled = true; }
}
}

View File

@@ -12,11 +12,11 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class Wait : IActivity
public class Wait : CancelableActivity
{
int remainingTicks;
bool interruptable = true;
public Wait(int period) { remainingTicks = period; }
public Wait(int period, bool interruptable)
{
@@ -24,20 +24,17 @@ namespace OpenRA.Mods.RA.Activities
this.interruptable = interruptable;
}
public IActivity Tick(Actor self)
public override IActivity Tick(Actor self)
{
if (remainingTicks-- == 0) return NextActivity;
return this;
}
public void Cancel(Actor self)
protected override bool OnCancel()
{
if (!interruptable)
return;
if( !interruptable ) return false;
remainingTicks = 0;
NextActivity = null;
return true;
}
public IActivity NextActivity { get; set; }
}
}

View File

@@ -36,13 +36,18 @@ namespace OpenRA.Mods.RA
public int Facing { get; set; }
[Sync]
public int Altitude { get; set; }
public float2 center;
AircraftInfo Info;
public Aircraft( ActorInitializer init , AircraftInfo info)
{
if (init.Contains<LocationInit>())
this.Location = init.Get<LocationInit,int2>();
if( init.Contains<LocationInit>() )
{
this.Location = init.Get<LocationInit, int2>();
this.center = Util.CenterOfCell( Location );
}
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : info.InitialFacing;
this.Altitude = init.Contains<AltitudeInit>() ? init.Get<AltitudeInit,int>() : 0;
@@ -61,27 +66,23 @@ namespace OpenRA.Mods.RA
public void SetPosition(Actor self, int2 cell)
{
Location = cell;
self.CenterLocation = Util.CenterOfCell(cell);
center = Util.CenterOfCell(cell);
}
public void SetPxPosition(Actor self, int2 px)
{
Location = Util.CellContaining(px);
center = px;
}
public bool AircraftCanEnter(Actor self, Actor a)
{
return Info.RearmBuildings.Contains( a.Info.Name )
|| Info.RepairBuildings.Contains( a.Info.Name );
}
public virtual IEnumerable<float2> GetCurrentPath(Actor self)
{
var move = self.GetCurrentActivity() as Activities.Fly;
if (move == null) return new float2[] { };
return new float2[] { move.Pos };
}
public bool CanEnterCell(int2 location) { return true; }
public float MovementCostForCell(Actor self, int2 cell) { return 1f; }
public float MovementSpeedForCell(Actor self, int2 cell)
{
var modifier = self
@@ -93,5 +94,6 @@ namespace OpenRA.Mods.RA
int2[] noCells = new int2[] { };
public IEnumerable<int2> OccupiedCells() { return noCells; }
public int2 PxPosition { get { return center.ToInt2(); } }
}
}

View File

@@ -41,6 +41,7 @@ namespace OpenRA.Mods.RA
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice
{
public bool IsAttacking { get; internal set; }
public Target target;
public List<Weapon> Weapons = new List<Weapon>();

View File

@@ -19,6 +19,8 @@ namespace OpenRA.Mods.RA
class AttackLeap : AttackBase
{
internal bool IsLeaping;
public AttackLeap(Actor self)
: base(self) {}
@@ -27,7 +29,7 @@ namespace OpenRA.Mods.RA
base.Tick(self);
if (!target.IsValid) return;
if (self.GetCurrentActivity() is Leap) return;
if (IsLeaping) return;
var weapon = self.Trait<AttackBase>().Weapons[0].Info;
if (weapon.Range * Game.CellSize * weapon.Range * Game.CellSize

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA
if (target != null)
attack.ResolveOrder(self, new Order("Attack", self, target));
else
if (self.GetCurrentActivity() is Attack)
if (attack.IsAttacking)
self.CancelActivity();
}

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