Last active
June 2, 2019 17:01
-
-
Save MustaphaTR/f999fa1fac160149736908cd5c962610 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Copyright & License Information | |
/* | |
* Copyright 2007-2019 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, either version 3 of | |
* the License, or (at your option) any later version. For more | |
* information, see COPYING. | |
*/ | |
#endregion | |
using System.Collections.Generic; | |
using System.Linq; | |
using OpenRA.Graphics; | |
using OpenRA.Mods.Common; | |
using OpenRA.Mods.Common.Traits; | |
using OpenRA.Primitives; | |
using OpenRA.Traits; | |
namespace OpenRA.Mods.SS.Traits | |
{ | |
[Desc("Spawns the initial unit for a Sole Survivor game. Handles different spawning logics.")] | |
public class SpawnSSUnitInfo : ITraitInfo, ILobbyOptions | |
{ | |
[Translate] | |
[Desc("Descriptive label for the team spawns checkbox in the lobby.")] | |
public readonly string TeamSpawnsCheckboxLabel = "Team Spawns"; | |
[Translate] | |
[Desc("Tooltip description for the team spawns checkbox in the lobby.")] | |
public readonly string TeamSpawnsCheckboxDescription = "Players with the same team spawn next to each other"; | |
[Desc("Default value of the team spawns checkbox in the lobby.")] | |
public readonly bool TeamSpawnsCheckboxEnabled = true; | |
[Desc("Prevent the team spawns state from being changed in the lobby.")] | |
public readonly bool TeamSpawnsCheckboxLocked = false; | |
[Desc("Whether to display the team spawns checkbox in the lobby.")] | |
public readonly bool TeamSpawnsCheckboxVisible = true; | |
[Desc("Display order for the team spawns checkbox in the lobby.")] | |
public readonly int TeamSpawnsCheckboxDisplayOrder = 0; | |
[Desc("Inner radius for spawning teammates")] | |
public readonly int InnerTeammateRadius = 2; | |
[Desc("Outer radius for spawning teammates")] | |
public readonly int OuterTeammateRadius = 4; | |
[Desc("Initial facing of the units.")] | |
public readonly int UnitFacing = 0; | |
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules) | |
{ | |
yield return new LobbyBooleanOption( | |
"teamspawns", | |
TeamSpawnsCheckboxLabel, | |
TeamSpawnsCheckboxDescription, | |
TeamSpawnsCheckboxVisible, | |
TeamSpawnsCheckboxDisplayOrder, | |
TeamSpawnsCheckboxEnabled, | |
TeamSpawnsCheckboxLocked); | |
} | |
public object Create(ActorInitializer init) { return new SpawnSSUnit(this); } | |
} | |
public class SpawnSSUnit : IWorldLoaded | |
{ | |
readonly SpawnSSUnitInfo info; | |
WorldRenderer wr; | |
bool teamSpawns; | |
Dictionary<CPos, bool> spawnPoints = new Dictionary<CPos, bool>(); | |
public SpawnSSUnit(SpawnSSUnitInfo info) | |
{ | |
this.info = info; | |
} | |
public void WorldLoaded(World world, WorldRenderer wr) | |
{ | |
this.wr = wr; | |
teamSpawns = world.LobbyInfo.GlobalSettings | |
.OptionOrDefault("teamspawns", info.TeamSpawnsCheckboxEnabled); | |
spawnPoints = world.Actors.Where(a => a.Info.Name == "mpspawn") | |
.Select(a => a.Location) | |
.ToDictionary(s => s, s => false); | |
var players = world.Players.Where(p => p.Playable); | |
if (teamSpawns) | |
{ | |
var teams = players.Select(p => p.PlayerReference.Team).Distinct(); | |
var leaders = new List<Player>(); | |
foreach (var team in teams.Where(t => t != 0)) | |
leaders.Add(players.First(p => p.PlayerReference.Team == team)); | |
foreach (var l in leaders) | |
{ | |
var sp = spawnPoints.Where(s => !s.Value).Random(world.SharedRandom).Key; | |
SpawnUnitForPlayer(world, l, sp); | |
var teamMateSpawnCells = world.Map.FindTilesInAnnulus(sp, info.InnerTeammateRadius + 1, info.OuterTeammateRadius); | |
foreach (var p in players.Where(p => p != l && p.PlayerReference.Team == l.PlayerReference.Team)) | |
{ | |
var actorRules = world.Map.Rules.Actors[p.Faction.InternalName.ToLowerInvariant()]; | |
var ip = actorRules.TraitInfo<IPositionableInfo>(); | |
var validCell = teamMateSpawnCells.Shuffle(world.SharedRandom).FirstOrDefault(c => ip.CanEnterCell(world, null, c)); | |
SpawnUnitForPlayer(world, l, validCell); | |
} | |
} | |
foreach (var p in players.Where(p => p.PlayerReference.Team == 0)) | |
{ | |
var sp = spawnPoints.Where(s => !s.Value).Random(world.SharedRandom).Key; | |
SpawnUnitForPlayer(world, p, sp); | |
} | |
} | |
else | |
{ | |
foreach (var p in players) | |
{ | |
var sp = spawnPoints.Where(s => !s.Value).Random(world.SharedRandom).Key; | |
SpawnUnitForPlayer(world, p, sp); | |
} | |
} | |
} | |
void SpawnUnitForPlayer(World w, Player p, CPos sp) | |
{ | |
w.CreateActor(p.Faction.InternalName.ToLowerInvariant(), new TypeDictionary | |
{ | |
new LocationInit(sp), | |
new OwnerInit(p), | |
new SkipMakeAnimsInit(), | |
new FacingInit(info.UnitFacing < 0 ? w.SharedRandom.Next(256) : info.UnitFacing), | |
}); | |
spawnPoints[sp] = true; | |
if (w.LocalPlayer == p) | |
wr.Viewport.Center(w.Map.CenterOfCell(sp)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment