diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index a2a956060f..3eea3d1ed0 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -43,6 +43,8 @@ namespace OpenRA return HasLocation.PxPosition; } } + + public Shroud.ActorVisibility Sight; [Sync] public Player Owner; @@ -85,6 +87,16 @@ namespace OpenRA return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2(); }); + if(this.HasTrait()) + { + Sight = new Shroud.ActorVisibility + { + range = this.Trait().RevealRange, + vis = Shroud.GetVisOrigins(this).ToArray() + }; + + } + ApplyIRender = x => x.Render(this); ApplyRenderModifier = (m, p) => p.ModifyRender(this, m); @@ -99,6 +111,11 @@ namespace OpenRA currentActivity = Util.RunActivity( this, currentActivity ); } + + public void UpdateSight() + { + Sight.vis = Shroud.GetVisOrigins(this).ToArray(); + } public bool IsIdle { diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index deb50a8494..38c23a069d 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -139,7 +139,7 @@ namespace OpenRA.Graphics foreach (var t in world.ActorsWithTrait()) { - if (!world.LocalShroud.IsVisible(t.Actor)) + if (!world.RenderedShroud.IsVisible(t.Actor)) continue; var color = t.Trait.RadarSignatureColor(t.Actor); @@ -158,7 +158,7 @@ namespace OpenRA.Graphics var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); - if (world.LocalShroud.Disabled) + if (world.RenderedShroud.Disabled) return bitmap; var bitmapData = bitmap.LockBits(bitmap.Bounds(), @@ -176,9 +176,9 @@ namespace OpenRA.Graphics { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; - if (!world.LocalShroud.IsExplored(mapX, mapY)) + if (!world.RenderedShroud.IsExplored(mapX, mapY)) *(c + (y * bitmapData.Stride >> 2) + x) = shroud; - else if (!world.LocalShroud.IsVisible(mapX,mapY)) + else if (!world.RenderedShroud.IsVisible(mapX,mapY)) *(c + (y * bitmapData.Stride >> 2) + x) = fog; } } diff --git a/OpenRA.Game/Graphics/ShroudRenderer.cs b/OpenRA.Game/Graphics/ShroudRenderer.cs index 24cf83fa8c..4229bf9da9 100644 --- a/OpenRA.Game/Graphics/ShroudRenderer.cs +++ b/OpenRA.Game/Graphics/ShroudRenderer.cs @@ -15,21 +15,25 @@ namespace OpenRA.Graphics { public class ShroudRenderer { - Traits.Shroud shroud; + World world; + Traits.Shroud shroud { + get { + return world.RenderedShroud; + } + } + Sprite[] shadowBits = Game.modData.SpriteLoader.LoadAllSprites("shadow"); Sprite[,] sprites, fogSprites; - bool dirty = true; Map map; public ShroudRenderer(World world) { - this.shroud = world.LocalShroud; + this.world = world; this.map = world.Map; sprites = new Sprite[map.MapSize.X, map.MapSize.Y]; fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y]; - shroud.Dirty += () => dirty = true; } static readonly byte[][] SpecialShroudTiles = @@ -103,9 +107,9 @@ namespace OpenRA.Graphics internal void Draw( WorldRenderer wr ) { - if (dirty) + if (shroud != null && shroud.dirty) { - dirty = false; + shroud.dirty = false; for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) sprites[i, j] = ChooseShroud(i, j); diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 5c33e5110e..573d480cd1 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -72,9 +72,9 @@ namespace OpenRA.Graphics if (firstRow < 0) firstRow = 0; if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height; - if (world.LocalPlayer != null && !world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue) + if (world.RenderedPlayer != null && !world.RenderedShroud.Disabled && world.RenderedShroud.Bounds.HasValue) { - var r = world.LocalShroud.Bounds.Value; + var r = world.RenderedShroud.Bounds.Value; if (firstRow < r.Top - map.Bounds.Top) firstRow = r.Top - map.Bounds.Top; diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 72725616a9..f5881d2e1e 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -202,7 +202,7 @@ namespace OpenRA.Graphics cachedScroll = scrollPosition; } - var b = world.LocalShroud.Bounds; + var b = world.RenderedShroud.Bounds; return (b.HasValue) ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect; } } diff --git a/OpenRA.Game/Network/UnitOrders.cs b/OpenRA.Game/Network/UnitOrders.cs index a7e1d9c730..8f0c4a6bf5 100755 --- a/OpenRA.Game/Network/UnitOrders.cs +++ b/OpenRA.Game/Network/UnitOrders.cs @@ -198,8 +198,7 @@ namespace OpenRA.Network { var oldStance = p.Stances[target]; p.Stances[target] = s; - if (target == w.LocalPlayer) - w.WorldActor.Trait().UpdatePlayerStance(w, p, oldStance, s); + target.Shroud.UpdatePlayerStance(w, p, oldStance, s); foreach (var nsc in w.ActorsWithTrait()) nsc.Trait.StanceChanged(nsc.Actor, p, target, oldStance, s); diff --git a/OpenRA.Game/Player.cs b/OpenRA.Game/Player.cs index 248e451af3..f7163c2c5e 100644 --- a/OpenRA.Game/Player.cs +++ b/OpenRA.Game/Player.cs @@ -36,7 +36,7 @@ namespace OpenRA public readonly PlayerReference PlayerReference; public bool IsBot; - public Shroud Shroud { get { return World.LocalShroud; } } + public Shroud Shroud; public World World { get; private set; } static CountryInfo ChooseCountry(World world, string name) @@ -68,7 +68,7 @@ namespace OpenRA else { // Map player - ClientIndex = 0; // Owned by the host (todo: fix this) + ClientIndex = -1; // Owned by the host (todo: fix this) ColorRamp = pr.ColorRamp; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; @@ -76,7 +76,8 @@ namespace OpenRA Country = ChooseCountry(world, pr.Race); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); - + Shroud = PlayerActor.Trait(); + Shroud.Owner = this; // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Game/Traits/CreatesShroud.cs index 9b0f009add..5f4bfdbb34 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Game/Traits/CreatesShroud.cs @@ -29,8 +29,12 @@ namespace OpenRA.Traits public void Tick(Actor self) { - if (!self.IsDisabled()) - self.World.WorldActor.Trait().HideActor(self, Info.Range); + if (!self.TraitsImplementing().Any(d => d.Disabled)) { + var shrouds = self.World.ActorsWithTrait().Select(s => s.Actor.Owner.Shroud); + foreach (var shroud in shrouds) { + shroud.HideActor(self, Info.Range); + } + } } } } \ No newline at end of file diff --git a/OpenRA.Game/Traits/Player/DeveloperMode.cs b/OpenRA.Game/Traits/Player/DeveloperMode.cs index 7d844842af..446fd6b3cf 100644 --- a/OpenRA.Game/Traits/Player/DeveloperMode.cs +++ b/OpenRA.Game/Traits/Player/DeveloperMode.cs @@ -77,7 +77,7 @@ namespace OpenRA.Traits { DisableShroud ^= true; if (self.World.LocalPlayer == self.Owner) - self.World.LocalShroud.Disabled = DisableShroud; + self.World.RenderedShroud.Disabled = DisableShroud; break; } case "DevPathDebug": @@ -88,7 +88,7 @@ namespace OpenRA.Traits case "DevGiveExploration": { if (self.World.LocalPlayer == self.Owner) - self.World.WorldActor.Trait().ExploreAll(self.World); + self.World.LocalPlayer.Shroud.ExploreAll(self.World); break; } case "DevUnlimitedPower": diff --git a/OpenRA.Game/Traits/RevealsShroud.cs b/OpenRA.Game/Traits/RevealsShroud.cs index 64ab26a019..64408e0ddb 100644 --- a/OpenRA.Game/Traits/RevealsShroud.cs +++ b/OpenRA.Game/Traits/RevealsShroud.cs @@ -29,11 +29,22 @@ namespace OpenRA.Traits public void Tick(Actor self) { // todo: don't tick all the time. - + World w = self.World; + if(self.Owner == null) return; + if (previousLocation != self.Location) { previousLocation = self.Location; - self.World.WorldActor.Trait().UpdateActor(self); + var actors = w.ActorsWithTrait(); + + foreach( var s in actors ) + s.Actor.Owner.Shroud.RemoveActor(self); + + self.UpdateSight(); + + foreach( var s in actors ) + s.Actor.Owner.Shroud.AddActor(self); + } } diff --git a/OpenRA.Game/Traits/SelectionDecorations.cs b/OpenRA.Game/Traits/SelectionDecorations.cs index 9bd07f3415..bd1111957a 100644 --- a/OpenRA.Game/Traits/SelectionDecorations.cs +++ b/OpenRA.Game/Traits/SelectionDecorations.cs @@ -54,7 +54,7 @@ namespace OpenRA.Traits void DrawPips(WorldRenderer wr, Actor self, float2 basePosition) { - if (self.Owner != self.World.LocalPlayer) return; + if (self.Owner != self.World.RenderedPlayer) return; var pipSources = self.TraitsImplementing(); if (pipSources.Count() == 0) @@ -95,7 +95,7 @@ namespace OpenRA.Traits void DrawTags(WorldRenderer wr, Actor self, float2 basePosition) { - if (self.Owner != self.World.LocalPlayer) return; + if (self.Owner != self.World.RenderedPlayer) return; // If a mod wants to implement a unit with multiple tags, then they are placed on multiple rows var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 8143ddcb6b..2380f474b9 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -83,7 +83,7 @@ namespace OpenRA.Traits Color RadarSignatureColor(Actor self); } - public interface IVisibilityModifier { bool IsVisible(Actor self); } + public interface IVisibilityModifier { bool IsVisible(Shroud s, Actor self); } public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } public interface IHasLocation { PPos PxPosition { get; } } @@ -226,7 +226,7 @@ namespace OpenRA.Traits public interface ILintPass { void Run(Action emitError, Action emitWarning); } public interface IObjectivesPanel { string ObjectivesPanel { get; } } - + public static class DisableExts { public static bool IsDisabled(this Actor a) diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index 047bec6d1b..5c1c35ffcf 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -40,7 +40,7 @@ namespace OpenRA.Traits for (int x = clip.Left; x < clip.Right; x++) for (int y = clip.Top; y < clip.Bottom; y++) { - if (!world.LocalShroud.IsExplored(new CPos(x, y))) + if (!world.RenderedShroud.IsExplored(new CPos(x, y))) continue; var c = content[x, y]; diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 9a552aad67..f7401e3d24 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -25,16 +25,23 @@ namespace OpenRA.Traits Map map; World world; + public Player Owner; public int[,] visibleCells; public bool[,] exploredCells; - Rectangle? exploredBounds; + public Rectangle? exploredBounds; bool disabled = false; + public bool dirty = true; public bool Disabled { - get { return disabled || world.LocalPlayer == null; } + get { return disabled; } set { disabled = value; Dirty(); } } + public bool Observing + { + get { return world.IsShellmap || (world.LocalPlayer == null && Owner == null);; } + } + public Rectangle? Bounds { get { return Disabled ? null : exploredBounds; } @@ -42,6 +49,12 @@ namespace OpenRA.Traits public event Action Dirty = () => { }; + public void Jank() + { + Dirty(); + } + + public Shroud(World world) { this.world = world; @@ -50,12 +63,13 @@ namespace OpenRA.Traits exploredCells = new bool[map.MapSize.X, map.MapSize.Y]; world.ActorAdded += AddActor; world.ActorRemoved += RemoveActor; + Dirty += () => dirty = true; } // cache of positions that were added, so no matter what crazy trait code does, it // can't make us invalid. - class ActorVisibility { public int range; public CPos[] vis; } - Dictionary vis = new Dictionary(); + public class ActorVisibility { public int range; public CPos[] vis; } + public Dictionary vis = new Dictionary(); static IEnumerable FindVisibleTiles(World world, CPos a, int r) { @@ -72,25 +86,13 @@ namespace OpenRA.Traits yield return new CPos(i, j); } - void AddActor(Actor a) + public void AddActor(Actor a) { - if (!a.HasTrait()) - return; - - if (a.Owner.World.LocalPlayer == null - || a.Owner.Stances[a.Owner.World.LocalPlayer] != Stance.Ally) return; - - if (vis.ContainsKey(a)) - { - Game.Debug("Warning: Actor {0}:{1} at {2} bad vis".F(a.Info.Name, a.ActorID, a.Location)); - RemoveActor(a); - } - - var v = new ActorVisibility - { - range = a.Trait().RevealRange, - vis = GetVisOrigins(a).ToArray() - }; + if (!a.HasTrait()) return; + if (a.Owner == null || Owner == null) return; + if(a.Owner.Stances[Owner] != Stance.Ally) return; + + ActorVisibility v = a.Sight; if (v.range == 0) return; // don't bother for things that can't see @@ -106,8 +108,6 @@ namespace OpenRA.Traits exploredBounds = (exploredBounds.HasValue) ? Rectangle.Union(exploredBounds.Value, box) : box; } - vis[a] = v; - if (!Disabled) Dirty(); } @@ -129,6 +129,16 @@ namespace OpenRA.Traits if (!Disabled) Dirty(); } + + public void MergeShroud(Shroud s) { + for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) { + for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) { + if (s.exploredCells[i,j] == true) + exploredCells[i, j] = true; + } + exploredBounds = Rectangle.Union(exploredBounds.Value, s.exploredBounds.Value); + } + } public void UpdatePlayerStance(World w, Player player, Stance oldStance, Stance newStance) { @@ -138,7 +148,7 @@ namespace OpenRA.Traits // No longer our ally; remove unit vis if (oldStance == Stance.Ally) { - var toRemove = vis.Select(a => a.Key).Where(a => a.Owner == player).ToList(); + var toRemove = w.Actors.Where(a => a.Owner == player).ToList(); foreach (var a in toRemove) RemoveActor(a); } @@ -147,6 +157,16 @@ namespace OpenRA.Traits foreach (var a in w.Actors.Where( a => a.Owner == player )) AddActor(a); } + + public int Explored() + { + int seen = 0; + for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) + for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) + if(exploredCells[i, j]) seen++; + + return seen; + } public static IEnumerable GetVisOrigins(Actor a) { @@ -160,17 +180,18 @@ namespace OpenRA.Traits return new[] { a.CenterLocation.ToCPos() }; } - void RemoveActor(Actor a) + public void RemoveActor(Actor a) { - ActorVisibility v; - if (!vis.TryGetValue(a, out v)) return; + if (!a.HasTrait())return; + if (a.Owner == null || Owner == null) return; + if(a.Owner.Stances[Owner] != Stance.Ally) return; + + ActorVisibility v = a.Sight; foreach (var p in v.vis) foreach (var q in FindVisibleTiles(a.World, p, v.range)) --visibleCells[q.X, q.Y]; - vis.Remove(a); - if (!Disabled) Dirty(); } @@ -222,7 +243,7 @@ namespace OpenRA.Traits if (!map.IsInMap(x, y)) return false; - if (Disabled) + if (Disabled || Observing) return true; return exploredCells[x,y]; @@ -231,7 +252,7 @@ namespace OpenRA.Traits public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); } public bool IsVisible(int x, int y) { - if (Disabled) + if (Disabled || Observing) return true; // Visibility is allowed to extend beyond the map cordon so that @@ -245,10 +266,20 @@ namespace OpenRA.Traits // Actors are hidden under shroud, but not under fog by default public bool IsVisible(Actor a) { - if (a.TraitsImplementing().Any(t => !t.IsVisible(a))) + // I need to pass in the current shroud, otherwise we're just checking that true==true + if (a.TraitsImplementing().Any(t => !t.IsVisible(this, a))) return false; - return Disabled || a.Owner == a.World.LocalPlayer || GetVisOrigins(a).Any(o => IsExplored(o)); + if(Owner == null) return true; + + return Disabled || Observing || a.Owner.Stances[Owner] == Stance.Ally || GetVisOrigins(a).Any(o => IsExplored(o)); + } + + public bool IsTargetable(Actor a) { + if (a.TraitsImplementing().Any(t => !t.IsVisible(this, a))) + return false; + + return GetVisOrigins(a).Any(o => IsVisible(o)); } } } diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 2022188277..4210d88a76 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -164,7 +164,7 @@ namespace OpenRA.Widgets IEnumerable SelectActorsInBox(World world, PPos a, PPos b, Func cond) { return world.FindUnits(a, b) - .Where( x => x.HasTrait() && world.LocalShroud.IsVisible(x) && cond(x) ) + .Where( x => x.HasTrait() && world.RenderedShroud.IsVisible(x) && cond(x) ) .GroupBy(x => x.GetSelectionPriority()) .OrderByDescending(g => g.Key) .Select( g => g.AsEnumerable() ) diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index e4c6dc4b50..7a29e942c7 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -41,10 +41,29 @@ namespace OpenRA public Player LocalPlayer { get; private set; } public readonly Shroud LocalShroud; + public Player RenderedPlayer; + public Shroud RenderedShroud { + get { + if(RenderedPlayer == null) + { + return LocalShroud; + }else{ + return RenderedPlayer.Shroud; + } + } + } + + public void SetLocalPlayer(string pr) { if (!(orderManager.Connection is ReplayConnection)) - LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); + { + LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); + RenderedPlayer = LocalPlayer; + }else{ + + } + } public readonly Actor WorldActor; @@ -138,6 +157,7 @@ namespace OpenRA a.IsInWorld = false; actors.Remove(a); ActorRemoved(a); + } public void Add(IEffect b) { effects.Add(b); } diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index 8c5c90f72a..ec5ce9559c 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -24,7 +24,7 @@ namespace OpenRA public static IEnumerable FindUnitsAtMouse(this World world, int2 mouseLocation) { var loc = Game.viewport.ViewToWorldPx(mouseLocation); - return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a)); + return FindUnits(world, loc, loc).Where(a => world.RenderedShroud.IsVisible(a)); } public static IEnumerable FindUnits(this World world, PPos a, PPos b) diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index 4768b162d3..cae2b93656 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -54,6 +54,9 @@ namespace OpenRA.Mods.RA.Activities if (!Target.IsValid) return NextActivity; + + if (!self.Owner.HasFogVisibility() && Target.Actor != null && Target.Actor.HasTrait() && !self.Owner.Shroud.IsTargetable(Target.Actor)) + return NextActivity; if (targetable != null && !targetable.TargetableBy(Target.Actor, self)) return NextActivity; diff --git a/OpenRA.Mods.RA/Attack/AttackTesla.cs b/OpenRA.Mods.RA/Attack/AttackTesla.cs index 77f7bba267..b0978e4d06 100644 --- a/OpenRA.Mods.RA/Attack/AttackTesla.cs +++ b/OpenRA.Mods.RA/Attack/AttackTesla.cs @@ -50,6 +50,7 @@ namespace OpenRA.Mods.RA { return new TeslaAttack( newTarget ); } + public override void ResolveOrder(Actor self, Order order) { diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 1504fe0d09..4725eeb837 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -111,11 +111,21 @@ namespace OpenRA.Mods.RA var inRange = self.World.FindUnitsInCircle(self.CenterLocation, (int)(Game.CellSize * range)); - return inRange - .Where(a => a.AppearsHostileTo(self)) - .Where(a => !a.HasTrait()) - .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) - .ClosestTo( self.CenterLocation ); + if (self.Owner.HasFogVisibility()) { + return inRange + .Where(a => a.AppearsHostileTo(self)) + .Where(a => !a.HasTrait()) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) + .ClosestTo( self.CenterLocation ); + } + else { + return inRange + .Where(a => a.AppearsHostileTo(self)) + .Where(a => !a.HasTrait()) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) + .Where(a => self.Owner.Shroud.IsTargetable(a)) + .ClosestTo( self.CenterLocation ); + } } } diff --git a/OpenRA.Mods.RA/Buildings/BibLayer.cs b/OpenRA.Mods.RA/Buildings/BibLayer.cs index e89f6db34d..efa1d48742 100755 --- a/OpenRA.Mods.RA/Buildings/BibLayer.cs +++ b/OpenRA.Mods.RA/Buildings/BibLayer.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA.Buildings { if (!cliprect.Contains(kv.Key.X, kv.Key.Y)) continue; - if (!world.LocalShroud.IsExplored(kv.Key)) + if (!world.RenderedShroud.IsExplored(kv.Key)) continue; bibSprites[kv.Value.type - 1][kv.Value.index].DrawAt(wr, kv.Key.ToPPos().ToFloat2(), "terrain"); diff --git a/OpenRA.Mods.RA/ChronoshiftDeploy.cs b/OpenRA.Mods.RA/ChronoshiftDeploy.cs index 102e90cf3c..23352e00a0 100644 --- a/OpenRA.Mods.RA/ChronoshiftDeploy.cs +++ b/OpenRA.Mods.RA/ChronoshiftDeploy.cs @@ -97,7 +97,7 @@ namespace OpenRA.Mods.RA if (chargeTick <= 0 // Can jump && (self.Location - xy).Length <= Info.JumpDistance // Within jump range && movement.CanEnterCell(xy) // Can enter cell - && (ignoreVis || self.World.LocalShroud.IsExplored(xy))) // Not in shroud + && (ignoreVis || self.Owner.Shroud.IsExplored(xy))) // Not in shroud return true; else return false; diff --git a/OpenRA.Mods.RA/Chronoshiftable.cs b/OpenRA.Mods.RA/Chronoshiftable.cs index 9cb43f8406..88670890e9 100755 --- a/OpenRA.Mods.RA/Chronoshiftable.cs +++ b/OpenRA.Mods.RA/Chronoshiftable.cs @@ -44,12 +44,10 @@ namespace OpenRA.Mods.RA } // Can't be used in synced code, except with ignoreVis. - public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation, bool ignoreVis) + public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation) { // Todo: Allow enemy units to be chronoshifted into bad terrain to kill them - return self.HasTrait() && - self.Trait().CanEnterCell(targetLocation) && - (ignoreVis || self.World.LocalShroud.IsExplored(targetLocation)); + return (self.HasTrait() && self.Trait().CanEnterCell(targetLocation)); } public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere) diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index e60f1107a8..e4924828d3 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -92,14 +92,27 @@ namespace OpenRA.Mods.RA lastPos = self.Location; } } - + public bool IsVisible(Actor self) { - if (!Cloaked || self.Owner == self.World.LocalPlayer || - self.World.LocalPlayer == null || - self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally) - return true; + return IsVisible(null, self); + } + public bool IsVisible(Shroud s, Actor self) + { + if (self.World.LocalPlayer != null) { + if (s == null) { + if (!Cloaked || self.Owner == self.World.LocalPlayer || + self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally) + return true; + } + else { + if (!Cloaked || self.Owner == s.Owner || + self.Owner.Stances[s.Owner] == Stance.Ally) + return true; + } + } + return self.World.ActorsWithTrait().Any(a => a.Actor.Owner.Stances[self.Owner] != Stance.Ally && (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get().Range); diff --git a/OpenRA.Mods.RA/ConquestVictoryConditions.cs b/OpenRA.Mods.RA/ConquestVictoryConditions.cs index 173f162aae..94675e9198 100644 --- a/OpenRA.Mods.RA/ConquestVictoryConditions.cs +++ b/OpenRA.Mods.RA/ConquestVictoryConditions.cs @@ -62,7 +62,7 @@ namespace OpenRA.Mods.RA if (self.Owner == self.World.LocalPlayer) { - self.World.LocalShroud.Disabled = true; + self.World.RenderedShroud.Disabled = true; Game.RunAfterDelay(Info.NotificationDelay, () => { if (Game.IsCurrentWorld(self.World)) @@ -79,7 +79,7 @@ namespace OpenRA.Mods.RA Game.Debug("{0} is victorious.".F(self.Owner.PlayerName)); if (self.Owner == self.World.LocalPlayer) { - self.World.LocalShroud.Disabled = true; + self.World.RenderedShroud.Disabled = true; Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.Owner, "Speech", "Win", self.Owner.Country.Race)); } } diff --git a/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs b/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs index 430ac22b7f..08fae19d0c 100644 --- a/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs @@ -25,8 +25,7 @@ namespace OpenRA.Mods.RA public override int GetSelectionShares (Actor collector) { // don't ever hide the map for people who have GPS. - var gpsWatcher = collector.Owner.PlayerActor.TraitOrDefault(); - if (gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies)) + if (collector.Owner.HasFogVisibility()) return 0; return base.GetSelectionShares (collector); @@ -36,7 +35,7 @@ namespace OpenRA.Mods.RA { base.Activate(collector); if (collector.Owner == collector.World.LocalPlayer) - collector.World.WorldActor.Trait().ResetExploration(); + collector.Owner.Shroud.ResetExploration(); } } } diff --git a/OpenRA.Mods.RA/Crates/RevealMapCrateAction.cs b/OpenRA.Mods.RA/Crates/RevealMapCrateAction.cs index 7b678f706b..3e099ffd9f 100644 --- a/OpenRA.Mods.RA/Crates/RevealMapCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/RevealMapCrateAction.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA base.Activate(collector); if (ShouldReveal( collector.Owner )) - collector.World.WorldActor.Trait().ExploreAll(collector.World); + collector.Owner.Shroud.ExploreAll(collector.World); } } } diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index 48f839e43b..dffa8b47bd 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -153,7 +153,7 @@ namespace OpenRA.Mods.RA.Effects var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at); var pos = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at) - new float2(0, altitude); - if (Args.firedBy.World.LocalShroud.IsVisible(((PPos) pos.ToInt2()).ToCPos())) + if (Args.firedBy.World.RenderedShroud.IsVisible(((PPos) pos.ToInt2()).ToCPos())) { if (Info.High || Info.Angle > 0) { diff --git a/OpenRA.Mods.RA/Effects/Contrail.cs b/OpenRA.Mods.RA/Effects/Contrail.cs index c59f30d5df..170da8bdc3 100755 --- a/OpenRA.Mods.RA/Effects/Contrail.cs +++ b/OpenRA.Mods.RA/Effects/Contrail.cs @@ -91,8 +91,8 @@ namespace OpenRA.Mods.RA var conPos = positions[i]; var nextPos = positions[i - 1]; - if (self.World.LocalShroud.IsVisible(conPos.ToCPos()) || - self.World.LocalShroud.IsVisible(nextPos.ToCPos())) + if (self.World.RenderedShroud.IsVisible(conPos.ToCPos()) || + self.World.RenderedShroud.IsVisible(nextPos.ToCPos())) { Game.Renderer.WorldLineRenderer.DrawLine(conPos.ToFloat2(), nextPos.ToFloat2(), trailStart, trailEnd); diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index 062f42ae41..21f1413628 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Effects if ( self.IsInWorld && (watcher.Granted || watcher.GrantedAllies) - && !self.Trait().IsVisible(self) + && !self.Trait().IsVisible(self.World.RenderedShroud, self) // WRONG && (!self.HasTrait() || !self.Trait().Cloaked) && (!self.HasTrait() || !self.Trait().Disguised) ) diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 4f307933b9..f6e84ae683 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -154,7 +154,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render() { - if (Args.firedBy.World.LocalShroud.IsVisible(PxPosition.ToCPos())) + if (Args.firedBy.World.RenderedShroud.IsVisible(PxPosition.ToCPos())) yield return new Renderable(anim.Image, PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude), Args.weapon.Underwater ? "shadow" : "effect", PxPosition.Y); diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index 06ee171ba2..da5a7ec35d 100644 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -428,7 +428,7 @@ namespace OpenRA.Mods.RA public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor) { // Don't leak info about resources under the shroud - if (!self.World.LocalShroud.IsExplored(location)) return false; + if (!self.Owner.Shroud.IsExplored(location)) return false; var res = self.World.WorldActor.Trait().GetResource(location); var info = self.Info.Traits.Get(); diff --git a/OpenRA.Mods.RA/InfiltrateForExploration.cs b/OpenRA.Mods.RA/InfiltrateForExploration.cs index d0ccefbe66..736d1a21aa 100644 --- a/OpenRA.Mods.RA/InfiltrateForExploration.cs +++ b/OpenRA.Mods.RA/InfiltrateForExploration.cs @@ -20,18 +20,9 @@ namespace OpenRA.Mods.RA { public void OnInfiltrate(Actor self, Actor spy) { - /* todo: changes for per-player shrouds: - * - apply this everywhere, not just on the victim's client - * - actually steal their exploration before resetting it - */ - if (self.World.LocalPlayer != null && self.World.LocalPlayer.Stances[self.Owner] == Stance.Ally) - { - var gpsWatcher = self.Owner.PlayerActor.TraitOrDefault(); - if (gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies)) - return; - - self.Owner.Shroud.ResetExploration(); - } + spy.Owner.Shroud.MergeShroud(self.Owner.Shroud); + if (!self.Owner.HasFogVisibility()) + self.Owner.Shroud.ResetExploration(); } } } diff --git a/OpenRA.Mods.RA/InvisibleToEnemy.cs b/OpenRA.Mods.RA/InvisibleToEnemy.cs index 1988677e3a..e3ff497308 100644 --- a/OpenRA.Mods.RA/InvisibleToEnemy.cs +++ b/OpenRA.Mods.RA/InvisibleToEnemy.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA class InvisibleToEnemy : IRenderModifier, IVisibilityModifier, IRadarColorModifier { - public bool IsVisible(Actor self) + public bool IsVisible(Shroud s, Actor self) { return self.World.LocalPlayer == null || self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally; @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA public IEnumerable ModifyRender(Actor self, IEnumerable r) { - return IsVisible(self) ? r : Nothing; + return IsVisible(self.Owner.Shroud, self) ? r : Nothing; } } } diff --git a/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs index 7fb35e0b2f..9354c46672 100644 --- a/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs @@ -18,15 +18,15 @@ namespace OpenRA.Mods.RA class FrozenUnderFog : IRenderModifier, IVisibilityModifier { - public bool IsVisible(Actor self) + public bool IsVisible(Shroud s, Actor self) { - return Shroud.GetVisOrigins(self).Any(o => self.World.LocalShroud.IsVisible(o)); + return Shroud.GetVisOrigins(self).Any(o => s.IsVisible(o)); } Renderable[] cache = { }; public IEnumerable ModifyRender(Actor self, IEnumerable r) { - if (IsVisible(self)) + if (IsVisible(self.World.RenderedShroud, self)) cache = r.ToArray(); return cache; } diff --git a/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs b/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs index 15a898671f..865cf7effb 100644 --- a/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs +++ b/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs @@ -18,15 +18,15 @@ namespace OpenRA.Mods.RA class HiddenUnderFog : IRenderModifier, IVisibilityModifier { - public bool IsVisible(Actor self) + public bool IsVisible(Shroud s, Actor self) { - return Shroud.GetVisOrigins(self).Any(o => self.World.LocalShroud.IsVisible(o)); + return Shroud.GetVisOrigins(self).Any(o => s.IsVisible(o)); } static Renderable[] Nothing = { }; public IEnumerable ModifyRender(Actor self, IEnumerable r) { - return IsVisible(self) ? r : Nothing; + return IsVisible(self.World.RenderedShroud, self) ? r : Nothing; } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index fd52a7a85e..9c41d37d09 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -276,6 +276,7 @@ + diff --git a/OpenRA.Mods.RA/PlayerExts.cs b/OpenRA.Mods.RA/PlayerExts.cs new file mode 100644 index 0000000000..7f46c26d6c --- /dev/null +++ b/OpenRA.Mods.RA/PlayerExts.cs @@ -0,0 +1,25 @@ +#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 + +using System; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public static class PlayerExts + { + public static bool HasFogVisibility( this Player a ) + { + var gpsWatcher = a.PlayerActor.TraitOrDefault(); + return gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies); + } + + } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/ProductionBar.cs b/OpenRA.Mods.RA/ProductionBar.cs index a678598c3c..6ca0ebf768 100644 --- a/OpenRA.Mods.RA/ProductionBar.cs +++ b/OpenRA.Mods.RA/ProductionBar.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA public float GetValue() { // only people we like should see our production status. - if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] != Stance.Ally) + if (self.World.RenderedPlayer != null && self.Owner.Stances[self.World.RenderedPlayer] != Stance.Ally) return 0; var queue = self.TraitsImplementing().FirstOrDefault(q => q.CurrentItem() != null); diff --git a/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs b/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs index 47ddcf1818..b6f031c858 100644 --- a/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs +++ b/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs @@ -25,7 +25,7 @@ namespace OpenRA.Scripting var target = kv.First; var targetCell = kv.Second; var cs = target.Trait(); - if (cs.CanChronoshiftTo(target, targetCell, true)) + if (chronosphere.Owner.Shroud.IsExplored(targetCell) && cs.CanChronoshiftTo(target, targetCell)) cs.Teleport(target, targetCell, duration, killCargo,chronosphere); } } diff --git a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs index 58f48a8e82..df6ac6f6bb 100644 --- a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs +++ b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.RA var altitude = new PVecInt(0, move.Altitude); position = (self.CenterLocation - Combat.GetTurretPosition(self, facing, smokeTurret)); - if (self.World.LocalShroud.IsVisible(position.ToCPos())) + if (self.World.RenderedShroud.IsVisible(position.ToCPos())) self.World.AddFrameEndTask( w => w.Add(new Smoke(w, position - altitude, "smokey"))); } diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index 38b0486994..2700551d8f 100755 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -45,9 +45,8 @@ namespace OpenRA.Mods.RA var targetCell = target.Location + (order.TargetLocation - order.ExtraLocation); var cpi = Info as ChronoshiftPowerInfo; - if (cs.CanChronoshiftTo(target, targetCell, true)) - cs.Teleport(target, targetCell, - cpi.Duration * 25, cpi.KillCargo, self); + if (self.Owner.Shroud.IsExplored(targetCell) && cs.CanChronoshiftTo(target, targetCell)) + cs.Teleport(target, targetCell, cpi.Duration * 25, cpi.KillCargo, self); } } @@ -61,6 +60,48 @@ namespace OpenRA.Mods.RA return units.Distinct().Where(a => a.HasTrait()); } + + + public bool SimilarTerrain(CPos xy, CPos sourceLocation) { + + if (!self.Owner.Shroud.IsExplored(xy)) + return false; + + int range = (Info as ChronoshiftPowerInfo).Range; + var sourceTiles = self.World.FindTilesInCircle(xy, range); + var destTiles = self.World.FindTilesInCircle(sourceLocation, range); + List sourceTerrain = new List(); + List destTerrain = new List(); + + int j = 0; + foreach (var t in sourceTiles) { + j = j + 1; + if (!self.Owner.Shroud.IsExplored(t)) + return false; + sourceTerrain.Add(self.World.GetTerrainType( t )); + } + j = 0; + foreach (var t in destTiles) { + j = j + 1; + if (!self.Owner.Shroud.IsExplored(t)) { + return false; + } + self.World.GetTerrainType( t ); + destTerrain.Add(self.World.GetTerrainType( t )); + } + + // HACK but I don't want to write a comparison function + if (sourceTerrain.Count != destTerrain.Count) + return false; + + for (int i = 0; i < sourceTerrain.Count; i++) { + if (!sourceTerrain[i].Equals(destTerrain[i])) + return false; + } + + return true; + } + class SelectTarget : IOrderGenerator { @@ -99,8 +140,11 @@ namespace OpenRA.Mods.RA { var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos); var targetUnits = power.UnitsInRange(xy); - foreach (var unit in targetUnits) - wr.DrawSelectionBox(unit, Color.Red); + foreach (var unit in targetUnits) { + if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility()) { + wr.DrawSelectionBox(unit, Color.Red); + } + } } public void RenderBeforeWorld(WorldRenderer wr, World world) @@ -175,8 +219,11 @@ namespace OpenRA.Mods.RA public void RenderAfterWorld(WorldRenderer wr, World world) { - foreach (var unit in power.UnitsInRange(sourceLocation)) - wr.DrawSelectionBox(unit, Color.Red); + foreach (var unit in power.UnitsInRange(sourceLocation)) { + if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility()) { + wr.DrawSelectionBox(unit, Color.Red); + } + } } public void RenderBeforeWorld(WorldRenderer wr, World world) @@ -194,20 +241,24 @@ namespace OpenRA.Mods.RA // Unit previews foreach (var unit in power.UnitsInRange(sourceLocation)) { - var targetCell = unit.Location + (xy - sourceLocation); - foreach (var r in unit.Render()) - r.Sprite.DrawAt(r.Pos - Traits.Util.CenterOfCell(unit.Location).ToFloat2() + Traits.Util.CenterOfCell(targetCell).ToFloat2(), - wr.GetPaletteIndex(r.Palette), - r.Scale*r.Sprite.size); + if (manager.self.Owner.Shroud.IsTargetable(unit)) { + var targetCell = unit.Location + (xy - sourceLocation); + foreach (var r in unit.Render()) + r.Sprite.DrawAt(r.Pos - Traits.Util.CenterOfCell(unit.Location).ToFloat2() + Traits.Util.CenterOfCell(targetCell).ToFloat2(), + wr.GetPaletteIndex(r.Palette), + r.Scale*r.Sprite.size); + } } // Unit tiles foreach (var unit in power.UnitsInRange(sourceLocation)) { - var targetCell = unit.Location + (xy - sourceLocation); - var canEnter = unit.Trait().CanChronoshiftTo(unit,targetCell, false); - var tile = canEnter ? validTile : invalidTile; - tile.DrawAt( wr, targetCell.ToPPos().ToFloat2(), "terrain" ); + 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().CanChronoshiftTo(unit,targetCell)); + var tile = canEnter ? validTile : invalidTile; + tile.DrawAt( wr, targetCell.ToPPos().ToFloat2(), "terrain" ); + } } } @@ -217,12 +268,18 @@ namespace OpenRA.Mods.RA foreach (var unit in power.UnitsInRange(sourceLocation)) { var targetCell = unit.Location + (xy - sourceLocation); - if (unit.Trait().CanChronoshiftTo(unit,targetCell, false)) + if (manager.self.Owner.Shroud.IsExplored(targetCell) && unit.Trait().CanChronoshiftTo(unit,targetCell)) { canTeleport = true; break; } } + if (!canTeleport) { + // Check the terrain types. This will allow chronoshifts to occur on empty terrain to terrain of + // a similar type. This also keeps the cursor from changing in non-visible property, alerting the + // chronoshifter of enemy unit presence + canTeleport = power.SimilarTerrain(sourceLocation,xy); + } return canTeleport; } diff --git a/OpenRA.Mods.RA/SupportPowers/GpsPower.cs b/OpenRA.Mods.RA/SupportPowers/GpsPower.cs index 6131919390..7b8bf92112 100755 --- a/OpenRA.Mods.RA/SupportPowers/GpsPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/GpsPower.cs @@ -58,15 +58,12 @@ namespace OpenRA.Mods.RA public void RefreshGps(Actor atek) { RefreshGranted(); - + foreach (TraitPair i in atek.World.ActorsWithTrait()) i.Trait.RefreshGranted(); - if (atek.World.LocalPlayer == null) - return; - - if ((Granted || GrantedAllies) && (atek.World.LocalPlayer.Stances[atek.Owner] == Stance.Ally)) - atek.World.WorldActor.Trait().ExploreAll(atek.World); + if ((Granted || GrantedAllies) && atek.World.LocalPlayer != null && (atek.World.LocalPlayer.Stances[atek.Owner] == Stance.Ally)) + atek.Owner.Shroud.ExploreAll(atek.World); } void RefreshGranted() @@ -74,6 +71,9 @@ namespace OpenRA.Mods.RA Granted = (actors.Count > 0 && Launched); GrantedAllies = owner.World.ActorsWithTrait().Any(p => p.Actor.Owner.Stances[owner] == Stance.Ally && p.Trait.Granted); + + if (Granted || GrantedAllies) + owner.Shroud.ExploreAll(owner.World); } } diff --git a/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs index f282115141..d6b91090a8 100755 --- a/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs +++ b/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs @@ -131,32 +131,38 @@ namespace OpenRA.Mods.RA Key = key; } + static bool InstanceDisabled(SupportPower sp) + { + return sp.self.TraitsImplementing().Any(d => d.Disabled); + } + bool notifiedCharging; bool notifiedReady; - public void Tick() { Active = !Disabled && Instances.Any(i => !i.self.IsDisabled()); if (!Active) return; - if (Manager.devMode.FastCharge && RemainingTime > 25) - RemainingTime = 25; - - if (RemainingTime > 0) --RemainingTime; - - var power = Instances.First(); - - if (!notifiedCharging) + if (Active) { - power.Charging(power.self, Key); - notifiedCharging = true; - } + var power = Instances.First(); + if (Manager.devMode.FastCharge && RemainingTime > 25) + RemainingTime = 25; - if (RemainingTime == 0 && !notifiedReady) - { - power.Charged(power.self, Key); - notifiedReady = true; + if (RemainingTime > 0) --RemainingTime; + if (!notifiedCharging) + { + power.Charging(power.self, Key); + notifiedCharging = true; + } + + if (RemainingTime == 0 + && !notifiedReady) + { + power.Charged(power.self, Key); + notifiedReady = true; + } } } @@ -173,7 +179,7 @@ namespace OpenRA.Mods.RA if (!Ready) return; - var power = Instances.First(i => !i.self.IsDisabled()); + var power = Instances.First(i => !InstanceDisabled(i)); // Note: order.Subject is the *player* actor power.Activate(power.self, order); diff --git a/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs b/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs index 82a62ec147..b81810dbe1 100755 --- a/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs +++ b/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Widgets var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos); if (!world.Map.IsInMap(cell)) return; - if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(cell)) + if (world.LocalPlayer != null && !world.RenderedShroud.IsExplored(cell)) { var utext = "Unexplored Terrain"; var usz = Game.Renderer.Fonts["Bold"].Measure(utext) + new int2(20, 24); diff --git a/OpenRA.Mods.RA/World/SmudgeLayer.cs b/OpenRA.Mods.RA/World/SmudgeLayer.cs index 9dce0ce445..440560d7c6 100755 --- a/OpenRA.Mods.RA/World/SmudgeLayer.cs +++ b/OpenRA.Mods.RA/World/SmudgeLayer.cs @@ -83,7 +83,7 @@ namespace OpenRA.Mods.RA { if (!cliprect.Contains(kv.Key.X,kv.Key.Y)) continue; - if (localPlayer != null && !localPlayer.Shroud.IsExplored(kv.Key)) + if (localPlayer != null && !world.RenderedShroud.IsExplored(kv.Key)) continue; smudgeSprites[kv.Value.type- 1][kv.Value.index].DrawAt(wr, kv.Key.ToPPos().ToFloat2(), "terrain"); diff --git a/mods/d2k/bits/TURRET1.aud b/mods/d2k/bits/TURRET1.aud index 74266f6ad0..7b89d0ca4e 100644 Binary files a/mods/d2k/bits/TURRET1.aud and b/mods/d2k/bits/TURRET1.aud differ diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 4ebf91f352..5b51cd4c91 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -188,6 +188,7 @@ Player: DebugResourceOre: DebugResourceOreCapacity: GpsWatcher: + Shroud: BaseAttackNotifier: World: