Move Shroud.IsTargetable to Player.

This commit is contained in:
Paul Chote
2015-06-13 18:27:00 +01:00
parent 1eb1841f2b
commit 0677c309f3
7 changed files with 26 additions and 28 deletions

View File

@@ -49,6 +49,8 @@ namespace OpenRA
public Shroud Shroud; public Shroud Shroud;
public World World { get; private set; } public World World { get; private set; }
readonly IFogVisibilityModifier[] fogVisibilities;
CountryInfo ChooseCountry(World world, string name, bool requireSelectable = true) CountryInfo ChooseCountry(World world, string name, bool requireSelectable = true)
{ {
var selectableCountries = world.Map.Rules.Actors["world"].Traits var selectableCountries = world.Map.Rules.Actors["world"].Traits
@@ -113,6 +115,9 @@ namespace OpenRA
PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) });
Shroud = PlayerActor.Trait<Shroud>(); Shroud = PlayerActor.Trait<Shroud>();
fogVisibilities = PlayerActor.TraitsImplementing<IFogVisibilityModifier>()
.ToArray();
// Enable the bot logic on the host // Enable the bot logic on the host
IsBot = botType != null; IsBot = botType != null;
if (IsBot && Game.IsHost) if (IsBot && Game.IsHost)
@@ -157,6 +162,19 @@ namespace OpenRA
return a.Trait<IDefaultVisibility>().IsVisible(a, this); return a.Trait<IDefaultVisibility>().IsVisible(a, this);
} }
public bool CanTargetActor(Actor a)
{
if (HasFogVisibility)
return true;
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
}
public bool HasFogVisibility { get { return fogVisibilities.Any(f => f.HasFogVisibility(this)); } }
#region Scripting interface #region Scripting interface
Lazy<ScriptPlayerInterface> luaInterface; Lazy<ScriptPlayerInterface> luaInterface;

View File

@@ -33,8 +33,6 @@ namespace OpenRA.Traits
readonly CellLayer<short> generatedShroudCount; readonly CellLayer<short> generatedShroudCount;
readonly CellLayer<bool> explored; readonly CellLayer<bool> explored;
readonly Lazy<IFogVisibilityModifier[]> fogVisibilities;
// Cache of visibility that was added, so no matter what crazy trait code does, it // Cache of visibility that was added, so no matter what crazy trait code does, it
// can't make us invalid. // can't make us invalid.
readonly Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>(); readonly Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>();
@@ -62,8 +60,6 @@ namespace OpenRA.Traits
self.World.ActorAdded += a => { CPos[] shrouded = null; AddShroudGeneration(a, ref shrouded); }; self.World.ActorAdded += a => { CPos[] shrouded = null; AddShroudGeneration(a, ref shrouded); };
self.World.ActorRemoved += RemoveShroudGeneration; self.World.ActorRemoved += RemoveShroudGeneration;
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
shroudEdgeTest = map.Contains; shroudEdgeTest = map.Contains;
isExploredTest = IsExploredCore; isExploredTest = IsExploredCore;
isVisibleTest = IsVisibleCore; isVisibleTest = IsVisibleCore;
@@ -389,22 +385,6 @@ namespace OpenRA.Traits
} }
} }
public bool IsTargetable(Actor a)
{
if (HasFogVisibility())
return true;
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, self.Owner)))
return false;
return GetVisOrigins(a).Any(IsVisible);
}
public bool HasFogVisibility()
{
return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner));
}
public bool Contains(MPos uv) public bool Contains(MPos uv)
{ {
// Check that uv is inside the map area. There is nothing special // Check that uv is inside the map area. There is nothing special

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities
// HACK: This would otherwise break targeting frozen actors // HACK: This would otherwise break targeting frozen actors
// The problem is that Shroud.IsTargetable returns false (as it should) for // The problem is that Shroud.IsTargetable returns false (as it should) for
// frozen actors, but we do want to explicitly target the underlying actor here. // frozen actors, but we do want to explicitly target the underlying actor here.
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.Shroud.IsTargetable(Target.Actor)) if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.CanTargetActor(Target.Actor))
return NextActivity; return NextActivity;
// Try to move within range // Try to move within range

View File

@@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Traits
a.AppearsHostileTo(self) && a.AppearsHostileTo(self) &&
!a.HasTrait<AutoTargetIgnore>() && !a.HasTrait<AutoTargetIgnore>() &&
attack.HasAnyValidWeapons(Target.FromActor(a)) && attack.HasAnyValidWeapons(Target.FromActor(a)) &&
self.Owner.Shroud.IsTargetable(a)) self.Owner.CanTargetActor(a))
.ClosestTo(self); .ClosestTo(self);
} }
} }

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits
public override int GetSelectionShares(Actor collector) public override int GetSelectionShares(Actor collector)
{ {
// don't ever hide the map for people who have GPS. // don't ever hide the map for people who have GPS.
if (collector.Owner.Shroud.HasFogVisibility()) if (collector.Owner.HasFogVisibility)
return 0; return 0;
return base.GetSelectionShares(collector); return base.GetSelectionShares(collector);

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
public void Infiltrated(Actor self, Actor infiltrator) public void Infiltrated(Actor self, Actor infiltrator)
{ {
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud); infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
if (!self.Owner.Shroud.HasFogVisibility()) if (!self.Owner.HasFogVisibility)
self.Owner.Shroud.ResetExploration(); self.Owner.Shroud.ResetExploration();
} }
} }

View File

@@ -137,7 +137,7 @@ namespace OpenRA.Mods.RA.Traits
var targetUnits = power.UnitsInRange(xy).Where(a => !world.FogObscures(a)); var targetUnits = power.UnitsInRange(xy).Where(a => !world.FogObscures(a));
foreach (var unit in targetUnits) foreach (var unit in targetUnits)
if (manager.Self.Owner.Shroud.IsTargetable(unit)) if (manager.Self.Owner.CanTargetActor(unit))
yield return new SelectionBoxRenderable(unit, Color.Red); yield return new SelectionBoxRenderable(unit, Color.Red);
} }
@@ -217,7 +217,7 @@ namespace OpenRA.Mods.RA.Traits
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world) public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
{ {
foreach (var unit in power.UnitsInRange(sourceLocation)) foreach (var unit in power.UnitsInRange(sourceLocation))
if (manager.Self.Owner.Shroud.IsTargetable(unit)) if (manager.Self.Owner.CanTargetActor(unit))
yield return new SelectionBoxRenderable(unit, Color.Red); yield return new SelectionBoxRenderable(unit, Color.Red);
} }
@@ -238,7 +238,7 @@ namespace OpenRA.Mods.RA.Traits
foreach (var unit in power.UnitsInRange(sourceLocation)) foreach (var unit in power.UnitsInRange(sourceLocation))
{ {
var offset = world.Map.CenterOfCell(xy) - world.Map.CenterOfCell(sourceLocation); var offset = world.Map.CenterOfCell(xy) - world.Map.CenterOfCell(sourceLocation);
if (manager.Self.Owner.Shroud.IsTargetable(unit)) if (manager.Self.Owner.CanTargetActor(unit))
foreach (var r in unit.Render(wr)) foreach (var r in unit.Render(wr))
yield return r.OffsetBy(offset); yield return r.OffsetBy(offset);
} }
@@ -246,7 +246,7 @@ namespace OpenRA.Mods.RA.Traits
// Unit tiles // Unit tiles
foreach (var unit in power.UnitsInRange(sourceLocation)) foreach (var unit in power.UnitsInRange(sourceLocation))
{ {
if (manager.Self.Owner.Shroud.IsTargetable(unit)) if (manager.Self.Owner.CanTargetActor(unit))
{ {
var targetCell = unit.Location + (xy - sourceLocation); var targetCell = unit.Location + (xy - sourceLocation);
var canEnter = manager.Self.Owner.Shroud.IsExplored(targetCell) && var canEnter = manager.Self.Owner.Shroud.IsExplored(targetCell) &&