From b5550102dbee9c4d73cca021c8c8d187ec25568e Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Jun 2015 19:46:33 +0100 Subject: [PATCH 1/5] Move world state tracking to Creates/RevealsShroud. --- OpenRA.Game/Traits/CreatesShroud.cs | 23 +++++++++++-- OpenRA.Game/Traits/RevealsShroud.cs | 23 +++++++++++-- OpenRA.Game/Traits/World/Shroud.cs | 53 ++++++----------------------- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Game/Traits/CreatesShroud.cs index 2b6a28b5fc..8d087251c4 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Game/Traits/CreatesShroud.cs @@ -19,7 +19,7 @@ namespace OpenRA.Traits public object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); } } - public class CreatesShroud : ITick, ISync + public class CreatesShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld { readonly CreatesShroudInfo info; readonly bool lobbyShroudFogDisabled; @@ -42,10 +42,29 @@ namespace OpenRA.Traits { cachedLocation = self.Location; cachedDisabled = disabled; - Shroud.UpdateShroudGeneration(self.World.Players.Select(p => p.Shroud), self); + + CPos[] shrouded = null; + foreach (var p in self.World.Players) + { + p.Shroud.RemoveShroudGeneration(self); + p.Shroud.AddShroudGeneration(self, ref shrouded); + } } } + public void AddedToWorld(Actor self) + { + CPos[] shrouded = null; + foreach (var p in self.World.Players) + p.Shroud.AddShroudGeneration(self, ref shrouded); + } + + public void RemovedFromWorld(Actor self) + { + foreach (var p in self.World.Players) + p.Shroud.RemoveShroudGeneration(self); + } + public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } } } \ No newline at end of file diff --git a/OpenRA.Game/Traits/RevealsShroud.cs b/OpenRA.Game/Traits/RevealsShroud.cs index cea05d54f4..adb1dc459f 100644 --- a/OpenRA.Game/Traits/RevealsShroud.cs +++ b/OpenRA.Game/Traits/RevealsShroud.cs @@ -19,7 +19,7 @@ namespace OpenRA.Traits public object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); } } - public class RevealsShroud : ITick, ISync + public class RevealsShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld { readonly RevealsShroudInfo info; readonly bool lobbyShroudFogDisabled; @@ -39,10 +39,29 @@ namespace OpenRA.Traits if (cachedLocation != self.Location) { cachedLocation = self.Location; - Shroud.UpdateVisibility(self.World.Players.Select(p => p.Shroud), self); + + CPos[] visible = null; + foreach (var p in self.World.Players) + { + p.Shroud.RemoveVisibility(self); + p.Shroud.AddVisibility(self, ref visible); + } } } + public void AddedToWorld(Actor self) + { + CPos[] visible = null; + foreach (var p in self.World.Players) + p.Shroud.AddVisibility(self, ref visible); + } + + public void RemovedFromWorld(Actor self) + { + foreach (var p in self.World.Players) + p.Shroud.RemoveVisibility(self); + } + public WRange Range { get { return info.Range; } } } } diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index ad8a58a5b3..462f8d39fa 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -54,12 +54,6 @@ namespace OpenRA.Traits generatedShroudCount = new CellLayer(map); explored = new CellLayer(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,20 +72,6 @@ namespace OpenRA.Traits Hash += 1; } - public static void UpdateVisibility(IEnumerable shrouds, Actor actor) - { - CPos[] visbility = null; - foreach (var shroud in shrouds) - shroud.UpdateVisibility(actor, ref visbility); - } - - public static void UpdateShroudGeneration(IEnumerable shrouds, Actor actor) - { - CPos[] shrouded = null; - foreach (var shroud in shrouds) - shroud.UpdateShroudGeneration(actor, ref shrouded); - } - static CPos[] FindVisibleTiles(Actor actor, WRange range) { return GetVisOrigins(actor).SelectMany(o => FindVisibleTiles(actor.World, o, range)).Distinct().ToArray(); @@ -109,7 +89,7 @@ namespace OpenRA.Traits yield return cell; } - void AddVisibility(Actor a, ref CPos[] visible) + public void AddVisibility(Actor a, ref CPos[] visible) { var rs = a.TraitOrDefault(); if (rs == null || !a.Owner.IsAlliedWith(self.Owner) || rs.Range == WRange.Zero) @@ -137,7 +117,7 @@ namespace OpenRA.Traits Invalidate(visible); } - void RemoveVisibility(Actor a) + public void RemoveVisibility(Actor a) { CPos[] visible; if (!visibility.TryGetValue(a, out visible)) @@ -154,17 +134,7 @@ namespace OpenRA.Traits Invalidate(visible); } - void UpdateVisibility(Actor a, ref CPos[] visible) - { - // Actors outside the world don't have any vis - if (!a.IsInWorld) - return; - - RemoveVisibility(a); - AddVisibility(a, ref visible); - } - - void AddShroudGeneration(Actor a, ref CPos[] shrouded) + public void AddShroudGeneration(Actor a, ref CPos[] shrouded) { var cs = a.TraitOrDefault(); if (cs == null || a.Owner.IsAlliedWith(self.Owner) || cs.Range == WRange.Zero) @@ -183,7 +153,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 +166,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,9 +174,14 @@ 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) + { + p.Shroud.RemoveVisibility(self); + p.Shroud.AddVisibility(self, ref visible); + p.Shroud.RemoveShroudGeneration(self); + p.Shroud.AddShroudGeneration(self, ref shrouded); + } } } From 10716f89792b9c8ff347282ce5bc34f1a0b3748d Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Jun 2015 19:54:23 +0100 Subject: [PATCH 2/5] Move shrouded/revealed tile calculation outside Shroud. --- OpenRA.Game/Traits/CreatesShroud.cs | 15 +++++++++---- OpenRA.Game/Traits/RevealsShroud.cs | 15 +++++++++---- OpenRA.Game/Traits/World/Shroud.cs | 33 ++++++++++++++--------------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Game/Traits/CreatesShroud.cs index 8d087251c4..c5729fad33 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Game/Traits/CreatesShroud.cs @@ -32,6 +32,13 @@ namespace OpenRA.Traits lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog; } + CPos[] ShroudedTiles(Actor self) + { + return Shroud.GetVisOrigins(self) + .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, Range)) + .Distinct().ToArray(); + } + public void Tick(Actor self) { if (lobbyShroudFogDisabled) @@ -43,20 +50,20 @@ namespace OpenRA.Traits cachedLocation = self.Location; cachedDisabled = disabled; - CPos[] shrouded = null; + var shrouded = ShroudedTiles(self); foreach (var p in self.World.Players) { p.Shroud.RemoveShroudGeneration(self); - p.Shroud.AddShroudGeneration(self, ref shrouded); + p.Shroud.AddShroudGeneration(self, shrouded); } } } public void AddedToWorld(Actor self) { - CPos[] shrouded = null; + var shrouded = ShroudedTiles(self); foreach (var p in self.World.Players) - p.Shroud.AddShroudGeneration(self, ref shrouded); + p.Shroud.AddShroudGeneration(self, shrouded); } public void RemovedFromWorld(Actor self) diff --git a/OpenRA.Game/Traits/RevealsShroud.cs b/OpenRA.Game/Traits/RevealsShroud.cs index adb1dc459f..f10bbedb10 100644 --- a/OpenRA.Game/Traits/RevealsShroud.cs +++ b/OpenRA.Game/Traits/RevealsShroud.cs @@ -31,6 +31,13 @@ namespace OpenRA.Traits lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog; } + CPos[] VisibleTiles(Actor self) + { + return Shroud.GetVisOrigins(self) + .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, Range)) + .Distinct().ToArray(); + } + public void Tick(Actor self) { if (lobbyShroudFogDisabled) @@ -40,20 +47,20 @@ namespace OpenRA.Traits { cachedLocation = self.Location; - CPos[] visible = null; + var visible = VisibleTiles(self); foreach (var p in self.World.Players) { p.Shroud.RemoveVisibility(self); - p.Shroud.AddVisibility(self, ref visible); + p.Shroud.AddVisibility(self, visible); } } } public void AddedToWorld(Actor self) { - CPos[] visible = null; + var visible = VisibleTiles(self); foreach (var p in self.World.Players) - p.Shroud.AddVisibility(self, ref visible); + p.Shroud.AddVisibility(self, visible); } public void RemovedFromWorld(Actor self) diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 462f8d39fa..4ced59c1ca 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -77,7 +77,7 @@ namespace OpenRA.Traits return GetVisOrigins(actor).SelectMany(o => FindVisibleTiles(actor.World, o, range)).Distinct().ToArray(); } - static IEnumerable FindVisibleTiles(World world, CPos position, WRange radius) + public static IEnumerable FindVisibleTiles(World world, CPos position, WRange radius) { var map = world.Map; var r = (radius.Range + 1023) / 1024; @@ -89,15 +89,11 @@ namespace OpenRA.Traits yield return cell; } - public void AddVisibility(Actor a, ref CPos[] visible) + public void AddVisibility(Actor a, CPos[] visible) { - var rs = a.TraitOrDefault(); - 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); @@ -134,15 +130,11 @@ namespace OpenRA.Traits Invalidate(visible); } - public void AddShroudGeneration(Actor a, ref CPos[] shrouded) + public void AddShroudGeneration(Actor a, CPos[] shrouded) { - var cs = a.TraitOrDefault(); - if (cs == null || a.Owner.IsAlliedWith(self.Owner) || cs.Range == WRange.Zero) + if (a.Owner.IsAlliedWith(self.Owner)) 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]++; @@ -177,10 +169,17 @@ namespace OpenRA.Traits CPos[] shrouded = null; foreach (var p in self.World.Players) { - p.Shroud.RemoveVisibility(self); - p.Shroud.AddVisibility(self, ref visible); - p.Shroud.RemoveShroudGeneration(self); - p.Shroud.AddShroudGeneration(self, ref shrouded); + 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); + } } } } From 2c3198dc27f87488b9dd12a726dcd383ad626a01 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 14 Jun 2015 14:07:15 +0100 Subject: [PATCH 3/5] Move shroud traits to Mods.Common. --- OpenRA.Game/OpenRA.Game.csproj | 2 -- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 2 ++ {OpenRA.Game => OpenRA.Mods.Common}/Traits/CreatesShroud.cs | 4 +--- {OpenRA.Game => OpenRA.Mods.Common}/Traits/RevealsShroud.cs | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) rename {OpenRA.Game => OpenRA.Mods.Common}/Traits/CreatesShroud.cs (97%) rename {OpenRA.Game => OpenRA.Mods.Common}/Traits/RevealsShroud.cs (96%) diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index fa6d6941db..ca101ce3fc 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -169,7 +169,6 @@ - @@ -177,7 +176,6 @@ - diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 7ddbb3a6a0..bfd03510a5 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -681,6 +681,8 @@ + + diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Mods.Common/Traits/CreatesShroud.cs similarity index 97% rename from OpenRA.Game/Traits/CreatesShroud.cs rename to OpenRA.Mods.Common/Traits/CreatesShroud.cs index c5729fad33..fd93d5bdaf 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Mods.Common/Traits/CreatesShroud.cs @@ -8,9 +8,7 @@ */ #endregion -using System.Linq; - -namespace OpenRA.Traits +namespace OpenRA.Mods.Common.Traits { public class CreatesShroudInfo : ITraitInfo { diff --git a/OpenRA.Game/Traits/RevealsShroud.cs b/OpenRA.Mods.Common/Traits/RevealsShroud.cs similarity index 96% rename from OpenRA.Game/Traits/RevealsShroud.cs rename to OpenRA.Mods.Common/Traits/RevealsShroud.cs index f10bbedb10..fab4058db6 100644 --- a/OpenRA.Game/Traits/RevealsShroud.cs +++ b/OpenRA.Mods.Common/Traits/RevealsShroud.cs @@ -9,8 +9,9 @@ #endregion using System.Linq; +using OpenRA.Traits; -namespace OpenRA.Traits +namespace OpenRA.Mods.Common.Traits { public class RevealsShroudInfo : ITraitInfo { From 01dc7edbe92090360ed10f899d4b80001e95d13d Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Jun 2015 19:36:19 +0100 Subject: [PATCH 4/5] Remove duplication between CreatesShroud and RevealsShroud. --- OpenRA.Mods.Common/Traits/CreatesShroud.cs | 61 +++------------------- OpenRA.Mods.Common/Traits/RevealsShroud.cs | 56 ++++++++++++++------ 2 files changed, 46 insertions(+), 71 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/CreatesShroud.cs b/OpenRA.Mods.Common/Traits/CreatesShroud.cs index fd93d5bdaf..862a599175 100644 --- a/OpenRA.Mods.Common/Traits/CreatesShroud.cs +++ b/OpenRA.Mods.Common/Traits/CreatesShroud.cs @@ -10,66 +10,19 @@ namespace OpenRA.Mods.Common.Traits { - public class CreatesShroudInfo : ITraitInfo + public class CreatesShroudInfo : RevealsShroudInfo { - public readonly WRange Range = WRange.Zero; - - public object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); } + public override object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); } } - public class CreatesShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld + public class CreatesShroud : RevealsShroud { - readonly CreatesShroudInfo info; - readonly bool lobbyShroudFogDisabled; - [Sync] CPos cachedLocation; - [Sync] bool cachedDisabled; - public CreatesShroud(Actor self, CreatesShroudInfo info) + : base(self, info) { - this.info = info; - lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog; + addCellsToPlayerShroud = (p, c) => p.Shroud.AddShroudGeneration(self, c); + removeCellsFromPlayerShroud = p => p.Shroud.RemoveShroudGeneration(self); + isDisabled = () => self.IsDisabled(); } - - CPos[] ShroudedTiles(Actor self) - { - return Shroud.GetVisOrigins(self) - .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, Range)) - .Distinct().ToArray(); - } - - public void Tick(Actor self) - { - if (lobbyShroudFogDisabled) - return; - - var disabled = self.IsDisabled(); - if (cachedLocation != self.Location || cachedDisabled != disabled) - { - cachedLocation = self.Location; - cachedDisabled = disabled; - - var shrouded = ShroudedTiles(self); - foreach (var p in self.World.Players) - { - p.Shroud.RemoveShroudGeneration(self); - p.Shroud.AddShroudGeneration(self, shrouded); - } - } - } - - public void AddedToWorld(Actor self) - { - var shrouded = ShroudedTiles(self); - foreach (var p in self.World.Players) - p.Shroud.AddShroudGeneration(self, shrouded); - } - - public void RemovedFromWorld(Actor self) - { - foreach (var p in self.World.Players) - p.Shroud.RemoveShroudGeneration(self); - } - - public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/RevealsShroud.cs b/OpenRA.Mods.Common/Traits/RevealsShroud.cs index fab4058db6..d51a22c533 100644 --- a/OpenRA.Mods.Common/Traits/RevealsShroud.cs +++ b/OpenRA.Mods.Common/Traits/RevealsShroud.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Linq; using OpenRA.Traits; @@ -17,59 +18,80 @@ namespace OpenRA.Mods.Common.Traits { public readonly WRange Range = WRange.Zero; - public object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); } + 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 addCellsToPlayerShroud; + protected Action removeCellsFromPlayerShroud; + protected Func 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[] VisibleTiles(Actor self) + CPos[] Cells(Actor self) { + var range = Range; + if (range == WRange.Zero) + return NoCells; + return Shroud.GetVisOrigins(self) - .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, Range)) + .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, range)) .Distinct().ToArray(); } public void Tick(Actor self) { - if (lobbyShroudFogDisabled) + if (lobbyShroudFogDisabled || !self.IsInWorld) return; - if (cachedLocation != self.Location) - { - cachedLocation = self.Location; + var location = self.Location; + var disabled = isDisabled(); + if (cachedLocation == location && cachedDisabled == disabled) + return; - var visible = VisibleTiles(self); - foreach (var p in self.World.Players) - { - p.Shroud.RemoveVisibility(self); - p.Shroud.AddVisibility(self, visible); - } + 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) { - var visible = VisibleTiles(self); + cachedLocation = self.Location; + cachedDisabled = isDisabled(); + + var cells = Cells(self); foreach (var p in self.World.Players) - p.Shroud.AddVisibility(self, visible); + addCellsToPlayerShroud(p, cells); } public void RemovedFromWorld(Actor self) { foreach (var p in self.World.Players) - p.Shroud.RemoveVisibility(self); + removeCellsFromPlayerShroud(p); } - public WRange Range { get { return info.Range; } } + public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } } } From 7d8ee64ce5d964884fe8f215e20f2754edf58135 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Jun 2015 20:53:39 +0100 Subject: [PATCH 5/5] Reorganize shroud cell queries. This is in preparation for a future PR that will remove GetVisOrigins. --- OpenRA.Game/Traits/World/Shroud.cs | 29 ++++++++++--------- OpenRA.Mods.Common/Traits/RevealsShroud.cs | 3 +- .../Traits/World/MPStartLocations.cs | 22 ++++++++++---- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 4ced59c1ca..473a1731b4 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -72,21 +72,20 @@ namespace OpenRA.Traits Hash += 1; } - static CPos[] FindVisibleTiles(Actor actor, WRange range) + public static IEnumerable CellsInRange(Map map, WPos pos, WRange range) { - return GetVisOrigins(actor).SelectMany(o => FindVisibleTiles(actor.World, o, range)).Distinct().ToArray(); + 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 IEnumerable FindVisibleTiles(World world, CPos position, WRange radius) + public static IEnumerable CellsInRange(Map map, CPos cell, WRange range) { - 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; + return CellsInRange(map, map.CenterOfCell(cell), range); } public void AddVisibility(Actor a, CPos[] visible) @@ -184,6 +183,8 @@ namespace OpenRA.Traits } } + // TODO: Actor vis will be split into separate cases for + // "cells that I reveal from" and "cells that reveal me" public static IEnumerable GetVisOrigins(Actor a) { var ios = a.OccupiesSpace; @@ -197,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 cells) { - var changed = new List(); - foreach (var c in FindVisibleTiles(world, center, range)) + var changed = new HashSet(); + foreach (var c in cells) { if (!explored[c]) { diff --git a/OpenRA.Mods.Common/Traits/RevealsShroud.cs b/OpenRA.Mods.Common/Traits/RevealsShroud.cs index d51a22c533..0c5ba61cf0 100644 --- a/OpenRA.Mods.Common/Traits/RevealsShroud.cs +++ b/OpenRA.Mods.Common/Traits/RevealsShroud.cs @@ -46,12 +46,13 @@ namespace OpenRA.Mods.Common.Traits CPos[] Cells(Actor self) { + var map = self.World.Map; var range = Range; if (range == WRange.Zero) return NoCells; return Shroud.GetVisOrigins(self) - .SelectMany(o => Shroud.FindVisibleTiles(self.World, o, range)) + .SelectMany(c => Shroud.CellsInRange(map, c, range)) .Distinct().ToArray(); } diff --git a/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs b/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs index db50067aae..3cd90e25ad 100644 --- a/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs +++ b/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs @@ -17,14 +17,23 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class MPStartLocationsInfo : TraitInfo + 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 Start = new Dictionary(); + readonly MPStartLocationsInfo info; + + public readonly Dictionary Start = new Dictionary(); + + 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().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)