Skip to content

Instantly share code, notes, and snippets.

@MustaphaTR
Last active June 2, 2019 17:01
Show Gist options
  • Save MustaphaTR/f999fa1fac160149736908cd5c962610 to your computer and use it in GitHub Desktop.
Save MustaphaTR/f999fa1fac160149736908cd5c962610 to your computer and use it in GitHub Desktop.
#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