Introduce World.LocalShroud. Breaks targeting stealth tanks. Probably breaks FrozenUnderFog.

This commit is contained in:
Paul Chote
2010-11-26 16:56:33 +13:00
parent 41fd19c766
commit 7c5c989eb2
25 changed files with 88 additions and 161 deletions

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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()

View File

@@ -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);

View File

@@ -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)

View File

@@ -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]];
}

View File

@@ -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":

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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));
}
}
}

View File

@@ -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() )

View File

@@ -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

View File

@@ -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);