sortof works
This commit is contained in:
@@ -50,8 +50,7 @@ namespace OpenRA
|
|||||||
public int PowerDrained = 0;
|
public int PowerDrained = 0;
|
||||||
|
|
||||||
public Shroud Shroud;
|
public Shroud Shroud;
|
||||||
|
public World World { get; private set; }
|
||||||
public World World { get { return PlayerActor.World; } }
|
|
||||||
|
|
||||||
public static List<Tuple<string, string, Color>> PlayerColors
|
public static List<Tuple<string, string, Color>> PlayerColors
|
||||||
{
|
{
|
||||||
@@ -66,6 +65,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
public Player( World world, Session.Client client )
|
public Player( World world, Session.Client client )
|
||||||
{
|
{
|
||||||
|
World = world;
|
||||||
Shroud = new Shroud(this, world.Map);
|
Shroud = new Shroud(this, world.Map);
|
||||||
|
|
||||||
PlayerActor = world.CreateActor("Player", new int2(int.MaxValue, int.MaxValue), this);
|
PlayerActor = world.CreateActor("Player", new int2(int.MaxValue, int.MaxValue), this);
|
||||||
@@ -176,7 +176,6 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
UpdatePower();
|
UpdatePower();
|
||||||
UpdateOreCapacity();
|
UpdateOreCapacity();
|
||||||
Shroud.Tick( World );
|
|
||||||
|
|
||||||
var totalMoney = Cash + Ore;
|
var totalMoney = Cash + Ore;
|
||||||
var diff = Math.Abs(totalMoney - DisplayCash);
|
var diff = Math.Abs(totalMoney - DisplayCash);
|
||||||
|
|||||||
@@ -31,29 +31,25 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class Shroud
|
public class Shroud
|
||||||
{
|
{
|
||||||
bool[,] explored;
|
Traits.Shroud shroud;
|
||||||
Sprite[] shadowBits = SpriteSheetBuilder.LoadAllSprites("shadow");
|
Sprite[] shadowBits = SpriteSheetBuilder.LoadAllSprites("shadow");
|
||||||
Sprite[,] sprites;
|
Sprite[,] sprites, fogSprites;
|
||||||
int gapOpaqueTicks = (int)(Rules.General.GapRegenInterval * 25 * 60);
|
|
||||||
int gapTicks;
|
|
||||||
int[,] gapField;
|
|
||||||
bool[,] gapActive;
|
|
||||||
|
|
||||||
bool dirty = true;
|
bool dirty = true;
|
||||||
bool hasGPS = false;
|
bool hasGPS = false;
|
||||||
Player owner;
|
Player owner;
|
||||||
Map map;
|
Map map;
|
||||||
public Rectangle? bounds;
|
|
||||||
|
public Rectangle? bounds { get { return shroud.exploredBounds; } }
|
||||||
|
|
||||||
public Shroud(Player owner, Map map)
|
public Shroud(Player owner, Map map)
|
||||||
{
|
{
|
||||||
|
this.shroud = owner.World.WorldActor.traits.Get<Traits.Shroud>();
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.map = map;
|
this.map = map;
|
||||||
|
|
||||||
explored = new bool[map.MapSize, map.MapSize];
|
|
||||||
sprites = new Sprite[map.MapSize, map.MapSize];
|
sprites = new Sprite[map.MapSize, map.MapSize];
|
||||||
gapField = new int[map.MapSize, map.MapSize];
|
fogSprites = new Sprite[map.MapSize, map.MapSize];
|
||||||
gapActive = new bool[map.MapSize, map.MapSize];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasGPS
|
public bool HasGPS
|
||||||
@@ -62,108 +58,15 @@ namespace OpenRA
|
|||||||
set { hasGPS = value; dirty = true;}
|
set { hasGPS = value; dirty = true;}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick( World world )
|
|
||||||
{
|
|
||||||
if (owner != owner.World.LocalPlayer) return;
|
|
||||||
|
|
||||||
if (gapTicks > 0) { --gapTicks; return; }
|
|
||||||
|
|
||||||
// Clear active flags
|
|
||||||
gapActive = new bool[map.MapSize, map.MapSize];
|
|
||||||
foreach (var a in world.Queries.WithTrait<GeneratesGap>().Where(a => owner != a.Actor.Owner))
|
|
||||||
foreach (var t in a.Trait.GetShroudedTiles())
|
|
||||||
{
|
|
||||||
gapActive[t.X, t.Y] = true;
|
|
||||||
explored[t.X, t.Y] = false;
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
gapTicks = gapOpaqueTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||||
public bool IsExplored(int x, int y)
|
bool IsExplored(int x, int y) { return shroud.exploredCells[x,y]; }
|
||||||
{
|
|
||||||
if (gapField[ x, y ] > 0)
|
public bool DisplayOnRadar(int x, int y) { return IsExplored(x, y); }
|
||||||
return false;
|
|
||||||
|
|
||||||
if (hasGPS)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return explored[ x, y ];
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DisplayOnRadar(int x, int y)
|
public void ResetExplored() { } // todo
|
||||||
{
|
|
||||||
// Active gap is never shown on radar, even if a unit is in range
|
|
||||||
if (gapActive[x , y])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return IsExplored(x,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetExplored()
|
|
||||||
{
|
|
||||||
if (owner != owner.World.LocalPlayer) return;
|
|
||||||
|
|
||||||
explored = new bool[map.MapSize, map.MapSize];
|
public void Explore(World w, int2 center, int range) { dirty = true; }
|
||||||
dirty = true;
|
public void Explore(Actor a) { if (a.Owner == a.World.LocalPlayer) dirty = true; }
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle MakeRect(int2 center, int range)
|
|
||||||
{
|
|
||||||
return new Rectangle(center.X - range, center.Y - range, 2 * range + 1, 2 * range + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Explore(World w, int2 center, int range)
|
|
||||||
{
|
|
||||||
if (owner != owner.World.LocalPlayer) return;
|
|
||||||
|
|
||||||
using (new PerfSample("explore"))
|
|
||||||
{
|
|
||||||
if (range == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var box = MakeRect(center, range);
|
|
||||||
bounds = bounds.HasValue ?
|
|
||||||
Rectangle.Union(bounds.Value, box) : box;
|
|
||||||
|
|
||||||
foreach (var t in w.FindTilesInCircle(center, range))
|
|
||||||
{
|
|
||||||
explored[t.X, t.Y] = true;
|
|
||||||
gapField[t.X, t.Y] = 0;
|
|
||||||
}
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Explore(Actor a)
|
|
||||||
{
|
|
||||||
if (owner != owner.World.LocalPlayer) return;
|
|
||||||
|
|
||||||
var sight = a.Info.Traits.Get<OwnedActorInfo>().Sight;
|
|
||||||
|
|
||||||
// Buildings: explore from each cell in the footprint
|
|
||||||
if (a.Info.Traits.Contains<BuildingInfo>())
|
|
||||||
{
|
|
||||||
var bi = a.Info.Traits.Get<BuildingInfo>();
|
|
||||||
foreach (var t in Footprint.Tiles(a.Info.Name, bi, a.Location))
|
|
||||||
Explore(a.World, t, sight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var mobile = a.traits.GetOrDefault<Mobile>();
|
|
||||||
if (mobile != null)
|
|
||||||
{
|
|
||||||
Explore(a.World, mobile.fromCell, sight);
|
|
||||||
Explore(a.World, mobile.toCell, sight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Explore(a.World,
|
|
||||||
(1f / Game.CellSize * a.CenterLocation).ToInt2(),
|
|
||||||
sight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static readonly byte[][] SpecialShroudTiles =
|
static readonly byte[][] SpecialShroudTiles =
|
||||||
{
|
{
|
||||||
@@ -209,6 +112,30 @@ namespace OpenRA
|
|||||||
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sprite ChooseFog(int i, int j)
|
||||||
|
{
|
||||||
|
if (shroud.visibleCells[i, j] == 0) 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; }
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
||||||
|
}
|
||||||
|
|
||||||
internal void Draw(SpriteRenderer r)
|
internal void Draw(SpriteRenderer r)
|
||||||
{
|
{
|
||||||
if (dirty)
|
if (dirty)
|
||||||
@@ -217,6 +144,9 @@ namespace OpenRA
|
|||||||
for (int j = map.YOffset; j < map.YOffset + map.Height; j++)
|
for (int j = map.YOffset; j < map.YOffset + map.Height; j++)
|
||||||
for (int i = map.XOffset; i < map.XOffset + map.Width; i++)
|
for (int i = map.XOffset; i < map.XOffset + map.Width; i++)
|
||||||
sprites[i, j] = ChooseShroud(i, j);
|
sprites[i, j] = ChooseShroud(i, j);
|
||||||
|
for (int j = map.YOffset; j < map.YOffset + map.Height; j++)
|
||||||
|
for (int i = map.XOffset; i < map.XOffset + map.Width; i++)
|
||||||
|
fogSprites[i, j] = ChooseFog(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
var miny = bounds.HasValue ? Math.Max(map.YOffset, bounds.Value.Top) : map.YOffset;
|
var miny = bounds.HasValue ? Math.Max(map.YOffset, bounds.Value.Top) : map.YOffset;
|
||||||
@@ -225,7 +155,39 @@ namespace OpenRA
|
|||||||
var minx = bounds.HasValue ? Math.Max(map.XOffset, bounds.Value.Left) : map.XOffset;
|
var minx = bounds.HasValue ? Math.Max(map.XOffset, bounds.Value.Left) : map.XOffset;
|
||||||
var maxx = bounds.HasValue ? Math.Min(map.XOffset + map.Width, bounds.Value.Right) : map.XOffset + map.Width;
|
var maxx = bounds.HasValue ? Math.Min(map.XOffset + map.Width, bounds.Value.Right) : map.XOffset + map.Width;
|
||||||
|
|
||||||
var shroudPalette = "shroud";
|
var shroudPalette = "fog";
|
||||||
|
|
||||||
|
for (var j = miny; j < maxy; j++)
|
||||||
|
{
|
||||||
|
var starti = minx;
|
||||||
|
for (var i = minx; i < maxx; i++)
|
||||||
|
{
|
||||||
|
if (fogSprites[i, j] == shadowBits[0x0f])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (starti != i)
|
||||||
|
{
|
||||||
|
r.DrawSprite(fogSprites[starti, j],
|
||||||
|
Game.CellSize * new float2(starti, j),
|
||||||
|
shroudPalette,
|
||||||
|
new float2(Game.CellSize * (i - starti), Game.CellSize));
|
||||||
|
starti = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.DrawSprite(fogSprites[i, j],
|
||||||
|
Game.CellSize * new float2(i, j),
|
||||||
|
shroudPalette);
|
||||||
|
starti = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starti < maxx)
|
||||||
|
r.DrawSprite(fogSprites[starti, j],
|
||||||
|
Game.CellSize * new float2(starti, j),
|
||||||
|
shroudPalette,
|
||||||
|
new float2(Game.CellSize * (maxx - starti), Game.CellSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
shroudPalette = "shroud";
|
||||||
|
|
||||||
for (var j = miny; j < maxy; j++)
|
for (var j = miny; j < maxy; j++)
|
||||||
{
|
{
|
||||||
@@ -237,17 +199,17 @@ namespace OpenRA
|
|||||||
|
|
||||||
if (starti != i)
|
if (starti != i)
|
||||||
{
|
{
|
||||||
r.DrawSprite(sprites[starti,j],
|
r.DrawSprite(sprites[starti, j],
|
||||||
Game.CellSize * new float2(starti, j),
|
Game.CellSize * new float2(starti, j),
|
||||||
shroudPalette,
|
shroudPalette,
|
||||||
new float2(Game.CellSize * (i - starti), Game.CellSize));
|
new float2(Game.CellSize * (i - starti), Game.CellSize));
|
||||||
starti = i+1;
|
starti = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r.DrawSprite(sprites[i, j],
|
r.DrawSprite(sprites[i, j],
|
||||||
Game.CellSize * new float2(i, j),
|
Game.CellSize * new float2(i, j),
|
||||||
shroudPalette);
|
shroudPalette);
|
||||||
starti = i+1;
|
starti = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starti < maxx)
|
if (starti < maxx)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
@@ -33,8 +34,10 @@ namespace OpenRA.Traits
|
|||||||
class Shroud
|
class Shroud
|
||||||
{
|
{
|
||||||
Map map;
|
Map map;
|
||||||
int[,] visibleCells;
|
|
||||||
bool[,] exploredCells;
|
public int[,] visibleCells;
|
||||||
|
public bool[,] exploredCells;
|
||||||
|
public Rectangle? exploredBounds;
|
||||||
|
|
||||||
public Shroud(Actor self, ShroudInfo info)
|
public Shroud(Actor self, ShroudInfo info)
|
||||||
{
|
{
|
||||||
@@ -53,7 +56,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
void AddActor(Actor a)
|
void AddActor(Actor a)
|
||||||
{
|
{
|
||||||
if (a.Owner != a.Owner.World.LocalPlayer) return;
|
if (a.Owner == null || a.Owner != a.Owner.World.LocalPlayer) return;
|
||||||
|
|
||||||
var v = new ActorVisibility
|
var v = new ActorVisibility
|
||||||
{
|
{
|
||||||
@@ -62,12 +65,18 @@ namespace OpenRA.Traits
|
|||||||
};
|
};
|
||||||
|
|
||||||
foreach (var p in v.vis)
|
foreach (var p in v.vis)
|
||||||
|
{
|
||||||
foreach (var q in a.World.FindTilesInCircle(p, v.range))
|
foreach (var q in a.World.FindTilesInCircle(p, v.range))
|
||||||
{
|
{
|
||||||
++visibleCells[q.X, q.Y];
|
++visibleCells[q.X, q.Y];
|
||||||
exploredCells[q.X, q.Y] = true;
|
exploredCells[q.X, q.Y] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var box = new Rectangle(p.X - v.range, p.Y - v.range, 2 * v.range + 1, 2 * v.range + 1);
|
||||||
|
exploredBounds = exploredBounds.HasValue ?
|
||||||
|
Rectangle.Union(exploredBounds.Value, box) : box;
|
||||||
|
}
|
||||||
|
|
||||||
vis[a] = v;
|
vis[a] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +111,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public void UpdateActor(Actor a)
|
public void UpdateActor(Actor a)
|
||||||
{
|
{
|
||||||
if (a.Owner != a.Owner.World.LocalPlayer) return;
|
if (a.Owner == null || a.Owner != a.Owner.World.LocalPlayer) return;
|
||||||
RemoveActor(a); AddActor(a);
|
RemoveActor(a); AddActor(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace OpenRA
|
|||||||
int localPlayerIndex;
|
int localPlayerIndex;
|
||||||
public Player LocalPlayer
|
public Player LocalPlayer
|
||||||
{
|
{
|
||||||
get { return players[localPlayerIndex]; }
|
get { return players.ContainsKey(localPlayerIndex) ? players[localPlayerIndex] : null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player NeutralPlayer { get; private set; }
|
public Player NeutralPlayer { get; private set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user