New types for cell and pixel coordinate position/vectors.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,6 +10,9 @@ obj
|
||||
*.manifest
|
||||
mods/*/*.dll
|
||||
|
||||
# ReSharper crap
|
||||
_ReSharper.*/
|
||||
|
||||
# Red Alert binary files
|
||||
mods/*/packages/*.[mM][iI][xX]
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Editor
|
||||
for (var u = 0; u < template.Size.X; u++)
|
||||
for (var v = 0; v < template.Size.Y; v++)
|
||||
{
|
||||
if (surface.Map.IsInMap(new int2(u, v) + pos))
|
||||
if (surface.Map.IsInMap(new CVec(u, v) + pos))
|
||||
{
|
||||
var z = u + v * template.Size.X;
|
||||
if (tile.TileBitmapBytes[z] != null)
|
||||
@@ -69,17 +69,17 @@ namespace OpenRA.Editor
|
||||
Brush.Bitmap.Height * surface.Zoom);
|
||||
}
|
||||
|
||||
void FloodFillWithBrush(Surface s, int2 pos)
|
||||
void FloodFillWithBrush(Surface s, CPos pos)
|
||||
{
|
||||
var queue = new Queue<int2>();
|
||||
var queue = new Queue<CPos>();
|
||||
var replace = s.Map.MapTiles.Value[pos.X, pos.Y];
|
||||
var touched = new bool[s.Map.MapSize.X, s.Map.MapSize.Y];
|
||||
|
||||
Action<int, int> MaybeEnqueue = (x, y) =>
|
||||
Action<int, int> maybeEnqueue = (x, y) =>
|
||||
{
|
||||
if (s.Map.IsInMap(x, y) && !touched[x, y])
|
||||
{
|
||||
queue.Enqueue(new int2(x, y));
|
||||
queue.Enqueue(new CPos(x, y));
|
||||
touched[x, y] = true;
|
||||
}
|
||||
};
|
||||
@@ -91,16 +91,16 @@ namespace OpenRA.Editor
|
||||
if (!s.Map.MapTiles.Value[p.X, p.Y].Equals(replace))
|
||||
continue;
|
||||
|
||||
var a = FindEdge(s, p, new int2(-1, 0), replace);
|
||||
var b = FindEdge(s, p, new int2(1, 0), replace);
|
||||
var a = FindEdge(s, p, new CVec(-1, 0), replace);
|
||||
var b = FindEdge(s, p, new CVec(1, 0), replace);
|
||||
|
||||
for (var x = a.X; x <= b.X; x++)
|
||||
{
|
||||
s.Map.MapTiles.Value[x, p.Y] = new TileReference<ushort, byte> { type = Brush.N, index = (byte)0 };
|
||||
if (s.Map.MapTiles.Value[x, p.Y - 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y - 1);
|
||||
maybeEnqueue(x, p.Y - 1);
|
||||
if (s.Map.MapTiles.Value[x, p.Y + 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y + 1);
|
||||
maybeEnqueue(x, p.Y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace OpenRA.Editor
|
||||
s.Chunks.Clear();
|
||||
}
|
||||
|
||||
int2 FindEdge(Surface s, int2 p, int2 d, TileReference<ushort, byte> replace)
|
||||
CPos FindEdge(Surface s, CPos p, CVec d, TileReference<ushort, byte> replace)
|
||||
{
|
||||
for (; ; )
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace OpenRA.Editor
|
||||
foreach( var kv in wps )
|
||||
{
|
||||
var a = new ActorReference("mpspawn");
|
||||
a.Add(new LocationInit(kv.Second));
|
||||
a.Add(new LocationInit((CPos)kv.Second));
|
||||
a.Add(new OwnerInit("Neutral"));
|
||||
Map.Actors.Value.Add("spawn" + kv.First, a);
|
||||
}
|
||||
@@ -276,7 +276,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(overlayActorMapping[raOverlayNames[o]])
|
||||
{
|
||||
new LocationInit( new int2(i, j) ),
|
||||
new LocationInit( new CPos(i, j) ),
|
||||
new OwnerInit( "Neutral" )
|
||||
});
|
||||
}
|
||||
@@ -294,7 +294,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(kv.Value.ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit("Neutral")
|
||||
});
|
||||
}
|
||||
@@ -323,7 +323,7 @@ namespace OpenRA.Editor
|
||||
foreach (KeyValuePair<string, string> kv in overlay)
|
||||
{
|
||||
var loc = int.Parse(kv.Key);
|
||||
var cell = new int2(loc % MapSize, loc / MapSize);
|
||||
var cell = new CPos(loc % MapSize, loc / MapSize);
|
||||
|
||||
var res = Pair.New((byte)0, (byte)0);
|
||||
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
|
||||
@@ -353,7 +353,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit("Neutral")
|
||||
});
|
||||
}
|
||||
@@ -380,7 +380,7 @@ namespace OpenRA.Editor
|
||||
|
||||
var actor = new ActorReference(parts[1].ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit(parts[0]),
|
||||
new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)/256),
|
||||
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
|
||||
@@ -432,7 +432,7 @@ namespace OpenRA.Editor
|
||||
(byte)(color.Second.GetBrightness() * 255))
|
||||
};
|
||||
|
||||
var Neutral = new [] {"Neutral"};
|
||||
var neutral = new [] {"Neutral"};
|
||||
foreach (var s in file.GetSection(section, true))
|
||||
{
|
||||
Console.WriteLine(s.Key);
|
||||
@@ -442,8 +442,8 @@ namespace OpenRA.Editor
|
||||
pr.InitialCash = int.Parse(s.Value);
|
||||
break;
|
||||
case "Allies":
|
||||
pr.Allies = s.Value.Split(',').Intersect(Players).Except(Neutral).ToArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(Neutral).ToArray();
|
||||
pr.Allies = s.Value.Split(',').Intersect(Players).Except(neutral).ToArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(neutral).ToArray();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,23 +157,23 @@ namespace OpenRA.Editor
|
||||
void Erase()
|
||||
{
|
||||
// Crash preventing
|
||||
var BrushLocation = GetBrushLocation();
|
||||
var brushLocation = GetBrushLocation();
|
||||
|
||||
if (Map == null || BrushLocation.X >= Map.MapSize.X ||
|
||||
BrushLocation.Y >= Map.MapSize.Y ||
|
||||
BrushLocation.X < 0 ||
|
||||
BrushLocation.Y < 0)
|
||||
if (Map == null || brushLocation.X >= Map.MapSize.X ||
|
||||
brushLocation.Y >= Map.MapSize.Y ||
|
||||
brushLocation.X < 0 ||
|
||||
brushLocation.Y < 0)
|
||||
return;
|
||||
|
||||
Tool = null;
|
||||
|
||||
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == BrushLocation);
|
||||
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == brushLocation);
|
||||
if (key.Key != null) Map.Actors.Value.Remove(key.Key);
|
||||
|
||||
if (Map.MapResources.Value[BrushLocation.X, BrushLocation.Y].type != 0)
|
||||
if (Map.MapResources.Value[brushLocation.X, brushLocation.Y].type != 0)
|
||||
{
|
||||
Map.MapResources.Value[BrushLocation.X, BrushLocation.Y] = new TileReference<byte, byte>();
|
||||
var ch = new int2((BrushLocation.X) / ChunkSize, (BrushLocation.Y) / ChunkSize);
|
||||
Map.MapResources.Value[brushLocation.X, brushLocation.Y] = new TileReference<byte, byte>();
|
||||
var ch = new int2((brushLocation.X) / ChunkSize, (brushLocation.Y) / ChunkSize);
|
||||
if (Chunks.ContainsKey(ch))
|
||||
{
|
||||
Chunks[ch].Dispose();
|
||||
@@ -267,31 +267,31 @@ namespace OpenRA.Editor
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public int2 GetBrushLocation()
|
||||
public CPos GetBrushLocation()
|
||||
{
|
||||
var vX = (int)Math.Floor((MousePos.X - Offset.X) / Zoom);
|
||||
var vY = (int)Math.Floor((MousePos.Y - Offset.Y) / Zoom);
|
||||
return new int2(vX / TileSet.TileSize, vY / TileSet.TileSize);
|
||||
return new CPos(vX / TileSet.TileSize, vY / TileSet.TileSize);
|
||||
}
|
||||
|
||||
public void DrawActor(SGraphics g, int2 p, ActorTemplate t, ColorPalette cp)
|
||||
public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp)
|
||||
{
|
||||
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
|
||||
DrawImage(g, t.Bitmap, p, centered, cp);
|
||||
}
|
||||
|
||||
float2 GetDrawPosition(int2 location, Bitmap bmp, bool centered)
|
||||
float2 GetDrawPosition(CPos location, Bitmap bmp, bool centered)
|
||||
{
|
||||
float OffsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
|
||||
float DrawX = TileSet.TileSize * location.X * Zoom + Offset.X - OffsetX;
|
||||
float offsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
|
||||
float drawX = TileSet.TileSize * location.X * Zoom + Offset.X - offsetX;
|
||||
|
||||
float OffsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
|
||||
float DrawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - OffsetY;
|
||||
float offsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
|
||||
float drawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - offsetY;
|
||||
|
||||
return new float2(DrawX, DrawY);
|
||||
return new float2(drawX, drawY);
|
||||
}
|
||||
|
||||
public void DrawImage(SGraphics g, Bitmap bmp, int2 location, bool centered, ColorPalette cp)
|
||||
public void DrawImage(SGraphics g, Bitmap bmp, CPos location, bool centered, ColorPalette cp)
|
||||
{
|
||||
var drawPos = GetDrawPosition(location, bmp, centered);
|
||||
|
||||
@@ -304,7 +304,7 @@ namespace OpenRA.Editor
|
||||
if (cp != null) bmp.Palette = restorePalette;
|
||||
}
|
||||
|
||||
void DrawActorBorder(SGraphics g, int2 p, ActorTemplate t)
|
||||
void DrawActorBorder(SGraphics g, CPos p, ActorTemplate t)
|
||||
{
|
||||
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
|
||||
var drawPos = GetDrawPosition(p, t.Bitmap, centered);
|
||||
@@ -399,9 +399,9 @@ namespace OpenRA.Editor
|
||||
|
||||
static class ActorReferenceExts
|
||||
{
|
||||
public static int2 Location(this ActorReference ar)
|
||||
public static CPos Location(this ActorReference ar)
|
||||
{
|
||||
return ar.InitDict.Get<LocationInit>().value;
|
||||
return (CPos)ar.InitDict.Get<LocationInit>().value;
|
||||
}
|
||||
|
||||
public static void DrawStringContrast(this SGraphics g, Font f, string s, int x, int y, Brush fg, Brush bg)
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace OpenRA
|
||||
|
||||
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } }
|
||||
|
||||
public int2 Location { get { return occupySpace.Value.TopLeft; } }
|
||||
public CPos Location { get { return occupySpace.Value.TopLeft; } }
|
||||
|
||||
public int2 CenterLocation
|
||||
public PPos CenterLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -123,22 +123,30 @@ namespace OpenRA
|
||||
// at its current altitude
|
||||
Rectangle CalculateBounds(bool useAltitude)
|
||||
{
|
||||
var size = Size.Value;
|
||||
var size = (PVecInt)(Size.Value);
|
||||
var loc = CenterLocation - size / 2;
|
||||
|
||||
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
||||
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
|
||||
{
|
||||
#if true
|
||||
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
|
||||
#else
|
||||
loc.X += si.Bounds[2];
|
||||
loc.Y += si.Bounds[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
var move = Move.Value;
|
||||
if (move != null)
|
||||
{
|
||||
#if true
|
||||
loc -= new PVecInt(0, move.Altitude);
|
||||
#else
|
||||
loc.Y -= move.Altitude;
|
||||
#endif
|
||||
if (useAltitude)
|
||||
size = new int2(size.X, size.Y + move.Altitude);
|
||||
size = new PVecInt(size.X, size.Y + move.Altitude);
|
||||
}
|
||||
|
||||
return new Rectangle(loc.X, loc.Y, size.X, size.Y);
|
||||
|
||||
@@ -62,12 +62,12 @@ namespace OpenRA
|
||||
public int Value( World world ) { return value; }
|
||||
}
|
||||
|
||||
public class LocationInit : IActorInit<int2>
|
||||
public class LocationInit : IActorInit<CPos>
|
||||
{
|
||||
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
|
||||
public LocationInit() { }
|
||||
public LocationInit( int2 init ) { value = init; }
|
||||
public int2 Value( World world ) { return value; }
|
||||
public LocationInit( CPos init ) { value = init.ToInt2(); }
|
||||
public CPos Value(World world) { return (CPos)value; }
|
||||
}
|
||||
|
||||
public class SubCellInit : IActorInit<SubCell>
|
||||
@@ -78,12 +78,12 @@ namespace OpenRA
|
||||
public SubCell Value(World world) { return (SubCell)value; }
|
||||
}
|
||||
|
||||
public class CenterLocationInit : IActorInit<int2>
|
||||
public class CenterLocationInit : IActorInit<PPos>
|
||||
{
|
||||
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
|
||||
public CenterLocationInit() { }
|
||||
public CenterLocationInit( int2 init ) { value = init; }
|
||||
public int2 Value( World world ) { return value; }
|
||||
public CenterLocationInit(PPos init) { value = init.ToInt2(); }
|
||||
public PPos Value(World world) { return (PPos)value; }
|
||||
}
|
||||
|
||||
public class OwnerInit : IActorInit<Player>
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA
|
||||
world.ActorRemoved += a => Remove( a, a.OccupiesSpace );
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> GetUnitsAt( int2 a )
|
||||
public IEnumerable<Actor> GetUnitsAt(CPos a)
|
||||
{
|
||||
if (!map.IsInMap(a)) yield break;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenRA
|
||||
yield return i.actor;
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> GetUnitsAt( int2 a, SubCell sub )
|
||||
public IEnumerable<Actor> GetUnitsAt(CPos a, SubCell sub)
|
||||
{
|
||||
if (!map.IsInMap(a)) yield break;
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA
|
||||
yield return i.actor;
|
||||
}
|
||||
|
||||
public bool HasFreeSubCell(int2 a)
|
||||
public bool HasFreeSubCell(CPos a)
|
||||
{
|
||||
if (!AnyUnitsAt(a))
|
||||
return true;
|
||||
@@ -64,12 +64,12 @@ namespace OpenRA
|
||||
SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b));
|
||||
}
|
||||
|
||||
public bool AnyUnitsAt(int2 a)
|
||||
public bool AnyUnitsAt(CPos a)
|
||||
{
|
||||
return influence[ a.X, a.Y ] != null;
|
||||
}
|
||||
|
||||
public bool AnyUnitsAt(int2 a, SubCell sub)
|
||||
public bool AnyUnitsAt(CPos a, SubCell sub)
|
||||
{
|
||||
for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next )
|
||||
if (i.subCell == sub || i.subCell == SubCell.FullCell)
|
||||
|
||||
71
OpenRA.Game/CPos.cs
Normal file
71
OpenRA.Game/CPos.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell coordinate position in the world (coarse).
|
||||
/// </summary>
|
||||
public struct CPos
|
||||
{
|
||||
public readonly int X, Y;
|
||||
|
||||
public CPos(int x, int y) { X = x; Y = y; }
|
||||
|
||||
public static readonly CPos Zero = new CPos(0, 0);
|
||||
|
||||
public static explicit operator CPos(int2 a) { return new CPos(a.X, a.Y); }
|
||||
|
||||
public static CPos operator +(CVec a, CPos b) { return new CPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static CPos operator +(CPos a, CVec b) { return new CPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static CVec operator -(CPos a, CPos b) { return new CVec(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static bool operator ==(CPos me, CPos other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(CPos me, CPos other) { return !(me == other); }
|
||||
|
||||
public static CPos Max(CPos a, CPos b) { return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static CPos Min(CPos a, CPos b) { return new CPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
public PPos ToPPos() { return new PPos(Game.CellSize * X, Game.CellSize * Y); }
|
||||
|
||||
public CPos Clamp(Rectangle r)
|
||||
{
|
||||
return new CPos(Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
CPos o = (CPos)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "{0},{1}".F(X, Y); }
|
||||
|
||||
}
|
||||
|
||||
public static class RectangleExtensions
|
||||
{
|
||||
public static CPos TopLeftAsCPos(this Rectangle r) { return new CPos(r.Left, r.Top); }
|
||||
public static CPos BottomRightAsCPos(this Rectangle r) { return new CPos(r.Right, r.Bottom); }
|
||||
}
|
||||
}
|
||||
76
OpenRA.Game/CVec.cs
Normal file
76
OpenRA.Game/CVec.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell coordinate vector (coarse).
|
||||
/// </summary>
|
||||
public struct CVec
|
||||
{
|
||||
public readonly int X, Y;
|
||||
|
||||
public CVec(int x, int y) { X = x; Y = y; }
|
||||
public CVec(Size p) { X = p.Width; Y = p.Height; }
|
||||
|
||||
public static readonly CVec Zero = new CVec(0, 0);
|
||||
|
||||
public static explicit operator CVec(int2 a) { return new CVec(a.X, a.Y); }
|
||||
public static explicit operator CVec(float2 a) { return new CVec((int)a.X, (int)a.Y); }
|
||||
|
||||
public static CVec operator +(CVec a, CVec b) { return new CVec(a.X + b.X, a.Y + b.Y); }
|
||||
public static CVec operator -(CVec a, CVec b) { return new CVec(a.X - b.X, a.Y - b.Y); }
|
||||
public static CVec operator *(int a, CVec b) { return new CVec(a * b.X, a * b.Y); }
|
||||
public static CVec operator *(CVec b, int a) { return new CVec(a * b.X, a * b.Y); }
|
||||
public static CVec operator /(CVec a, int b) { return new CVec(a.X / b, a.Y / b); }
|
||||
|
||||
public static CVec operator -(CVec a) { return new CVec(-a.X, -a.Y); }
|
||||
|
||||
public static bool operator ==(CVec me, CVec other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(CVec me, CVec other) { return !(me == other); }
|
||||
|
||||
public static CVec Max(CVec a, CVec b) { return new CVec(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static CVec Min(CVec a, CVec b) { return new CVec(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public static int Dot(CVec a, CVec b) { return a.X * b.X + a.Y * b.Y; }
|
||||
|
||||
public CVec Sign() { return new CVec(Math.Sign(X), Math.Sign(Y)); }
|
||||
public CVec Abs() { return new CVec(Math.Abs(X), Math.Abs(Y)); }
|
||||
public int LengthSquared { get { return X * X + Y * Y; } }
|
||||
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
|
||||
public CVec Clamp(Rectangle r)
|
||||
{
|
||||
return new CVec(
|
||||
Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top))
|
||||
);
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
CVec o = (CVec)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "{0},{1}".F(X, Y); }
|
||||
}
|
||||
}
|
||||
@@ -72,11 +72,11 @@ namespace OpenRA.GameRules
|
||||
{
|
||||
public WeaponInfo weapon;
|
||||
public Actor firedBy;
|
||||
public int2 src;
|
||||
public PPos src;
|
||||
public int srcAltitude;
|
||||
public int facing;
|
||||
public Target target;
|
||||
public int2 dest;
|
||||
public PPos dest;
|
||||
public int destAltitude;
|
||||
public float firepowerModifier = 1.0f;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
|
||||
public Renderable Image(Actor self, string pal)
|
||||
{
|
||||
var p = self.CenterLocation;
|
||||
var loc = p - 0.5f * Animation.Image.size
|
||||
var loc = p.ToFloat2() - 0.5f * Animation.Image.size
|
||||
+ (OffsetFunc != null ? OffsetFunc() : float2.Zero);
|
||||
var r = new Renderable(Animation.Image, loc, pal, p.Y);
|
||||
|
||||
|
||||
@@ -149,18 +149,18 @@ namespace OpenRA.Graphics
|
||||
}
|
||||
|
||||
// Convert from viewport coords to cell coords (not px)
|
||||
public float2 ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
|
||||
public float2 ViewToWorld(int2 loc)
|
||||
public CPos ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
|
||||
public CPos ViewToWorld(int2 loc)
|
||||
{
|
||||
return (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location);
|
||||
return (CPos)( (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location) ).ToInt2();
|
||||
}
|
||||
|
||||
public int2 ViewToWorldPx(int2 loc) { return (1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
|
||||
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
|
||||
public PPos ViewToWorldPx(int2 loc) { return (PPos)(1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
|
||||
public PPos ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
|
||||
|
||||
public void Center(float2 loc)
|
||||
{
|
||||
scrollPosition = NormalizeScrollPosition((Game.CellSize*loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
scrollPosition = NormalizeScrollPosition((Game.CellSize * loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
}
|
||||
|
||||
public void Center(IEnumerable<Actor> actors)
|
||||
@@ -168,9 +168,9 @@ namespace OpenRA.Graphics
|
||||
if (!actors.Any()) return;
|
||||
|
||||
var avgPos = actors
|
||||
.Select(a => a.CenterLocation)
|
||||
.Select(a => (PVecInt)a.CenterLocation)
|
||||
.Aggregate((a, b) => a + b) / actors.Count();
|
||||
scrollPosition = NormalizeScrollPosition((avgPos - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
|
||||
}
|
||||
|
||||
// Rectangle (in viewport coords) that contains things to be drawn
|
||||
|
||||
@@ -53,8 +53,9 @@ namespace OpenRA.Graphics
|
||||
var comparer = new SpriteComparer();
|
||||
|
||||
var actors = world.FindUnits(
|
||||
new int2(Game.CellSize*bounds.Left, Game.CellSize*bounds.Top),
|
||||
new int2(Game.CellSize*bounds.Right, Game.CellSize*bounds.Bottom));
|
||||
bounds.TopLeftAsCPos().ToPPos(),
|
||||
bounds.BottomRightAsCPos().ToPPos()
|
||||
);
|
||||
|
||||
var renderables = actors.SelectMany(a => a.Render())
|
||||
.OrderBy(r => r, comparer);
|
||||
@@ -140,25 +141,21 @@ namespace OpenRA.Graphics
|
||||
selectable.DrawRollover(this, unit);
|
||||
}
|
||||
|
||||
public void DrawLocus(Color c, int2[] cells)
|
||||
public void DrawLocus(Color c, CPos[] cells)
|
||||
{
|
||||
var dict = cells.ToDictionary(a => a, a => 0);
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
|
||||
foreach (var t in dict.Keys)
|
||||
{
|
||||
if (!dict.ContainsKey(t + new int2(-1, 0)))
|
||||
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(0, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(1, 0)))
|
||||
wlr.DrawLine(Game.CellSize * (t + new int2(1, 0)), Game.CellSize * (t + new int2(1, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(0, -1)))
|
||||
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(1, 0)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(0, 1)))
|
||||
wlr.DrawLine(Game.CellSize * (t + new int2(0, 1)), Game.CellSize * (t + new int2(1, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(-1, 0)))
|
||||
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(0, 1)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(1, 0)))
|
||||
wlr.DrawLine((t + new CVec(1, 0)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(0, -1)))
|
||||
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(1, 0)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(0, 1)))
|
||||
wlr.DrawLine((t + new CVec(0, 1)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace OpenRA
|
||||
return dataStream.ToArray();
|
||||
}
|
||||
|
||||
public bool IsInMap(int2 xy) { return IsInMap(xy.X, xy.Y); }
|
||||
public bool IsInMap(CPos xy) { return IsInMap(xy.X, xy.Y); }
|
||||
public bool IsInMap(int x, int y) { return Bounds.Contains(x,y); }
|
||||
|
||||
static T[,] ResizeArray<T>(T[,] ts, T t, int width, int height)
|
||||
|
||||
@@ -39,15 +39,15 @@ namespace OpenRA
|
||||
public readonly Actor Subject;
|
||||
public readonly bool Queued;
|
||||
public Actor TargetActor;
|
||||
public int2 TargetLocation;
|
||||
public CPos TargetLocation;
|
||||
public string TargetString;
|
||||
public int2 ExtraLocation;
|
||||
public CPos ExtraLocation;
|
||||
public bool IsImmediate;
|
||||
|
||||
public Player Player { get { return Subject.Owner; } }
|
||||
|
||||
Order(string orderString, Actor subject,
|
||||
Actor targetActor, int2 targetLocation, string targetString, bool queued, int2 extraLocation)
|
||||
Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation)
|
||||
{
|
||||
this.OrderString = orderString;
|
||||
this.Subject = subject;
|
||||
@@ -60,10 +60,10 @@ namespace OpenRA
|
||||
|
||||
// For scripting special powers
|
||||
public Order()
|
||||
: this(null, null, null, int2.Zero, null, false, int2.Zero) { }
|
||||
: this(null, null, null, CPos.Zero, null, false, CPos.Zero) { }
|
||||
|
||||
public Order(string orderString, Actor subject, bool queued)
|
||||
: this(orderString, subject, null, int2.Zero, null, queued, int2.Zero) { }
|
||||
: this(orderString, subject, null, CPos.Zero, null, queued, CPos.Zero) { }
|
||||
|
||||
public Order(string orderstring, Order order)
|
||||
: this(orderstring, order.Subject, order.TargetActor, order.TargetLocation,
|
||||
@@ -98,21 +98,21 @@ namespace OpenRA
|
||||
|
||||
OrderFields fields = 0;
|
||||
if (TargetActor != null) fields |= OrderFields.TargetActor;
|
||||
if (TargetLocation != int2.Zero) fields |= OrderFields.TargetLocation;
|
||||
if (TargetLocation != CPos.Zero) fields |= OrderFields.TargetLocation;
|
||||
if (TargetString != null) fields |= OrderFields.TargetString;
|
||||
if (Queued) fields |= OrderFields.Queued;
|
||||
if (ExtraLocation != int2.Zero) fields |= OrderFields.ExtraLocation;
|
||||
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
|
||||
|
||||
w.Write((byte)fields);
|
||||
|
||||
if (TargetActor != null)
|
||||
w.Write(UIntFromActor(TargetActor));
|
||||
if (TargetLocation != int2.Zero)
|
||||
w.Write(TargetLocation);
|
||||
if (TargetLocation != CPos.Zero)
|
||||
w.Write(TargetLocation.ToInt2());
|
||||
if (TargetString != null)
|
||||
w.Write(TargetString);
|
||||
if (ExtraLocation != int2.Zero)
|
||||
w.Write(ExtraLocation);
|
||||
if (ExtraLocation != CPos.Zero)
|
||||
w.Write(ExtraLocation.ToInt2());
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
@@ -130,10 +130,10 @@ namespace OpenRA
|
||||
var flags = (OrderFields)r.ReadByte();
|
||||
|
||||
var targetActorId = flags.HasField(OrderFields.TargetActor) ? r.ReadUInt32() : 0xffffffff;
|
||||
var targetLocation = flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero;
|
||||
var targetLocation = (CPos)( flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero );
|
||||
var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
|
||||
var queued = flags.HasField(OrderFields.Queued);
|
||||
var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero;
|
||||
var extraLocation = (CPos)(flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero);
|
||||
|
||||
Actor subject, targetActor;
|
||||
if( !TryGetActorFromUInt( world, subjectId, out subject ) || !TryGetActorFromUInt( world, targetActorId, out targetActor ) )
|
||||
@@ -218,17 +218,17 @@ namespace OpenRA
|
||||
|
||||
public static Order StartProduction(Actor subject, string item, int count)
|
||||
{
|
||||
return new Order("StartProduction", subject, false) { TargetLocation = new int2(count, 0), TargetString = item };
|
||||
return new Order("StartProduction", subject, false) { TargetLocation = new CPos(count, 0), TargetString = item };
|
||||
}
|
||||
|
||||
public static Order PauseProduction(Actor subject, string item, bool pause)
|
||||
{
|
||||
return new Order("PauseProduction", subject, false) { TargetLocation = new int2(pause ? 1 : 0, 0), TargetString = item };
|
||||
return new Order("PauseProduction", subject, false) { TargetLocation = new CPos(pause ? 1 : 0, 0), TargetString = item };
|
||||
}
|
||||
|
||||
public static Order CancelProduction(Actor subject, string item, int count)
|
||||
{
|
||||
return new Order("CancelProduction", subject, false) { TargetLocation = new int2(count, 0), TargetString = item };
|
||||
return new Order("CancelProduction", subject, false) { TargetLocation = new CPos(count, 0), TargetString = item };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
<Compile Include="ActorInitializer.cs" />
|
||||
<Compile Include="ActorMap.cs" />
|
||||
<Compile Include="ActorReference.cs" />
|
||||
<Compile Include="PVecInt.cs" />
|
||||
<Compile Include="PVecFloat.cs" />
|
||||
<Compile Include="PPos.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="Effects\DelayedAction.cs" />
|
||||
<Compile Include="Effects\FlashTarget.cs" />
|
||||
@@ -114,6 +117,8 @@
|
||||
<Compile Include="Graphics\WorldRenderer.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="InputHandler.cs" />
|
||||
<Compile Include="CVec.cs" />
|
||||
<Compile Include="CPos.cs" />
|
||||
<Compile Include="Map.cs" />
|
||||
<Compile Include="ModData.cs" />
|
||||
<Compile Include="Network\Connection.cs" />
|
||||
|
||||
@@ -48,14 +48,14 @@ namespace OpenRA.Orders
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button != expectedButton)
|
||||
world.CancelInputMode();
|
||||
return OrderInner(world, xy, mi);
|
||||
}
|
||||
|
||||
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
||||
IEnumerable<Order> OrderInner(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == expectedButton && world.Map.IsInMap(xy))
|
||||
{
|
||||
@@ -68,6 +68,6 @@ namespace OpenRA.Orders
|
||||
public virtual void Tick(World world) { }
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
public string GetCursor(World world, CPos xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ namespace OpenRA
|
||||
{
|
||||
public interface IOrderGenerator
|
||||
{
|
||||
IEnumerable<Order> Order(World world, int2 xy, MouseInput mi);
|
||||
IEnumerable<Order> Order(World world, CPos xy, MouseInput mi);
|
||||
void Tick(World world);
|
||||
void RenderBeforeWorld(WorldRenderer wr, World world);
|
||||
void RenderAfterWorld(WorldRenderer wr, World world);
|
||||
string GetCursor(World world, int2 xy, MouseInput mi);
|
||||
string GetCursor(World world, CPos xy, MouseInput mi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Orders
|
||||
{
|
||||
class UnitOrderGenerator : IOrderGenerator
|
||||
{
|
||||
public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi )
|
||||
public IEnumerable<Order> Order( World world, CPos xy, MouseInput mi )
|
||||
{
|
||||
var underCursor = world.FindUnitsAtMouse(mi.Location)
|
||||
.Where(a => a.HasTrait<ITargetable>())
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Orders
|
||||
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
|
||||
public void RenderAfterWorld( WorldRenderer wr, World world ) { }
|
||||
|
||||
public string GetCursor( World world, int2 xy, MouseInput mi )
|
||||
public string GetCursor(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
bool useSelect = false;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace OpenRA.Orders
|
||||
return orders[0].cursor ?? ((useSelect) ? "select" : "default");
|
||||
}
|
||||
|
||||
static UnitOrderResult OrderForUnit( Actor self, int2 xy, MouseInput mi, Actor underCursor )
|
||||
static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
return null;
|
||||
|
||||
70
OpenRA.Game/PPos.cs
Normal file
70
OpenRA.Game/PPos.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Pixel coordinate position in the world (fine).
|
||||
/// </summary>
|
||||
public struct PPos
|
||||
{
|
||||
public readonly int X, Y;
|
||||
|
||||
public PPos(int x, int y) { X = x; Y = y; }
|
||||
|
||||
public static readonly PPos Zero = new PPos(0, 0);
|
||||
|
||||
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
|
||||
|
||||
public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); }
|
||||
public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); }
|
||||
|
||||
public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
|
||||
public static PPos operator -(PPos a, PVecInt b) { return new PPos(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static bool operator ==(PPos me, PPos other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(PPos me, PPos other) { return !(me == other); }
|
||||
|
||||
public static PPos Max(PPos a, PPos b) { return new PPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static PPos Min(PPos a, PPos b) { return new PPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public static PPos Lerp(PPos a, PPos b, int mul, int div)
|
||||
{
|
||||
return a + ((PVecInt)(b - a) * mul / div);
|
||||
}
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
public CPos ToCPos() { return new CPos((int)(1f / Game.CellSize * X), (int)(1f / Game.CellSize * Y)); }
|
||||
|
||||
public PPos Clamp(Rectangle r)
|
||||
{
|
||||
return new PPos(Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
PPos o = (PPos)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "{0},{1}".F(X, Y); }
|
||||
}
|
||||
}
|
||||
97
OpenRA.Game/PVecFloat.cs
Normal file
97
OpenRA.Game/PVecFloat.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Pixel coordinate vector (fine; float)
|
||||
/// </summary>
|
||||
public struct PVecFloat
|
||||
{
|
||||
public readonly float X, Y;
|
||||
|
||||
public PVecFloat(float x, float y) { X = x; Y = y; }
|
||||
public PVecFloat(Size p) { X = p.Width; Y = p.Height; }
|
||||
|
||||
public static readonly PVecFloat Zero = new PVecFloat(0, 0);
|
||||
|
||||
public static explicit operator PVecInt(PVecFloat a) { return new PVecInt((int)a.X, (int)a.Y); }
|
||||
public static explicit operator PVecFloat(float2 a) { return new PVecFloat(a.X, a.Y); }
|
||||
|
||||
public static PVecFloat operator +(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X + b.X, a.Y + b.Y); }
|
||||
public static PVecFloat operator -(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X - b.X, a.Y - b.Y); }
|
||||
public static PVecFloat operator *(float a, PVecFloat b) { return new PVecFloat(a * b.X, a * b.Y); }
|
||||
public static PVecFloat operator *(PVecFloat b, float a) { return new PVecFloat(a * b.X, a * b.Y); }
|
||||
public static PVecFloat operator /(PVecFloat a, float b) { return new PVecFloat(a.X / b, a.Y / b); }
|
||||
|
||||
public static PVecFloat operator -(PVecFloat a) { return new PVecFloat(-a.X, -a.Y); }
|
||||
|
||||
public static bool operator ==(PVecFloat me, PVecFloat other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(PVecFloat me, PVecFloat other) { return !(me == other); }
|
||||
|
||||
public static PVecFloat Max(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static PVecFloat Min(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public static float Dot(PVecFloat a, PVecFloat b) { return a.X * b.X + a.Y * b.Y; }
|
||||
|
||||
public static PVecFloat FromAngle(float a) { return new PVecFloat((float)Math.Sin(a), (float)Math.Cos(a)); }
|
||||
|
||||
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, float t)
|
||||
{
|
||||
return new PVecFloat(
|
||||
float2.Lerp(a.X, b.X, t),
|
||||
float2.Lerp(a.Y, b.Y, t)
|
||||
);
|
||||
}
|
||||
|
||||
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, PVecFloat t)
|
||||
{
|
||||
return new PVecFloat(
|
||||
float2.Lerp(a.X, b.X, t.X),
|
||||
float2.Lerp(a.Y, b.Y, t.Y)
|
||||
);
|
||||
}
|
||||
|
||||
public PVecFloat Sign() { return new PVecFloat(Math.Sign(X), Math.Sign(Y)); }
|
||||
public PVecFloat Abs() { return new PVecFloat(Math.Abs(X), Math.Abs(Y)); }
|
||||
public PVecFloat Round() { return new PVecFloat((float)Math.Round(X), (float)Math.Round(Y)); }
|
||||
public float LengthSquared { get { return X * X + Y * Y; } }
|
||||
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2((int)X, (int)Y); }
|
||||
|
||||
static float Constrain(float x, float a, float b) { return x < a ? a : x > b ? b : x; }
|
||||
|
||||
public PVecFloat Constrain(PVecFloat min, PVecFloat max)
|
||||
{
|
||||
return new PVecFloat(
|
||||
Constrain(X, min.X, max.X),
|
||||
Constrain(Y, min.Y, max.Y)
|
||||
);
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
PVecFloat o = (PVecFloat)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "({0},{1})".F(X, Y); }
|
||||
}
|
||||
}
|
||||
79
OpenRA.Game/PVecInt.cs
Normal file
79
OpenRA.Game/PVecInt.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Pixel coordinate vector (fine; integer)
|
||||
/// </summary>
|
||||
public struct PVecInt
|
||||
{
|
||||
public readonly int X, Y;
|
||||
|
||||
public PVecInt(int x, int y) { X = x; Y = y; }
|
||||
public PVecInt(Size p) { X = p.Width; Y = p.Height; }
|
||||
|
||||
public static readonly PVecInt Zero = new PVecInt(0, 0);
|
||||
public static PVecInt OneCell { get { return new PVecInt(Game.CellSize, Game.CellSize); } }
|
||||
|
||||
public static implicit operator PVecFloat(PVecInt a) { return new PVecFloat((float)a.X, (float)a.Y); }
|
||||
public static explicit operator PVecInt(int2 a) { return new PVecInt(a.X, a.Y); }
|
||||
|
||||
public static PVecInt FromRadius(int r) { return new PVecInt(r, r); }
|
||||
|
||||
public static PVecInt operator +(PVecInt a, PVecInt b) { return new PVecInt(a.X + b.X, a.Y + b.Y); }
|
||||
public static PVecInt operator -(PVecInt a, PVecInt b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
|
||||
public static PVecInt operator *(int a, PVecInt b) { return new PVecInt(a * b.X, a * b.Y); }
|
||||
public static PVecInt operator *(PVecInt b, int a) { return new PVecInt(a * b.X, a * b.Y); }
|
||||
public static PVecInt operator /(PVecInt a, int b) { return new PVecInt(a.X / b, a.Y / b); }
|
||||
|
||||
public static PVecInt operator -(PVecInt a) { return new PVecInt(-a.X, -a.Y); }
|
||||
|
||||
public static bool operator ==(PVecInt me, PVecInt other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(PVecInt me, PVecInt other) { return !(me == other); }
|
||||
|
||||
public static PVecInt Max(PVecInt a, PVecInt b) { return new PVecInt(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static PVecInt Min(PVecInt a, PVecInt b) { return new PVecInt(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public static int Dot(PVecInt a, PVecInt b) { return a.X * b.X + a.Y * b.Y; }
|
||||
|
||||
public PVecInt Sign() { return new PVecInt(Math.Sign(X), Math.Sign(Y)); }
|
||||
public PVecInt Abs() { return new PVecInt(Math.Abs(X), Math.Abs(Y)); }
|
||||
public int LengthSquared { get { return X * X + Y * Y; } }
|
||||
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
|
||||
public PVecInt Clamp(Rectangle r)
|
||||
{
|
||||
return new PVecInt(
|
||||
Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top))
|
||||
);
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
PVecInt o = (PVecInt)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "{0},{1}".F(X, Y); }
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA
|
||||
|
||||
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
|
||||
|
||||
static ISound Play(Player player, string name, bool headRelative, float2 pos, float volumeModifier)
|
||||
static ISound Play(Player player, string name, bool headRelative, PPos pos, float volumeModifier)
|
||||
{
|
||||
if (player != null && player != player.World.LocalPlayer)
|
||||
return null;
|
||||
@@ -72,16 +72,16 @@ namespace OpenRA
|
||||
return null;
|
||||
|
||||
return soundEngine.Play2D(sounds[name],
|
||||
false, headRelative, pos,
|
||||
false, headRelative, pos.ToFloat2(),
|
||||
InternalSoundVolume * volumeModifier);
|
||||
}
|
||||
|
||||
public static ISound Play(string name) { return Play(null, name, true, float2.Zero, 1); }
|
||||
public static ISound Play(string name, float2 pos) { return Play(null, name, false, pos, 1); }
|
||||
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, float2.Zero, volumeModifier); }
|
||||
public static ISound Play(string name, float2 pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
|
||||
public static ISound PlayToPlayer(Player player, string name) { return Play( player, name, true, float2.Zero, 1); }
|
||||
public static ISound PlayToPlayer(Player player, string name, float2 pos) { return Play(player, name, false, pos, 1); }
|
||||
public static ISound Play(string name) { return Play(null, name, true, PPos.Zero, 1); }
|
||||
public static ISound Play(string name, PPos pos) { return Play(null, name, false, pos, 1); }
|
||||
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, PPos.Zero, volumeModifier); }
|
||||
public static ISound Play(string name, PPos pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
|
||||
public static ISound PlayToPlayer(Player player, string name) { return Play(player, name, true, PPos.Zero, 1); }
|
||||
public static ISound PlayToPlayer(Player player, string name, PPos pos) { return Play(player, name, false, pos, 1); }
|
||||
|
||||
public static void PlayVideo(byte[] raw)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,26 @@ namespace OpenRA
|
||||
il.EmitCall(OpCodes.Call, ((Func<int2, int>)hash_int2).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(CPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<CPos, int>)hash_CPos).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(CVec))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<CVec, int>)hash_CVec).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PPos, int>)hash_PPos).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PVecInt))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PVecInt, int>)hash_PVecInt).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(TypeDictionary))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<TypeDictionary, int>)hash_tdict).Method, null);
|
||||
@@ -110,6 +130,26 @@ namespace OpenRA
|
||||
return ( ( i2.X * 5 ) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
public static int hash_CPos( CPos i2 )
|
||||
{
|
||||
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
public static int hash_CVec( CVec i2 )
|
||||
{
|
||||
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
public static int hash_PPos( PPos i2 )
|
||||
{
|
||||
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
public static int hash_PVecInt( PVecInt i2 )
|
||||
{
|
||||
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
public static int hash_tdict( TypeDictionary d )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -52,12 +52,12 @@ namespace OpenRA.Traits
|
||||
return;
|
||||
|
||||
var move = self.TraitOrDefault<IMove>();
|
||||
var origin = move != null ? self.CenterLocation - new int2(0, move.Altitude) : self.CenterLocation;
|
||||
var origin = (move != null ? self.CenterLocation - new PVecInt(0, move.Altitude) : self.CenterLocation).ToFloat2();
|
||||
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
|
||||
wlr.DrawLine(origin, target.CenterLocation, c, c);
|
||||
DrawTargetMarker(wlr, target.CenterLocation);
|
||||
wlr.DrawLine(origin, target.CenterLocation.ToFloat2(), c, c);
|
||||
DrawTargetMarker(wlr, target.CenterLocation.ToFloat2());
|
||||
DrawTargetMarker(wlr, origin);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Traits
|
||||
class RevealsShroud : ITick
|
||||
{
|
||||
RevealsShroudInfo Info;
|
||||
int2 previousLocation;
|
||||
CPos previousLocation;
|
||||
|
||||
public RevealsShroud(RevealsShroudInfo info)
|
||||
{
|
||||
|
||||
@@ -146,12 +146,12 @@ namespace OpenRA.Traits
|
||||
{
|
||||
var alt = new float2(0, -mobile.Altitude);
|
||||
var targets = activity.GetTargets(self);
|
||||
var start = self.CenterLocation + alt;
|
||||
var start = self.CenterLocation.ToFloat2() + alt;
|
||||
|
||||
var c = Color.Green;
|
||||
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
foreach (var step in targets.Select(p => p.CenterLocation))
|
||||
foreach (var step in targets.Select(p => p.CenterLocation.ToFloat2()))
|
||||
{
|
||||
var stp = step + alt;
|
||||
wlr.DrawLine(stp + new float2(-1, -1), stp + new float2(-1, 1), c, c);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Traits
|
||||
|
||||
Actor actor;
|
||||
Player owner;
|
||||
int2 pos;
|
||||
PPos pos;
|
||||
bool valid;
|
||||
|
||||
public static Target FromActor(Actor a)
|
||||
@@ -28,8 +28,8 @@ namespace OpenRA.Traits
|
||||
owner = (a != null) ? a.Owner : null
|
||||
};
|
||||
}
|
||||
public static Target FromPos(int2 p) { return new Target { pos = p, valid = true }; }
|
||||
public static Target FromCell(int2 c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
|
||||
public static Target FromPos(PPos p) { return new Target { pos = p, valid = true }; }
|
||||
public static Target FromCell(CPos c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
|
||||
public static Target FromOrder(Order o)
|
||||
{
|
||||
return o.TargetActor != null
|
||||
@@ -40,8 +40,8 @@ namespace OpenRA.Traits
|
||||
public static readonly Target None = new Target();
|
||||
|
||||
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && actor.Owner == owner)); } }
|
||||
public int2 PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
||||
public int2 CenterLocation { get { return PxPosition; } }
|
||||
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
||||
public PPos CenterLocation { get { return PxPosition; } }
|
||||
|
||||
public Actor Actor { get { return IsActor ? actor : null; } }
|
||||
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Traits
|
||||
string OrderID { get; }
|
||||
int OrderPriority { get; }
|
||||
bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool IsQueued { get; }
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Traits
|
||||
public interface INotifyKilled { void Killed(Actor self, AttackInfo e); }
|
||||
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
|
||||
public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
|
||||
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); }
|
||||
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, CPos exit); }
|
||||
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
|
||||
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
|
||||
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
|
||||
@@ -79,23 +79,23 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface IRadarSignature
|
||||
{
|
||||
IEnumerable<int2> RadarSignatureCells(Actor self);
|
||||
IEnumerable<CPos> RadarSignatureCells(Actor self);
|
||||
Color RadarSignatureColor(Actor self);
|
||||
}
|
||||
|
||||
public interface IVisibilityModifier { bool IsVisible(Actor self); }
|
||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||
public interface IHasLocation { int2 PxPosition { get; } }
|
||||
public interface IHasLocation { PPos PxPosition { get; } }
|
||||
|
||||
public interface IOccupySpace : IHasLocation
|
||||
{
|
||||
int2 TopLeft { get; }
|
||||
IEnumerable<Pair<int2, SubCell>> OccupiedCells();
|
||||
CPos TopLeft { get; }
|
||||
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
|
||||
}
|
||||
|
||||
public static class IOccupySpaceExts
|
||||
{
|
||||
public static int2 NearestCellTo(this IOccupySpace ios, int2 other)
|
||||
public static CPos NearestCellTo(this IOccupySpace ios, CPos other)
|
||||
{
|
||||
var nearest = ios.TopLeft;
|
||||
var nearestDistance = int.MaxValue;
|
||||
@@ -125,10 +125,10 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface ITeleportable : IHasLocation /* crap name! */
|
||||
{
|
||||
bool CanEnterCell(int2 location);
|
||||
void SetPosition(Actor self, int2 cell);
|
||||
void SetPxPosition(Actor self, int2 px);
|
||||
void AdjustPxPosition(Actor self, int2 px); /* works like SetPxPosition, but visual only */
|
||||
bool CanEnterCell(CPos location);
|
||||
void SetPosition(Actor self, CPos cell);
|
||||
void SetPxPosition(Actor self, PPos px);
|
||||
void AdjustPxPosition(Actor self, PPos px); /* works like SetPxPosition, but visual only */
|
||||
}
|
||||
|
||||
public interface IMove : ITeleportable { int Altitude { get; set; } }
|
||||
@@ -212,7 +212,7 @@ namespace OpenRA.Traits
|
||||
public interface ITargetable
|
||||
{
|
||||
string[] TargetTypes { get; }
|
||||
IEnumerable<int2> TargetableCells(Actor self);
|
||||
IEnumerable<CPos> TargetableCells(Actor self);
|
||||
bool TargetableBy(Actor self, Actor byActor);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,16 @@ namespace OpenRA.Traits
|
||||
return ( facing - rot ) & 0xFF;
|
||||
}
|
||||
|
||||
public static int GetFacing(PVecInt d, int currentFacing)
|
||||
{
|
||||
return GetFacing(d.ToInt2(), currentFacing);
|
||||
}
|
||||
|
||||
public static int GetFacing(CVec d, int currentFacing)
|
||||
{
|
||||
return GetFacing(d.ToInt2(), currentFacing);
|
||||
}
|
||||
|
||||
public static int GetFacing( int2 d, int currentFacing )
|
||||
{
|
||||
if (d == int2.Zero)
|
||||
@@ -80,14 +90,14 @@ namespace OpenRA.Traits
|
||||
ecc * (cosAngle * v.Y - sinAngle * v.X));
|
||||
}
|
||||
|
||||
public static int2 CenterOfCell(int2 loc)
|
||||
public static PPos CenterOfCell(CPos loc)
|
||||
{
|
||||
return new int2( Game.CellSize / 2, Game.CellSize / 2 ) + Game.CellSize * loc;
|
||||
return loc.ToPPos() + new PVecInt(Game.CellSize / 2, Game.CellSize / 2);
|
||||
}
|
||||
|
||||
public static int2 BetweenCells(int2 from, int2 to)
|
||||
public static PPos BetweenCells(CPos from, CPos to)
|
||||
{
|
||||
return int2.Lerp( CenterOfCell( from ), CenterOfCell( to ), 1, 2 );
|
||||
return PPos.Lerp(CenterOfCell(from), CenterOfCell(to), 1, 2);
|
||||
}
|
||||
|
||||
public static int2 AsInt2(this int[] xs) { return new int2(xs[0], xs[1]); }
|
||||
@@ -120,6 +130,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public static Color ArrayToColor(int[] x) { return Color.FromArgb(x[0], x[1], x[2]); }
|
||||
|
||||
[Obsolete("Use ToCPos() method", true)]
|
||||
public static int2 CellContaining(float2 pos) { return (1f / Game.CellSize * pos).ToInt2(); }
|
||||
|
||||
/* pretty crap */
|
||||
@@ -134,39 +145,39 @@ namespace OpenRA.Traits
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<int2> Neighbours(int2 c, bool allowDiagonal)
|
||||
static IEnumerable<CPos> Neighbours(CPos c, bool allowDiagonal)
|
||||
{
|
||||
yield return c;
|
||||
yield return new int2(c.X - 1, c.Y);
|
||||
yield return new int2(c.X + 1, c.Y);
|
||||
yield return new int2(c.X, c.Y - 1);
|
||||
yield return new int2(c.X, c.Y + 1);
|
||||
yield return new CPos(c.X - 1, c.Y);
|
||||
yield return new CPos(c.X + 1, c.Y);
|
||||
yield return new CPos(c.X, c.Y - 1);
|
||||
yield return new CPos(c.X, c.Y + 1);
|
||||
|
||||
if (allowDiagonal)
|
||||
{
|
||||
yield return new int2(c.X - 1, c.Y - 1);
|
||||
yield return new int2(c.X + 1, c.Y - 1);
|
||||
yield return new int2(c.X - 1, c.Y + 1);
|
||||
yield return new int2(c.X + 1, c.Y + 1);
|
||||
yield return new CPos(c.X - 1, c.Y - 1);
|
||||
yield return new CPos(c.X + 1, c.Y - 1);
|
||||
yield return new CPos(c.X - 1, c.Y + 1);
|
||||
yield return new CPos(c.X + 1, c.Y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> ExpandFootprint(IEnumerable<int2> cells, bool allowDiagonal)
|
||||
public static IEnumerable<CPos> ExpandFootprint(IEnumerable<CPos> cells, bool allowDiagonal)
|
||||
{
|
||||
var result = new Dictionary<int2, bool>();
|
||||
var result = new Dictionary<CPos, bool>();
|
||||
foreach (var c in cells.SelectMany(c => Neighbours(c, allowDiagonal)))
|
||||
result[c] = true;
|
||||
return result.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> AdjacentCells( Target target )
|
||||
public static IEnumerable<CPos> AdjacentCells(Target target)
|
||||
{
|
||||
var cells = target.IsActor
|
||||
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
|
||||
: new int2[] {};
|
||||
: new CPos[] {};
|
||||
|
||||
if (cells.Length == 0)
|
||||
cells = new [] { Util.CellContaining(target.CenterLocation) };
|
||||
cells = new CPos[] { target.CenterLocation.ToCPos() };
|
||||
|
||||
return Util.ExpandFootprint(cells, true);
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@ namespace OpenRA.Traits
|
||||
|
||||
class Waypoint : IOccupySpace, ISync
|
||||
{
|
||||
[Sync] int2 location;
|
||||
[Sync] CPos location;
|
||||
|
||||
public Waypoint(ActorInitializer init)
|
||||
{
|
||||
this.location = init.Get<LocationInit,int2>();
|
||||
this.location = init.Get<LocationInit, CPos>();
|
||||
}
|
||||
|
||||
public int2 TopLeft { get { return location; } }
|
||||
public CPos TopLeft { get { return location; } }
|
||||
|
||||
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { yield break; }
|
||||
public int2 PxPosition { get { return Util.CenterOfCell( location ); } }
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield break; }
|
||||
public PPos PxPosition { get { return Util.CenterOfCell(location); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,13 @@ namespace OpenRA.Traits
|
||||
for (int x = clip.Left; x < clip.Right; x++)
|
||||
for (int y = clip.Top; y < clip.Bottom; y++)
|
||||
{
|
||||
if (!world.LocalShroud.IsExplored(new int2(x, y)))
|
||||
if (!world.LocalShroud.IsExplored(new CPos(x, y)))
|
||||
continue;
|
||||
|
||||
var c = content[x, y];
|
||||
if (c.image != null)
|
||||
c.image[c.density].DrawAt(
|
||||
Game.CellSize * new int2(x, y),
|
||||
new CPos(x, y).ToPPos().ToFloat2(),
|
||||
c.type.info.PaletteIndex);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Traits
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (!AllowResourceAt(type, new int2(x,y)))
|
||||
if (!AllowResourceAt(type, new CPos(x,y)))
|
||||
continue;
|
||||
|
||||
content[x, y].type = type;
|
||||
@@ -86,7 +86,7 @@ namespace OpenRA.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public bool AllowResourceAt(ResourceType rt, int2 a)
|
||||
public bool AllowResourceAt(ResourceType rt, CPos a)
|
||||
{
|
||||
if (!world.Map.IsInMap(a.X, a.Y)) return false;
|
||||
if (!rt.info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type)) return false;
|
||||
@@ -136,7 +136,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public bool IsFull(int i, int j) { return content[i, j].density == content[i, j].image.Length - 1; }
|
||||
|
||||
public ResourceType Harvest(int2 p)
|
||||
public ResourceType Harvest(CPos p)
|
||||
{
|
||||
var type = content[p.X,p.Y].type;
|
||||
if (type == null) return null;
|
||||
@@ -150,7 +150,7 @@ namespace OpenRA.Traits
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Destroy(int2 p)
|
||||
public void Destroy(CPos p)
|
||||
{
|
||||
// Don't break other users of CustomTerrain if there are no resources
|
||||
if (content[p.X, p.Y].type == null)
|
||||
@@ -162,7 +162,7 @@ namespace OpenRA.Traits
|
||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
||||
}
|
||||
|
||||
public ResourceType GetResource(int2 p) { return content[p.X, p.Y].type; }
|
||||
public ResourceType GetResource(CPos p) { return content[p.X, p.Y].type; }
|
||||
|
||||
public struct CellContents
|
||||
{
|
||||
|
||||
@@ -54,22 +54,22 @@ namespace OpenRA.Traits
|
||||
|
||||
// cache of positions that were added, so no matter what crazy trait code does, it
|
||||
// can't make us invalid.
|
||||
class ActorVisibility { public int range; public int2[] vis; }
|
||||
class ActorVisibility { public int range; public CPos[] vis; }
|
||||
Dictionary<Actor, ActorVisibility> vis = new Dictionary<Actor, ActorVisibility>();
|
||||
|
||||
static IEnumerable<int2> FindVisibleTiles(World world, int2 a, int r)
|
||||
static IEnumerable<CPos> FindVisibleTiles(World world, CPos a, int r)
|
||||
{
|
||||
var min = a - new int2(r, r);
|
||||
var max = a + new int2(r, r);
|
||||
if (min.X < world.Map.Bounds.Left - 1) min.X = world.Map.Bounds.Left - 1;
|
||||
if (min.Y < world.Map.Bounds.Top - 1) min.Y = world.Map.Bounds.Top - 1;
|
||||
if (max.X > world.Map.Bounds.Right) max.X = world.Map.Bounds.Right;
|
||||
if (max.Y > world.Map.Bounds.Bottom) max.Y = world.Map.Bounds.Bottom;
|
||||
var min = a - new CVec(r, r);
|
||||
var max = a + new CVec(r, r);
|
||||
if (min.X < world.Map.Bounds.Left - 1) min = new CPos(world.Map.Bounds.Left - 1, min.Y);
|
||||
if (min.Y < world.Map.Bounds.Top - 1) min = new CPos(min.X, world.Map.Bounds.Top - 1);
|
||||
if (max.X > world.Map.Bounds.Right) max = new CPos(world.Map.Bounds.Right, max.Y);
|
||||
if (max.Y > world.Map.Bounds.Bottom) max = new CPos(max.X, world.Map.Bounds.Bottom);
|
||||
|
||||
for (var j = min.Y; j <= max.Y; j++)
|
||||
for (var i = min.X; i <= max.X; i++)
|
||||
if (r * r >= (new int2(i, j) - a).LengthSquared)
|
||||
yield return new int2(i, j);
|
||||
if (r * r >= (new CPos(i, j) - a).LengthSquared)
|
||||
yield return new CPos(i, j);
|
||||
}
|
||||
|
||||
void AddActor(Actor a)
|
||||
@@ -148,7 +148,7 @@ namespace OpenRA.Traits
|
||||
AddActor(a);
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> GetVisOrigins(Actor a)
|
||||
public static IEnumerable<CPos> GetVisOrigins(Actor a)
|
||||
{
|
||||
var ios = a.OccupiesSpace;
|
||||
if (ios != null)
|
||||
@@ -157,7 +157,7 @@ namespace OpenRA.Traits
|
||||
if (cells.Any()) return cells.Select(c => c.First);
|
||||
}
|
||||
|
||||
return new[] { a.CenterLocation / Game.CellSize };
|
||||
return new[] { a.CenterLocation.ToCPos() };
|
||||
}
|
||||
|
||||
void RemoveActor(Actor a)
|
||||
@@ -183,7 +183,7 @@ namespace OpenRA.Traits
|
||||
RemoveActor(a); AddActor(a);
|
||||
}
|
||||
|
||||
public void Explore(World world, int2 center, int range)
|
||||
public void Explore(World world, CPos center, int range)
|
||||
{
|
||||
foreach (var q in FindVisibleTiles(world, center, range))
|
||||
exploredCells[q.X, q.Y] = true;
|
||||
@@ -216,7 +216,7 @@ namespace OpenRA.Traits
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(CPos xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(int x, int y)
|
||||
{
|
||||
if (!map.IsInMap(x, y))
|
||||
@@ -228,7 +228,7 @@ namespace OpenRA.Traits
|
||||
return exploredCells[x,y];
|
||||
}
|
||||
|
||||
public bool IsVisible(int2 xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(int x, int y)
|
||||
{
|
||||
if (Disabled)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Traits
|
||||
yield return a;
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> ActorsInBox(int2 a, int2 b)
|
||||
public IEnumerable<Actor> ActorsInBox(PPos a, PPos b)
|
||||
{
|
||||
var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y);
|
||||
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace OpenRA.Widgets
|
||||
return;
|
||||
}
|
||||
|
||||
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First, selbox.Value.Second, Color.White);
|
||||
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First.ToFloat2(), selbox.Value.Second.ToFloat2(), Color.White);
|
||||
foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second, _ => true))
|
||||
worldRenderer.DrawRollover(u);
|
||||
}
|
||||
|
||||
int2 dragStart, dragEnd;
|
||||
PPos dragStart, dragEnd;
|
||||
|
||||
public override bool HandleMouseInput(MouseInput mi)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Widgets
|
||||
return true;
|
||||
}
|
||||
|
||||
public Pair<int2, int2>? SelectionBox
|
||||
public Pair<PPos, PPos>? SelectionBox
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -110,11 +110,11 @@ namespace OpenRA.Widgets
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyOrders(World world, int2 xy, MouseInput mi)
|
||||
public void ApplyOrders(World world, PPos xy, MouseInput mi)
|
||||
{
|
||||
if (world.OrderGenerator == null) return;
|
||||
|
||||
var orders = world.OrderGenerator.Order(world, Traits.Util.CellContaining(xy), mi).ToArray();
|
||||
var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray();
|
||||
orders.Do( o => world.IssueOrder( o ) );
|
||||
|
||||
world.PlayVoiceForOrders(orders);
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Widgets
|
||||
};
|
||||
|
||||
// TODO: fix this up.
|
||||
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi );
|
||||
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi), mi );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace OpenRA.Widgets
|
||||
}
|
||||
|
||||
static readonly Actor[] NoActors = {};
|
||||
IEnumerable<Actor> SelectActorsInBox(World world, int2 a, int2 b, Func<Actor, bool> cond)
|
||||
IEnumerable<Actor> SelectActorsInBox(World world, PPos a, PPos b, Func<Actor, bool> cond)
|
||||
{
|
||||
return world.FindUnits(a, b)
|
||||
.Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) && cond(x) )
|
||||
|
||||
@@ -27,24 +27,24 @@ namespace OpenRA
|
||||
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
|
||||
}
|
||||
|
||||
public static IEnumerable<Actor> FindUnits(this World world, int2 a, int2 b)
|
||||
public static IEnumerable<Actor> FindUnits(this World world, PPos a, PPos b)
|
||||
{
|
||||
var u = float2.Min(a, b).ToInt2();
|
||||
var v = float2.Max(a, b).ToInt2();
|
||||
var u = PPos.Min(a, b);
|
||||
var v = PPos.Max(a, b);
|
||||
return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v);
|
||||
}
|
||||
|
||||
public static Actor ClosestTo( this IEnumerable<Actor> actors, int2 px )
|
||||
public static Actor ClosestTo(this IEnumerable<Actor> actors, PPos px)
|
||||
{
|
||||
return actors.OrderBy( a => (a.CenterLocation - px).LengthSquared ).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static IEnumerable<Actor> FindUnitsInCircle(this World world, int2 a, int r)
|
||||
public static IEnumerable<Actor> FindUnitsInCircle(this World world, PPos a, int r)
|
||||
{
|
||||
using (new PerfSample("FindUnitsInCircle"))
|
||||
{
|
||||
var min = a - new int2(r, r);
|
||||
var max = a + new int2(r, r);
|
||||
var min = a - PVecInt.FromRadius(r);
|
||||
var max = a + PVecInt.FromRadius(r);
|
||||
|
||||
var actors = world.FindUnits(min, max);
|
||||
|
||||
@@ -56,48 +56,48 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> FindTilesInCircle(this World world, int2 a, int r)
|
||||
public static IEnumerable<CPos> FindTilesInCircle(this World world, CPos a, int r)
|
||||
{
|
||||
var min = world.ClampToWorld(a - new int2(r, r));
|
||||
var max = world.ClampToWorld(a + new int2(r, r));
|
||||
var min = world.ClampToWorld(a - new CVec(r, r));
|
||||
var max = world.ClampToWorld(a + new CVec(r, r));
|
||||
for (var j = min.Y; j <= max.Y; j++)
|
||||
for (var i = min.X; i <= max.X; i++)
|
||||
if (r * r >= (new int2(i, j) - a).LengthSquared)
|
||||
yield return new int2(i, j);
|
||||
if (r * r >= (new CPos(i, j) - a).LengthSquared)
|
||||
yield return new CPos(i, j);
|
||||
}
|
||||
|
||||
public static string GetTerrainType(this World world, int2 cell)
|
||||
public static string GetTerrainType(this World world, CPos cell)
|
||||
{
|
||||
var custom = world.Map.CustomTerrain[cell.X, cell.Y];
|
||||
return custom != null ? custom : world.TileSet.GetTerrainType(world.Map.MapTiles.Value[cell.X, cell.Y]);
|
||||
}
|
||||
|
||||
public static TerrainTypeInfo GetTerrainInfo(this World world, int2 cell)
|
||||
public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
|
||||
{
|
||||
return world.TileSet.Terrain[world.GetTerrainType(cell)];
|
||||
}
|
||||
|
||||
public static int2 ClampToWorld( this World world, int2 xy )
|
||||
public static CPos ClampToWorld(this World world, CPos xy)
|
||||
{
|
||||
var r = world.Map.Bounds;
|
||||
return xy.Clamp(new Rectangle(r.X,r.Y,r.Width-1, r.Height-1));
|
||||
}
|
||||
|
||||
public static int2 ChooseRandomEdgeCell(this World w)
|
||||
public static CPos ChooseRandomEdgeCell(this World w)
|
||||
{
|
||||
var isX = w.SharedRandom.Next(2) == 0;
|
||||
var edge = w.SharedRandom.Next(2) == 0;
|
||||
|
||||
return new int2(
|
||||
return new CPos(
|
||||
isX ? w.SharedRandom.Next(w.Map.Bounds.Left, w.Map.Bounds.Right)
|
||||
: (edge ? w.Map.Bounds.Left : w.Map.Bounds.Right),
|
||||
!isX ? w.SharedRandom.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom)
|
||||
: (edge ? w.Map.Bounds.Top : w.Map.Bounds.Bottom));
|
||||
}
|
||||
|
||||
public static int2 ChooseRandomCell(this World w, Thirdparty.Random r)
|
||||
public static CPos ChooseRandomCell(this World w, Thirdparty.Random r)
|
||||
{
|
||||
return new int2(
|
||||
return new CPos(
|
||||
r.Next(w.Map.Bounds.Left, w.Map.Bounds.Right),
|
||||
r.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom));
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace OpenRA.Mods.Cnc
|
||||
readonly RenderUnit ru;
|
||||
State state;
|
||||
|
||||
int2 startDock;
|
||||
int2 endDock;
|
||||
PPos startDock;
|
||||
PPos endDock;
|
||||
public HarvesterDockSequence(Actor self, Actor proc)
|
||||
{
|
||||
this.proc = proc;
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Cnc
|
||||
harv = self.Trait<Harvester>();
|
||||
ru = self.Trait<RenderUnit>();
|
||||
startDock = self.Trait<IHasLocation>().PxPosition;
|
||||
endDock = proc.Trait<IHasLocation>().PxPosition + new int2(-15,8);
|
||||
endDock = proc.Trait<IHasLocation>().PxPosition + new PVecInt(-15,8);
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
Animation anim;
|
||||
Actor firedBy;
|
||||
|
||||
public IonCannon(Actor firedBy, World world, int2 location)
|
||||
public IonCannon(Actor firedBy, World world, CPos location)
|
||||
{
|
||||
this.firedBy = firedBy;
|
||||
target = Target.FromCell(location);
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image,
|
||||
target.CenterLocation - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
|
||||
target.CenterLocation.ToFloat2() - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
|
||||
"effect", (int)target.CenterLocation.Y);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
Sound.Play(Info.LaunchSound, order.TargetLocation.ToPPos());
|
||||
w.Add(new IonCannon(self, w, order.TargetLocation));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace OpenRA.Mods.RA
|
||||
class CncShellmapScript: IWorldLoaded, ITick
|
||||
{
|
||||
Dictionary<string, Actor> Actors;
|
||||
static int2 ViewportOrigin;
|
||||
static CPos ViewportOrigin;
|
||||
|
||||
public void WorldLoaded(World w)
|
||||
{
|
||||
var b = w.Map.Bounds;
|
||||
ViewportOrigin = new int2(b.Left + b.Width/2, b.Top + b.Height/2);
|
||||
Game.MoveViewport(ViewportOrigin);
|
||||
ViewportOrigin = new CPos(b.Left + b.Width/2, b.Top + b.Height/2);
|
||||
Game.MoveViewport(ViewportOrigin.ToFloat2());
|
||||
|
||||
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
||||
void SetViewport()
|
||||
{
|
||||
var t = (ticks + 45) % (360f * speed) * (Math.PI / 180) * 1f / speed;
|
||||
var loc = ViewportOrigin + new float2(-15,4) * float2.FromAngle( (float)t );
|
||||
var loc = ViewportOrigin.ToFloat2() + (new float2(-15,4) * float2.FromAngle( (float)t ));
|
||||
Game.viewport.Center(loc);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA
|
||||
}));
|
||||
}
|
||||
|
||||
void LoopTrack(Actor self, int2 left, int2 right)
|
||||
void LoopTrack(Actor self, CPos left, CPos right)
|
||||
{
|
||||
var mobile = self.Trait<Mobile>();
|
||||
self.QueueActivity(mobile.ScriptedMove(left));
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
|
||||
Players = w.Players.ToDictionary(p => p.InternalName);
|
||||
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
|
||||
var b = w.Map.Bounds;
|
||||
Game.MoveViewport(new int2(b.Left + b.Width/2, b.Top + b.Height/2));
|
||||
Game.MoveViewport(new CPos(b.Left + b.Width/2, b.Top + b.Height/2).ToFloat2());
|
||||
|
||||
Scripting.Media.PlayFMVFullscreen(w, "gdi1.vqa",
|
||||
() => Scripting.Media.PlayFMVFullscreen(w, "landing.vqa", () =>
|
||||
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"e1","e1","e1"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"e1","e1","e1"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"jeep"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"jeep"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace OpenRA.Mods.Cnc
|
||||
self.QueueActivity(new CallFunc(() => SetGunboatPath()));
|
||||
}
|
||||
|
||||
void ReinforceFromSea(World world, int2 startPos, int2 endPos, int2 unload, string[] items, Player player)
|
||||
void ReinforceFromSea(World world, CPos startPos, CPos endPos, CPos unload, string[] items, Player player)
|
||||
{
|
||||
world.AddFrameEndTask(w =>
|
||||
{
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
// Start a fixed distance away: the width of the map.
|
||||
// This makes the production timing independent of spawnpoint
|
||||
var startPos = self.Location + new int2(owner.World.Map.Bounds.Width, 0);
|
||||
var endPos = new int2(owner.World.Map.Bounds.Left - 5, self.Location.Y);
|
||||
var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0);
|
||||
var endPos = new CPos(owner.World.Map.Bounds.Left - 5, self.Location.Y);
|
||||
|
||||
// Assume a single exit point for simplicity
|
||||
var exit = self.Info.Traits.WithInterface<ExitInfo>().First();
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Cnc
|
||||
new AltitudeInit( Rules.Info[actorType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
a.QueueActivity(Fly.ToCell(self.Location + new int2(6,0)));
|
||||
a.QueueActivity(Fly.ToCell(self.Location + new CVec(6, 0)));
|
||||
a.QueueActivity(new Land(Target.FromActor(self)));
|
||||
a.QueueActivity(new CallFunc(() =>
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public void UpdateMouseover()
|
||||
{
|
||||
TooltipType = WorldTooltipType.None;
|
||||
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
if (!world.Map.IsInMap(cell))
|
||||
return;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
readonly HackyAIInfo Info;
|
||||
|
||||
Cache<Player,Enemy> aggro = new Cache<Player, Enemy>( _ => new Enemy() );
|
||||
int2 baseCenter;
|
||||
CPos baseCenter;
|
||||
XRandom random = new XRandom(); //we do not use the synced random number generator.
|
||||
BaseBuilder[] builders;
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue)
|
||||
{
|
||||
var buildableThings = queue.BuildableItems();
|
||||
if (buildableThings.Count() == 0) return null;
|
||||
if (!buildableThings.Any()) return null;
|
||||
return buildableThings.ElementAtOrDefault(random.Next(buildableThings.Count()));
|
||||
}
|
||||
|
||||
@@ -154,13 +154,13 @@ namespace OpenRA.Mods.RA.AI
|
||||
return null;
|
||||
}
|
||||
|
||||
bool NoBuildingsUnder(IEnumerable<int2> cells)
|
||||
bool NoBuildingsUnder(IEnumerable<CPos> cells)
|
||||
{
|
||||
var bi = world.WorldActor.Trait<BuildingInfluence>();
|
||||
return cells.All(c => bi.GetBuildingAt(c) == null);
|
||||
}
|
||||
|
||||
public int2? ChooseBuildLocation(string actorType)
|
||||
public CPos? ChooseBuildLocation(string actorType)
|
||||
{
|
||||
var bi = Rules.Info[actorType].Traits.Get<BuildingInfo>();
|
||||
|
||||
@@ -200,12 +200,12 @@ namespace OpenRA.Mods.RA.AI
|
||||
//A bunch of hardcoded lists to keep track of which units are doing what.
|
||||
List<Actor> unitsHangingAroundTheBase = new List<Actor>();
|
||||
List<Actor> attackForce = new List<Actor>();
|
||||
int2? attackTarget;
|
||||
CPos? attackTarget;
|
||||
|
||||
//Units that the ai already knows about. Any unit not on this list needs to be given a role.
|
||||
List<Actor> activeUnits = new List<Actor>();
|
||||
|
||||
int2? ChooseEnemyTarget()
|
||||
CPos? ChooseEnemyTarget()
|
||||
{
|
||||
var liveEnemies = world.Players
|
||||
.Where(q => p != q && p.Stances[q] == Stance.Enemy)
|
||||
@@ -219,14 +219,14 @@ namespace OpenRA.Mods.RA.AI
|
||||
if (leastLikedEnemies == null)
|
||||
return null;
|
||||
|
||||
var enemy = leastLikedEnemies != null ? leastLikedEnemies.Random(random) : null;
|
||||
var enemy = leastLikedEnemies.Random(random);
|
||||
|
||||
/* pick something worth attacking owned by that player */
|
||||
var targets = world.Actors
|
||||
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>());
|
||||
Actor target=null;
|
||||
Actor target = null;
|
||||
|
||||
if (targets.Count()>0)
|
||||
if (targets.Any())
|
||||
target = targets.Random(random);
|
||||
|
||||
if (target == null)
|
||||
@@ -346,7 +346,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRallyPointValid(int2 x)
|
||||
bool IsRallyPointValid(CPos x)
|
||||
{
|
||||
// this is actually WRONG as soon as HackyAI is building units with a variety of
|
||||
// movement capabilities. (has always been wrong)
|
||||
@@ -363,16 +363,15 @@ namespace OpenRA.Mods.RA.AI
|
||||
BotDebug("Bot {0} needs to find rallypoints for {1} buildings.",
|
||||
p.PlayerName, buildings.Length);
|
||||
|
||||
|
||||
foreach (var a in buildings)
|
||||
{
|
||||
int2 newRallyPoint = ChooseRallyLocationNear(a.Actor.Location);
|
||||
CPos newRallyPoint = ChooseRallyLocationNear(a.Actor.Location);
|
||||
world.IssueOrder(new Order("SetRallyPoint", a.Actor, false) { TargetLocation = newRallyPoint });
|
||||
}
|
||||
}
|
||||
|
||||
//won't work for shipyards...
|
||||
int2 ChooseRallyLocationNear(int2 startPos)
|
||||
CPos ChooseRallyLocationNear(CPos startPos)
|
||||
{
|
||||
var possibleRallyPoints = world.FindTilesInCircle(startPos, 8).Where(IsRallyPointValid).ToArray();
|
||||
if (possibleRallyPoints.Length == 0)
|
||||
@@ -384,18 +383,18 @@ namespace OpenRA.Mods.RA.AI
|
||||
return possibleRallyPoints.Random(random);
|
||||
}
|
||||
|
||||
int2? ChooseDestinationNear(Actor a, int2 desiredMoveTarget)
|
||||
CPos? ChooseDestinationNear(Actor a, CPos desiredMoveTarget)
|
||||
{
|
||||
var move = a.TraitOrDefault<IMove>();
|
||||
if (move == null) return null;
|
||||
|
||||
int2 xy;
|
||||
CPos xy;
|
||||
int loopCount = 0; //avoid infinite loops.
|
||||
int range = 2;
|
||||
do
|
||||
{
|
||||
//loop until we find a valid move location
|
||||
xy = new int2(desiredMoveTarget.X + random.Next(-range, range), desiredMoveTarget.Y + random.Next(-range, range));
|
||||
xy = new CPos(desiredMoveTarget.X + random.Next(-range, range), desiredMoveTarget.Y + random.Next(-range, range));
|
||||
loopCount++;
|
||||
range = Math.Max(range, loopCount / 2);
|
||||
if (loopCount > 10) return null;
|
||||
@@ -406,7 +405,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
//try very hard to find a valid move destination near the target.
|
||||
//(Don't accept a move onto the subject's current position. maybe this is already not allowed? )
|
||||
bool TryToMove(Actor a, int2 desiredMoveTarget, bool attackMove)
|
||||
bool TryToMove(Actor a, CPos desiredMoveTarget, bool attackMove)
|
||||
{
|
||||
var xy = ChooseDestinationNear(a, desiredMoveTarget);
|
||||
if (xy == null)
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
public override IEnumerable<Target> GetTargets(Actor self)
|
||||
{
|
||||
yield return Target.FromPos(self.Location);
|
||||
yield return Target.FromCell(self.Location);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
if (IsCanceled) return NextActivity;
|
||||
if (!Target.IsValid) return NextActivity;
|
||||
|
||||
var inRange = ( Util.CellContaining( Target.CenterLocation ) - self.Location ).LengthSquared < Range * Range;
|
||||
var inRange = ( Target.CenterLocation.ToCPos() - self.Location ).LengthSquared < Range * Range;
|
||||
|
||||
if( inRange ) return this;
|
||||
if (--nextPathTime > 0) return this;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
return Util.SequenceActivities(
|
||||
new MoveAdjacentTo(Target.FromActor(rearmTarget)),
|
||||
mobile.MoveTo(Traits.Util.CellContaining(rearmTarget.CenterLocation), rearmTarget),
|
||||
mobile.MoveTo(rearmTarget.CenterLocation.ToCPos(), rearmTarget),
|
||||
new Rearm(self),
|
||||
new Repair(rearmTarget),
|
||||
this );
|
||||
@@ -65,11 +65,10 @@ namespace OpenRA.Mods.RA.Activities
|
||||
return new Wait(20); // nothing to do here
|
||||
}
|
||||
|
||||
bool ShouldLayMine(Actor self, int2 p)
|
||||
bool ShouldLayMine(Actor self, CPos p)
|
||||
{
|
||||
// if there is no unit (other than me) here, we want to place a mine here
|
||||
return !self.World.ActorMap
|
||||
.GetUnitsAt(p).Any(a => a != self);
|
||||
return !self.World.ActorMap.GetUnitsAt(p).Any(a => a != self);
|
||||
}
|
||||
|
||||
void LayMine(Actor self)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
class Leap : Activity
|
||||
{
|
||||
Target target;
|
||||
int2 initialLocation;
|
||||
PPos initialLocation;
|
||||
|
||||
int moveFraction;
|
||||
const int delay = 6;
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
public Leap(Actor self, Target target)
|
||||
{
|
||||
this.target = target;
|
||||
initialLocation = self.Trait<Mobile>().PxPosition;
|
||||
initialLocation = (PPos) self.Trait<Mobile>().PxPosition;
|
||||
|
||||
self.Trait<RenderInfantry>().Attacking(self, target);
|
||||
Sound.Play("dogg5p.aud", self.CenterLocation);
|
||||
@@ -41,12 +41,12 @@ namespace OpenRA.Mods.RA.Activities
|
||||
var mobile = self.Trait<Mobile>();
|
||||
++moveFraction;
|
||||
|
||||
mobile.PxPosition = int2.Lerp(initialLocation, target.PxPosition, moveFraction, delay);
|
||||
mobile.PxPosition = PPos.Lerp(initialLocation, target.PxPosition, moveFraction, delay);
|
||||
|
||||
if (moveFraction >= delay)
|
||||
{
|
||||
self.TraitsImplementing<IMove>().FirstOrDefault()
|
||||
.SetPosition(self, Util.CellContaining(target.CenterLocation));
|
||||
.SetPosition(self, target.CenterLocation.ToCPos());
|
||||
|
||||
if (target.IsActor)
|
||||
target.Actor.Kill(self);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell );
|
||||
|
||||
var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, Util.CellContaining(target.CenterLocation), true );
|
||||
var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, target.CenterLocation.ToCPos(), true );
|
||||
var ret = self.World.WorldActor.Trait<PathFinder>().FindBidiPath( ps1, ps2 );
|
||||
|
||||
return Util.SequenceActivities( mobile.MoveTo( () => ret ), this );
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public class Teleport : Activity
|
||||
{
|
||||
int2 destination;
|
||||
CPos destination;
|
||||
|
||||
public Teleport(int2 destination)
|
||||
public Teleport(CPos destination)
|
||||
{
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
class Transform : Activity
|
||||
{
|
||||
public readonly string ToActor = null;
|
||||
public int2 Offset = new int2(0,0);
|
||||
public CVec Offset = new CVec(0, 0);
|
||||
public int Facing = 96;
|
||||
public string[] Sounds = {};
|
||||
public int ForceHealthPercentage = 0;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public class UnloadCargo : Activity
|
||||
{
|
||||
int2? ChooseExitTile(Actor self, Actor cargo)
|
||||
CPos? ChooseExitTile(Actor self, Actor cargo)
|
||||
{
|
||||
// is anyone still hogging this tile?
|
||||
if (self.World.ActorMap.GetUnitsAt(self.Location).Count() > 1)
|
||||
@@ -29,8 +29,8 @@ namespace OpenRA.Mods.RA.Activities
|
||||
for (var i = -1; i < 2; i++)
|
||||
for (var j = -1; j < 2; j++)
|
||||
if ((i != 0 || j != 0) &&
|
||||
mobile.CanEnterCell(self.Location + new int2(i, j)))
|
||||
return self.Location + new int2(i, j);
|
||||
mobile.CanEnterCell(self.Location + new CVec(i, j)))
|
||||
return self.Location + new CVec(i, j);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
if (actor.Destroyed) return;
|
||||
|
||||
var mobile = actor.Trait<Mobile>();
|
||||
mobile.Facing = Util.GetFacing( exitPx - currentPx, mobile.Facing );
|
||||
mobile.Facing = Util.GetFacing( (exitPx - currentPx).ToInt2(), mobile.Facing );
|
||||
mobile.SetPosition(actor, exitTile.Value);
|
||||
mobile.AdjustPxPosition(actor, currentPx);
|
||||
var speed = mobile.MovementSpeedForCell(actor, exitTile.Value);
|
||||
|
||||
@@ -108,8 +108,8 @@ namespace OpenRA.Mods.RA.Air
|
||||
public int Altitude { get; set; }
|
||||
[Sync]
|
||||
public int2 SubPxPosition;
|
||||
public int2 PxPosition { get { return new int2( SubPxPosition.X / 1024, SubPxPosition.Y / 1024 ); } }
|
||||
public int2 TopLeft { get { return Util.CellContaining( PxPosition ); } }
|
||||
public PPos PxPosition { get { return new PPos( SubPxPosition.X / 1024, SubPxPosition.Y / 1024 ); } }
|
||||
public CPos TopLeft { get { return PxPosition.ToCPos(); } }
|
||||
|
||||
readonly AircraftInfo Info;
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
this.self = init.self;
|
||||
if( init.Contains<LocationInit>() )
|
||||
this.SubPxPosition = 1024 * Util.CenterOfCell( init.Get<LocationInit, int2>() );
|
||||
this.SubPxPosition = 1024 * Util.CenterOfCell( init.Get<LocationInit, CPos>() ).ToInt2();
|
||||
|
||||
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : info.InitialFacing;
|
||||
this.Altitude = init.Contains<AltitudeInit>() ? init.Get<AltitudeInit,int>() : 0;
|
||||
@@ -151,17 +151,17 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
public int InitialFacing { get { return Info.InitialFacing; } }
|
||||
|
||||
public void SetPosition(Actor self, int2 cell)
|
||||
public void SetPosition(Actor self, CPos cell)
|
||||
{
|
||||
SetPxPosition( self, Util.CenterOfCell( cell ) );
|
||||
}
|
||||
|
||||
public void SetPxPosition( Actor self, int2 px )
|
||||
public void SetPxPosition( Actor self, PPos px )
|
||||
{
|
||||
SubPxPosition = px * 1024;
|
||||
SubPxPosition = px.ToInt2() * 1024;
|
||||
}
|
||||
|
||||
public void AdjustPxPosition(Actor self, int2 px) { SetPxPosition(self, px); }
|
||||
public void AdjustPxPosition(Actor self, PPos px) { SetPxPosition(self, px); }
|
||||
|
||||
public bool AircraftCanEnter(Actor a)
|
||||
{
|
||||
@@ -170,7 +170,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
|| Info.RepairBuildings.Contains( a.Info.Name );
|
||||
}
|
||||
|
||||
public bool CanEnterCell(int2 location) { return true; }
|
||||
public bool CanEnterCell(CPos location) { return true; }
|
||||
|
||||
public int MovementSpeed
|
||||
{
|
||||
@@ -183,8 +183,8 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
}
|
||||
|
||||
Pair<int2, SubCell>[] noCells = new Pair<int2, SubCell>[] { };
|
||||
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { return noCells; }
|
||||
Pair<CPos, SubCell>[] noCells = new Pair<CPos, SubCell>[] { };
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return noCells; }
|
||||
|
||||
public void TickMove( int speed, int facing )
|
||||
{
|
||||
@@ -192,7 +192,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
SubPxPosition += rawspeed * -Util.SubPxVector[facing];
|
||||
}
|
||||
|
||||
public bool CanLand(int2 cell)
|
||||
public bool CanLand(CPos cell)
|
||||
{
|
||||
if (!self.World.Map.IsInMap(cell))
|
||||
return false;
|
||||
@@ -230,7 +230,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
return new Order(order.OrderID, self, queued) { TargetActor = target.Actor };
|
||||
|
||||
if (order.OrderID == "Move")
|
||||
return new Order(order.OrderID, self, queued) { TargetLocation = Util.CellContaining(target.CenterLocation) };
|
||||
return new Order(order.OrderID, self, queued) { TargetLocation = target.CenterLocation.ToCPos() };
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
|
||||
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
|
||||
{
|
||||
IsQueued = forceQueued;
|
||||
cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked";
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
self.World.AddFrameEndTask(w => w.Add(
|
||||
new Parachute(pilot.Owner,
|
||||
Util.CenterOfCell(Util.CellContaining(self.CenterLocation)),
|
||||
Util.CenterOfCell(self.CenterLocation.ToCPos()),
|
||||
aircraft.Altitude, pilot)));
|
||||
|
||||
Sound.Play(info.ChuteSound, self.CenterLocation);
|
||||
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA
|
||||
pilot.Destroy();
|
||||
}
|
||||
|
||||
bool IsSuitableCell(Actor actorToDrop, int2 p)
|
||||
bool IsSuitableCell(Actor actorToDrop, CPos p)
|
||||
{
|
||||
return actorToDrop.Trait<ITeleportable>().CanEnterCell(p);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class Fly : Activity
|
||||
{
|
||||
public readonly int2 Pos;
|
||||
public readonly PPos Pos;
|
||||
|
||||
Fly( int2 px ) { Pos = px; }
|
||||
Fly(PPos px) { Pos = px; }
|
||||
|
||||
public static Fly ToPx( int2 px ) { return new Fly( px ); }
|
||||
public static Fly ToCell( int2 pos ) { return new Fly( Util.CenterOfCell( pos ) ); }
|
||||
public static Fly ToPx( PPos px ) { return new Fly( px ); }
|
||||
public static Fly ToCell(CPos pos) { return new Fly(Util.CenterOfCell(pos)); }
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
|
||||
var desiredFacing = Util.GetFacing(d, aircraft.Facing);
|
||||
var desiredFacing = Util.GetFacing(d.ToInt2(), aircraft.Facing);
|
||||
if (aircraft.Altitude == cruiseAltitude)
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
var desiredFacing = Util.GetFacing(dist, aircraft.Facing);
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
if( !float2.WithinEpsilon( float2.Zero, dist, range * Game.CellSize ) )
|
||||
if( !float2.WithinEpsilon( float2.Zero, dist.ToFloat2(), range * Game.CellSize ) )
|
||||
aircraft.TickMove( 1024 * aircraft.MovementSpeed, desiredFacing );
|
||||
|
||||
attack.DoAttack( self, target );
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
class HeliFly : Activity
|
||||
{
|
||||
public readonly int2 Dest;
|
||||
public HeliFly(int2 dest)
|
||||
public readonly PPos Dest;
|
||||
public HeliFly(PPos dest)
|
||||
{
|
||||
Dest = dest;
|
||||
}
|
||||
@@ -36,9 +36,9 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
|
||||
var dist = Dest - aircraft.PxPosition;
|
||||
if (float2.WithinEpsilon(float2.Zero, dist, 2))
|
||||
if (float2.WithinEpsilon(float2.Zero, dist.ToFloat2(), 2))
|
||||
{
|
||||
aircraft.SubPxPosition = Dest * 1024;
|
||||
aircraft.SubPxPosition = (Dest.ToInt2() * 1024);
|
||||
return NextActivity;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ namespace OpenRA.Mods.RA.Air
|
||||
var nearestHpad = self.World.ActorsWithTrait<Reservable>()
|
||||
.Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name))
|
||||
.Select(a => a.Actor)
|
||||
.ClosestTo(self.CenterLocation);
|
||||
|
||||
if (nearestHpad == null)
|
||||
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true), NextActivity);
|
||||
else
|
||||
.ClosestTo(self.CenterLocation);
|
||||
|
||||
if (nearestHpad == null)
|
||||
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true), NextActivity);
|
||||
else
|
||||
return Util.SequenceActivities(new HeliFly(Util.CenterOfCell(nearestHpad.Location)));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
heli.reservation = res.Reserve(dest, self, heli);
|
||||
|
||||
var exit = dest.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||
var offset = exit != null ? exit.SpawnOffset : int2.Zero;
|
||||
var offset = exit != null ? exit.SpawnOffsetVector : PVecInt.Zero;
|
||||
|
||||
return Util.SequenceActivities(
|
||||
new HeliFly(dest.Trait<IHasLocation>().PxPosition + offset),
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
reservation = res.Reserve(order.TargetActor, self, this);
|
||||
|
||||
var exit = order.TargetActor.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||
var offset = exit != null ? exit.SpawnOffset : int2.Zero;
|
||||
var offset = exit != null ? exit.SpawnOffsetVector : PVecInt.Zero;
|
||||
|
||||
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
|
||||
|
||||
@@ -118,9 +118,9 @@ namespace OpenRA.Mods.RA.Air
|
||||
.Select(h => GetRepulseForce(self, h))
|
||||
.Aggregate(int2.Zero, (a, b) => a + b);
|
||||
|
||||
int RepulsionFacing = Util.GetFacing( f, -1 );
|
||||
if( RepulsionFacing != -1 )
|
||||
TickMove( 1024 * MovementSpeed, RepulsionFacing );
|
||||
int repulsionFacing = Util.GetFacing( f, -1 );
|
||||
if( repulsionFacing != -1 )
|
||||
TickMove( 1024 * MovementSpeed, repulsionFacing );
|
||||
}
|
||||
|
||||
// Returns an int2 in subPx units
|
||||
@@ -137,7 +137,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
if (d.LengthSquared < 1)
|
||||
return Util.SubPxVector[self.World.SharedRandom.Next(255)];
|
||||
return (5120 / d.LengthSquared) * d;
|
||||
return (5120 / d.LengthSquared) * d.ToInt2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
public class Plane : Aircraft, IResolveOrder, ITick, ISync
|
||||
{
|
||||
[Sync] public int2 RTBPathHash;
|
||||
[Sync] public PVecInt RTBPathHash;
|
||||
|
||||
public Plane( ActorInitializer init, PlaneInfo info )
|
||||
: base( init, info ) { }
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
bool isCalculated;
|
||||
Actor dest;
|
||||
|
||||
int2 w1, w2, w3; /* tangent points to turn circles */
|
||||
PPos w1, w2, w3; /* tangent points to turn circles */
|
||||
|
||||
public static Actor ChooseAirfield(Actor self)
|
||||
{
|
||||
@@ -52,19 +52,18 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
var speed = .2f * aircraft.MovementSpeed;
|
||||
|
||||
var approachStart = landPos - new float2(aircraft.Altitude * speed, 0);
|
||||
var approachStart = landPos.ToFloat2() - new float2(aircraft.Altitude * speed, 0);
|
||||
var turnRadius = (128f / self.Info.Traits.Get<AircraftInfo>().ROT) * speed / (float)Math.PI;
|
||||
|
||||
/* work out the center points */
|
||||
var fwd = -float2.FromAngle(aircraft.Facing / 128f * (float)Math.PI);
|
||||
var side = new float2(-fwd.Y, fwd.X); /* rotate */
|
||||
var sideTowardBase = new[] { side, -side }
|
||||
.OrderBy(a => float2.Dot(a, self.CenterLocation - approachStart))
|
||||
.OrderBy(a => float2.Dot(a, self.CenterLocation.ToFloat2() - approachStart))
|
||||
.First();
|
||||
|
||||
var c1 = self.CenterLocation + turnRadius * sideTowardBase;
|
||||
var c2 = approachStart + new float2(0,
|
||||
turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point
|
||||
var c1 = self.CenterLocation.ToFloat2() + turnRadius * sideTowardBase;
|
||||
var c2 = approachStart + new float2(0, turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point
|
||||
|
||||
/* work out tangent points */
|
||||
var d = c2 - c1;
|
||||
@@ -75,10 +74,10 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
if (f.X > 0) f = -f;
|
||||
|
||||
w1 = (c1 + f).ToInt2();
|
||||
w2 = (c2 + f).ToInt2();
|
||||
w3 = (approachStart).ToInt2();
|
||||
plane.RTBPathHash = w1 + w2 + w3;
|
||||
w1 = (PPos)(c1 + f).ToInt2();
|
||||
w2 = (PPos)(c2 + f).ToInt2();
|
||||
w3 = (PPos)(approachStart).ToInt2();
|
||||
plane.RTBPathHash = (PVecInt)w1 + (PVecInt)w2 + (PVecInt)w3;
|
||||
|
||||
isCalculated = true;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public AppearsOnRadar(AppearsOnRadarInfo info) { this.info = info; }
|
||||
|
||||
public IEnumerable<int2> RadarSignatureCells(Actor self)
|
||||
public IEnumerable<CPos> RadarSignatureCells(Actor self)
|
||||
{
|
||||
if (info.UseLocation)
|
||||
return new int2[] { self.Location };
|
||||
return new CPos[] { self.Location };
|
||||
else
|
||||
return self.OccupiesSpace.OccupiedCells().Select(c => c.First);
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace OpenRA.Mods.RA
|
||||
if( target.IsActor )
|
||||
return new Order("Attack", self, queued) { TargetActor = target.Actor };
|
||||
else
|
||||
return new Order( "Attack", self, queued ) { TargetLocation = Util.CellContaining( target.CenterLocation ) };
|
||||
return new Order( "Attack", self, queued ) { TargetLocation = target.CenterLocation.ToCPos() };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ namespace OpenRA.Mods.RA
|
||||
return self.Owner.Stances[ target.Owner ] == targetableRelationship;
|
||||
}
|
||||
|
||||
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
|
||||
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
|
||||
{
|
||||
if (!self.World.Map.IsInMap(location))
|
||||
return false;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
var target = Util.SubPxVector[self.World.SharedRandom.Next(255)]* Info.MoveRadius / 1024 + self.Location;
|
||||
var target = (CVec)( Util.SubPxVector[self.World.SharedRandom.Next(255)] * Info.MoveRadius / 1024) + self.Location;
|
||||
self.Trait<AttackMove>().ResolveOrder(self, new Order("AttackMove", self, false) { TargetLocation = target });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class AttackMove : IResolveOrder, IOrderVoice, INotifyIdle, ISync
|
||||
{
|
||||
[Sync] public int2 _targetLocation { get { return TargetLocation.HasValue ? TargetLocation.Value : int2.Zero; } }
|
||||
public int2? TargetLocation = null;
|
||||
[Sync] public CPos _targetLocation { get { return TargetLocation.HasValue ? TargetLocation.Value : CPos.Zero; } }
|
||||
public CPos? TargetLocation = null;
|
||||
|
||||
readonly Mobile mobile;
|
||||
readonly AttackMoveInfo Info;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA
|
||||
static string cachedTileset;
|
||||
static Cache<TileReference<ushort,byte>, Sprite> sprites;
|
||||
|
||||
Dictionary<ushort, Dictionary<int2, Sprite>> TileSprites = new Dictionary<ushort, Dictionary<int2, Sprite>>();
|
||||
Dictionary<ushort, Dictionary<CPos, Sprite>> TileSprites = new Dictionary<ushort, Dictionary<CPos, Sprite>>();
|
||||
Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
ushort currentTemplate;
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace OpenRA.Mods.RA
|
||||
this.Type = self.Info.Name;
|
||||
}
|
||||
|
||||
public void Create(ushort template, Dictionary<int2, byte> subtiles)
|
||||
public void Create(ushort template, Dictionary<CPos, byte> subtiles)
|
||||
{
|
||||
currentTemplate = template;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace OpenRA.Mods.RA
|
||||
foreach (var t in Info.Templates)
|
||||
{
|
||||
Templates.Add(t.First,self.World.TileSet.Templates[t.First]);
|
||||
TileSprites.Add(t.First,subtiles.ToDictionary(
|
||||
TileSprites.Add(t.First, subtiles.ToDictionary(
|
||||
a => a.Key,
|
||||
a => sprites[new TileReference<ushort,byte>(t.First, (byte)a.Value)]));
|
||||
}
|
||||
@@ -113,10 +113,10 @@ namespace OpenRA.Mods.RA
|
||||
self.World.Map.CustomTerrain[c.X, c.Y] = GetTerrainType(c);
|
||||
}
|
||||
|
||||
public string GetTerrainType(int2 cell)
|
||||
public string GetTerrainType(CPos cell)
|
||||
{
|
||||
var dx = cell - self.Location;
|
||||
var index = dx.X + Templates[currentTemplate].Size.X*dx.Y;
|
||||
var index = dx.X + Templates[currentTemplate].Size.X * dx.Y;
|
||||
return self.World.TileSet.GetTerrainType(new TileReference<ushort, byte>(currentTemplate,(byte)index));
|
||||
}
|
||||
|
||||
@@ -132,13 +132,13 @@ namespace OpenRA.Mods.RA
|
||||
public Bridge GetNeighbor(int[] offset, BridgeLayer bridges)
|
||||
{
|
||||
if (offset == null) return null;
|
||||
return bridges.GetBridge(self.Location + new int2(offset[0], offset[1]));
|
||||
return bridges.GetBridge(self.Location + new CVec(offset[0], offset[1]));
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> RenderAsTerrain(Actor self)
|
||||
{
|
||||
foreach (var t in TileSprites[currentTemplate])
|
||||
yield return new Renderable(t.Value, Game.CellSize * t.Key, "terrain", Game.CellSize * t.Key.Y);
|
||||
yield return new Renderable(t.Value, t.Key.ToPPos().ToFloat2(), "terrain", Game.CellSize * t.Key.Y);
|
||||
}
|
||||
|
||||
bool IsIntact(Bridge b)
|
||||
|
||||
@@ -75,12 +75,12 @@ namespace OpenRA.Mods.RA
|
||||
// Create a new actor for this bridge and keep track of which subtiles this bridge includes
|
||||
var bridge = w.CreateActor(BridgeTypes[tile].First, new TypeDictionary
|
||||
{
|
||||
new LocationInit( new int2(ni, nj) ),
|
||||
new LocationInit( new CPos(ni, nj) ),
|
||||
new OwnerInit( w.WorldActor.Owner ),
|
||||
new HealthInit( BridgeTypes[tile].Second ),
|
||||
}).Trait<Bridge>();
|
||||
|
||||
Dictionary<int2, byte> subTiles = new Dictionary<int2, byte>();
|
||||
var subTiles = new Dictionary<CPos, byte>();
|
||||
|
||||
// For each subtile in the template
|
||||
for (byte ind = 0; ind < template.Size.X*template.Size.Y; ind++)
|
||||
@@ -97,16 +97,16 @@ namespace OpenRA.Mods.RA
|
||||
if (!w.Map.IsInMap(x, y) || w.Map.MapTiles.Value[x, y].index != ind)
|
||||
continue;
|
||||
|
||||
subTiles.Add(new int2(x,y),ind);
|
||||
subTiles.Add(new CPos(x, y), ind);
|
||||
Bridges[x,y] = bridge;
|
||||
}
|
||||
bridge.Create(tile, subTiles);
|
||||
}
|
||||
|
||||
// Used to check for neighbouring bridges
|
||||
public Bridge GetBridge(int2 cell)
|
||||
public Bridge GetBridge(CPos cell)
|
||||
{
|
||||
if (!world.Map.IsInMap(cell.X, cell.Y))
|
||||
if (!world.Map.IsInMap(cell))
|
||||
return null;
|
||||
|
||||
return Bridges[ cell.X, cell.Y ];
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
{
|
||||
World world;
|
||||
BibLayerInfo info;
|
||||
Dictionary<int2, TileReference<byte, byte>> tiles;
|
||||
Dictionary<CPos, TileReference<byte, byte>> tiles;
|
||||
Sprite[][] bibSprites;
|
||||
|
||||
public BibLayer(Actor self, BibLayerInfo info)
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
public void WorldLoaded(World w)
|
||||
{
|
||||
world = w;
|
||||
tiles = new Dictionary<int2, TileReference<byte, byte>>();
|
||||
tiles = new Dictionary<CPos, TileReference<byte, byte>>();
|
||||
}
|
||||
|
||||
public void DoBib(Actor b, bool isAdd)
|
||||
@@ -63,9 +63,9 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
for (int i = 0; i < 2 * size; i++)
|
||||
{
|
||||
var p = b.Location + new int2(i % size, i / size + bibOffset);
|
||||
var p = b.Location + new CVec(i % size, i / size + bibOffset);
|
||||
if (isAdd)
|
||||
tiles[p] = new TileReference<byte, byte>((byte)((isAdd) ? bib + 1 : 0), (byte)i);
|
||||
tiles[p] = new TileReference<byte, byte>((byte)(bib + 1), (byte)i);
|
||||
else
|
||||
tiles.Remove(p);
|
||||
}
|
||||
@@ -81,8 +81,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (!world.LocalShroud.IsExplored(kv.Key))
|
||||
continue;
|
||||
|
||||
bibSprites[kv.Value.type - 1][kv.Value.index].DrawAt( wr,
|
||||
Game.CellSize * kv.Key, "terrain");
|
||||
bibSprites[kv.Value.type - 1][kv.Value.index].DrawAt(wr, kv.Key.ToPPos().ToFloat2(), "terrain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,28 +32,28 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
public object Create(ActorInitializer init) { return new Building(init, this); }
|
||||
|
||||
public bool IsCloseEnoughToBase(World world, Player p, string buildingName, int2 topLeft)
|
||||
public bool IsCloseEnoughToBase(World world, Player p, string buildingName, CPos topLeft)
|
||||
{
|
||||
if (p.PlayerActor.Trait<DeveloperMode>().BuildAnywhere)
|
||||
return true;
|
||||
|
||||
var buildingMaxBounds = Dimensions;
|
||||
var buildingMaxBounds = (CVec)Dimensions;
|
||||
if( Rules.Info[ buildingName ].Traits.Contains<BibInfo>() )
|
||||
buildingMaxBounds.Y += 1;
|
||||
buildingMaxBounds += new CVec(0, 1);
|
||||
|
||||
var scanStart = world.ClampToWorld( topLeft - new int2( Adjacent, Adjacent ) );
|
||||
var scanEnd = world.ClampToWorld( topLeft + buildingMaxBounds + new int2( Adjacent, Adjacent ) );
|
||||
var scanStart = world.ClampToWorld( topLeft - new CVec( Adjacent, Adjacent ) );
|
||||
var scanEnd = world.ClampToWorld(topLeft + buildingMaxBounds + new CVec(Adjacent, Adjacent));
|
||||
|
||||
var nearnessCandidates = new List<int2>();
|
||||
var nearnessCandidates = new List<CPos>();
|
||||
|
||||
var bi = world.WorldActor.Trait<BuildingInfluence>();
|
||||
|
||||
for( int y = scanStart.Y ; y < scanEnd.Y ; y++ )
|
||||
for( int x = scanStart.X ; x < scanEnd.X ; x++ )
|
||||
{
|
||||
var at = bi.GetBuildingAt( new int2( x, y ) );
|
||||
var at = bi.GetBuildingAt( new CPos( x, y ) );
|
||||
if( at != null && at.Owner.Stances[ p ] == Stance.Ally && at.HasTrait<GivesBuildableArea>() )
|
||||
nearnessCandidates.Add( new int2( x, y ) );
|
||||
nearnessCandidates.Add( new CPos( x, y ) );
|
||||
}
|
||||
|
||||
var buildingTiles = FootprintUtils.Tiles( buildingName, this, topLeft ).ToList();
|
||||
@@ -68,27 +68,26 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
{
|
||||
readonly Actor self;
|
||||
public readonly BuildingInfo Info;
|
||||
[Sync]
|
||||
readonly int2 topLeft;
|
||||
[Sync] readonly CPos topLeft;
|
||||
|
||||
PowerManager PlayerPower;
|
||||
int2 pxPosition;
|
||||
PPos pxPosition;
|
||||
|
||||
public int2 TopLeft { get { return topLeft; } }
|
||||
public int2 PxPosition { get { return pxPosition; } }
|
||||
public CPos TopLeft { get { return topLeft; } }
|
||||
public PPos PxPosition { get { return pxPosition; } }
|
||||
|
||||
public IEnumerable<string> ProvidesPrerequisites { get { yield return self.Info.Name; } }
|
||||
|
||||
public Building(ActorInitializer init, BuildingInfo info)
|
||||
{
|
||||
this.self = init.self;
|
||||
this.topLeft = init.Get<LocationInit,int2>();
|
||||
this.topLeft = init.Get<LocationInit, CPos>();
|
||||
this.Info = info;
|
||||
this.PlayerPower = init.self.Owner.PlayerActor.Trait<PowerManager>();
|
||||
|
||||
occupiedCells = FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft )
|
||||
.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
|
||||
pxPosition = ( 2 * topLeft + Info.Dimensions ) * Game.CellSize / 2;
|
||||
pxPosition = (PPos) (( 2 * topLeft.ToInt2() + Info.Dimensions ) * Game.CellSize / 2);
|
||||
}
|
||||
|
||||
public int GetPowerUsage()
|
||||
@@ -107,8 +106,8 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
PlayerPower.UpdateActor(self, GetPowerUsage());
|
||||
}
|
||||
|
||||
Pair<int2,SubCell>[] occupiedCells;
|
||||
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { return occupiedCells; }
|
||||
Pair<CPos, SubCell>[] occupiedCells;
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return occupiedCells; }
|
||||
|
||||
public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
influence[ u.X, u.Y ] = isAdd ? a : null;
|
||||
}
|
||||
|
||||
public Actor GetBuildingAt(int2 cell)
|
||||
public Actor GetBuildingAt(CPos cell)
|
||||
{
|
||||
if (!map.IsInMap(cell)) return null;
|
||||
return influence[cell.X, cell.Y];
|
||||
|
||||
@@ -16,34 +16,34 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
{
|
||||
public static class FootprintUtils
|
||||
{
|
||||
public static IEnumerable<int2> Tiles( string name, BuildingInfo buildingInfo, int2 topLeft )
|
||||
public static IEnumerable<CPos> Tiles(string name, BuildingInfo buildingInfo, CPos topLeft)
|
||||
{
|
||||
var dim = buildingInfo.Dimensions;
|
||||
var dim = (CVec)buildingInfo.Dimensions;
|
||||
|
||||
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
||||
|
||||
if (Rules.Info[ name ].Traits.Contains<BibInfo>())
|
||||
{
|
||||
dim.Y += 1;
|
||||
dim += new CVec(0, 1);
|
||||
footprint = footprint.Concat(new char[dim.X]);
|
||||
}
|
||||
|
||||
return TilesWhere( name, dim, footprint.ToArray(), a => a != '_' ).Select( t => t + topLeft );
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> Tiles(Actor a)
|
||||
public static IEnumerable<CPos> Tiles(Actor a)
|
||||
{
|
||||
return Tiles( a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), a.Location );
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> UnpathableTiles( string name, BuildingInfo buildingInfo, int2 position )
|
||||
public static IEnumerable<CPos> UnpathableTiles(string name, BuildingInfo buildingInfo, CPos position)
|
||||
{
|
||||
var footprint = buildingInfo.Footprint.Where( x => !char.IsWhiteSpace( x ) ).ToArray();
|
||||
foreach( var tile in TilesWhere( name, buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
||||
foreach( var tile in TilesWhere( name, (CVec)buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
||||
yield return tile + position;
|
||||
}
|
||||
|
||||
static IEnumerable<int2> TilesWhere( string name, int2 dim, char[] footprint, Func<char, bool> cond )
|
||||
static IEnumerable<CVec> TilesWhere(string name, CVec dim, char[] footprint, Func<char, bool> cond)
|
||||
{
|
||||
if( footprint.Length != dim.X * dim.Y )
|
||||
throw new InvalidOperationException( "Invalid footprint for " + name );
|
||||
@@ -52,13 +52,13 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
for( int y = 0 ; y < dim.Y ; y++ )
|
||||
for( int x = 0 ; x < dim.X ; x++ )
|
||||
if( cond( footprint[ index++ ] ) )
|
||||
yield return new int2( x, y );
|
||||
yield return new CVec(x, y);
|
||||
}
|
||||
|
||||
public static int2 AdjustForBuildingSize( BuildingInfo buildingInfo )
|
||||
public static CVec AdjustForBuildingSize( BuildingInfo buildingInfo )
|
||||
{
|
||||
var dim = buildingInfo.Dimensions;
|
||||
return new int2( dim.X / 2, dim.Y > 1 ? ( dim.Y + 1 ) / 2 : 0 );
|
||||
return new CVec(dim.X / 2, dim.Y > 1 ? (dim.Y + 1) / 2 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
self.World.WorldActor.Trait<ScreenShaker>().AddEffect(Info.Intensity, self.CenterLocation, 1);
|
||||
self.World.WorldActor.Trait<ScreenShaker>().AddEffect(Info.Intensity, self.CenterLocation.ToFloat2(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
{
|
||||
public static class BuildingUtils
|
||||
{
|
||||
public static bool IsCellBuildable(this World world, int2 a, BuildingInfo bi)
|
||||
public static bool IsCellBuildable(this World world, CPos a, BuildingInfo bi)
|
||||
{
|
||||
return world.IsCellBuildable(a, bi, null);
|
||||
}
|
||||
|
||||
public static bool IsCellBuildable(this World world, int2 a, BuildingInfo bi, Actor toIgnore)
|
||||
public static bool IsCellBuildable(this World world, CPos a, BuildingInfo bi, Actor toIgnore)
|
||||
{
|
||||
if (world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(a) != null) return false;
|
||||
if (world.ActorMap.GetUnitsAt(a).Any(b => b != toIgnore)) return false;
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
return world.Map.IsInMap(a) && bi.TerrainTypes.Contains(world.GetTerrainType(a));
|
||||
}
|
||||
|
||||
public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, int2 topLeft, Actor toIgnore)
|
||||
public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, CPos topLeft, Actor toIgnore)
|
||||
{
|
||||
var res = world.WorldActor.Trait<ResourceLayer>();
|
||||
return FootprintUtils.Tiles(name, building, topLeft).All(
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
world.IsCellBuildable(t, building, toIgnore));
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> GetLineBuildCells(World world, int2 location, string name, BuildingInfo bi)
|
||||
public static IEnumerable<CPos> GetLineBuildCells(World world, CPos location, string name, BuildingInfo bi)
|
||||
{
|
||||
int range = Rules.Info[name].Traits.Get<LineBuildInfo>().Range;
|
||||
var topLeft = location; // 1x1 assumption!
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
// Start at place location, search outwards
|
||||
// TODO: First make it work, then make it nice
|
||||
var vecs = new[] { new int2(1, 0), new int2(0, 1), new int2(-1, 0), new int2(0, -1) };
|
||||
var vecs = new[] { new CVec(1, 0), new CVec(0, 1), new CVec(-1, 0), new CVec(0, -1) };
|
||||
int[] dirs = { 0, 0, 0, 0 };
|
||||
for (int d = 0; d < 4; d++)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (dirs[d] != 0)
|
||||
continue;
|
||||
|
||||
int2 cell = topLeft + i * vecs[d];
|
||||
CPos cell = topLeft + i * vecs[d];
|
||||
if (world.IsCellBuildable(cell, bi))
|
||||
continue; // Cell is empty; continue search
|
||||
|
||||
|
||||
@@ -24,8 +24,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class Burns : ITick, ISync
|
||||
{
|
||||
[Sync]
|
||||
int ticks;
|
||||
[Sync] int ticks;
|
||||
BurnsInfo Info;
|
||||
|
||||
public Burns(Actor self, BurnsInfo info)
|
||||
|
||||
@@ -22,16 +22,16 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class CarpetBomb : ITick // todo: maybe integrate this better with the normal weapons system?
|
||||
{
|
||||
int2 Target;
|
||||
CPos Target;
|
||||
int dropDelay;
|
||||
|
||||
public void SetTarget(int2 targetCell) { Target = targetCell; }
|
||||
public void SetTarget(CPos targetCell) { Target = targetCell; }
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var info = self.Info.Traits.Get<CarpetBombInfo>();
|
||||
|
||||
if( !Combat.IsInRange( self.CenterLocation, info.Range, Target * Game.CellSize ) )
|
||||
if( !Combat.IsInRange( self.CenterLocation, info.Range, Target.ToPPos() ) )
|
||||
return;
|
||||
|
||||
var limitedAmmo = self.TraitOrDefault<LimitedAmmo>();
|
||||
|
||||
@@ -26,8 +26,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class CashTrickler : ITick, ISync
|
||||
{
|
||||
[Sync]
|
||||
int ticks;
|
||||
[Sync] int ticks;
|
||||
CashTricklerInfo Info;
|
||||
public CashTrickler(CashTricklerInfo info)
|
||||
{
|
||||
|
||||
@@ -24,8 +24,7 @@ namespace OpenRA.Mods.RA
|
||||
class ChronoshiftDeploy : IIssueOrder, IResolveOrder, ITick, IPips, IOrderVoice, ISync
|
||||
{
|
||||
// Recharge logic
|
||||
[Sync]
|
||||
int chargeTick = 0; // How long until we can chronoshift again?
|
||||
[Sync] int chargeTick = 0; // How long until we can chronoshift again?
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
@@ -60,7 +59,7 @@ namespace OpenRA.Mods.RA
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Teleport(order.TargetLocation));
|
||||
Sound.Play("chrotnk1.aud", self.CenterLocation);
|
||||
Sound.Play("chrotnk1.aud", Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
Sound.Play("chrotnk1.aud", order.TargetLocation.ToPPos());
|
||||
chargeTick = 25 * self.Info.Traits.Get<ChronoshiftDeployInfo>().ChargeTime;
|
||||
|
||||
foreach (var a in self.World.ActorsWithTrait<ChronoshiftPaletteEffect>())
|
||||
|
||||
@@ -18,10 +18,8 @@ namespace OpenRA.Mods.RA
|
||||
public class Chronoshiftable : ITick, ISync
|
||||
{
|
||||
// Return-to-sender logic
|
||||
[Sync]
|
||||
int2 chronoshiftOrigin;
|
||||
[Sync]
|
||||
int chronoshiftReturnTicks = 0;
|
||||
[Sync] CPos chronoshiftOrigin;
|
||||
[Sync] int chronoshiftReturnTicks = 0;
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
@@ -41,7 +39,7 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
|
||||
// Can't be used in synced code, except with ignoreVis.
|
||||
public virtual bool CanChronoshiftTo(Actor self, int2 targetLocation, bool ignoreVis)
|
||||
public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation, bool ignoreVis)
|
||||
{
|
||||
// Todo: Allow enemy units to be chronoshifted into bad terrain to kill them
|
||||
return self.HasTrait<ITeleportable>() &&
|
||||
@@ -49,7 +47,7 @@ namespace OpenRA.Mods.RA
|
||||
(ignoreVis || self.World.LocalShroud.IsExplored(targetLocation));
|
||||
}
|
||||
|
||||
public virtual bool Teleport(Actor self, int2 targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||
public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||
{
|
||||
/// Set up return-to-sender info
|
||||
chronoshiftOrigin = self.Location;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA
|
||||
public static void DoImpact(WarheadInfo warhead, ProjectileArgs args)
|
||||
{
|
||||
var world = args.firedBy.World;
|
||||
var targetTile = Util.CellContaining(args.dest);
|
||||
var targetTile = args.dest.ToCPos();
|
||||
|
||||
if (!world.Map.IsInMap(targetTile))
|
||||
return;
|
||||
@@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA
|
||||
case DamageModel.PerCell:
|
||||
{
|
||||
foreach (var t in world.FindTilesInCircle(targetTile, warhead.Size[0]))
|
||||
foreach (var unit in world.FindUnits(Game.CellSize * t, Game.CellSize * (t + new int2(1,1))))
|
||||
foreach (var unit in world.FindUnits(t.ToPPos(), (t + new CVec(1,1)).ToPPos()))
|
||||
unit.InflictDamage(args.firedBy,
|
||||
(int)(warhead.Damage * warhead.EffectivenessAgainst(unit)), warhead);
|
||||
} break;
|
||||
@@ -103,16 +103,19 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
foreach (var warhead in args.weapon.Warheads)
|
||||
{
|
||||
Action a = () => DoImpact(warhead, args);
|
||||
// NOTE(jsd): Fixed access to modified closure bug!
|
||||
var warheadClosed = warhead;
|
||||
|
||||
Action a = () => DoImpact(warheadClosed, args);
|
||||
if (warhead.Delay > 0)
|
||||
args.firedBy.World.AddFrameEndTask(
|
||||
w => w.Add(new DelayedAction(warhead.Delay, a)));
|
||||
w => w.Add(new DelayedAction(warheadClosed.Delay, a)));
|
||||
else
|
||||
a();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoExplosion(Actor attacker, string weapontype, int2 pos, int altitude)
|
||||
public static void DoExplosion(Actor attacker, string weapontype, PPos pos, int altitude)
|
||||
{
|
||||
var args = new ProjectileArgs
|
||||
{
|
||||
@@ -174,7 +177,7 @@ namespace OpenRA.Mods.RA
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool WeaponValidForTarget( WeaponInfo weapon, World world, int2 location )
|
||||
public static bool WeaponValidForTarget( WeaponInfo weapon, World world, CPos location )
|
||||
{
|
||||
if( weapon.ValidTargets.Contains( "Ground" ) && world.GetTerrainType( location ) != "Water" ) return true;
|
||||
if( weapon.ValidTargets.Contains( "Water" ) && world.GetTerrainType( location ) == "Water" ) return true;
|
||||
@@ -192,7 +195,7 @@ namespace OpenRA.Mods.RA
|
||||
return Util.RotateVectorByFacing(localRecoil, facing, .7f);
|
||||
}
|
||||
|
||||
public static float2 GetTurretPosition(Actor self, IFacing facing, Turret turret)
|
||||
public static PVecInt GetTurretPosition(Actor self, IFacing facing, Turret turret)
|
||||
{
|
||||
if (facing == null) return turret.ScreenSpacePosition; /* things that don't have a rotating base don't need the turrets repositioned */
|
||||
|
||||
@@ -201,41 +204,41 @@ namespace OpenRA.Mods.RA
|
||||
var bodyFacing = facing.Facing;
|
||||
var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs);
|
||||
|
||||
return (Util.RotateVectorByFacing(turret.UnitSpacePosition, quantizedFacing, .7f)
|
||||
return (PVecInt) ((PVecFloat)(Util.RotateVectorByFacing(turret.UnitSpacePosition.ToFloat2(), quantizedFacing, .7f)
|
||||
+ GetRecoil(self, turret.Recoil))
|
||||
+ turret.ScreenSpacePosition;
|
||||
+ turret.ScreenSpacePosition);
|
||||
}
|
||||
|
||||
// gets the screen-space position of a barrel.
|
||||
public static float2 GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel)
|
||||
public static PVecInt GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel)
|
||||
{
|
||||
var turreted = self.TraitOrDefault<Turreted>();
|
||||
|
||||
if (turreted == null && facing == null)
|
||||
return float2.Zero;
|
||||
return PVecInt.Zero;
|
||||
|
||||
var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing;
|
||||
|
||||
return GetTurretPosition(self, facing, turret) + barrel.ScreenSpaceOffset
|
||||
+ Util.RotateVectorByFacing(barrel.TurretSpaceOffset, turretFacing, .7f);
|
||||
+ (PVecInt)(PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f);
|
||||
}
|
||||
|
||||
public static bool IsInRange( float2 attackOrigin, float range, Actor target )
|
||||
public static bool IsInRange( PPos attackOrigin, float range, Actor target )
|
||||
{
|
||||
var rsq = range * range * Game.CellSize * Game.CellSize;
|
||||
foreach( var cell in target.Trait<ITargetable>().TargetableCells( target ) )
|
||||
if( ( attackOrigin - cell * Game.CellSize ).LengthSquared <= rsq )
|
||||
foreach ( var cell in target.Trait<ITargetable>().TargetableCells( target ) )
|
||||
if ( (attackOrigin - cell.ToPPos()).LengthSquared <= rsq )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsInRange( float2 attackOrigin, float range, float2 targetLocation )
|
||||
public static bool IsInRange(PPos attackOrigin, float range, PPos targetLocation)
|
||||
{
|
||||
var rsq = range * range * Game.CellSize * Game.CellSize;
|
||||
return ( attackOrigin - targetLocation ).LengthSquared <= rsq;
|
||||
}
|
||||
|
||||
public static bool IsInRange( float2 attackOrigin, float range, Target target )
|
||||
public static bool IsInRange(PPos attackOrigin, float range, Target target)
|
||||
{
|
||||
if( !target.IsValid ) return false;
|
||||
if( target.IsActor )
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
readonly Actor self;
|
||||
[Sync] int ticks;
|
||||
[Sync] public int2 Location;
|
||||
[Sync] public CPos Location;
|
||||
CrateInfo Info;
|
||||
|
||||
public Crate(ActorInitializer init, CrateInfo info)
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA
|
||||
this.self = init.self;
|
||||
if (init.Contains<LocationInit>())
|
||||
{
|
||||
this.Location = init.Get<LocationInit, int2>();
|
||||
this.Location = init.Get<LocationInit, CPos>();
|
||||
PxPosition = Util.CenterOfCell(Location);
|
||||
}
|
||||
this.Info = info;
|
||||
@@ -79,19 +79,19 @@ namespace OpenRA.Mods.RA
|
||||
self.Destroy();
|
||||
}
|
||||
|
||||
public int2 TopLeft { get { return Location; } }
|
||||
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); }
|
||||
public CPos TopLeft { get { return Location; } }
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); }
|
||||
|
||||
public int2 PxPosition { get; private set; }
|
||||
public PPos PxPosition { get; private set; }
|
||||
|
||||
public void SetPxPosition( Actor self, int2 px )
|
||||
public void SetPxPosition(Actor self, PPos px)
|
||||
{
|
||||
SetPosition( self, Util.CellContaining( px ) );
|
||||
SetPosition( self, px.ToCPos() );
|
||||
}
|
||||
|
||||
public void AdjustPxPosition(Actor self, int2 px) { SetPxPosition(self, px); }
|
||||
public void AdjustPxPosition(Actor self, PPos px) { SetPxPosition(self, px); }
|
||||
|
||||
public bool CanEnterCell(int2 cell)
|
||||
public bool CanEnterCell(CPos cell)
|
||||
{
|
||||
if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false;
|
||||
var type = self.World.GetTerrainType(cell);
|
||||
@@ -104,7 +104,7 @@ namespace OpenRA.Mods.RA
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetPosition(Actor self, int2 cell)
|
||||
public void SetPosition(Actor self, CPos cell)
|
||||
{
|
||||
if( self.IsInWorld )
|
||||
self.World.ActorMap.Remove(self, this);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
|
||||
int2? ChooseDropCell(Actor self, bool inWater, int maxTries)
|
||||
CPos? ChooseDropCell(Actor self, bool inWater, int maxTries)
|
||||
{
|
||||
for( var n = 0; n < maxTries; n++ )
|
||||
{
|
||||
|
||||
@@ -60,17 +60,17 @@ namespace OpenRA.Mods.RA.Crates
|
||||
base.Activate(collector);
|
||||
}
|
||||
|
||||
IEnumerable<int2> GetSuitableCells(int2 near)
|
||||
IEnumerable<CPos> GetSuitableCells(CPos near)
|
||||
{
|
||||
var mi = Rules.Info[Info.Unit].Traits.Get<MobileInfo>();
|
||||
|
||||
for (var i = -1; i < 2; i++)
|
||||
for (var j = -1; j < 2; j++)
|
||||
if (mi.CanEnterCell(self.World, self.Owner, near + new int2(i, j), null, true))
|
||||
yield return near + new int2(i, j);
|
||||
if (mi.CanEnterCell(self.World, self.Owner, near + new CVec(i, j), null, true))
|
||||
yield return near + new CVec(i, j);
|
||||
}
|
||||
|
||||
int2? ChooseEmptyCellNear(Actor a)
|
||||
CPos? ChooseEmptyCellNear(Actor a)
|
||||
{
|
||||
var possibleCells = GetSuitableCells(a.Location).ToArray();
|
||||
if (possibleCells.Length == 0)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA
|
||||
class DemoTruck : Chronoshiftable, INotifyKilled
|
||||
{
|
||||
// Explode on chronoshift
|
||||
public override bool Teleport(Actor self, int2 targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||
public override bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||
{
|
||||
Detonate(self, chronosphere);
|
||||
return false;
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (info.Inaccuracy > 0)
|
||||
{
|
||||
var factor = ((Args.dest - Args.src).Length / Game.CellSize) / args.weapon.Range;
|
||||
Args.dest += (info.Inaccuracy * factor * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
|
||||
var factor = ((Args.dest - Args.src).Length / (float)Game.CellSize) / args.weapon.Range;
|
||||
Args.dest += (PVecInt) (info.Inaccuracy * factor * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
|
||||
}
|
||||
|
||||
if (Info.Image != null)
|
||||
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
var at = (float)t / TotalTime();
|
||||
var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at);
|
||||
var pos = float2.Lerp(Args.src, Args.dest, at) - new float2(0, altitude);
|
||||
var pos = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at) - new float2(0, altitude);
|
||||
|
||||
var highPos = (Info.High || Info.Angle > 0)
|
||||
? (pos - new float2(0, GetAltitude()))
|
||||
@@ -119,24 +119,24 @@ namespace OpenRA.Mods.RA.Effects
|
||||
if (Info.Trail != null && --ticksToNextSmoke < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(
|
||||
new Smoke(w, highPos.ToInt2(), Info.Trail)));
|
||||
new Smoke(w, (PPos) highPos.ToInt2(), Info.Trail)));
|
||||
ticksToNextSmoke = Info.TrailInterval;
|
||||
}
|
||||
|
||||
if (Trail != null)
|
||||
Trail.Tick(highPos);
|
||||
Trail.Tick((PPos)highPos.ToInt2());
|
||||
}
|
||||
|
||||
if (!Info.High) // check for hitting a wall
|
||||
{
|
||||
var at = (float)t / TotalTime();
|
||||
var pos = float2.Lerp(Args.src, Args.dest, at);
|
||||
var cell = Traits.Util.CellContaining(pos);
|
||||
var pos = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at);
|
||||
var cell = ((PPos) pos.ToInt2()).ToCPos();
|
||||
|
||||
if (world.ActorMap.GetUnitsAt(cell).Any(
|
||||
a => a.HasTrait<IBlocksBullets>()))
|
||||
{
|
||||
Args.dest = pos.ToInt2();
|
||||
Args.dest = (PPos) pos.ToInt2();
|
||||
Explode(world);
|
||||
}
|
||||
}
|
||||
@@ -151,9 +151,9 @@ namespace OpenRA.Mods.RA.Effects
|
||||
var at = (float)t / TotalTime();
|
||||
|
||||
var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at);
|
||||
var pos = float2.Lerp(Args.src, Args.dest, at) - new float2(0, altitude);
|
||||
var pos = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at) - new float2(0, altitude);
|
||||
|
||||
if (Args.firedBy.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(pos)))
|
||||
if (Args.firedBy.World.LocalShroud.IsVisible(((PPos) pos.ToInt2()).ToCPos()))
|
||||
{
|
||||
if (Info.High || Info.Angle > 0)
|
||||
{
|
||||
|
||||
@@ -18,19 +18,20 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class CashTick : IEffect
|
||||
{
|
||||
string s;
|
||||
readonly string s;
|
||||
int remaining;
|
||||
int velocity;
|
||||
float2 pos, offset;
|
||||
Color color;
|
||||
SpriteFont font;
|
||||
readonly int velocity;
|
||||
PPos pos;
|
||||
readonly float2 offset;
|
||||
readonly Color color;
|
||||
readonly SpriteFont font;
|
||||
|
||||
static string FormatCashAmount(int x) { return "{0}${1}".F(x < 0 ? "-" : "+", x); }
|
||||
|
||||
public CashTick(int value, int lifetime, int velocity, float2 pos, Color color)
|
||||
public CashTick(int value, int lifetime, int velocity, PPos pos, Color color)
|
||||
: this( FormatCashAmount(value), lifetime, velocity, pos, color ) { }
|
||||
|
||||
public CashTick(string value, int lifetime, int velocity, float2 pos, Color color)
|
||||
public CashTick(string value, int lifetime, int velocity, PPos pos, Color color)
|
||||
{
|
||||
this.color = color;
|
||||
this.velocity = velocity;
|
||||
@@ -45,12 +46,12 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
if (--remaining <= 0)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
pos.Y -= velocity;
|
||||
pos -= new PVecInt(0, velocity);
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
font.DrawTextWithContrast(s, Game.viewport.Zoom*(pos - Game.viewport.Location) - offset, color, Color.Black,1);
|
||||
font.DrawTextWithContrast(s, Game.viewport.Zoom*(pos.ToFloat2() - Game.viewport.Location) - offset, color, Color.Black,1);
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
history.Tick(self.CenterLocation - new int2(0, move.Altitude)
|
||||
- Combat.GetTurretPosition(self, facing, contrailTurret));
|
||||
history.Tick(self.CenterLocation - new PVecInt(0, move.Altitude) - Combat.GetTurretPosition(self, facing, contrailTurret));
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(self); }
|
||||
@@ -54,7 +53,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class ContrailHistory
|
||||
{
|
||||
List<float2> positions = new List<float2>();
|
||||
List<PPos> positions = new List<PPos>();
|
||||
readonly int TrailLength;
|
||||
readonly Color Color;
|
||||
readonly int StartSkip;
|
||||
@@ -75,7 +74,7 @@ namespace OpenRA.Mods.RA
|
||||
this.StartSkip = startSkip;
|
||||
}
|
||||
|
||||
public void Tick(float2 currentPos)
|
||||
public void Tick(PPos currentPos)
|
||||
{
|
||||
positions.Add(currentPos);
|
||||
if (positions.Count >= TrailLength)
|
||||
@@ -85,22 +84,20 @@ namespace OpenRA.Mods.RA
|
||||
public void Render(Actor self)
|
||||
{
|
||||
Color trailStart = Color;
|
||||
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R,
|
||||
trailStart.G, trailStart.B);
|
||||
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R, trailStart.G, trailStart.B);
|
||||
|
||||
for (int i = positions.Count - 1 - StartSkip; i >= 1; --i)
|
||||
{
|
||||
var conPos = positions[i];
|
||||
var nextPos = positions[i - 1];
|
||||
|
||||
if (self.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(conPos)) ||
|
||||
self.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(nextPos)))
|
||||
if (self.World.LocalShroud.IsVisible(conPos.ToCPos()) ||
|
||||
self.World.LocalShroud.IsVisible(nextPos.ToCPos()))
|
||||
{
|
||||
Game.Renderer.WorldLineRenderer.DrawLine(conPos, nextPos, trailStart, trailEnd);
|
||||
Game.Renderer.WorldLineRenderer.DrawLine(conPos.ToFloat2(), nextPos.ToFloat2(), trailStart, trailEnd);
|
||||
|
||||
trailStart = trailEnd;
|
||||
trailEnd = Color.FromArgb(trailStart.A - 255 / positions.Count, trailStart.R,
|
||||
trailStart.G, trailStart.B);
|
||||
trailEnd = Color.FromArgb(trailStart.A - 255 / positions.Count, trailStart.R, trailStart.G, trailStart.B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
anim.PlayThen(sequence,
|
||||
() => fromActor.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
|
||||
pos = fromActor.CenterLocation;
|
||||
pos = fromActor.CenterLocation.ToFloat2();
|
||||
}
|
||||
|
||||
public void Tick( World world ) { anim.Tick(); }
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
if (a.IsInWorld)
|
||||
yield return new Renderable(anim.Image,
|
||||
a.CenterLocation - .5f * anim.Image.size + offset, "effect", (int)a.CenterLocation.Y);
|
||||
a.CenterLocation.ToFloat2() - .5f * anim.Image.size + offset, "effect", (int)a.CenterLocation.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace OpenRA.Mods.RA.Effects
|
||||
public class Explosion : IEffect
|
||||
{
|
||||
Animation anim;
|
||||
int2 pos;
|
||||
PPos pos;
|
||||
int altitude;
|
||||
|
||||
public Explosion(World world, int2 pixelPos, string style, bool isWater, int altitude)
|
||||
public Explosion(World world, PPos pixelPos, string style, bool isWater, int altitude)
|
||||
{
|
||||
this.pos = pixelPos;
|
||||
this.altitude = altitude;
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image,
|
||||
pos - .5f * anim.Image.size - new int2(0,altitude),
|
||||
pos.ToFloat2() - .5f * anim.Image.size - new int2(0,altitude),
|
||||
"effect", (int)pos.Y - altitude);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
if (show && !self.Destroyed)
|
||||
{
|
||||
var p = self.CenterLocation;
|
||||
yield return new Renderable(anim.Image, p - 0.5f * anim.Image.size, rs.Palette(self.Owner), p.Y)
|
||||
yield return new Renderable(anim.Image, p.ToFloat2() - 0.5f * anim.Image.size, rs.Palette(self.Owner), p.Y)
|
||||
.WithScale(1.5f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image,
|
||||
Args.dest - new int2(0, altitude) - .5f * anim.Image.size, "effect", Args.dest.Y);
|
||||
Args.dest.ToInt2() - new int2(0, altitude) - .5f * anim.Image.size, "effect", Args.dest.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
if (explosion != null)
|
||||
yield return new Renderable(explosion.Image,
|
||||
args.dest - .5f * explosion.Image.size, "effect", (int)args.dest.Y);
|
||||
args.dest.ToFloat2() - .5f * explosion.Image.size, "effect", (int)args.dest.Y);
|
||||
|
||||
if (ticks >= info.BeamDuration)
|
||||
yield break;
|
||||
@@ -87,7 +87,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
wlr.LineWidth = info.BeamRadius * 2;
|
||||
wlr.DrawLine(args.src, args.dest, rc, rc);
|
||||
wlr.DrawLine(args.src.ToFloat2(), args.dest.ToFloat2(), rc, rc);
|
||||
wlr.Flush();
|
||||
wlr.LineWidth = 1f;
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace OpenRA.Mods.RA.Effects
|
||||
readonly MissileInfo Info;
|
||||
readonly ProjectileArgs Args;
|
||||
|
||||
int2 offset;
|
||||
PVecInt offset;
|
||||
public int2 SubPxPosition;
|
||||
public int2 PxPosition { get { return new int2( SubPxPosition.X / 1024, SubPxPosition.Y / 1024 ); } }
|
||||
public PPos PxPosition { get { return new PPos(SubPxPosition.X / 1024, SubPxPosition.Y / 1024); } }
|
||||
|
||||
readonly Animation anim;
|
||||
int Facing;
|
||||
@@ -61,12 +61,12 @@ namespace OpenRA.Mods.RA.Effects
|
||||
Info = info;
|
||||
Args = args;
|
||||
|
||||
SubPxPosition = 1024 * Args.src;
|
||||
SubPxPosition = 1024 * Args.src.ToInt2();
|
||||
Altitude = Args.srcAltitude;
|
||||
Facing = Args.facing;
|
||||
|
||||
if (info.Inaccuracy > 0)
|
||||
offset = (info.Inaccuracy * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
|
||||
offset = (PVecInt)(info.Inaccuracy * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
|
||||
|
||||
if (Info.Image != null)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (Info.Trail != null)
|
||||
{
|
||||
var sp = (SubPxPosition - (move * 3) / 2) / 1024 - new int2(0, Altitude);
|
||||
var sp = (PPos)((SubPxPosition - (move * 3) / 2) / 1024) - new PVecInt(0, Altitude);
|
||||
|
||||
if (--ticksToNextSmoke < 0)
|
||||
{
|
||||
@@ -135,14 +135,13 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (!Info.High) // check for hitting a wall
|
||||
{
|
||||
var cell = Traits.Util.CellContaining(PxPosition);
|
||||
if (world.ActorMap.GetUnitsAt(cell).Any(
|
||||
a => a.HasTrait<IBlocksBullets>()))
|
||||
var cell = PxPosition.ToCPos();
|
||||
if (world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait<IBlocksBullets>()))
|
||||
Explode(world);
|
||||
}
|
||||
|
||||
if (Trail != null)
|
||||
Trail.Tick(PxPosition - new float2(0,Altitude));
|
||||
Trail.Tick(PxPosition - new PVecInt(0, Altitude));
|
||||
}
|
||||
|
||||
void Explode(World world)
|
||||
@@ -155,8 +154,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
if (Args.firedBy.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(PxPosition.ToFloat2())))
|
||||
yield return new Renderable(anim.Image,PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude),
|
||||
if (Args.firedBy.World.LocalShroud.IsVisible(PxPosition.ToCPos()))
|
||||
yield return new Renderable(anim.Image, PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude),
|
||||
Args.weapon.Underwater ? "shadow" : "effect", PxPosition.Y);
|
||||
|
||||
if (Trail != null)
|
||||
|
||||
@@ -19,13 +19,13 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
readonly Player firedBy;
|
||||
Animation anim;
|
||||
int2 pos;
|
||||
int2 targetLocation;
|
||||
PPos pos;
|
||||
CPos targetLocation;
|
||||
int altitude;
|
||||
bool goingUp = true;
|
||||
string weapon;
|
||||
|
||||
public NukeLaunch(Player firedBy, Actor silo, string weapon, int2 spawnOffset, int2 targetLocation)
|
||||
public NukeLaunch(Player firedBy, Actor silo, string weapon, PVecInt spawnOffset, CPos targetLocation)
|
||||
{
|
||||
this.firedBy = firedBy;
|
||||
this.targetLocation = targetLocation;
|
||||
@@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
Combat.DoExplosion(firedBy.PlayerActor, weapon, pos, 0);
|
||||
world.WorldActor.Trait<ScreenShaker>().AddEffect(20, pos, 5);
|
||||
world.WorldActor.Trait<ScreenShaker>().AddEffect(20, pos.ToFloat2(), 5);
|
||||
|
||||
foreach (var a in world.ActorsWithTrait<NukePaletteEffect>())
|
||||
a.Trait.Enable();
|
||||
@@ -79,7 +79,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image, pos - 0.5f * anim.Image.size - new float2(0, altitude),
|
||||
yield return new Renderable(anim.Image, pos.ToFloat2() - 0.5f * anim.Image.size - new float2(0, altitude),
|
||||
"effect", (int)pos.Y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
readonly Animation anim;
|
||||
readonly string palette;
|
||||
readonly Animation paraAnim;
|
||||
readonly float2 location;
|
||||
readonly PPos location;
|
||||
|
||||
readonly Actor cargo;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
float altitude;
|
||||
const float fallRate = .3f;
|
||||
|
||||
public Parachute(Player owner, float2 location, int altitude, Actor cargo)
|
||||
public Parachute(Player owner, PPos location, int altitude, Actor cargo)
|
||||
{
|
||||
this.location = location;
|
||||
this.altitude = altitude;
|
||||
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
world.AddFrameEndTask(w =>
|
||||
{
|
||||
w.Remove(this);
|
||||
var loc = Traits.Util.CellContaining(location);
|
||||
var loc = location.ToCPos();
|
||||
cargo.CancelActivity();
|
||||
cargo.Trait<ITeleportable>().SetPosition(cargo, loc);
|
||||
w.Add(cargo);
|
||||
@@ -72,8 +72,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
var pos = location - new float2(0, altitude);
|
||||
yield return new Renderable(anim.Image, location - .5f * anim.Image.size, "shadow", 0);
|
||||
var pos = location.ToFloat2() - new float2(0, altitude);
|
||||
yield return new Renderable(anim.Image, location.ToFloat2() - .5f * anim.Image.size, "shadow", 0);
|
||||
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, palette, 2);
|
||||
yield return new Renderable(paraAnim.Image, pos - .5f * paraAnim.Image.size + offset, palette, 3);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
if (!a.Destroyed && (a.World.LocalPlayer == null || a.Owner.Stances[a.Owner.World.LocalPlayer] == Stance.Ally))
|
||||
yield return new Renderable(anim.Image,
|
||||
a.CenterLocation - .5f * anim.Image.size, "chrome", (int)a.CenterLocation.Y);
|
||||
a.CenterLocation.ToFloat2() - .5f * anim.Image.size, "chrome", (int)a.CenterLocation.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class RallyPoint : IEffect
|
||||
{
|
||||
Actor building;
|
||||
RA.RallyPoint rp;
|
||||
readonly Actor building;
|
||||
readonly RA.RallyPoint rp;
|
||||
public Animation flag = new Animation("rallypoint");
|
||||
public Animation circles = new Animation("rallypoint");
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
circles.Play("circles");
|
||||
}
|
||||
|
||||
int2 cachedLocation;
|
||||
CPos cachedLocation;
|
||||
public void Tick( World world )
|
||||
{
|
||||
flag.Tick();
|
||||
@@ -55,11 +55,11 @@ namespace OpenRA.Mods.RA.Effects
|
||||
var palette = building.Trait<RenderSimple>().Palette(building.Owner);
|
||||
|
||||
yield return new Renderable(circles.Image,
|
||||
pos - .5f * circles.Image.size,
|
||||
pos.ToFloat2() - .5f * circles.Image.size,
|
||||
palette, (int)pos.Y);
|
||||
|
||||
yield return new Renderable(flag.Image,
|
||||
pos + new float2(-1,-17),
|
||||
pos.ToFloat2() + new float2(-1,-17),
|
||||
palette, (int)pos.Y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
var palette = building.Trait<RenderSimple>().Palette(player);
|
||||
|
||||
yield return new Renderable(anim.Image,
|
||||
building.CenterLocation - .5f * anim.Image.size, palette, (int)building.CenterLocation.Y);
|
||||
building.CenterLocation.ToFloat2() - .5f * anim.Image.size, palette, (int)building.CenterLocation.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
doors.PlayThen("active",
|
||||
() => a.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
|
||||
pos = a.CenterLocation - .5f * doors.Image.size + doorOffset;
|
||||
pos = a.CenterLocation.ToFloat2() - .5f * doors.Image.size + doorOffset;
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
public class Smoke : IEffect
|
||||
{
|
||||
readonly int2 pos;
|
||||
readonly PPos pos;
|
||||
readonly Animation anim;
|
||||
|
||||
public Smoke(World world, int2 pos, string trail)
|
||||
public Smoke(World world, PPos pos, string trail)
|
||||
{
|
||||
this.pos = pos;
|
||||
anim = new Animation(trail);
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "effect", (int)pos.Y);
|
||||
yield return new Renderable(anim.Image, pos.ToFloat2() - .5f * anim.Image.size, "effect", (int)pos.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user