Merge pull request #8479 from pchote/merge-shroud-traits
Move more shroud logic to RevealsShroud / GeneratesShroud
This commit is contained in:
@@ -169,7 +169,6 @@
|
||||
<Compile Include="Sync.cs" />
|
||||
<Compile Include="TraitDictionary.cs" />
|
||||
<Compile Include="Traits\Armor.cs" />
|
||||
<Compile Include="Traits\CreatesShroud.cs" />
|
||||
<Compile Include="Traits\DrawLineToTarget.cs" />
|
||||
<Compile Include="Traits\EditorTilesetFilter.cs" />
|
||||
<Compile Include="Traits\Health.cs" />
|
||||
@@ -177,7 +176,6 @@
|
||||
<Compile Include="Traits\RejectsOrders.cs" />
|
||||
<Compile Include="Traits\Player\DeveloperMode.cs" />
|
||||
<Compile Include="Traits\Player\PlayerResources.cs" />
|
||||
<Compile Include="Traits\RevealsShroud.cs" />
|
||||
<Compile Include="Traits\Selectable.cs" />
|
||||
<Compile Include="Traits\Target.cs" />
|
||||
<Compile Include="Traits\TraitsInterfaces.cs" />
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class CreatesShroudInfo : ITraitInfo
|
||||
{
|
||||
public readonly WRange Range = WRange.Zero;
|
||||
|
||||
public object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); }
|
||||
}
|
||||
|
||||
public class CreatesShroud : ITick, ISync
|
||||
{
|
||||
readonly CreatesShroudInfo info;
|
||||
readonly bool lobbyShroudFogDisabled;
|
||||
[Sync] CPos cachedLocation;
|
||||
[Sync] bool cachedDisabled;
|
||||
|
||||
public CreatesShroud(Actor self, CreatesShroudInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (lobbyShroudFogDisabled)
|
||||
return;
|
||||
|
||||
var disabled = self.IsDisabled();
|
||||
if (cachedLocation != self.Location || cachedDisabled != disabled)
|
||||
{
|
||||
cachedLocation = self.Location;
|
||||
cachedDisabled = disabled;
|
||||
Shroud.UpdateShroudGeneration(self.World.Players.Select(p => p.Shroud), self);
|
||||
}
|
||||
}
|
||||
|
||||
public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class RevealsShroudInfo : ITraitInfo
|
||||
{
|
||||
public readonly WRange Range = WRange.Zero;
|
||||
|
||||
public object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); }
|
||||
}
|
||||
|
||||
public class RevealsShroud : ITick, ISync
|
||||
{
|
||||
readonly RevealsShroudInfo info;
|
||||
readonly bool lobbyShroudFogDisabled;
|
||||
[Sync] CPos cachedLocation;
|
||||
|
||||
public RevealsShroud(Actor self, RevealsShroudInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (lobbyShroudFogDisabled)
|
||||
return;
|
||||
|
||||
if (cachedLocation != self.Location)
|
||||
{
|
||||
cachedLocation = self.Location;
|
||||
Shroud.UpdateVisibility(self.World.Players.Select(p => p.Shroud), self);
|
||||
}
|
||||
}
|
||||
|
||||
public WRange Range { get { return info.Range; } }
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,6 @@ namespace OpenRA.Traits
|
||||
generatedShroudCount = new CellLayer<short>(map);
|
||||
explored = new CellLayer<bool>(map);
|
||||
|
||||
self.World.ActorAdded += a => { CPos[] visible = null; AddVisibility(a, ref visible); };
|
||||
self.World.ActorRemoved += RemoveVisibility;
|
||||
|
||||
self.World.ActorAdded += a => { CPos[] shrouded = null; AddShroudGeneration(a, ref shrouded); };
|
||||
self.World.ActorRemoved += RemoveShroudGeneration;
|
||||
|
||||
shroudEdgeTest = map.Contains;
|
||||
isExploredTest = IsExploredCore;
|
||||
isVisibleTest = IsVisibleCore;
|
||||
@@ -78,46 +72,27 @@ namespace OpenRA.Traits
|
||||
Hash += 1;
|
||||
}
|
||||
|
||||
public static void UpdateVisibility(IEnumerable<Shroud> shrouds, Actor actor)
|
||||
public static IEnumerable<CPos> CellsInRange(Map map, WPos pos, WRange range)
|
||||
{
|
||||
CPos[] visbility = null;
|
||||
foreach (var shroud in shrouds)
|
||||
shroud.UpdateVisibility(actor, ref visbility);
|
||||
var r = (range.Range + 1023) / 1024;
|
||||
var limit = range.RangeSquared;
|
||||
var cell = map.CellContaining(pos);
|
||||
|
||||
foreach (var c in map.FindTilesInCircle(cell, r, true))
|
||||
if ((map.CenterOfCell(c) - pos).HorizontalLengthSquared <= limit)
|
||||
yield return c;
|
||||
}
|
||||
|
||||
public static void UpdateShroudGeneration(IEnumerable<Shroud> shrouds, Actor actor)
|
||||
public static IEnumerable<CPos> CellsInRange(Map map, CPos cell, WRange range)
|
||||
{
|
||||
CPos[] shrouded = null;
|
||||
foreach (var shroud in shrouds)
|
||||
shroud.UpdateShroudGeneration(actor, ref shrouded);
|
||||
return CellsInRange(map, map.CenterOfCell(cell), range);
|
||||
}
|
||||
|
||||
static CPos[] FindVisibleTiles(Actor actor, WRange range)
|
||||
public void AddVisibility(Actor a, CPos[] visible)
|
||||
{
|
||||
return GetVisOrigins(actor).SelectMany(o => FindVisibleTiles(actor.World, o, range)).Distinct().ToArray();
|
||||
}
|
||||
|
||||
static IEnumerable<CPos> FindVisibleTiles(World world, CPos position, WRange radius)
|
||||
{
|
||||
var map = world.Map;
|
||||
var r = (radius.Range + 1023) / 1024;
|
||||
var limit = radius.RangeSquared;
|
||||
var pos = map.CenterOfCell(position);
|
||||
|
||||
foreach (var cell in map.FindTilesInCircle(position, r, true))
|
||||
if ((map.CenterOfCell(cell) - pos).HorizontalLengthSquared <= limit)
|
||||
yield return cell;
|
||||
}
|
||||
|
||||
void AddVisibility(Actor a, ref CPos[] visible)
|
||||
{
|
||||
var rs = a.TraitOrDefault<RevealsShroud>();
|
||||
if (rs == null || !a.Owner.IsAlliedWith(self.Owner) || rs.Range == WRange.Zero)
|
||||
if (!a.Owner.IsAlliedWith(self.Owner))
|
||||
return;
|
||||
|
||||
// Lazily generate the visible tiles, allowing the caller to re-use them if desired.
|
||||
visible = visible ?? FindVisibleTiles(a, rs.Range);
|
||||
|
||||
foreach (var c in visible)
|
||||
{
|
||||
var uv = c.ToMPos(map);
|
||||
@@ -137,7 +112,7 @@ namespace OpenRA.Traits
|
||||
Invalidate(visible);
|
||||
}
|
||||
|
||||
void RemoveVisibility(Actor a)
|
||||
public void RemoveVisibility(Actor a)
|
||||
{
|
||||
CPos[] visible;
|
||||
if (!visibility.TryGetValue(a, out visible))
|
||||
@@ -154,25 +129,11 @@ namespace OpenRA.Traits
|
||||
Invalidate(visible);
|
||||
}
|
||||
|
||||
void UpdateVisibility(Actor a, ref CPos[] visible)
|
||||
public void AddShroudGeneration(Actor a, CPos[] shrouded)
|
||||
{
|
||||
// Actors outside the world don't have any vis
|
||||
if (!a.IsInWorld)
|
||||
if (a.Owner.IsAlliedWith(self.Owner))
|
||||
return;
|
||||
|
||||
RemoveVisibility(a);
|
||||
AddVisibility(a, ref visible);
|
||||
}
|
||||
|
||||
void AddShroudGeneration(Actor a, ref CPos[] shrouded)
|
||||
{
|
||||
var cs = a.TraitOrDefault<CreatesShroud>();
|
||||
if (cs == null || a.Owner.IsAlliedWith(self.Owner) || cs.Range == WRange.Zero)
|
||||
return;
|
||||
|
||||
// Lazily generate the shrouded tiles, allowing the caller to re-use them if desired.
|
||||
shrouded = shrouded ?? FindVisibleTiles(a, cs.Range);
|
||||
|
||||
foreach (var c in shrouded)
|
||||
generatedShroudCount[c]++;
|
||||
|
||||
@@ -183,7 +144,7 @@ namespace OpenRA.Traits
|
||||
Invalidate(shrouded);
|
||||
}
|
||||
|
||||
void RemoveShroudGeneration(Actor a)
|
||||
public void RemoveShroudGeneration(Actor a)
|
||||
{
|
||||
CPos[] shrouded;
|
||||
if (!generation.TryGetValue(a, out shrouded))
|
||||
@@ -196,12 +157,6 @@ namespace OpenRA.Traits
|
||||
Invalidate(shrouded);
|
||||
}
|
||||
|
||||
void UpdateShroudGeneration(Actor a, ref CPos[] shrouded)
|
||||
{
|
||||
RemoveShroudGeneration(a);
|
||||
AddShroudGeneration(a, ref shrouded);
|
||||
}
|
||||
|
||||
public void UpdatePlayerStance(World w, Player player, Stance oldStance, Stance newStance)
|
||||
{
|
||||
if (oldStance == newStance)
|
||||
@@ -210,12 +165,26 @@ namespace OpenRA.Traits
|
||||
foreach (var a in w.Actors.Where(a => a.Owner == player))
|
||||
{
|
||||
CPos[] visible = null;
|
||||
UpdateVisibility(a, ref visible);
|
||||
CPos[] shrouded = null;
|
||||
UpdateShroudGeneration(a, ref shrouded);
|
||||
foreach (var p in self.World.Players)
|
||||
{
|
||||
if (p.Shroud.visibility.TryGetValue(self, out visible))
|
||||
{
|
||||
p.Shroud.RemoveVisibility(self);
|
||||
p.Shroud.AddVisibility(self, visible);
|
||||
}
|
||||
|
||||
if (p.Shroud.generation.TryGetValue(self, out shrouded))
|
||||
{
|
||||
p.Shroud.RemoveShroudGeneration(self);
|
||||
p.Shroud.AddShroudGeneration(self, shrouded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Actor vis will be split into separate cases for
|
||||
// "cells that I reveal from" and "cells that reveal me"
|
||||
public static IEnumerable<CPos> GetVisOrigins(Actor a)
|
||||
{
|
||||
var ios = a.OccupiesSpace;
|
||||
@@ -229,10 +198,10 @@ namespace OpenRA.Traits
|
||||
return new[] { a.World.Map.CellContaining(a.CenterPosition) };
|
||||
}
|
||||
|
||||
public void Explore(World world, CPos center, WRange range)
|
||||
public void Explore(World world, IEnumerable<CPos> cells)
|
||||
{
|
||||
var changed = new List<CPos>();
|
||||
foreach (var c in FindVisibleTiles(world, center, range))
|
||||
var changed = new HashSet<CPos>();
|
||||
foreach (var c in cells)
|
||||
{
|
||||
if (!explored[c])
|
||||
{
|
||||
|
||||
@@ -681,6 +681,8 @@
|
||||
<Compile Include="Traits\Modifiers\HiddenUnderShroud.cs" />
|
||||
<Compile Include="Lint\CheckDefaultVisibility.cs" />
|
||||
<Compile Include="Traits\Modifiers\AlwaysVisible.cs" />
|
||||
<Compile Include="Traits\CreatesShroud.cs" />
|
||||
<Compile Include="Traits\RevealsShroud.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
||||
28
OpenRA.Mods.Common/Traits/CreatesShroud.cs
Normal file
28
OpenRA.Mods.Common/Traits/CreatesShroud.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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.Common.Traits
|
||||
{
|
||||
public class CreatesShroudInfo : RevealsShroudInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); }
|
||||
}
|
||||
|
||||
public class CreatesShroud : RevealsShroud
|
||||
{
|
||||
public CreatesShroud(Actor self, CreatesShroudInfo info)
|
||||
: base(self, info)
|
||||
{
|
||||
addCellsToPlayerShroud = (p, c) => p.Shroud.AddShroudGeneration(self, c);
|
||||
removeCellsFromPlayerShroud = p => p.Shroud.RemoveShroudGeneration(self);
|
||||
isDisabled = () => self.IsDisabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
98
OpenRA.Mods.Common/Traits/RevealsShroud.cs
Normal file
98
OpenRA.Mods.Common/Traits/RevealsShroud.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class RevealsShroudInfo : ITraitInfo
|
||||
{
|
||||
public readonly WRange Range = WRange.Zero;
|
||||
|
||||
public virtual object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); }
|
||||
}
|
||||
|
||||
public class RevealsShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
|
||||
{
|
||||
static readonly CPos[] NoCells = { };
|
||||
|
||||
readonly RevealsShroudInfo info;
|
||||
readonly bool lobbyShroudFogDisabled;
|
||||
[Sync] CPos cachedLocation;
|
||||
[Sync] bool cachedDisabled;
|
||||
|
||||
protected Action<Player, CPos[]> addCellsToPlayerShroud;
|
||||
protected Action<Player> removeCellsFromPlayerShroud;
|
||||
protected Func<bool> isDisabled;
|
||||
|
||||
public RevealsShroud(Actor self, RevealsShroudInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog;
|
||||
|
||||
addCellsToPlayerShroud = (p, c) => p.Shroud.AddVisibility(self, c);
|
||||
removeCellsFromPlayerShroud = p => p.Shroud.RemoveVisibility(self);
|
||||
isDisabled = () => false;
|
||||
}
|
||||
|
||||
CPos[] Cells(Actor self)
|
||||
{
|
||||
var map = self.World.Map;
|
||||
var range = Range;
|
||||
if (range == WRange.Zero)
|
||||
return NoCells;
|
||||
|
||||
return Shroud.GetVisOrigins(self)
|
||||
.SelectMany(c => Shroud.CellsInRange(map, c, range))
|
||||
.Distinct().ToArray();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (lobbyShroudFogDisabled || !self.IsInWorld)
|
||||
return;
|
||||
|
||||
var location = self.Location;
|
||||
var disabled = isDisabled();
|
||||
if (cachedLocation == location && cachedDisabled == disabled)
|
||||
return;
|
||||
|
||||
cachedLocation = location;
|
||||
cachedDisabled = disabled;
|
||||
|
||||
var cells = Cells(self);
|
||||
foreach (var p in self.World.Players)
|
||||
{
|
||||
removeCellsFromPlayerShroud(p);
|
||||
addCellsToPlayerShroud(p, cells);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
cachedLocation = self.Location;
|
||||
cachedDisabled = isDisabled();
|
||||
|
||||
var cells = Cells(self);
|
||||
foreach (var p in self.World.Players)
|
||||
addCellsToPlayerShroud(p, cells);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
foreach (var p in self.World.Players)
|
||||
removeCellsFromPlayerShroud(p);
|
||||
}
|
||||
|
||||
public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } }
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,23 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class MPStartLocationsInfo : TraitInfo<MPStartLocations>
|
||||
public class MPStartLocationsInfo : ITraitInfo
|
||||
{
|
||||
public readonly WRange InitialExploreRange = WRange.FromCells(5);
|
||||
|
||||
public virtual object Create(ActorInitializer init) { return new MPStartLocations(this); }
|
||||
}
|
||||
|
||||
public class MPStartLocations : IWorldLoaded
|
||||
{
|
||||
public Dictionary<Player, CPos> Start = new Dictionary<Player, CPos>();
|
||||
readonly MPStartLocationsInfo info;
|
||||
|
||||
public readonly Dictionary<Player, CPos> Start = new Dictionary<Player, CPos>();
|
||||
|
||||
public MPStartLocations(MPStartLocationsInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void WorldLoaded(World world, WorldRenderer wr)
|
||||
{
|
||||
@@ -52,15 +61,18 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
// Explore allied shroud
|
||||
var explore = world.WorldActor.Info.Traits.Get<MPStartLocationsInfo>().InitialExploreRange;
|
||||
var map = world.Map;
|
||||
foreach (var p in Start.Keys)
|
||||
{
|
||||
var cells = Shroud.CellsInRange(map, Start[p], info.InitialExploreRange);
|
||||
foreach (var q in world.Players)
|
||||
if (p.IsAlliedWith(q))
|
||||
q.Shroud.Explore(world, Start[p], explore);
|
||||
q.Shroud.Explore(world, cells);
|
||||
}
|
||||
|
||||
// Set viewport
|
||||
if (world.LocalPlayer != null && Start.ContainsKey(world.LocalPlayer))
|
||||
wr.Viewport.Center(world.Map.CenterOfCell(Start[world.LocalPlayer]));
|
||||
wr.Viewport.Center(map.CenterOfCell(Start[world.LocalPlayer]));
|
||||
}
|
||||
|
||||
static Player FindPlayerInSlot(World world, string pr)
|
||||
|
||||
Reference in New Issue
Block a user