Track visibility modifiers on FrozenActors.
This commit is contained in:
committed by
Oliver Brakmann
parent
5f79c31a57
commit
224377f078
@@ -46,7 +46,17 @@ namespace OpenRA.Traits
|
|||||||
public DamageState DamageState { get; private set; }
|
public DamageState DamageState { get; private set; }
|
||||||
readonly IHealth health;
|
readonly IHealth health;
|
||||||
|
|
||||||
|
// The Visible flag is tied directly to the actor visibility under the fog.
|
||||||
|
// If Visible is true, the actor is made invisible (via FrozenUnderFog/IDefaultVisibility)
|
||||||
|
// and this FrozenActor is rendered instead.
|
||||||
|
// The Hidden flag covers the edge case that occurs when the backing actor was last "seen"
|
||||||
|
// to be cloaked or otherwise not CanBeViewedByPlayer()ed. Setting Visible to true when
|
||||||
|
// the actor is hidden under the fog would leak the actors position via the tooltips and
|
||||||
|
// AutoTargetability, and keeping Visible as false would cause the actor to be rendered
|
||||||
|
// under the fog.
|
||||||
public bool Visible = true;
|
public bool Visible = true;
|
||||||
|
public bool Hidden = false;
|
||||||
|
|
||||||
public bool Shrouded { get; private set; }
|
public bool Shrouded { get; private set; }
|
||||||
public bool NeedRenderables { get; set; }
|
public bool NeedRenderables { get; set; }
|
||||||
public IRenderable[] Renderables = NoRenderables;
|
public IRenderable[] Renderables = NoRenderables;
|
||||||
@@ -101,6 +111,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
Owner = actor.Owner;
|
Owner = actor.Owner;
|
||||||
TargetTypes = actor.GetEnabledTargetTypes();
|
TargetTypes = actor.GetEnabledTargetTypes();
|
||||||
|
Hidden = !actor.CanBeViewedByPlayer(viewer);
|
||||||
|
|
||||||
if (health != null)
|
if (health != null)
|
||||||
{
|
{
|
||||||
@@ -145,6 +156,11 @@ namespace OpenRA.Traits
|
|||||||
NeedRenderables |= Visible && !wasVisible;
|
NeedRenderables |= Visible && !wasVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Invalidate()
|
||||||
|
{
|
||||||
|
Owner = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void Flash()
|
public void Flash()
|
||||||
{
|
{
|
||||||
flashTicks = 5;
|
flashTicks = 5;
|
||||||
|
|||||||
@@ -80,13 +80,21 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool IsValidFor(Actor targeter)
|
public bool IsValidFor(Actor targeter)
|
||||||
{
|
{
|
||||||
if (targeter == null || Type == TargetType.Invalid)
|
if (targeter == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actor != null && !actor.IsTargetableBy(targeter))
|
switch (Type)
|
||||||
return false;
|
{
|
||||||
|
case TargetType.Actor:
|
||||||
return true;
|
return actor.IsTargetableBy(targeter);
|
||||||
|
case TargetType.FrozenActor:
|
||||||
|
return frozen.IsValid && frozen.Visible && !frozen.Hidden;
|
||||||
|
case TargetType.Invalid:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
case TargetType.Terrain:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently all or nothing.
|
// Currently all or nothing.
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
static readonly FrozenActorAction Remove = (fufubg, fal, gps, fa) =>
|
static readonly FrozenActorAction Remove = (fufubg, fal, gps, fa) =>
|
||||||
{
|
{
|
||||||
// Removes the frozen actor. Once done, we no longer need to track GPS updates.
|
// Removes the frozen actor. Once done, we no longer need to track GPS updates.
|
||||||
|
fa.Invalidate();
|
||||||
fal.Remove(fa);
|
fal.Remove(fa);
|
||||||
gps.UnregisterForOnGpsRefreshed(fufubg.self, fufubg);
|
gps.UnregisterForOnGpsRefreshed(fufubg.self, fufubg);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,11 +68,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
frozenStates = new PlayerDictionary<FrozenState>(self.World, (player, playerIndex) =>
|
frozenStates = new PlayerDictionary<FrozenState>(self.World, (player, playerIndex) =>
|
||||||
{
|
{
|
||||||
var frozenActor = new FrozenActor(self, footprint, player, startsRevealed);
|
var frozenActor = new FrozenActor(self, footprint, player, startsRevealed);
|
||||||
if (startsRevealed)
|
|
||||||
UpdateFrozenActor(self, frozenActor, playerIndex);
|
|
||||||
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
|
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
|
||||||
return new FrozenState(frozenActor) { IsVisible = startsRevealed };
|
return new FrozenState(frozenActor) { IsVisible = startsRevealed };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (startsRevealed)
|
||||||
|
for (var playerIndex = 0; playerIndex < frozenStates.Count; playerIndex++)
|
||||||
|
UpdateFrozenActor(self, frozenStates[playerIndex].FrozenActor, playerIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateFrozenActor(Actor self, FrozenActor frozenActor, int playerIndex)
|
void UpdateFrozenActor(Actor self, FrozenActor frozenActor, int playerIndex)
|
||||||
|
|||||||
@@ -246,26 +246,20 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
var frozen = world.ScreenMap.FrozenActorsAtMouse(world.RenderPlayer, worldPixel)
|
var frozen = world.ScreenMap.FrozenActorsAtMouse(world.RenderPlayer, worldPixel)
|
||||||
.Where(a => a.TooltipInfo != null && a.IsValid)
|
.Where(a => a.TooltipInfo != null && a.IsValid && a.Visible && !a.Hidden)
|
||||||
.WithHighestSelectionPriority(worldPixel);
|
.WithHighestSelectionPriority(worldPixel);
|
||||||
|
|
||||||
if (frozen != null)
|
if (frozen != null)
|
||||||
{
|
{
|
||||||
var actor = frozen.Actor;
|
FrozenActorTooltip = frozen;
|
||||||
|
|
||||||
// HACK: This leaks the cloak state through the fog (cloaked buildings will not show tooltips)
|
// HACK: This leaks the tooltip state through the fog
|
||||||
if (actor == null || actor.TraitsImplementing<IVisibilityModifier>().All(t => t.IsVisible(actor, world.RenderPlayer)))
|
// This will cause issues for any downstream mods that use IProvideTooltipInfo on enemy actors
|
||||||
{
|
if (frozen.Actor != null)
|
||||||
FrozenActorTooltip = frozen;
|
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
|
||||||
|
|
||||||
// HACK: This leaks the tooltip state through the fog
|
TooltipType = WorldTooltipType.FrozenActor;
|
||||||
// This will cause issues for any downstream mods that use IProvideTooltipInfo on enemy actors
|
return;
|
||||||
if (frozen.Actor != null)
|
|
||||||
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
|
|
||||||
|
|
||||||
TooltipType = WorldTooltipType.FrozenActor;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceLayer != null)
|
if (resourceLayer != null)
|
||||||
|
|||||||
Reference in New Issue
Block a user