Refactor AutoTarget scan and GPS interaction, and cache trait lookup for a slight performance boost
This commit is contained in:
@@ -112,6 +112,8 @@ namespace OpenRA.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
|
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 IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||||
|
|
||||||
public interface IOccupySpaceInfo { }
|
public interface IOccupySpaceInfo { }
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ namespace OpenRA.Traits
|
|||||||
int[,] generatedShroudCount;
|
int[,] generatedShroudCount;
|
||||||
bool[,] explored;
|
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.
|
||||||
Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>();
|
Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>();
|
||||||
@@ -57,6 +59,8 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
if (!self.World.LobbyInfo.GlobalSettings.Shroud)
|
if (!self.World.LobbyInfo.GlobalSettings.Shroud)
|
||||||
ExploredBounds = map.Bounds;
|
ExploredBounds = map.Bounds;
|
||||||
|
|
||||||
|
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Invalidate()
|
void Invalidate()
|
||||||
@@ -278,10 +282,18 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool IsTargetable(Actor a)
|
public bool IsTargetable(Actor a)
|
||||||
{
|
{
|
||||||
|
if (HasFogVisibility())
|
||||||
|
return true;
|
||||||
|
|
||||||
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, self.Owner)))
|
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, self.Owner)))
|
||||||
return false;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
// TODO: This is horrible, and probably wrong. Work out what it is trying to solve, then redo it properly.
|
// 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;
|
return NextActivity;
|
||||||
|
|
||||||
if (!Target.IsInRange(self.CenterPosition, Range))
|
if (!Target.IsInRange(self.CenterPosition, Range))
|
||||||
|
|||||||
@@ -147,16 +147,6 @@ namespace OpenRA.Mods.RA
|
|||||||
nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval);
|
nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval);
|
||||||
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range);
|
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
|
return inRange
|
||||||
.Where(a => a.AppearsHostileTo(self))
|
.Where(a => a.AppearsHostileTo(self))
|
||||||
.Where(a => !a.HasTrait<AutoTargetIgnore>())
|
.Where(a => !a.HasTrait<AutoTargetIgnore>())
|
||||||
@@ -165,7 +155,6 @@ namespace OpenRA.Mods.RA
|
|||||||
.ClosestTo(self);
|
.ClosestTo(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Desc("Will not get automatically targeted by enemy (like walls)")]
|
[Desc("Will not get automatically targeted by enemy (like walls)")]
|
||||||
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
|
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#region Copyright & License Information
|
#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
|
* 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
|
* available to you under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation. For more information,
|
* as published by the Free Software Foundation. For more information,
|
||||||
@@ -18,15 +18,15 @@ namespace OpenRA.Mods.RA
|
|||||||
class HideMapCrateAction : CrateAction
|
class HideMapCrateAction : CrateAction
|
||||||
{
|
{
|
||||||
public HideMapCrateAction(Actor self, HideMapCrateActionInfo info)
|
public HideMapCrateAction(Actor self, HideMapCrateActionInfo info)
|
||||||
: base(self, info) {}
|
: base(self, info) { }
|
||||||
|
|
||||||
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.HasFogVisibility())
|
if (collector.Owner.Shroud.HasFogVisibility())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return base.GetSelectionShares (collector);
|
return base.GetSelectionShares(collector);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Activate(Actor collector)
|
public override void Activate(Actor collector)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#region Copyright & License Information
|
#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
|
* 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
|
* available to you under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation. For more information,
|
* as published by the Free Software Foundation. For more information,
|
||||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
// Steal and reset the owners exploration
|
// Steal and reset the owners exploration
|
||||||
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
|
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
|
||||||
if (!self.Owner.HasFogVisibility())
|
if (!self.Owner.Shroud.HasFogVisibility())
|
||||||
self.Owner.Shroud.ResetExploration();
|
self.Owner.Shroud.ResetExploration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,7 +304,6 @@
|
|||||||
<Compile Include="PortableChrono.cs" />
|
<Compile Include="PortableChrono.cs" />
|
||||||
<Compile Include="World\RadarPings.cs" />
|
<Compile Include="World\RadarPings.cs" />
|
||||||
<Compile Include="Player\TechTree.cs" />
|
<Compile Include="Player\TechTree.cs" />
|
||||||
<Compile Include="PlayerExts.cs" />
|
|
||||||
<Compile Include="PrimaryBuilding.cs" />
|
<Compile Include="PrimaryBuilding.cs" />
|
||||||
<Compile Include="Production.cs" />
|
<Compile Include="Production.cs" />
|
||||||
<Compile Include="ProductionBar.cs" />
|
<Compile Include="ProductionBar.cs" />
|
||||||
@@ -572,10 +571,4 @@ cd "$(SolutionDir)thirdparty/"
|
|||||||
copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
|
copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
|
||||||
cd "$(SolutionDir)"</PostBuildEvent>
|
cd "$(SolutionDir)"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Scripting\Global\" />
|
|
||||||
<Folder Include="Scripting\Properties\" />
|
|
||||||
<Folder Include="Console\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA
|
|||||||
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
|
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
|
||||||
var targetUnits = power.UnitsInRange(xy);
|
var targetUnits = power.UnitsInRange(xy);
|
||||||
foreach (var unit in targetUnits)
|
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);
|
wr.DrawSelectionBox(unit, Color.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.RA
|
|||||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
public void 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) || manager.self.Owner.HasFogVisibility())
|
if (manager.self.Owner.Shroud.IsTargetable(unit))
|
||||||
wr.DrawSelectionBox(unit, Color.Red);
|
wr.DrawSelectionBox(unit, Color.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,8 +256,8 @@ namespace OpenRA.Mods.RA
|
|||||||
if (manager.self.Owner.Shroud.IsTargetable(unit))
|
if (manager.self.Owner.Shroud.IsTargetable(unit))
|
||||||
{
|
{
|
||||||
var targetCell = unit.Location + (xy - sourceLocation);
|
var targetCell = unit.Location + (xy - sourceLocation);
|
||||||
var canEnter = ((manager.self.Owner.Shroud.IsExplored(targetCell) || manager.self.Owner.HasFogVisibility()) &&
|
var canEnter = manager.self.Owner.Shroud.IsExplored(targetCell) &&
|
||||||
unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit,targetCell));
|
unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit, targetCell);
|
||||||
var tile = canEnter ? validTile : invalidTile;
|
var tile = canEnter ? validTile : invalidTile;
|
||||||
yield return new SpriteRenderable(tile, targetCell.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
yield return new SpriteRenderable(tile, targetCell.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA
|
|||||||
public object Create (ActorInitializer init) { return new GpsWatcher(init.self.Owner); }
|
public object Create (ActorInitializer init) { return new GpsWatcher(init.self.Owner); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class GpsWatcher : ISync
|
class GpsWatcher : ISync, IFogVisibilityModifier
|
||||||
{
|
{
|
||||||
[Sync] bool Launched = false;
|
[Sync] bool Launched = false;
|
||||||
[Sync] public bool GrantedAllies = false;
|
[Sync] public bool GrantedAllies = false;
|
||||||
@@ -73,6 +73,11 @@ namespace OpenRA.Mods.RA
|
|||||||
if (Granted || GrantedAllies)
|
if (Granted || GrantedAllies)
|
||||||
owner.Shroud.ExploreAll(owner.World);
|
owner.Shroud.ExploreAll(owner.World);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasFogVisibility(Player byPlayer)
|
||||||
|
{
|
||||||
|
return Granted || GrantedAllies;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GpsPowerInfo : SupportPowerInfo
|
class GpsPowerInfo : SupportPowerInfo
|
||||||
|
|||||||
Reference in New Issue
Block a user