Traits: add ICreatePlayersInfo

Signed-off-by: Clément Bœsch <u@pkh.me>
This commit is contained in:
Paul Chote
2020-09-23 17:10:02 +02:00
committed by abcdefg30
parent 41814a881d
commit dd18829def
3 changed files with 61 additions and 2 deletions

View File

@@ -367,6 +367,12 @@ namespace OpenRA.Traits
[RequireExplicitImplementation]
public interface ICreatePlayers { void CreatePlayers(World w); }
[RequireExplicitImplementation]
public interface ICreatePlayersInfo : ITraitInfoInterface
{
void CreateServerPlayers(MapPreview map, Session lobbyInfo, List<GameInformation.Player> players);
}
public interface IBotInfo : ITraitInfoInterface
{
string Type { get; }

View File

@@ -18,7 +18,54 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Attach this to the world actor.")]
public class CreateMPPlayersInfo : TraitInfo<CreateMPPlayers> { }
public class CreateMPPlayersInfo : TraitInfo<CreateMPPlayers>, ICreatePlayersInfo
{
/// <summary>
/// Returns a list of GameInformation.Players that matches the indexing of ICreatePlayers.CreatePlayers.
/// Non-playable players appear as null in the list.
/// </summary>
void ICreatePlayersInfo.CreateServerPlayers(MapPreview map, Session lobbyInfo, List<GameInformation.Player> players)
{
// Create the unplayable map players -- neutral, shellmap, scripted, etc.
foreach (var p in map.Players.Players.Where(p => !p.Value.Playable))
players.Add(null);
// Create the regular playable players.
var factions = map.Rules.Actors["world"].TraitInfos<FactionInfo>().ToArray();
var bots = map.Rules.Actors["player"].TraitInfos<IBotInfo>().ToArray();
foreach (var kv in lobbyInfo.Slots)
{
var client = lobbyInfo.ClientInSlot(kv.Key);
if (client == null)
continue;
var clientFaction = factions.First(f => client.Faction == f.InternalName);
// TODO: Resolve random SpawnPoint and Faction to real values
var player = new GameInformation.Player
{
ClientIndex = client.Index,
Name = Player.ResolvePlayerName(client, lobbyInfo.Clients, bots),
IsHuman = client.Bot == null,
IsBot = client.Bot != null,
FactionName = clientFaction.Name,
FactionId = clientFaction.InternalName,
Color = client.Color,
Team = client.Team,
SpawnPoint = client.SpawnPoint,
IsRandomFaction = clientFaction.RandomFactionMembers.Any(),
IsRandomSpawnPoint = client.SpawnPoint == 0,
Fingerprint = client.Fingerprint,
};
players.Add(player);
}
// Create a player that is allied with everyone for shared observer shroud.
players.Add(null);
}
}
public class CreateMPPlayers : ICreatePlayers
{

View File

@@ -14,17 +14,23 @@ using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits.Render;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Required for the map editor to work. Attach this to the world actor.")]
public class EditorActorLayerInfo : TraitInfo
public class EditorActorLayerInfo : TraitInfo, ICreatePlayersInfo
{
[Desc("Size of partition bins (world pixels)")]
public readonly int BinSize = 250;
void ICreatePlayersInfo.CreateServerPlayers(MapPreview map, Session lobbyInfo, List<GameInformation.Player> players)
{
throw new NotImplementedException("EditorActorLayer must not be defined on the world actor");
}
public override object Create(ActorInitializer init) { return new EditorActorLayer(init.Self, this); }
}