Avoid duplicated frozen visibility checks.
The FrozenUnderFog.Tick method will now reuse the calculation do by the frozen actor when it had to calculate its visibility, this prevents it having to re-do the fairly expensive visibility calculation.
This commit is contained in:
committed by
RoosterDragon
parent
721ba5e9c3
commit
c3531d6f70
@@ -40,7 +40,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool Visible;
|
public bool Visible;
|
||||||
|
|
||||||
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion)
|
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud)
|
||||||
{
|
{
|
||||||
actor = self;
|
actor = self;
|
||||||
Footprint = footprint;
|
Footprint = footprint;
|
||||||
@@ -48,6 +48,8 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
CenterPosition = self.CenterPosition;
|
CenterPosition = self.CenterPosition;
|
||||||
Bounds = self.Bounds;
|
Bounds = self.Bounds;
|
||||||
|
|
||||||
|
UpdateVisibility(shroud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ID { get { return actor.ActorID; } }
|
public uint ID { get { return actor.ActorID; } }
|
||||||
@@ -56,7 +58,15 @@ namespace OpenRA.Traits
|
|||||||
public Actor Actor { get { return !actor.IsDead ? actor : null; } }
|
public Actor Actor { get { return !actor.IsDead ? actor : null; } }
|
||||||
|
|
||||||
int flashTicks;
|
int flashTicks;
|
||||||
public void Tick(World world, Shroud shroud)
|
public void Tick(Shroud shroud)
|
||||||
|
{
|
||||||
|
UpdateVisibility(shroud);
|
||||||
|
|
||||||
|
if (flashTicks > 0)
|
||||||
|
flashTicks--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateVisibility(Shroud shroud)
|
||||||
{
|
{
|
||||||
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path.
|
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path.
|
||||||
// Visible = !Footprint.Any(shroud.IsVisibleTest(FootprintRegion));
|
// Visible = !Footprint.Any(shroud.IsVisibleTest(FootprintRegion));
|
||||||
@@ -68,9 +78,6 @@ namespace OpenRA.Traits
|
|||||||
Visible = false;
|
Visible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flashTicks > 0)
|
|
||||||
flashTicks--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flash()
|
public void Flash()
|
||||||
@@ -129,22 +136,24 @@ namespace OpenRA.Traits
|
|||||||
VisibilityHash = 0;
|
VisibilityHash = 0;
|
||||||
FrozenHash = 0;
|
FrozenHash = 0;
|
||||||
|
|
||||||
foreach (var kv in frozen)
|
foreach (var kvp in frozen)
|
||||||
{
|
{
|
||||||
FrozenHash += (int)kv.Key;
|
var hash = (int)kvp.Key;
|
||||||
|
FrozenHash += hash;
|
||||||
|
|
||||||
kv.Value.Tick(self.World, self.Owner.Shroud);
|
var frozenActor = kvp.Value;
|
||||||
if (kv.Value.Visible)
|
frozenActor.Tick(self.Owner.Shroud);
|
||||||
VisibilityHash += (int)kv.Key;
|
|
||||||
|
|
||||||
if (!kv.Value.Visible && kv.Value.Actor == null)
|
if (frozenActor.Visible)
|
||||||
remove.Add(kv.Key);
|
VisibilityHash += hash;
|
||||||
|
else if (frozenActor.Actor == null)
|
||||||
|
remove.Add(kvp.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var r in remove)
|
foreach (var actorID in remove)
|
||||||
{
|
{
|
||||||
world.ScreenMap.Remove(owner, frozen[r]);
|
world.ScreenMap.Remove(owner, frozen[actorID]);
|
||||||
frozen.Remove(r);
|
frozen.Remove(actorID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray();
|
footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray();
|
||||||
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells);
|
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells);
|
||||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
||||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
|
||||||
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
||||||
|
|
||||||
frozen = new Dictionary<Player, FrozenActor>();
|
frozen = new Dictionary<Player, FrozenActor>();
|
||||||
@@ -66,55 +65,43 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
VisibilityHash = 0;
|
VisibilityHash = 0;
|
||||||
foreach (var p in self.World.Players)
|
|
||||||
{
|
|
||||||
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path.
|
|
||||||
// var isVisible = footprint.Any(p.Shroud.IsVisibleTest(footprintRegion));
|
|
||||||
var isVisibleTest = p.Shroud.IsVisibleTest(footprintRegion);
|
|
||||||
var isVisible = false;
|
|
||||||
foreach (var uv in footprint)
|
|
||||||
if (isVisibleTest(uv))
|
|
||||||
{
|
|
||||||
isVisible = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
visible[p] = isVisible;
|
|
||||||
if (isVisible)
|
|
||||||
VisibilityHash += p.ClientIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
foreach (var p in self.World.Players)
|
|
||||||
{
|
|
||||||
visible[p] |= startsRevealed;
|
|
||||||
p.PlayerActor.Trait<FrozenActorLayer>().Add(frozen[p] = new FrozenActor(self, footprint, footprintRegion));
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var player in self.World.Players)
|
foreach (var player in self.World.Players)
|
||||||
{
|
{
|
||||||
if (!visible[player])
|
bool isVisible;
|
||||||
|
FrozenActor frozenActor;
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
frozen[player] = frozenActor = new FrozenActor(self, footprint, footprintRegion, player.Shroud);
|
||||||
|
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
|
||||||
|
isVisible = visible[player] |= startsRevealed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frozenActor = frozen[player];
|
||||||
|
isVisible = visible[player] = !frozenActor.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isVisible)
|
||||||
|
VisibilityHash += player.ClientIndex;
|
||||||
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var actor = frozen[player];
|
frozenActor.Owner = self.Owner;
|
||||||
actor.Owner = self.Owner;
|
|
||||||
|
|
||||||
if (health.Value != null)
|
if (health.Value != null)
|
||||||
{
|
{
|
||||||
actor.HP = health.Value.HP;
|
frozenActor.HP = health.Value.HP;
|
||||||
actor.DamageState = health.Value.DamageState;
|
frozenActor.DamageState = health.Value.DamageState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltip.Value != null)
|
if (tooltip.Value != null)
|
||||||
{
|
{
|
||||||
actor.TooltipInfo = tooltip.Value.TooltipInfo;
|
frozenActor.TooltipInfo = tooltip.Value.TooltipInfo;
|
||||||
actor.TooltipOwner = tooltip.Value.Owner;
|
frozenActor.TooltipOwner = tooltip.Value.Owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TickRender(WorldRenderer wr, Actor self)
|
public void TickRender(WorldRenderer wr, Actor self)
|
||||||
|
|||||||
Reference in New Issue
Block a user