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>())
|
||||
{
|
||||
if (!t.Actor.IsVisible(player))
|
||||
if (!world.LocalShroud.IsVisible(t.Actor))
|
||||
continue;
|
||||
|
||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||
@@ -159,7 +159,7 @@ namespace OpenRA.Graphics
|
||||
var map = world.Map;
|
||||
var size = Util.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
|
||||
Bitmap bitmap = new Bitmap(size, size);
|
||||
if (world.LocalPlayer == null || world.LocalPlayer.Shroud == null)
|
||||
if (world.LocalShroud.Disabled)
|
||||
return bitmap;
|
||||
|
||||
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||
@@ -167,8 +167,6 @@ namespace OpenRA.Graphics
|
||||
|
||||
var shroud = Color.Black.ToArgb();
|
||||
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
||||
|
||||
var playerShroud = world.LocalPlayer.Shroud;
|
||||
|
||||
unsafe
|
||||
{
|
||||
@@ -179,9 +177,9 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var mapX = x + map.Bounds.Left;
|
||||
var mapY = y + map.Bounds.Top;
|
||||
if (!playerShroud.IsExplored(mapX, mapY))
|
||||
if (!world.LocalShroud.IsExplored(mapX, mapY))
|
||||
*(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,9 +79,9 @@ namespace OpenRA.Graphics
|
||||
if (firstRow < 0) firstRow = 0;
|
||||
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)
|
||||
firstRow = r.Top - map.Bounds.Top;
|
||||
|
||||
|
||||
@@ -125,11 +125,9 @@ namespace OpenRA.Graphics
|
||||
|
||||
public Rectangle ShroudBounds( World world )
|
||||
{
|
||||
var localPlayer = world.LocalPlayer;
|
||||
if( localPlayer == null ) return world.Map.Bounds;
|
||||
if( localPlayer.Shroud.Disabled ) return world.Map.Bounds;
|
||||
if( !localPlayer.Shroud.Bounds.HasValue ) return world.Map.Bounds;
|
||||
return Rectangle.Intersect( localPlayer.Shroud.Bounds.Value, world.Map.Bounds );
|
||||
if( world.LocalShroud.Disabled || !world.LocalShroud.Bounds.HasValue )
|
||||
return world.Map.Bounds;
|
||||
return Rectangle.Intersect( world.LocalShroud.Bounds.Value, world.Map.Bounds );
|
||||
}
|
||||
|
||||
public Rectangle ViewBounds()
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Graphics
|
||||
this.world = world;
|
||||
|
||||
terrainRenderer = new TerrainRenderer(world, this);
|
||||
shroudRenderer = new ShroudRenderer(world.WorldActor.Trait<Shroud>(), world.Map);
|
||||
shroudRenderer = new ShroudRenderer(world);
|
||||
uiOverlay = new UiOverlay();
|
||||
palette = new HardwarePalette(world.Map);
|
||||
|
||||
@@ -53,9 +53,8 @@ namespace OpenRA.Graphics
|
||||
|
||||
Rectangle GetBoundsRect()
|
||||
{
|
||||
var r = (world.LocalPlayer != null && !world.LocalPlayer.Shroud.Disabled && world.LocalPlayer.Shroud.Bounds.HasValue)?
|
||||
world.LocalPlayer.Shroud.Bounds.Value : world.Map.Bounds;
|
||||
r.Intersect(world.Map.Bounds);
|
||||
var r = (!world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)?
|
||||
Rectangle.Intersect(world.LocalShroud.Bounds.Value,world.Map.Bounds) : world.Map.Bounds;
|
||||
|
||||
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var bounds = selectedUnit.GetBounds(true);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA
|
||||
public readonly PlayerReference PlayerRef;
|
||||
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 Player(World world, PlayerReference pr, int index)
|
||||
|
||||
@@ -23,26 +23,16 @@ namespace OpenRA
|
||||
bool dirty = true;
|
||||
Map map;
|
||||
|
||||
public ShroudRenderer(Traits.Shroud shroud, Map map)
|
||||
public ShroudRenderer(World world)
|
||||
{
|
||||
this.shroud = shroud;
|
||||
this.map = map;
|
||||
this.shroud = world.LocalShroud;
|
||||
this.map = world.Map;
|
||||
|
||||
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||
fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||
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 =
|
||||
{
|
||||
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)
|
||||
{
|
||||
if( !IsExplored( i, j ) ) return shadowBits[ 0xf ];
|
||||
if( !shroud.IsExplored( i, j ) ) return shadowBits[ 0xf ];
|
||||
|
||||
// bits are for unexploredness: up, right, down, left
|
||||
var v = 0;
|
||||
// bits are for unexploredness: TL, TR, BR, BL
|
||||
var u = 0;
|
||||
|
||||
if( !IsExplored( i, j - 1 ) ) { v |= 1; u |= 3; }
|
||||
if( !IsExplored( i + 1, j ) ) { v |= 2; u |= 6; }
|
||||
if( !IsExplored( i, j + 1 ) ) { v |= 4; u |= 12; }
|
||||
if( !IsExplored( i - 1, j ) ) { v |= 8; u |= 9; }
|
||||
if( !shroud.IsExplored( i, j - 1 ) ) { v |= 1; u |= 3; }
|
||||
if( !shroud.IsExplored( i + 1, j ) ) { v |= 2; u |= 6; }
|
||||
if( !shroud.IsExplored( i, j + 1 ) ) { v |= 4; u |= 12; }
|
||||
if( !shroud.IsExplored( i - 1, j ) ) { v |= 8; u |= 9; }
|
||||
|
||||
var uSides = u;
|
||||
|
||||
if( !IsExplored( i - 1, j - 1 ) ) u |= 1;
|
||||
if( !IsExplored( i + 1, j - 1 ) ) u |= 2;
|
||||
if( !IsExplored( i + 1, j + 1 ) ) u |= 4;
|
||||
if( !IsExplored( i - 1, j + 1 ) ) u |= 8;
|
||||
if( !shroud.IsExplored( i - 1, j - 1 ) ) u |= 1;
|
||||
if( !shroud.IsExplored( i + 1, j - 1 ) ) u |= 2;
|
||||
if( !shroud.IsExplored( i + 1, j + 1 ) ) u |= 4;
|
||||
if( !shroud.IsExplored( i - 1, j + 1 ) ) u |= 8;
|
||||
|
||||
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
||||
}
|
||||
|
||||
Sprite ChooseFog(int i, int j)
|
||||
{
|
||||
if (!IsVisible(i,j)) return shadowBits[0xf];
|
||||
if (!IsExplored(i, j)) return shadowBits[0xf];
|
||||
if (!shroud.IsVisible(i,j)) return shadowBits[0xf];
|
||||
if (!shroud.IsExplored(i, j)) return shadowBits[0xf];
|
||||
|
||||
// bits are for unexploredness: up, right, down, left
|
||||
var v = 0;
|
||||
// bits are for unexploredness: TL, TR, BR, BL
|
||||
var u = 0;
|
||||
|
||||
if (!IsVisible(i, j - 1)) { v |= 1; u |= 3; }
|
||||
if (!IsVisible(i + 1, j)) { v |= 2; u |= 6; }
|
||||
if (!IsVisible(i, j + 1)) { v |= 4; u |= 12; }
|
||||
if (!IsVisible(i - 1, j)) { v |= 8; u |= 9; }
|
||||
if (!shroud.IsVisible(i, j - 1)) { v |= 1; u |= 3; }
|
||||
if (!shroud.IsVisible(i + 1, j)) { v |= 2; u |= 6; }
|
||||
if (!shroud.IsVisible(i, j + 1)) { v |= 4; u |= 12; }
|
||||
if (!shroud.IsVisible(i - 1, j)) { v |= 8; u |= 9; }
|
||||
|
||||
var uSides = u;
|
||||
|
||||
if (!IsVisible(i - 1, j - 1)) u |= 1;
|
||||
if (!IsVisible(i + 1, j - 1)) u |= 2;
|
||||
if (!IsVisible(i + 1, j + 1)) u |= 4;
|
||||
if (!IsVisible(i - 1, j + 1)) u |= 8;
|
||||
if (!shroud.IsVisible(i - 1, j - 1)) u |= 1;
|
||||
if (!shroud.IsVisible(i + 1, j - 1)) u |= 2;
|
||||
if (!shroud.IsVisible(i + 1, j + 1)) u |= 4;
|
||||
if (!shroud.IsVisible(i - 1, j + 1)) u |= 8;
|
||||
|
||||
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
DisableShroud ^= true;
|
||||
if (self.World.LocalPlayer == self.Owner)
|
||||
self.World.LocalPlayer.Shroud.Disabled = DisableShroud;
|
||||
self.World.LocalShroud.Disabled = DisableShroud;
|
||||
break;
|
||||
}
|
||||
case "DevPathDebug":
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenRA.Traits
|
||||
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 IHasLocation
|
||||
{
|
||||
|
||||
@@ -38,15 +38,11 @@ namespace OpenRA.Traits
|
||||
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
|
||||
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 y = miny; y < maxy; y++)
|
||||
{
|
||||
if (shroud != null && !shroud.IsExplored(new int2(x, y)))
|
||||
continue;
|
||||
if (!world.LocalShroud.IsExplored(new int2(x, y)))
|
||||
continue;
|
||||
|
||||
var c = content[x, y];
|
||||
if (c.image != null)
|
||||
|
||||
@@ -213,6 +213,14 @@ namespace OpenRA.Traits
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
.OrderByDescending(g => g.Key)
|
||||
.Select( g => g.AsEnumerable() )
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace OpenRA
|
||||
{
|
||||
get { return players.ContainsKey(localPlayerIndex) ? players[localPlayerIndex] : null; }
|
||||
}
|
||||
public readonly Shroud LocalShroud;
|
||||
|
||||
public void SetLocalPlayer(int index)
|
||||
{
|
||||
@@ -51,7 +52,6 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
public readonly Actor WorldActor;
|
||||
|
||||
public readonly Map Map;
|
||||
public readonly TileSet TileSet;
|
||||
|
||||
@@ -98,6 +98,8 @@ namespace OpenRA
|
||||
SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed);
|
||||
|
||||
WorldActor = CreateActor( "World", new TypeDictionary() );
|
||||
LocalShroud = WorldActor.Trait<Shroud>();
|
||||
|
||||
Queries = new AllQueries(this);
|
||||
|
||||
// Add players
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
||||
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
|
||||
{
|
||||
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)
|
||||
@@ -72,22 +72,6 @@ namespace OpenRA
|
||||
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 )
|
||||
{
|
||||
return xy.Clamp(world.Map.Bounds);
|
||||
|
||||
Reference in New Issue
Block a user