Merge pull request #11364 from pchote/lobby-trait-options

Unhardcode the lobby options backend.
This commit is contained in:
reaperrr
2016-06-11 13:40:09 +02:00
committed by GitHub
22 changed files with 423 additions and 546 deletions

View File

@@ -54,7 +54,8 @@ namespace OpenRA.Mods.Common.Traits
var map = init.World.Map;
// Explore map-placed actors if the "Explore Map" option is enabled
var exploredMap = !init.World.LobbyInfo.GlobalSettings.Shroud;
var shroudInfo = init.World.Map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
var exploredMap = init.World.LobbyInfo.GlobalSettings.OptionOrDefault("explored", shroudInfo.ExploredMapEnabled);
startsRevealed = exploredMap && init.Contains<SpawnedByMapInit>() && !init.Contains<HiddenUnderFogInit>();
var footprintCells = FootprintUtils.FrozenUnderFogTiles(init.Self).ToList();
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();

View File

@@ -15,7 +15,14 @@ namespace OpenRA.Mods.Common.Traits
{
public class ProvidesTechPrerequisiteInfo : ITechTreePrerequisiteInfo
{
[Desc("Internal id for this tech level.")]
public readonly string Id;
[Translate]
[Desc("Name shown in the lobby options.")]
public readonly string Name;
[Desc("Prerequisites to grant when this tech level is active.")]
public readonly string[] Prerequisites = { };
public object Create(ActorInitializer init) { return new ProvidesTechPrerequisite(this, init); }
@@ -23,8 +30,9 @@ namespace OpenRA.Mods.Common.Traits
public class ProvidesTechPrerequisite : ITechTreePrerequisite
{
ProvidesTechPrerequisiteInfo info;
readonly ProvidesTechPrerequisiteInfo info;
bool enabled;
static readonly string[] NoPrerequisites = new string[0];
public string Name { get { return info.Name; } }
@@ -40,7 +48,8 @@ namespace OpenRA.Mods.Common.Traits
public ProvidesTechPrerequisite(ProvidesTechPrerequisiteInfo info, ActorInitializer init)
{
this.info = info;
enabled = info.Name == init.World.LobbyInfo.GlobalSettings.TechLevel;
var mapOptions = init.World.WorldActor.TraitOrDefault<MapOptions>();
enabled = mapOptions != null && mapOptions.TechLevel == info.Id;
}
}
}

View File

@@ -13,12 +13,13 @@ using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Activities;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class CrateSpawnerInfo : ITraitInfo
public class CrateSpawnerInfo : ITraitInfo, ILobbyOptions
{
[Desc("Default value of the crates checkbox in the lobby.")]
public readonly bool Enabled = true;
@@ -64,27 +65,39 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Spawn and remove the plane this far outside the map.")]
public readonly WDist Cordon = new WDist(5120);
public object Create(ActorInitializer init) { return new CrateSpawner(this, init.Self); }
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{
yield return new LobbyBooleanOption("crates", "Crates", Enabled, Locked);
}
public object Create(ActorInitializer init) { return new CrateSpawner(init.Self, this); }
}
public class CrateSpawner : ITick
public class CrateSpawner : ITick, INotifyCreated
{
readonly CrateSpawnerInfo info;
readonly Actor self;
int crates = 0;
int ticks = 0;
readonly CrateSpawnerInfo info;
bool enabled;
int crates;
int ticks;
public CrateSpawner(CrateSpawnerInfo info, Actor self)
public CrateSpawner(Actor self, CrateSpawnerInfo info)
{
this.info = info;
this.self = self;
this.info = info;
ticks = info.InitialSpawnDelay;
}
void INotifyCreated.Created(Actor self)
{
enabled = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("crates", info.Enabled);
}
public void Tick(Actor self)
{
if (!self.World.LobbyInfo.GlobalSettings.Crates)
if (!enabled)
return;
if (--ticks <= 0)

View File

@@ -15,22 +15,36 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the build radius checkboxes in the lobby options.")]
public class MapBuildRadiusInfo : TraitInfo<MapBuildRadius>
public class MapBuildRadiusInfo : ITraitInfo, ILobbyOptions
{
[Desc("Default value of the ally build radius checkbox in the lobby.")]
public readonly bool AllyBuildRadiusEnabled = true;
[Desc("Prevent the ally build radius state from being changed in the lobby.")]
public readonly bool AllyBuildRadiusLocked = false;
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{
yield return new LobbyBooleanOption("allybuild", "Build off Allies' ConYards", AllyBuildRadiusEnabled, AllyBuildRadiusLocked);
}
public object Create(ActorInitializer init) { return new MapBuildRadius(this); }
}
public class MapBuildRadius : INotifyCreated
{
readonly MapBuildRadiusInfo info;
public bool AllyBuildRadiusEnabled { get; private set; }
public MapBuildRadius(MapBuildRadiusInfo info)
{
this.info = info;
}
void INotifyCreated.Created(Actor self)
{
AllyBuildRadiusEnabled = self.World.LobbyInfo.GlobalSettings.AllyBuildRadius;
AllyBuildRadiusEnabled = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("allybuild", info.AllyBuildRadiusEnabled);
}
}
}

View File

@@ -15,22 +15,36 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the 'Creeps' checkbox in the lobby options.")]
public class MapCreepsInfo : TraitInfo<MapCreeps>
public class MapCreepsInfo : ITraitInfo, ILobbyOptions
{
[Desc("Default value of the creeps checkbox in the lobby.")]
public readonly bool Enabled = true;
[Desc("Prevent the creeps state from being changed in the lobby.")]
public readonly bool Locked = false;
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{
yield return new LobbyBooleanOption("creeps", "Worms", Enabled, Locked);
}
public object Create(ActorInitializer init) { return new MapCreeps(this); }
}
public class MapCreeps : INotifyCreated
{
readonly MapCreepsInfo info;
public bool Enabled { get; private set; }
public MapCreeps(MapCreepsInfo info)
{
this.info = info;
}
void INotifyCreated.Created(Actor self)
{
Enabled = self.World.LobbyInfo.GlobalSettings.Creeps;
Enabled = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("creeps", info.Enabled);
}
}
}

View File

@@ -10,12 +10,13 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the map difficulty, tech level, and short game lobby options.")]
public class MapOptionsInfo : TraitInfo<MapOptions>
public class MapOptionsInfo : ITraitInfo, ILobbyOptions
{
[Desc("Default value of the short game checkbox in the lobby.")]
public readonly bool ShortGameEnabled = true;
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly bool ShortGameLocked = false;
[Desc("Default tech level.")]
public readonly string TechLevel = "Unrestricted";
public readonly string TechLevel = "unrestricted";
[Desc("Prevent the tech level from being changed in the lobby.")]
public readonly bool TechLevelLocked = false;
@@ -37,15 +38,42 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Prevent the difficulty from being changed in the lobby.")]
public readonly bool DifficultyLocked = false;
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{
yield return new LobbyBooleanOption("shortgame", "Short Game", ShortGameEnabled, ShortGameLocked);
var techLevels = rules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>()
.ToDictionary(t => t.Id, t => t.Name);
if (techLevels.Any())
yield return new LobbyOption("techlevel", "Tech Level",
new ReadOnlyDictionary<string, string>(techLevels),
TechLevel, TechLevelLocked);
}
public object Create(ActorInitializer init) { return new MapOptions(this); }
}
public class MapOptions : INotifyCreated
{
readonly MapOptionsInfo info;
public bool ShortGame { get; private set; }
public string TechLevel { get; private set; }
public MapOptions(MapOptionsInfo info)
{
this.info = info;
}
void INotifyCreated.Created(Actor self)
{
ShortGame = self.World.LobbyInfo.GlobalSettings.ShortGame;
ShortGame = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("shortgame", info.ShortGameEnabled);
TechLevel = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("techlevel", info.TechLevel);
}
}
}

View File

@@ -10,6 +10,7 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
@@ -18,25 +19,48 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Spawn base actor at the spawnpoint and support units in an annulus around the base actor. Both are defined at MPStartUnits. Attach this to the world actor.")]
public class SpawnMPUnitsInfo : TraitInfo<SpawnMPUnits>, Requires<MPStartLocationsInfo>, Requires<MPStartUnitsInfo>
public class SpawnMPUnitsInfo : ITraitInfo, Requires<MPStartLocationsInfo>, Requires<MPStartUnitsInfo>, ILobbyOptions
{
public readonly string StartingUnitsClass = "none";
[Desc("Prevent the starting units option from being changed in the lobby.")]
public bool Locked = false;
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{
var startingUnits = new Dictionary<string, string>();
// Duplicate classes are defined for different race variants
foreach (var t in rules.Actors["world"].TraitInfos<MPStartUnitsInfo>())
startingUnits[t.Class] = t.ClassName;
if (startingUnits.Any())
yield return new LobbyOption("startingunits", "Starting Units", new ReadOnlyDictionary<string, string>(startingUnits), StartingUnitsClass, Locked);
}
public object Create(ActorInitializer init) { return new SpawnMPUnits(this); }
}
public class SpawnMPUnits : IWorldLoaded
{
readonly SpawnMPUnitsInfo info;
public SpawnMPUnits(SpawnMPUnitsInfo info)
{
this.info = info;
}
public void WorldLoaded(World world, WorldRenderer wr)
{
foreach (var s in world.WorldActor.Trait<MPStartLocations>().Start)
SpawnUnitsForPlayer(world, s.Key, s.Value);
}
static void SpawnUnitsForPlayer(World w, Player p, CPos sp)
void SpawnUnitsForPlayer(World w, Player p, CPos sp)
{
var spawnClass = p.PlayerReference.StartingUnitsClass ?? w.LobbyInfo.GlobalSettings.StartingUnitsClass;
var spawnClass = p.PlayerReference.StartingUnitsClass ?? w.LobbyInfo.GlobalSettings
.OptionOrDefault("startingunits", info.StartingUnitsClass);
var unitGroup = w.Map.Rules.Actors["world"].TraitInfos<MPStartUnitsInfo>()
.Where(g => g.Class == spawnClass && g.Factions != null && g.Factions.Contains(p.Faction.InternalName))
.RandomOrDefault(w.SharedRandom);