diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index 9305dbf739..2e9179aeb6 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -27,6 +27,7 @@ namespace OpenRA public bool? Crates; public bool? Fog; public bool? Shroud; + public bool? AllyBuildRadius; public bool? FragileAlliances; public bool ConfigurableStartingUnits = true; public string[] Difficulties = { }; @@ -41,6 +42,8 @@ namespace OpenRA settings.Fog = Fog.Value; if (Shroud.HasValue) settings.Shroud = Shroud.Value; + if (AllyBuildRadius.HasValue) + settings.AllyBuildRadius = AllyBuildRadius.Value; if (FragileAlliances.HasValue) settings.FragileAlliances = FragileAlliances.Value; } diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 32c9df85a2..6c6483239a 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -94,6 +94,7 @@ namespace OpenRA.Network public bool Crates = true; public bool Shroud = true; public bool Fog = true; + public bool AllyBuildRadius = true; public string StartingUnitsClass = "none"; public bool AllowVersionMismatch; } diff --git a/OpenRA.Mods.RA/Buildings/BaseProvider.cs b/OpenRA.Mods.RA/Buildings/BaseProvider.cs index 880a3b0089..e0f6fdc284 100755 --- a/OpenRA.Mods.RA/Buildings/BaseProvider.cs +++ b/OpenRA.Mods.RA/Buildings/BaseProvider.cs @@ -56,11 +56,17 @@ namespace OpenRA.Mods.RA.Buildings return devMode.FastBuild || progress == 0; } + bool ValidRenderPlayer() + { + var allyBuildRadius = self.World.LobbyInfo.GlobalSettings.AllyBuildRadius; + return self.Owner == self.World.RenderPlayer || (allyBuildRadius && self.Owner.IsAlliedWith(self.World.RenderPlayer)); + } + // Range circle public void RenderAfterWorld(WorldRenderer wr) { // Visible to player and allies - if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) + if (!ValidRenderPlayer()) return; wr.DrawRangeCircleWithContrast( @@ -73,7 +79,7 @@ namespace OpenRA.Mods.RA.Buildings public float GetValue() { // Visible to player and allies - if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) + if (!ValidRenderPlayer()) return 0f; // Ready or delay disabled diff --git a/OpenRA.Mods.RA/Buildings/Building.cs b/OpenRA.Mods.RA/Buildings/Building.cs index ef99c3eb38..be027171d7 100755 --- a/OpenRA.Mods.RA/Buildings/Building.cs +++ b/OpenRA.Mods.RA/Buildings/Building.cs @@ -43,7 +43,8 @@ namespace OpenRA.Mods.RA.Buildings var center = topLeft.CenterPosition + FootprintUtils.CenterOffset(this); foreach (var bp in world.ActorsWithTrait()) { - if (bp.Actor.Owner.Stances[p] != Stance.Ally || !bp.Trait.Ready()) + var validOwner = bp.Actor.Owner == p || (world.LobbyInfo.GlobalSettings.AllyBuildRadius && bp.Actor.Owner.Stances[p] == Stance.Ally); + if (!validOwner || !bp.Trait.Ready()) continue; // Range is counted from the center of the actor, not from each cell. @@ -72,14 +73,21 @@ namespace OpenRA.Mods.RA.Buildings var nearnessCandidates = new List(); var bi = world.WorldActor.Trait(); + var allyBuildRadius = world.LobbyInfo.GlobalSettings.AllyBuildRadius; for (var y = scanStart.Y; y < scanEnd.Y; y++) + { for (var x = scanStart.X; x < scanEnd.X; x++) { - var at = bi.GetBuildingAt(new CPos(x, y)); - if (at != null && at.Owner.Stances[p] == Stance.Ally && at.HasTrait()) - nearnessCandidates.Add(new CPos(x, y)); + var pos = new CPos(x, y); + var at = bi.GetBuildingAt(pos); + if (at == null || !at.HasTrait()) + continue; + + if (at.Owner == p || (allyBuildRadius && at.Owner.Stances[p] == Stance.Ally)) + nearnessCandidates.Add(pos); } + } var buildingTiles = FootprintUtils.Tiles(buildingName, this, topLeft).ToList(); return nearnessCandidates diff --git a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs index 68628381b3..cfdbe97cb8 100644 --- a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs @@ -437,6 +437,25 @@ namespace OpenRA.Mods.RA.Server server.SyncLobbyInfo(); return true; }}, + { "allybuildradius", + s => + { + if (!client.IsAdmin) + { + server.SendOrderTo(conn, "Message", "Only the host can set that option"); + return true; + } + + if (server.Map.Options.AllyBuildRadius.HasValue) + { + server.SendOrderTo(conn, "Message", "Map has disabled ally build radius configuration"); + return true; + } + + bool.TryParse(s, out server.lobbyInfo.GlobalSettings.AllyBuildRadius); + server.SyncLobbyInfo(); + return true; + }}, { "difficulty", s => { diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index a8bbac988a..b239589c82 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -286,6 +286,15 @@ namespace OpenRA.Mods.RA.Widgets.Logic "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); } + var allybuildradius = optionsBin.GetOrNull("ALLYBUILDRADIUS_CHECKBOX"); + if (allybuildradius != null) + { + allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; + allybuildradius.IsDisabled = () => Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); + allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( + "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); + } + var fragileAlliance = optionsBin.GetOrNull("FRAGILEALLIANCES_CHECKBOX"); if (fragileAlliance != null) { diff --git a/mods/cnc/chrome/dialogs.yaml b/mods/cnc/chrome/dialogs.yaml index 5d2c15a685..ac7c407a96 100644 --- a/mods/cnc/chrome/dialogs.yaml +++ b/mods/cnc/chrome/dialogs.yaml @@ -243,6 +243,12 @@ Background@LOBBY_OPTIONS_BIN: Width:230 Height:20 Text:Crates Appear + Checkbox@ALLYBUILDRADIUS_CHECKBOX: + X:280 + Y:35 + Width:230 + Height:20 + Text:Build off Ally ConYards Label@STARTINGUNITS_DESC: X:PARENT_RIGHT - WIDTH - 145 Y:72 diff --git a/mods/cnc/maps/gdi01/map.yaml b/mods/cnc/maps/gdi01/map.yaml index c5907cc2f6..9393004b4d 100644 --- a/mods/cnc/maps/gdi01/map.yaml +++ b/mods/cnc/maps/gdi01/map.yaml @@ -24,6 +24,7 @@ Options: Crates: false Fog: false Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/cnc/maps/nod01/map.yaml b/mods/cnc/maps/nod01/map.yaml index 40897c2a68..6a2cc30589 100644 --- a/mods/cnc/maps/nod01/map.yaml +++ b/mods/cnc/maps/nod01/map.yaml @@ -24,6 +24,7 @@ Options: Crates: false Fog: false Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/cnc/maps/the-hot-box/map.yaml b/mods/cnc/maps/the-hot-box/map.yaml index 7eafb51baf..1a1f5df620 100755 --- a/mods/cnc/maps/the-hot-box/map.yaml +++ b/mods/cnc/maps/the-hot-box/map.yaml @@ -22,6 +22,7 @@ Options: Fog: false Shroud: false Crates: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/chrome/lobby-dialogs.yaml b/mods/ra/chrome/lobby-dialogs.yaml index 249fce701d..63c5eda0de 100644 --- a/mods/ra/chrome/lobby-dialogs.yaml +++ b/mods/ra/chrome/lobby-dialogs.yaml @@ -96,6 +96,12 @@ Background@LOBBY_OPTIONS_BIN: Width:230 Height:20 Text:Crates Appear + Checkbox@ALLYBUILDRADIUS_CHECKBOX: + X:310 + Y:40 + Width:230 + Height:20 + Text:Build off Ally ConYards Label@STARTINGUNITS_DESC: X:PARENT_RIGHT - WIDTH - 145 Y:87 diff --git a/mods/ra/maps/Fort-Lonestar/map.yaml b/mods/ra/maps/Fort-Lonestar/map.yaml index 3072dfd7cf..dd91037eb0 100644 --- a/mods/ra/maps/Fort-Lonestar/map.yaml +++ b/mods/ra/maps/Fort-Lonestar/map.yaml @@ -21,6 +21,7 @@ Type: Minigame Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/Survival01/map.yaml b/mods/ra/maps/Survival01/map.yaml index faf43728bb..3a889eae56 100644 --- a/mods/ra/maps/Survival01/map.yaml +++ b/mods/ra/maps/Survival01/map.yaml @@ -21,6 +21,7 @@ Type: Minigame Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false Difficulties: Easy,Normal,Hard diff --git a/mods/ra/maps/Survival02/map.yaml b/mods/ra/maps/Survival02/map.yaml index 9ce437abd4..a5be8dd06f 100644 --- a/mods/ra/maps/Survival02/map.yaml +++ b/mods/ra/maps/Survival02/map.yaml @@ -21,6 +21,7 @@ Type: Minigame Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/allies-01/map.yaml b/mods/ra/maps/allies-01/map.yaml index fa3769a3d7..7d95ac6010 100644 --- a/mods/ra/maps/allies-01/map.yaml +++ b/mods/ra/maps/allies-01/map.yaml @@ -23,6 +23,7 @@ Type: Campaign Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false Difficulties: Easy, Normal diff --git a/mods/ra/maps/allies-02/map.yaml b/mods/ra/maps/allies-02/map.yaml index 93ff88674a..1ad0acc4ca 100644 --- a/mods/ra/maps/allies-02/map.yaml +++ b/mods/ra/maps/allies-02/map.yaml @@ -23,6 +23,7 @@ Type: Campaign Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/allies-03/map.yaml b/mods/ra/maps/allies-03/map.yaml index c48aeecae4..57d343749f 100644 --- a/mods/ra/maps/allies-03/map.yaml +++ b/mods/ra/maps/allies-03/map.yaml @@ -23,6 +23,7 @@ Type: Campaign Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false Difficulties: Easy, Normal, Hard diff --git a/mods/ra/maps/allies-04/map.yaml b/mods/ra/maps/allies-04/map.yaml index d96b91c28c..656436bbe4 100644 --- a/mods/ra/maps/allies-04/map.yaml +++ b/mods/ra/maps/allies-04/map.yaml @@ -15,6 +15,7 @@ Tileset: TEMPERAT Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false Difficulties: Easy,Normal,Hard diff --git a/mods/ra/maps/bomber-john/map.yaml b/mods/ra/maps/bomber-john/map.yaml index a1e75707d8..0727ba62b4 100644 --- a/mods/ra/maps/bomber-john/map.yaml +++ b/mods/ra/maps/bomber-john/map.yaml @@ -21,6 +21,7 @@ Type: Minigame Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml b/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml index 646afc9323..bcbd44f5b0 100644 --- a/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml +++ b/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml @@ -22,6 +22,7 @@ Options: Fog: false Shroud: false Crates: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/drop-zone-w/map.yaml b/mods/ra/maps/drop-zone-w/map.yaml index 60b8045f8c..a2fa753a33 100644 --- a/mods/ra/maps/drop-zone-w/map.yaml +++ b/mods/ra/maps/drop-zone-w/map.yaml @@ -22,6 +22,7 @@ Options: Fog: false Shroud: false Crates: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/drop-zone/map.yaml b/mods/ra/maps/drop-zone/map.yaml index 561a2bab06..1e2cb864ac 100644 --- a/mods/ra/maps/drop-zone/map.yaml +++ b/mods/ra/maps/drop-zone/map.yaml @@ -22,6 +22,7 @@ Options: Fog: false Shroud: false Crates: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/monster-tank-madness/map.yaml b/mods/ra/maps/monster-tank-madness/map.yaml index 68a204951f..c4c609744b 100644 --- a/mods/ra/maps/monster-tank-madness/map.yaml +++ b/mods/ra/maps/monster-tank-madness/map.yaml @@ -23,6 +23,7 @@ Type: Campaign Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/soviet-01-classic/map.yaml b/mods/ra/maps/soviet-01-classic/map.yaml index 558f52ec1e..b945c15766 100644 --- a/mods/ra/maps/soviet-01-classic/map.yaml +++ b/mods/ra/maps/soviet-01-classic/map.yaml @@ -23,6 +23,7 @@ Type: Campaign Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false diff --git a/mods/ra/maps/training-camp/map.yaml b/mods/ra/maps/training-camp/map.yaml index f1a5a0fd65..961a08e641 100644 --- a/mods/ra/maps/training-camp/map.yaml +++ b/mods/ra/maps/training-camp/map.yaml @@ -21,6 +21,7 @@ Type: Minigame Options: Fog: true Shroud: true + AllyBuildRadius: false FragileAlliances: false ConfigurableStartingUnits: false