Move FrozenActor creation to Created in FrozenUnderFog

This commit is contained in:
atlimit8
2015-09-26 15:26:45 -05:00
parent f7c6938e27
commit 4744f436d3
2 changed files with 46 additions and 53 deletions

View File

@@ -11,7 +11,7 @@ namespace OpenRA.Primitives
readonly T[] valueByPlayerIndex; readonly T[] valueByPlayerIndex;
readonly Dictionary<Player, T> valueByPlayer; readonly Dictionary<Player, T> valueByPlayer;
public PlayerDictionary(World world, Func<Player, T> valueFactory) public PlayerDictionary(World world, Func<Player, int, T> valueFactory)
{ {
var players = world.Players; var players = world.Players;
if (players.Length == 0) if (players.Length == 0)
@@ -24,12 +24,16 @@ namespace OpenRA.Primitives
for (var i = 0; i < players.Length; i++) for (var i = 0; i < players.Length; i++)
{ {
var player = players[i]; var player = players[i];
var state = valueFactory(player); var state = valueFactory(player, i);
valueByPlayerIndex[i] = state; valueByPlayerIndex[i] = state;
valueByPlayer[player] = state; valueByPlayer[player] = state;
} }
} }
public PlayerDictionary(World world, Func<Player, T> valueFactory)
: this(world, (player, _) => valueFactory(player))
{ }
/// <summary>Gets the value for the specified player. This is slower than specifying a player index.</summary> /// <summary>Gets the value for the specified player. This is slower than specifying a player index.</summary>
public T this[Player player] { get { return valueByPlayer[player]; } } public T this[Player player] { get { return valueByPlayer[player]; } }

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new FrozenUnderFog(init, this); } public object Create(ActorInitializer init) { return new FrozenUnderFog(init, this); }
} }
public class FrozenUnderFog : IRenderModifier, IDefaultVisibility, ITick, ITickRender, ISync public class FrozenUnderFog : IRenderModifier, IDefaultVisibility, ITick, ITickRender, ISync, INotifyCreated
{ {
[Sync] public int VisibilityHash; [Sync] public int VisibilityHash;
@@ -39,7 +39,6 @@ namespace OpenRA.Mods.Common.Traits
PlayerDictionary<FrozenState> frozenStates; PlayerDictionary<FrozenState> frozenStates;
ITooltip tooltip; ITooltip tooltip;
Health health; Health health;
bool initialized;
bool isRendering; bool isRendering;
class FrozenState class FrozenState
@@ -64,13 +63,47 @@ namespace OpenRA.Mods.Common.Traits
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray(); footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();
} }
public void Created(Actor self)
{
tooltip = self.TraitsImplementing<ITooltip>().FirstOrDefault();
health = self.TraitOrDefault<Health>();
frozenStates = new PlayerDictionary<FrozenState>(self.World, (player, playerIndex) =>
{
var frozenActor = new FrozenActor(self, footprint, player.Shroud, startsRevealed);
if (startsRevealed)
UpdateFrozenActor(self, frozenActor, playerIndex);
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
return new FrozenState(frozenActor) { IsVisible = startsRevealed };
});
}
void UpdateFrozenActor(Actor self, FrozenActor frozenActor, int playerIndex)
{
VisibilityHash |= 1 << (playerIndex % 32);
frozenActor.Owner = self.Owner;
if (health != null)
{
frozenActor.HP = health.HP;
frozenActor.DamageState = health.DamageState;
}
if (tooltip != null)
{
frozenActor.TooltipInfo = tooltip.TooltipInfo;
frozenActor.TooltipOwner = tooltip.Owner;
}
}
bool IsVisibleInner(Actor self, Player byPlayer) bool IsVisibleInner(Actor self, Player byPlayer)
{ {
// If fog is disabled visibility is determined by shroud // If fog is disabled visibility is determined by shroud
if (!byPlayer.Shroud.FogEnabled) if (!byPlayer.Shroud.FogEnabled)
return byPlayer.Shroud.AnyExplored(self.OccupiesSpace.OccupiedCells()); return byPlayer.Shroud.AnyExplored(self.OccupiesSpace.OccupiedCells());
return initialized && frozenStates[byPlayer].IsVisible; return frozenStates[byPlayer].IsVisible;
} }
public bool IsVisible(Actor self, Player byPlayer) public bool IsVisible(Actor self, Player byPlayer)
@@ -89,61 +122,20 @@ namespace OpenRA.Mods.Common.Traits
VisibilityHash = 0; VisibilityHash = 0;
if (!initialized)
{
frozenStates = new PlayerDictionary<FrozenState>(self.World, player =>
{
var frozenActor = new FrozenActor(self, footprint, player.Shroud, startsRevealed);
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
return new FrozenState(frozenActor) { IsVisible = startsRevealed };
});
tooltip = self.TraitsImplementing<ITooltip>().FirstOrDefault();
health = self.TraitOrDefault<Health>();
}
for (var playerIndex = 0; playerIndex < frozenStates.Count; playerIndex++) for (var playerIndex = 0; playerIndex < frozenStates.Count; playerIndex++)
{ {
var state = frozenStates[playerIndex]; var state = frozenStates[playerIndex];
var frozenActor = state.FrozenActor; var frozenActor = state.FrozenActor;
bool isVisible; var isVisible = !frozenActor.Visible;
if (!initialized) state.IsVisible = isVisible;
{
isVisible = state.IsVisible;
}
else
{
isVisible = !frozenActor.Visible;
state.IsVisible = isVisible;
}
if (isVisible) if (isVisible)
VisibilityHash |= 1 << (playerIndex % 32); UpdateFrozenActor(self, frozenActor, playerIndex);
else
continue;
frozenActor.Owner = self.Owner;
if (health != null)
{
frozenActor.HP = health.HP;
frozenActor.DamageState = health.DamageState;
}
if (tooltip != null)
{
frozenActor.TooltipInfo = tooltip.TooltipInfo;
frozenActor.TooltipOwner = tooltip.Owner;
}
} }
initialized = true;
} }
public void TickRender(WorldRenderer wr, Actor self) public void TickRender(WorldRenderer wr, Actor self)
{ {
if (!initialized)
return;
IRenderable[] renderables = null; IRenderable[] renderables = null;
for (var playerIndex = 0; playerIndex < frozenStates.Count; playerIndex++) for (var playerIndex = 0; playerIndex < frozenStates.Count; playerIndex++)
{ {
@@ -165,10 +157,7 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r) public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
{ {
return return IsVisible(self, self.World.RenderPlayer) || isRendering ? r : SpriteRenderable.None;
IsVisible(self, self.World.RenderPlayer) ||
(initialized && isRendering) ?
r : SpriteRenderable.None;
} }
} }
} }