Introduce World.LocalShroud. Breaks targeting stealth tanks. Probably breaks FrozenUnderFog.
This commit is contained in:
@@ -140,7 +140,7 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
foreach (var t in world.Queries.WithTraitMultiple<IRadarSignature>())
|
foreach (var t in world.Queries.WithTraitMultiple<IRadarSignature>())
|
||||||
{
|
{
|
||||||
if (!t.Actor.IsVisible(player))
|
if (!world.LocalShroud.IsVisible(t.Actor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||||
@@ -159,7 +159,7 @@ namespace OpenRA.Graphics
|
|||||||
var map = world.Map;
|
var map = world.Map;
|
||||||
var size = Util.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
|
var size = Util.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
|
||||||
Bitmap bitmap = new Bitmap(size, size);
|
Bitmap bitmap = new Bitmap(size, size);
|
||||||
if (world.LocalPlayer == null || world.LocalPlayer.Shroud == null)
|
if (world.LocalShroud.Disabled)
|
||||||
return bitmap;
|
return bitmap;
|
||||||
|
|
||||||
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||||
@@ -168,8 +168,6 @@ namespace OpenRA.Graphics
|
|||||||
var shroud = Color.Black.ToArgb();
|
var shroud = Color.Black.ToArgb();
|
||||||
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
||||||
|
|
||||||
var playerShroud = world.LocalPlayer.Shroud;
|
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int* c = (int*)bitmapData.Scan0;
|
int* c = (int*)bitmapData.Scan0;
|
||||||
@@ -179,9 +177,9 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var mapX = x + map.Bounds.Left;
|
var mapX = x + map.Bounds.Left;
|
||||||
var mapY = y + map.Bounds.Top;
|
var mapY = y + map.Bounds.Top;
|
||||||
if (!playerShroud.IsExplored(mapX, mapY))
|
if (!world.LocalShroud.IsExplored(mapX, mapY))
|
||||||
*(c + (y * bitmapData.Stride >> 2) + x) = shroud;
|
*(c + (y * bitmapData.Stride >> 2) + x) = shroud;
|
||||||
else if (!playerShroud.IsVisible(mapX,mapY))
|
else if (!world.LocalShroud.IsVisible(mapX,mapY))
|
||||||
*(c + (y * bitmapData.Stride >> 2) + x) = fog;
|
*(c + (y * bitmapData.Stride >> 2) + x) = fog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ namespace OpenRA.Graphics
|
|||||||
if (firstRow < 0) firstRow = 0;
|
if (firstRow < 0) firstRow = 0;
|
||||||
if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height;
|
if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height;
|
||||||
|
|
||||||
if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.Disabled && world.LocalPlayer.Shroud.Bounds.HasValue)
|
if (world.LocalPlayer != null && !world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)
|
||||||
{
|
{
|
||||||
var r = world.LocalPlayer.Shroud.Bounds.Value;
|
var r = world.LocalShroud.Bounds.Value;
|
||||||
if (firstRow < r.Top - map.Bounds.Top)
|
if (firstRow < r.Top - map.Bounds.Top)
|
||||||
firstRow = r.Top - map.Bounds.Top;
|
firstRow = r.Top - map.Bounds.Top;
|
||||||
|
|
||||||
|
|||||||
@@ -125,11 +125,9 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public Rectangle ShroudBounds( World world )
|
public Rectangle ShroudBounds( World world )
|
||||||
{
|
{
|
||||||
var localPlayer = world.LocalPlayer;
|
if( world.LocalShroud.Disabled || !world.LocalShroud.Bounds.HasValue )
|
||||||
if( localPlayer == null ) return world.Map.Bounds;
|
return world.Map.Bounds;
|
||||||
if( localPlayer.Shroud.Disabled ) return world.Map.Bounds;
|
return Rectangle.Intersect( world.LocalShroud.Bounds.Value, world.Map.Bounds );
|
||||||
if( !localPlayer.Shroud.Bounds.HasValue ) return world.Map.Bounds;
|
|
||||||
return Rectangle.Intersect( localPlayer.Shroud.Bounds.Value, world.Map.Bounds );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rectangle ViewBounds()
|
public Rectangle ViewBounds()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace OpenRA.Graphics
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
|
|
||||||
terrainRenderer = new TerrainRenderer(world, this);
|
terrainRenderer = new TerrainRenderer(world, this);
|
||||||
shroudRenderer = new ShroudRenderer(world.WorldActor.Trait<Shroud>(), world.Map);
|
shroudRenderer = new ShroudRenderer(world);
|
||||||
uiOverlay = new UiOverlay();
|
uiOverlay = new UiOverlay();
|
||||||
palette = new HardwarePalette(world.Map);
|
palette = new HardwarePalette(world.Map);
|
||||||
|
|
||||||
@@ -53,9 +53,8 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
Rectangle GetBoundsRect()
|
Rectangle GetBoundsRect()
|
||||||
{
|
{
|
||||||
var r = (world.LocalPlayer != null && !world.LocalPlayer.Shroud.Disabled && world.LocalPlayer.Shroud.Bounds.HasValue)?
|
var r = (!world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)?
|
||||||
world.LocalPlayer.Shroud.Bounds.Value : world.Map.Bounds;
|
Rectangle.Intersect(world.LocalShroud.Bounds.Value,world.Map.Bounds) : world.Map.Bounds;
|
||||||
r.Intersect(world.Map.Bounds);
|
|
||||||
|
|
||||||
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X);
|
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X);
|
||||||
var top = (int)(Game.CellSize * r.Top - Game.viewport.Location.Y);
|
var top = (int)(Game.CellSize * r.Top - Game.viewport.Location.Y);
|
||||||
@@ -135,20 +134,6 @@ namespace OpenRA.Graphics
|
|||||||
Game.Renderer.LineRenderer.DrawLine(a, a + c, color, color);
|
Game.Renderer.LineRenderer.DrawLine(a, a + c, color, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBins(RectangleF bounds)
|
|
||||||
{
|
|
||||||
DrawBox(bounds, Color.Red);
|
|
||||||
if (world.LocalPlayer != null)
|
|
||||||
DrawBox(world.LocalPlayer.Shroud.Bounds.Value, Color.Blue);
|
|
||||||
|
|
||||||
for (var j = 0; j < world.Map.MapSize.Y;
|
|
||||||
j += world.WorldActor.Info.Traits.Get<SpatialBinsInfo>().BinSize)
|
|
||||||
{
|
|
||||||
Game.Renderer.LineRenderer.DrawLine(new float2(0, j * Game.CellSize), new float2(world.Map.MapSize.X * Game.CellSize, j * Game.CellSize), Color.Black, Color.Black);
|
|
||||||
Game.Renderer.LineRenderer.DrawLine(new float2(j * Game.CellSize, 0), new float2(j * Game.CellSize, world.Map.MapSize.Y * Game.CellSize), Color.Black, Color.Black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawSelectionBox(Actor selectedUnit, Color c)
|
public void DrawSelectionBox(Actor selectedUnit, Color c)
|
||||||
{
|
{
|
||||||
var bounds = selectedUnit.GetBounds(true);
|
var bounds = selectedUnit.GetBounds(true);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace OpenRA
|
|||||||
public readonly PlayerReference PlayerRef;
|
public readonly PlayerReference PlayerRef;
|
||||||
public bool IsBot;
|
public bool IsBot;
|
||||||
|
|
||||||
public Shroud Shroud { get { return World.WorldActor.Trait<Shroud>(); }}
|
public Shroud Shroud { get { return World.LocalShroud; }}
|
||||||
public World World { get; private set; }
|
public World World { get; private set; }
|
||||||
|
|
||||||
public Player(World world, PlayerReference pr, int index)
|
public Player(World world, PlayerReference pr, int index)
|
||||||
|
|||||||
@@ -23,26 +23,16 @@ namespace OpenRA
|
|||||||
bool dirty = true;
|
bool dirty = true;
|
||||||
Map map;
|
Map map;
|
||||||
|
|
||||||
public ShroudRenderer(Traits.Shroud shroud, Map map)
|
public ShroudRenderer(World world)
|
||||||
{
|
{
|
||||||
this.shroud = shroud;
|
this.shroud = world.LocalShroud;
|
||||||
this.map = map;
|
this.map = world.Map;
|
||||||
|
|
||||||
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||||
fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||||
shroud.Dirty += () => dirty = true;
|
shroud.Dirty += () => dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsExplored(int x, int y)
|
|
||||||
{
|
|
||||||
return (shroud == null) ? true : shroud.IsExplored(x,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsVisible(int x, int y)
|
|
||||||
{
|
|
||||||
return (shroud == null) ? true : shroud.IsVisible(x,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static readonly byte[][] SpecialShroudTiles =
|
static readonly byte[][] SpecialShroudTiles =
|
||||||
{
|
{
|
||||||
new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||||
@@ -65,49 +55,49 @@ namespace OpenRA
|
|||||||
|
|
||||||
Sprite ChooseShroud(int i, int j)
|
Sprite ChooseShroud(int i, int j)
|
||||||
{
|
{
|
||||||
if( !IsExplored( i, j ) ) return shadowBits[ 0xf ];
|
if( !shroud.IsExplored( i, j ) ) return shadowBits[ 0xf ];
|
||||||
|
|
||||||
// bits are for unexploredness: up, right, down, left
|
// bits are for unexploredness: up, right, down, left
|
||||||
var v = 0;
|
var v = 0;
|
||||||
// bits are for unexploredness: TL, TR, BR, BL
|
// bits are for unexploredness: TL, TR, BR, BL
|
||||||
var u = 0;
|
var u = 0;
|
||||||
|
|
||||||
if( !IsExplored( i, j - 1 ) ) { v |= 1; u |= 3; }
|
if( !shroud.IsExplored( i, j - 1 ) ) { v |= 1; u |= 3; }
|
||||||
if( !IsExplored( i + 1, j ) ) { v |= 2; u |= 6; }
|
if( !shroud.IsExplored( i + 1, j ) ) { v |= 2; u |= 6; }
|
||||||
if( !IsExplored( i, j + 1 ) ) { v |= 4; u |= 12; }
|
if( !shroud.IsExplored( i, j + 1 ) ) { v |= 4; u |= 12; }
|
||||||
if( !IsExplored( i - 1, j ) ) { v |= 8; u |= 9; }
|
if( !shroud.IsExplored( i - 1, j ) ) { v |= 8; u |= 9; }
|
||||||
|
|
||||||
var uSides = u;
|
var uSides = u;
|
||||||
|
|
||||||
if( !IsExplored( i - 1, j - 1 ) ) u |= 1;
|
if( !shroud.IsExplored( i - 1, j - 1 ) ) u |= 1;
|
||||||
if( !IsExplored( i + 1, j - 1 ) ) u |= 2;
|
if( !shroud.IsExplored( i + 1, j - 1 ) ) u |= 2;
|
||||||
if( !IsExplored( i + 1, j + 1 ) ) u |= 4;
|
if( !shroud.IsExplored( i + 1, j + 1 ) ) u |= 4;
|
||||||
if( !IsExplored( i - 1, j + 1 ) ) u |= 8;
|
if( !shroud.IsExplored( i - 1, j + 1 ) ) u |= 8;
|
||||||
|
|
||||||
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite ChooseFog(int i, int j)
|
Sprite ChooseFog(int i, int j)
|
||||||
{
|
{
|
||||||
if (!IsVisible(i,j)) return shadowBits[0xf];
|
if (!shroud.IsVisible(i,j)) return shadowBits[0xf];
|
||||||
if (!IsExplored(i, j)) return shadowBits[0xf];
|
if (!shroud.IsExplored(i, j)) return shadowBits[0xf];
|
||||||
|
|
||||||
// bits are for unexploredness: up, right, down, left
|
// bits are for unexploredness: up, right, down, left
|
||||||
var v = 0;
|
var v = 0;
|
||||||
// bits are for unexploredness: TL, TR, BR, BL
|
// bits are for unexploredness: TL, TR, BR, BL
|
||||||
var u = 0;
|
var u = 0;
|
||||||
|
|
||||||
if (!IsVisible(i, j - 1)) { v |= 1; u |= 3; }
|
if (!shroud.IsVisible(i, j - 1)) { v |= 1; u |= 3; }
|
||||||
if (!IsVisible(i + 1, j)) { v |= 2; u |= 6; }
|
if (!shroud.IsVisible(i + 1, j)) { v |= 2; u |= 6; }
|
||||||
if (!IsVisible(i, j + 1)) { v |= 4; u |= 12; }
|
if (!shroud.IsVisible(i, j + 1)) { v |= 4; u |= 12; }
|
||||||
if (!IsVisible(i - 1, j)) { v |= 8; u |= 9; }
|
if (!shroud.IsVisible(i - 1, j)) { v |= 8; u |= 9; }
|
||||||
|
|
||||||
var uSides = u;
|
var uSides = u;
|
||||||
|
|
||||||
if (!IsVisible(i - 1, j - 1)) u |= 1;
|
if (!shroud.IsVisible(i - 1, j - 1)) u |= 1;
|
||||||
if (!IsVisible(i + 1, j - 1)) u |= 2;
|
if (!shroud.IsVisible(i + 1, j - 1)) u |= 2;
|
||||||
if (!IsVisible(i + 1, j + 1)) u |= 4;
|
if (!shroud.IsVisible(i + 1, j + 1)) u |= 4;
|
||||||
if (!IsVisible(i - 1, j + 1)) u |= 8;
|
if (!shroud.IsVisible(i - 1, j + 1)) u |= 8;
|
||||||
|
|
||||||
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
DisableShroud ^= true;
|
DisableShroud ^= true;
|
||||||
if (self.World.LocalPlayer == self.Owner)
|
if (self.World.LocalPlayer == self.Owner)
|
||||||
self.World.LocalPlayer.Shroud.Disabled = DisableShroud;
|
self.World.LocalShroud.Disabled = DisableShroud;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "DevPathDebug":
|
case "DevPathDebug":
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace OpenRA.Traits
|
|||||||
Color RadarSignatureColor(Actor self);
|
Color RadarSignatureColor(Actor self);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
|
public interface IVisibilityModifier { bool IsVisible(Actor self); }
|
||||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||||
public interface IHasLocation
|
public interface IHasLocation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,15 +38,11 @@ namespace OpenRA.Traits
|
|||||||
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
|
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
|
||||||
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
|
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
|
||||||
|
|
||||||
Shroud shroud = null;
|
|
||||||
if( world.LocalPlayer != null )
|
|
||||||
shroud = world.LocalPlayer.Shroud;
|
|
||||||
|
|
||||||
for (int x = minx; x < maxx; x++)
|
for (int x = minx; x < maxx; x++)
|
||||||
for (int y = miny; y < maxy; y++)
|
for (int y = miny; y < maxy; y++)
|
||||||
{
|
{
|
||||||
if (shroud != null && !shroud.IsExplored(new int2(x, y)))
|
if (!world.LocalShroud.IsExplored(new int2(x, y)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var c = content[x, y];
|
var c = content[x, y];
|
||||||
if (c.image != null)
|
if (c.image != null)
|
||||||
|
|||||||
@@ -214,5 +214,13 @@ namespace OpenRA.Traits
|
|||||||
return visibleCells[x,y] != 0;
|
return visibleCells[x,y] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actors are hidden under shroud, but not under fog by default
|
||||||
|
public bool IsVisible(Actor a)
|
||||||
|
{
|
||||||
|
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return disabled || a.Owner == a.World.LocalPlayer || GetVisOrigins(a).Any(o => IsExplored(o));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace OpenRA.Widgets
|
|||||||
IEnumerable<Actor> SelectActorsInBox(World world, float2 a, float2 b)
|
IEnumerable<Actor> SelectActorsInBox(World world, float2 a, float2 b)
|
||||||
{
|
{
|
||||||
return world.FindUnits(a, b)
|
return world.FindUnits(a, b)
|
||||||
.Where( x => x.HasTrait<Selectable>() && x.IsVisible(world.LocalPlayer) )
|
.Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) )
|
||||||
.GroupBy(x => (x.Owner == world.LocalPlayer) ? x.Info.Traits.Get<SelectableInfo>().Priority : 0)
|
.GroupBy(x => (x.Owner == world.LocalPlayer) ? x.Info.Traits.Get<SelectableInfo>().Priority : 0)
|
||||||
.OrderByDescending(g => g.Key)
|
.OrderByDescending(g => g.Key)
|
||||||
.Select( g => g.AsEnumerable() )
|
.Select( g => g.AsEnumerable() )
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
get { return players.ContainsKey(localPlayerIndex) ? players[localPlayerIndex] : null; }
|
get { return players.ContainsKey(localPlayerIndex) ? players[localPlayerIndex] : null; }
|
||||||
}
|
}
|
||||||
|
public readonly Shroud LocalShroud;
|
||||||
|
|
||||||
public void SetLocalPlayer(int index)
|
public void SetLocalPlayer(int index)
|
||||||
{
|
{
|
||||||
@@ -51,7 +52,6 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
public readonly Actor WorldActor;
|
public readonly Actor WorldActor;
|
||||||
|
|
||||||
public readonly Map Map;
|
public readonly Map Map;
|
||||||
public readonly TileSet TileSet;
|
public readonly TileSet TileSet;
|
||||||
|
|
||||||
@@ -98,6 +98,8 @@ namespace OpenRA
|
|||||||
SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed);
|
SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed);
|
||||||
|
|
||||||
WorldActor = CreateActor( "World", new TypeDictionary() );
|
WorldActor = CreateActor( "World", new TypeDictionary() );
|
||||||
|
LocalShroud = WorldActor.Trait<Shroud>();
|
||||||
|
|
||||||
Queries = new AllQueries(this);
|
Queries = new AllQueries(this);
|
||||||
|
|
||||||
// Add players
|
// Add players
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
|||||||
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
|
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
|
||||||
{
|
{
|
||||||
var loc = mouseLocation + Game.viewport.Location;
|
var loc = mouseLocation + Game.viewport.Location;
|
||||||
return FindUnits(world, loc, loc).Where(a => a.IsVisible(world.LocalPlayer));
|
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Actor> FindUnits(this World world, float2 a, float2 b)
|
public static IEnumerable<Actor> FindUnits(this World world, float2 a, float2 b)
|
||||||
@@ -72,22 +72,6 @@ namespace OpenRA
|
|||||||
return world.TileSet.Terrain[world.GetTerrainType(cell)];
|
return world.TileSet.Terrain[world.GetTerrainType(cell)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsVisible(this Actor a, Player byPlayer) /* must never be relied on in synced code! */
|
|
||||||
{
|
|
||||||
if (byPlayer == null) return true; // Observer
|
|
||||||
if (a.World.LocalPlayer != null && a.World.LocalPlayer.Shroud.Disabled)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var shroud = a.World.WorldActor.Trait<Shroud>();
|
|
||||||
if (!Shroud.GetVisOrigins(a).Any(o => a.World.Map.IsInMap(o) && shroud.exploredCells[o.X, o.Y])) // covered by shroud
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, byPlayer)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int2 ClampToWorld( this World world, int2 xy )
|
public static int2 ClampToWorld( this World world, int2 xy )
|
||||||
{
|
{
|
||||||
return xy.Clamp(world.Map.Bounds);
|
return xy.Clamp(world.Map.Bounds);
|
||||||
|
|||||||
@@ -214,7 +214,6 @@ namespace OpenRA.Mods.RA
|
|||||||
return inRange
|
return inRange
|
||||||
.Where(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Enemy)
|
.Where(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Enemy)
|
||||||
.Where(a => HasAnyValidWeapons(Target.FromActor(a)))
|
.Where(a => HasAnyValidWeapons(Target.FromActor(a)))
|
||||||
.Where(a => !a.HasTrait<Cloak>() || a.Trait<Cloak>().IsVisible(a, self.Owner))
|
|
||||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
{
|
{
|
||||||
if (!cliprect.Contains(kv.Key.X, kv.Key.Y))
|
if (!cliprect.Contains(kv.Key.X, kv.Key.Y))
|
||||||
continue;
|
continue;
|
||||||
if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(kv.Key))
|
if (!world.LocalShroud.IsExplored(kv.Key))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bibSprites[kv.Value.type - 1][kv.Value.image].DrawAt( wr,
|
bibSprites[kv.Value.type - 1][kv.Value.image].DrawAt( wr,
|
||||||
|
|||||||
@@ -40,12 +40,13 @@ namespace OpenRA.Mods.RA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can't be used in synced code
|
||||||
public virtual bool CanChronoshiftTo(Actor self, int2 targetLocation)
|
public virtual bool CanChronoshiftTo(Actor self, int2 targetLocation)
|
||||||
{
|
{
|
||||||
// Todo: Allow enemy units to be chronoshifted into bad terrain to kill them
|
// Todo: Allow enemy units to be chronoshifted into bad terrain to kill them
|
||||||
return self.HasTrait<ITeleportable>() &&
|
return self.HasTrait<ITeleportable>() &&
|
||||||
self.Trait<ITeleportable>().CanEnterCell(targetLocation) &&
|
self.Trait<ITeleportable>().CanEnterCell(targetLocation) &&
|
||||||
(self.World.LocalPlayer == null || self.World.LocalPlayer.Shroud.IsExplored(targetLocation));
|
(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, int2 targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (remainingTime > 0)
|
if (remainingTime > 0)
|
||||||
return rs;
|
return rs;
|
||||||
|
|
||||||
if (Cloaked && IsVisible(self, self.World.LocalPlayer))
|
if (Cloaked && IsVisible(self))
|
||||||
return rs.Select(a => a.WithPalette("shadow"));
|
return rs.Select(a => a.WithPalette("shadow"));
|
||||||
else
|
else
|
||||||
return new Renderable[] { };
|
return new Renderable[] { };
|
||||||
@@ -101,14 +101,6 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public bool Cloaked { get { return remainingTime == 0; } }
|
public bool Cloaked { get { return remainingTime == 0; } }
|
||||||
|
|
||||||
public bool IsVisible(Actor self, Player byPlayer)
|
|
||||||
{
|
|
||||||
if (!Cloaked || self.Owner.Stances[byPlayer] == Stance.Ally)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return self.World.Queries.WithTrait<DetectCloaked>().Any(a => a.Actor.Owner == byPlayer && (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get<DetectCloakedInfo>().Range);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsVisible(Actor self)
|
public bool IsVisible(Actor self)
|
||||||
{
|
{
|
||||||
return !Cloaked || self.Owner == self.World.LocalPlayer;
|
return !Cloaked || self.Owner == self.World.LocalPlayer;
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ namespace OpenRA.Mods.RA
|
|||||||
foreach (var a in self.World.Queries.OwnedBy[self.Owner])
|
foreach (var a in self.World.Queries.OwnedBy[self.Owner])
|
||||||
a.Kill(a);
|
a.Kill(a);
|
||||||
|
|
||||||
self.Owner.Shroud.Disabled = true;
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
|
self.World.LocalShroud.Disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Win(Actor self)
|
public void Win(Actor self)
|
||||||
@@ -59,7 +59,8 @@ namespace OpenRA.Mods.RA
|
|||||||
self.Owner.WinState = WinState.Won;
|
self.Owner.WinState = WinState.Won;
|
||||||
|
|
||||||
Game.Debug("{0} is victorious.".F(self.Owner.PlayerName));
|
Game.Debug("{0} is victorious.".F(self.Owner.PlayerName));
|
||||||
self.Owner.Shroud.Disabled = true;
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
|
self.World.LocalShroud.Disabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,19 +73,13 @@ namespace OpenRA.Mods.RA
|
|||||||
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R,
|
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R,
|
||||||
trailStart.G, trailStart.B);
|
trailStart.G, trailStart.B);
|
||||||
|
|
||||||
// LocalPlayer is null on shellmap
|
|
||||||
Shroud shroud = null;
|
|
||||||
if (self.World.LocalPlayer != null)
|
|
||||||
shroud = self.World.LocalPlayer.Shroud;
|
|
||||||
|
|
||||||
for (int i = positions.Count - 1; i >= 1; --i)
|
for (int i = positions.Count - 1; i >= 1; --i)
|
||||||
{
|
{
|
||||||
var conPos = positions[i];
|
var conPos = positions[i];
|
||||||
var nextPos = positions[i - 1];
|
var nextPos = positions[i - 1];
|
||||||
|
|
||||||
if (shroud == null ||
|
if (self.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(conPos)) ||
|
||||||
shroud.IsVisible(OpenRA.Traits.Util.CellContaining(conPos)) ||
|
self.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(nextPos)))
|
||||||
shroud.IsVisible(OpenRA.Traits.Util.CellContaining(nextPos)))
|
|
||||||
{
|
{
|
||||||
Game.Renderer.LineRenderer.DrawLine(conPos, nextPos, trailStart, trailEnd);
|
Game.Renderer.LineRenderer.DrawLine(conPos, nextPos, trailStart, trailEnd);
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace OpenRA.Mods.RA
|
|||||||
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor)
|
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor)
|
||||||
{
|
{
|
||||||
// Don't leak info about resources under the shroud
|
// Don't leak info about resources under the shroud
|
||||||
if (!self.World.LocalPlayer.Shroud.IsExplored(location)) return false;
|
if (!self.World.LocalShroud.IsExplored(location)) return false;
|
||||||
|
|
||||||
var res = self.World.WorldActor.Trait<ResourceLayer>().GetResource( location );
|
var res = self.World.WorldActor.Trait<ResourceLayer>().GetResource( location );
|
||||||
var info = self.Info.Traits.Get<HarvesterInfo>();
|
var info = self.Info.Traits.Get<HarvesterInfo>();
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
class InvisibleToOthers : IRenderModifier, IVisibilityModifier, IRadarColorModifier
|
class InvisibleToOthers : IRenderModifier, IVisibilityModifier, IRadarColorModifier
|
||||||
{
|
{
|
||||||
public bool IsVisible(Actor self, Player byPlayer)
|
public bool IsVisible(Actor self)
|
||||||
{
|
{
|
||||||
return self.Owner == byPlayer;
|
return self.World.LocalPlayer == null || self.Owner == self.World.LocalPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color RadarColorOverride(Actor self)
|
public Color RadarColorOverride(Actor self)
|
||||||
|
|||||||
@@ -14,34 +14,15 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.RA
|
namespace OpenRA.Mods.RA
|
||||||
{
|
{
|
||||||
class FrozenUnderFogInfo : ITraitInfo
|
class FrozenUnderFogInfo : TraitInfo<FrozenUnderFog> {}
|
||||||
{
|
|
||||||
public object Create(ActorInitializer init) { return new FrozenUnderFog(init.self); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class FrozenUnderFog : IRenderModifier, IVisibilityModifier
|
class FrozenUnderFog : IRenderModifier
|
||||||
{
|
{
|
||||||
Shroud shroud;
|
|
||||||
Renderable[] cache = { };
|
Renderable[] cache = { };
|
||||||
|
|
||||||
public FrozenUnderFog(Actor self)
|
|
||||||
{
|
|
||||||
shroud = self.World.WorldActor.Trait<Shroud>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsVisible(Actor self, Player byPlayer)
|
|
||||||
{
|
|
||||||
return self.World.LocalPlayer == null
|
|
||||||
|| self.Owner == byPlayer
|
|
||||||
|| self.World.LocalPlayer.Shroud.Disabled
|
|
||||||
|| Shroud.GetVisOrigins(self).Any(o => self.World.Map.IsInMap(o) && shroud.visibleCells[o.X, o.Y] != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||||
{
|
{
|
||||||
if (IsVisible(self, self.World.LocalPlayer))
|
if (self.World.LocalShroud.IsVisible(self))
|
||||||
cache = r.ToArray();
|
cache = r.ToArray();
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,36 +9,24 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA
|
namespace OpenRA.Mods.RA
|
||||||
{
|
{
|
||||||
class HiddenUnderFogInfo : ITraitInfo
|
class HiddenUnderFogInfo : TraitInfo<HiddenUnderFog> {}
|
||||||
{
|
|
||||||
public object Create(ActorInitializer init) { return new HiddenUnderFog(init.self); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class HiddenUnderFog : IRenderModifier, IVisibilityModifier
|
class HiddenUnderFog : IRenderModifier, IVisibilityModifier
|
||||||
{
|
{
|
||||||
Shroud shroud;
|
public bool IsVisible(Actor self)
|
||||||
|
|
||||||
public HiddenUnderFog(Actor self)
|
|
||||||
{
|
{
|
||||||
shroud = self.World.WorldActor.Trait<Shroud>();
|
return Shroud.GetVisOrigins(self).Any(o => self.World.LocalShroud.IsVisible(o));
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsVisible(Actor self, Player byPlayer)
|
|
||||||
{
|
|
||||||
return self.World.LocalPlayer == null
|
|
||||||
|| self.Owner == byPlayer
|
|
||||||
|| self.World.LocalPlayer.Shroud.Disabled
|
|
||||||
|| shroud.visibleCells[self.Location.X, self.Location.Y] > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Renderable[] Nothing = { };
|
static Renderable[] Nothing = { };
|
||||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||||
{
|
{
|
||||||
return IsVisible(self, self.World.LocalPlayer) ? r : Nothing;
|
return IsVisible(self) ? r : Nothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA
|
namespace OpenRA.Mods.RA
|
||||||
@@ -32,5 +33,14 @@ namespace OpenRA.Mods.RA
|
|||||||
get { return (Cloak.Cloaked) ? info.CloakedTargetTypes
|
get { return (Cloak.Cloaked) ? info.CloakedTargetTypes
|
||||||
: info.TargetTypes;}
|
: info.TargetTypes;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo: Finish me
|
||||||
|
public bool TargetableBy(Actor self, Actor byActor)
|
||||||
|
{
|
||||||
|
if (!Cloak.Cloaked || self.Owner == byActor.Owner || self.Owner.Stances[byActor.Owner] == Stance.Ally)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return self.World.Queries.WithTrait<DetectCloaked>().Any(a => (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get<DetectCloakedInfo>().Range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
var actor = world.FindUnitsAtMouse(Viewport.LastMousePos).FirstOrDefault();
|
var actor = world.FindUnitsAtMouse(Viewport.LastMousePos).FirstOrDefault();
|
||||||
if (actor == null || !actor.IsVisible(world.LocalPlayer))
|
if (actor == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var text = actor.Info.Traits.Contains<TooltipInfo>()
|
var text = actor.Info.Traits.Contains<TooltipInfo>()
|
||||||
|
|||||||
Reference in New Issue
Block a user