Refactor AutoTarget scan and GPS interaction, and cache trait lookup for a slight performance boost

This commit is contained in:
ScottNZ
2014-06-07 02:05:10 +12:00
parent 5784444720
commit 7e6f7c51e1
10 changed files with 39 additions and 60 deletions

View File

@@ -112,6 +112,8 @@ namespace OpenRA.Traits
}
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
public interface IFogVisibilityModifier { bool HasFogVisibility(Player byPlayer); }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IOccupySpaceInfo { }

View File

@@ -31,6 +31,8 @@ namespace OpenRA.Traits
int[,] generatedShroudCount;
bool[,] explored;
readonly Lazy<IFogVisibilityModifier[]> fogVisibilities;
// Cache of visibility that was added, so no matter what crazy trait code does, it
// can't make us invalid.
Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>();
@@ -57,6 +59,8 @@ namespace OpenRA.Traits
if (!self.World.LobbyInfo.GlobalSettings.Shroud)
ExploredBounds = map.Bounds;
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
}
void Invalidate()
@@ -278,10 +282,18 @@ 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(o => IsVisible(o));
return GetVisOrigins(a).Any(IsVisible);
}
public bool HasFogVisibility()
{
return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner));
}
}
}

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA.Activities
return NextActivity;
// TODO: This is horrible, and probably wrong. Work out what it is trying to solve, then redo it properly.
if (type == TargetType.Actor && !self.Owner.HasFogVisibility() && Target.Actor.HasTrait<Mobile>() && !self.Owner.Shroud.IsTargetable(Target.Actor))
if (type == TargetType.Actor && Target.Actor.HasTrait<Mobile>() && !self.Owner.Shroud.IsTargetable(Target.Actor))
return NextActivity;
if (!Target.IsInRange(self.CenterPosition, Range))

View File

@@ -147,16 +147,6 @@ namespace OpenRA.Mods.RA
nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval);
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range);
if (self.Owner.HasFogVisibility())
{
return inRange
.Where(a => a.AppearsHostileTo(self))
.Where(a => !a.HasTrait<AutoTargetIgnore>())
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
.ClosestTo(self);
}
else
{
return inRange
.Where(a => a.AppearsHostileTo(self))
.Where(a => !a.HasTrait<AutoTargetIgnore>())
@@ -165,7 +155,6 @@ namespace OpenRA.Mods.RA
.ClosestTo(self);
}
}
}
[Desc("Will not get automatically targeted by enemy (like walls)")]
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.RA
public override int GetSelectionShares(Actor collector)
{
// don't ever hide the map for people who have GPS.
if (collector.Owner.HasFogVisibility())
if (collector.Owner.Shroud.HasFogVisibility())
return 0;
return base.GetSelectionShares(collector);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA
{
// Steal and reset the owners exploration
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
if (!self.Owner.HasFogVisibility())
if (!self.Owner.Shroud.HasFogVisibility())
self.Owner.Shroud.ResetExploration();
}
}

View File

@@ -304,7 +304,6 @@
<Compile Include="PortableChrono.cs" />
<Compile Include="World\RadarPings.cs" />
<Compile Include="Player\TechTree.cs" />
<Compile Include="PlayerExts.cs" />
<Compile Include="PrimaryBuilding.cs" />
<Compile Include="Production.cs" />
<Compile Include="ProductionBar.cs" />
@@ -572,10 +571,4 @@ cd "$(SolutionDir)thirdparty/"
copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
cd "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="Scripting\Global\" />
<Folder Include="Scripting\Properties\" />
<Folder Include="Console\" />
</ItemGroup>
</Project>

View File

@@ -1,22 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
namespace OpenRA.Mods.RA
{
public static class PlayerExts
{
public static bool HasFogVisibility( this Player a )
{
var gpsWatcher = a.PlayerActor.TraitOrDefault<GpsWatcher>();
return gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies);
}
}
}

View File

@@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var targetUnits = power.UnitsInRange(xy);
foreach (var unit in targetUnits)
if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility())
if (manager.self.Owner.Shroud.IsTargetable(unit))
wr.DrawSelectionBox(unit, Color.Red);
}
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.RA
public void RenderAfterWorld(WorldRenderer wr, World world)
{
foreach (var unit in power.UnitsInRange(sourceLocation))
if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility())
if (manager.self.Owner.Shroud.IsTargetable(unit))
wr.DrawSelectionBox(unit, Color.Red);
}
@@ -256,8 +256,8 @@ namespace OpenRA.Mods.RA
if (manager.self.Owner.Shroud.IsTargetable(unit))
{
var targetCell = unit.Location + (xy - sourceLocation);
var canEnter = ((manager.self.Owner.Shroud.IsExplored(targetCell) || manager.self.Owner.HasFogVisibility()) &&
unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell));
var canEnter = manager.self.Owner.Shroud.IsExplored(targetCell) &&
unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit, targetCell);
var tile = canEnter ? validTile : invalidTile;
yield return new SpriteRenderable(tile, targetCell.CenterPosition, WVec.Zero, -511, pal, 1f, true);
}

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA
public object Create (ActorInitializer init) { return new GpsWatcher(init.self.Owner); }
}
class GpsWatcher : ISync
class GpsWatcher : ISync, IFogVisibilityModifier
{
[Sync] bool Launched = false;
[Sync] public bool GrantedAllies = false;
@@ -73,6 +73,11 @@ namespace OpenRA.Mods.RA
if (Granted || GrantedAllies)
owner.Shroud.ExploreAll(owner.World);
}
public bool HasFogVisibility(Player byPlayer)
{
return Granted || GrantedAllies;
}
}
class GpsPowerInfo : SupportPowerInfo