diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 7867a84ff5..e5ab86ae3d 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -138,11 +138,9 @@ namespace OpenRA internal static void Initialize(string mapName, Renderer renderer, int2 clientSize, int localPlayer, Controller controller) { - Game.renderer = renderer; Game.clientSize = clientSize; - // todo Sound.Initialize(); PerfHistory.items["render"].hasNormalTick = false; PerfHistory.items["batches"].hasNormalTick = false; @@ -284,46 +282,14 @@ namespace OpenRA { if( Game.orderManager.GameStarted ) return; Game.chat.Reset(); - - var taken = LobbyInfo.Clients.Where(c => c.SpawnPoint != 0) - .Select(c => world.Map.SpawnPoints.ElementAt(c.SpawnPoint - 1)).ToList(); - var available = world.Map.SpawnPoints.Except(taken).ToList(); - - foreach (var client in LobbyInfo.Clients) - { - var sp = (client.SpawnPoint == 0) - ? ChooseSpawnPoint(available, taken) - : world.Map.SpawnPoints.ElementAt(client.SpawnPoint - 1); - - foreach (var ssu in world.players[client.Index].PlayerActor - .traits.WithInterface()) - ssu.GameStarted(world.players[client.Index], sp); - } + foreach (var gs in Game.world.WorldActor.traits.WithInterface()) + gs.GameStarted(world); Game.viewport.GoToStartLocation( Game.world.LocalPlayer ); orderManager.StartGame(); } - static int2 ChooseSpawnPoint(List available, List taken) - { - if (available.Count == 0) - throw new InvalidOperationException("No free spawnpoint."); - - var n = taken.Count == 0 - ? world.SharedRandom.Next(available.Count) - : available // pick the most distant spawnpoint from everyone else - .Select((k,i) => Pair.New(k,i)) - .OrderByDescending(a => taken.Sum(t => (t - a.First).LengthSquared)) - .Select(a => a.Second) - .First(); - - var sp = available[n]; - available.RemoveAt(n); - taken.Add(sp); - return sp; - } - static int2 lastPos; public static void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e, Modifiers modifierKeys) { diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 7ab04b4af1..70b7889425 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -116,7 +116,7 @@ - + diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 51f3cb26c0..eddedd868b 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -124,7 +124,7 @@ namespace OpenRA.Traits public interface INotifySelection { void SelectionChanged(); } public interface ILoadWorldHook { void WorldLoaded(World w); } - public interface IOnGameStart { void GameStarted(Player p, int2 sp); } + public interface IGameStarted { void GameStarted(World w); } public interface IActivity { diff --git a/OpenRA.Game/Traits/World/SpawnDefaultUnits.cs b/OpenRA.Game/Traits/World/SpawnDefaultUnits.cs new file mode 100644 index 0000000000..5c18dae2b2 --- /dev/null +++ b/OpenRA.Game/Traits/World/SpawnDefaultUnits.cs @@ -0,0 +1,72 @@ +#region Copyright & License Information +/* + * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. + * This file is part of OpenRA. + * + * OpenRA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenRA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenRA. If not, see . + */ +#endregion + +using System.Collections.Generic; +using System; +using System.Linq; +using OpenRA.FileFormats; + +namespace OpenRA.Traits +{ + class SpawnDefaultUnitsInfo : StatelessTraitInfo { } + + class SpawnDefaultUnits : IGameStarted + { + public void GameStarted(World world) + { + var taken = Game.LobbyInfo.Clients.Where(c => c.SpawnPoint != 0) + .Select(c => world.Map.SpawnPoints.ElementAt(c.SpawnPoint - 1)).ToList(); + + var available = world.Map.SpawnPoints.Except(taken).ToList(); + + foreach (var client in Game.LobbyInfo.Clients) + { + SpawnUnitsForPlayer(world.players[client.Index], + (client.SpawnPoint == 0) + ? ChooseSpawnPoint(world, available, taken) + : world.Map.SpawnPoints.ElementAt(client.SpawnPoint - 1)); + } + } + + void SpawnUnitsForPlayer(Player p, int2 sp) + { + p.World.CreateActor("mcv", sp, p); + } + + static int2 ChooseSpawnPoint(World world, List available, List taken) + { + if (available.Count == 0) + throw new InvalidOperationException("No free spawnpoint."); + + var n = taken.Count == 0 + ? world.SharedRandom.Next(available.Count) + : available // pick the most distant spawnpoint from everyone else + .Select((k, i) => Pair.New(k, i)) + .OrderByDescending(a => taken.Sum(t => (t - a.First).LengthSquared)) + .Select(a => a.Second) + .First(); + + var sp = available[n]; + available.RemoveAt(n); + taken.Add(sp); + return sp; + } + } +} diff --git a/mods/cnc/system.yaml b/mods/cnc/system.yaml index a1db97ab6a..b94af8e34c 100644 --- a/mods/cnc/system.yaml +++ b/mods/cnc/system.yaml @@ -22,7 +22,6 @@ Player: NavalUnitLost: unitlost.aud PrimaryBuildingSelected: pribldg1.aud PlaceBuilding: - SpawnDefaultUnits: World: ScreenShaker: @@ -207,4 +206,5 @@ World: ValuePerUnit: 30 Name: Tiberium GrowthInterval: 1 - SpreadInterval: 6 \ No newline at end of file + SpreadInterval: 6 + SpawnDefaultUnits: \ No newline at end of file diff --git a/mods/ra/rules.yaml b/mods/ra/rules.yaml index 622d0c8cea..5af5dd605a 100644 --- a/mods/ra/rules.yaml +++ b/mods/ra/rules.yaml @@ -59,7 +59,6 @@ Player: TechLevel: 5 GivenAuto: no OneShot: yes - SpawnDefaultUnits: World: ScreenShaker: @@ -266,6 +265,7 @@ World: Templates:templates.ini Tileset:tileSet.til MapColors:temperat.col + SpawnDefaultUnits: MGG: GeneratesGap: