Begin refactoring Shroud. ShroudRenderer is now internal to WorldRenderer; all traits interact with Shroud directly. Gives soft-edges at the map border for free, but breaks shellmap and observers.
This commit is contained in:
@@ -159,6 +159,9 @@ 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)
|
||||
return bitmap;
|
||||
|
||||
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public readonly World world;
|
||||
internal readonly TerrainRenderer terrainRenderer;
|
||||
internal readonly ShroudRenderer shroudRenderer;
|
||||
|
||||
public readonly UiOverlay uiOverlay;
|
||||
internal readonly HardwarePalette palette;
|
||||
|
||||
@@ -29,6 +31,7 @@ namespace OpenRA.Graphics
|
||||
this.world = world;
|
||||
|
||||
terrainRenderer = new TerrainRenderer(world, this);
|
||||
shroudRenderer = new ShroudRenderer(world.WorldActor.Trait<Shroud>(), world.Map);
|
||||
uiOverlay = new UiOverlay();
|
||||
palette = new HardwarePalette(world.Map);
|
||||
|
||||
@@ -110,9 +113,7 @@ namespace OpenRA.Graphics
|
||||
if (world.OrderGenerator != null)
|
||||
world.OrderGenerator.RenderAfterWorld(this, world);
|
||||
|
||||
if (world.LocalPlayer != null)
|
||||
world.LocalPlayer.Shroud.Draw( this );
|
||||
|
||||
shroudRenderer.Draw( this );
|
||||
Game.Renderer.DisableScissor();
|
||||
|
||||
foreach (var a in world.Selection.Actors)
|
||||
|
||||
@@ -40,13 +40,12 @@ namespace OpenRA
|
||||
public readonly PlayerReference PlayerRef;
|
||||
public bool IsBot;
|
||||
|
||||
public ShroudRenderer Shroud;
|
||||
public Shroud Shroud { get { return World.WorldActor.Trait<Shroud>(); }}
|
||||
public World World { get; private set; }
|
||||
|
||||
public Player(World world, PlayerReference pr, int index)
|
||||
{
|
||||
World = world;
|
||||
Shroud = new ShroudRenderer(this, world.Map);
|
||||
|
||||
Index = index;
|
||||
Palette = "player" + index;
|
||||
@@ -69,8 +68,6 @@ namespace OpenRA
|
||||
public Player(World world, Session.Client client, PlayerReference pr, int index)
|
||||
{
|
||||
World = world;
|
||||
Shroud = new ShroudRenderer(this, world.Map);
|
||||
|
||||
Index = index;
|
||||
Palette = "player" + index;
|
||||
Color = client.Color1;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -20,44 +21,26 @@ namespace OpenRA
|
||||
Sprite[,] sprites, fogSprites;
|
||||
|
||||
bool dirty = true;
|
||||
bool disabled = false;
|
||||
Map map;
|
||||
|
||||
public Rectangle? Bounds { get { return shroud.exploredBounds; } }
|
||||
|
||||
public ShroudRenderer(Player owner, Map map)
|
||||
public ShroudRenderer(Traits.Shroud shroud, Map map)
|
||||
{
|
||||
this.shroud = owner.World.WorldActor.Trait<Traits.Shroud>();
|
||||
this.shroud = shroud;
|
||||
this.map = 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 Disabled
|
||||
{
|
||||
get { return disabled; }
|
||||
set { disabled = value; dirty = true;}
|
||||
}
|
||||
|
||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(int x, int y)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
return shroud.exploredCells[x,y];
|
||||
return (shroud == null) ? true : shroud.IsExplored(x,y);
|
||||
}
|
||||
|
||||
public bool IsVisible(int2 xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(int x, int y)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
if (!map.IsInMap(x, y))
|
||||
return false;
|
||||
return shroud.visibleCells[x,y] != 0;
|
||||
return (shroud == null) ? true : shroud.IsVisible(x,y);
|
||||
}
|
||||
|
||||
static readonly byte[][] SpecialShroudTiles =
|
||||
@@ -82,58 +65,55 @@ namespace OpenRA
|
||||
|
||||
Sprite ChooseShroud(int i, int j)
|
||||
{
|
||||
if( !shroud.exploredCells[ i, j ] ) return shadowBits[ 0xf ];
|
||||
if( !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( !shroud.exploredCells[ i, j - 1 ] ) { v |= 1; u |= 3; }
|
||||
if( !shroud.exploredCells[ i + 1, j ] ) { v |= 2; u |= 6; }
|
||||
if( !shroud.exploredCells[ i, j + 1 ] ) { v |= 4; u |= 12; }
|
||||
if( !shroud.exploredCells[ i - 1, j ] ) { v |= 8; u |= 9; }
|
||||
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; }
|
||||
|
||||
var uSides = u;
|
||||
|
||||
if( !shroud.exploredCells[ i - 1, j - 1 ] ) u |= 1;
|
||||
if( !shroud.exploredCells[ i + 1, j - 1 ] ) u |= 2;
|
||||
if( !shroud.exploredCells[ i + 1, j + 1 ] ) u |= 4;
|
||||
if( !shroud.exploredCells[ i - 1, j + 1 ] ) u |= 8;
|
||||
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;
|
||||
|
||||
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
||||
}
|
||||
|
||||
Sprite ChooseFog(int i, int j)
|
||||
{
|
||||
if (shroud.visibleCells[i, j] == 0) return shadowBits[0xf];
|
||||
if (!shroud.exploredCells[i, j]) return shadowBits[0xf];
|
||||
if (!IsVisible(i,j)) return shadowBits[0xf];
|
||||
if (!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 (shroud.visibleCells[i, j - 1] == 0) { v |= 1; u |= 3; }
|
||||
if (shroud.visibleCells[i + 1, j] == 0) { v |= 2; u |= 6; }
|
||||
if (shroud.visibleCells[i, j + 1] == 0) { v |= 4; u |= 12; }
|
||||
if (shroud.visibleCells[i - 1, j] == 0) { v |= 8; u |= 9; }
|
||||
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; }
|
||||
|
||||
var uSides = u;
|
||||
|
||||
if (shroud.visibleCells[i - 1, j - 1] == 0) u |= 1;
|
||||
if (shroud.visibleCells[i + 1, j - 1] == 0) u |= 2;
|
||||
if (shroud.visibleCells[i + 1, j + 1] == 0) u |= 4;
|
||||
if (shroud.visibleCells[i - 1, j + 1] == 0) u |= 8;
|
||||
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;
|
||||
|
||||
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
||||
}
|
||||
|
||||
internal void Draw( WorldRenderer wr )
|
||||
{
|
||||
if (disabled)
|
||||
return;
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
dirty = false;
|
||||
@@ -146,7 +126,7 @@ namespace OpenRA
|
||||
fogSprites[i, j] = ChooseFog(i, j);
|
||||
}
|
||||
|
||||
var clipRect = Bounds.HasValue ? Rectangle.Intersect(Bounds.Value, map.Bounds) : map.Bounds;
|
||||
var clipRect = (shroud != null && shroud.Bounds.HasValue) ? Rectangle.Intersect(shroud.Bounds.Value, map.Bounds) : map.Bounds;
|
||||
clipRect = Rectangle.Intersect(Game.viewport.ViewBounds(), clipRect);
|
||||
var miny = clipRect.Top;
|
||||
var maxy = clipRect.Bottom;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Traits
|
||||
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
|
||||
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
|
||||
|
||||
ShroudRenderer shroud = null;
|
||||
Shroud shroud = null;
|
||||
if( world.LocalPlayer != null )
|
||||
shroud = world.LocalPlayer.Shroud;
|
||||
|
||||
|
||||
@@ -27,6 +27,14 @@ namespace OpenRA.Traits
|
||||
public int[,] visibleCells;
|
||||
public bool[,] exploredCells;
|
||||
public Rectangle? exploredBounds;
|
||||
bool disabled = false;
|
||||
public bool Disabled
|
||||
{
|
||||
get { return disabled; }
|
||||
set { disabled = value; Dirty(); }
|
||||
}
|
||||
|
||||
public Rectangle? Bounds { get { return exploredBounds; } }
|
||||
public event Action Dirty = () => { };
|
||||
|
||||
public Shroud(World world)
|
||||
@@ -181,5 +189,30 @@ namespace OpenRA.Traits
|
||||
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(int x, int y)
|
||||
{
|
||||
if (!map.IsInMap(x, y))
|
||||
return false;
|
||||
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
return exploredCells[x,y];
|
||||
}
|
||||
|
||||
public bool IsVisible(int2 xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(int x, int y)
|
||||
{
|
||||
if (!map.IsInMap(x, y))
|
||||
return false;
|
||||
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
return visibleCells[x,y] != 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.RA
|
||||
trailStart.G, trailStart.B);
|
||||
|
||||
// LocalPlayer is null on shellmap
|
||||
ShroudRenderer shroud = null;
|
||||
Shroud shroud = null;
|
||||
if (self.World.LocalPlayer != null)
|
||||
shroud = self.World.LocalPlayer.Shroud;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user