Actual randomized humanoids (#11574)

This commit is contained in:
Flipp Syder
2022-10-20 06:46:05 -07:00
committed by GitHub
parent e4c67e998f
commit 0fe9f38968
8 changed files with 418 additions and 175 deletions

View File

@@ -1,5 +1,6 @@
using Content.Server.GameTicking.Rules.Configurations; using Content.Server.GameTicking.Rules.Configurations;
using Content.Shared.Dataset; using Content.Shared.Dataset;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Roles; using Content.Shared.Roles;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -25,8 +26,8 @@ public sealed class NukeopsRuleConfiguration : GameRuleConfiguration
[DataField("maxOps")] [DataField("maxOps")]
public int MaxOperatives = 5; public int MaxOperatives = 5;
[DataField("spawnEntityProto", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] [DataField("randomHumanoidSettings", customTypeSerializer: typeof(PrototypeIdSerializer<RandomHumanoidSettingsPrototype>))]
public string SpawnEntityPrototype = "MobHumanNukeOp"; public string RandomHumanoidSettingsPrototype = "NukeOp";
[DataField("spawnPointProto", customTypeSerializer: typeof(PrototypeIdSerializer<StartingGearPrototype>))] [DataField("spawnPointProto", customTypeSerializer: typeof(PrototypeIdSerializer<StartingGearPrototype>))]
public string SpawnPointPrototype = "SpawnPointNukies"; public string SpawnPointPrototype = "SpawnPointNukies";

View File

@@ -35,6 +35,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Player; using Robust.Shared.Player;
using Content.Server.Administration.Commands; using Content.Server.Administration.Commands;
using Content.Server.Humanoid.Systems;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Content.Server.Preferences.Managers; using Content.Server.Preferences.Managers;
@@ -57,6 +58,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
[Dependency] private readonly RoundEndSystem _roundEndSystem = default!; [Dependency] private readonly RoundEndSystem _roundEndSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly RandomHumanoidSystem _randomHumanoid = default!;
private enum WinType private enum WinType
@@ -732,7 +734,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
if (sessions.TryGetValue(i, out var session)) if (sessions.TryGetValue(i, out var session))
{ {
var mob = EntityManager.SpawnEntity(_nukeopsRuleConfig.SpawnEntityPrototype, _random.Pick(spawns)); var mob = _randomHumanoid.SpawnRandomHumanoid(_nukeopsRuleConfig.RandomHumanoidSettingsPrototype, _random.Pick(spawns), string.Empty);
var profile = _prefs.GetPreferences(session.UserId).SelectedCharacter as HumanoidCharacterProfile; var profile = _prefs.GetPreferences(session.UserId).SelectedCharacter as HumanoidCharacterProfile;
SetupOperativeEntity(mob, spawnDetails.Name, spawnDetails.Gear, profile); SetupOperativeEntity(mob, spawnDetails.Name, spawnDetails.Gear, profile);

View File

@@ -0,0 +1,16 @@
using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Humanoid.Components;
/// <summary>
/// This is added to a marker entity in order to spawn a randomized
/// humanoid ingame.
/// </summary>
[RegisterComponent]
public sealed class RandomHumanoidSpawnerComponent : Component
{
[DataField("settings", customTypeSerializer: typeof(PrototypeIdSerializer<RandomHumanoidSettingsPrototype>))]
public string SettingsPrototypeId = default!;
}

View File

@@ -0,0 +1,66 @@
using Content.Server.Humanoid.Components;
using Content.Server.RandomMetadata;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
namespace Content.Server.Humanoid.Systems;
/// <summary>
/// This deals with spawning and setting up random humanoids.
/// </summary>
public sealed class RandomHumanoidSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IComponentFactory _compFactory = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly HumanoidSystem _humanoid = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<RandomHumanoidSpawnerComponent, MapInitEvent>(OnMapInit,
after: new []{ typeof(RandomMetadataSystem) });
}
private void OnMapInit(EntityUid uid, RandomHumanoidSpawnerComponent component, MapInitEvent args)
{
QueueDel(uid);
SpawnRandomHumanoid(component.SettingsPrototypeId, Transform(uid).Coordinates, MetaData(uid).EntityName);
}
public EntityUid SpawnRandomHumanoid(string prototypeId, EntityCoordinates coordinates, string name)
{
if (!_prototypeManager.TryIndex<RandomHumanoidSettingsPrototype>(prototypeId, out var prototype))
{
throw new ArgumentException("Could not get random humanoid settings");
}
var profile = HumanoidCharacterProfile.Random(prototype.SpeciesBlacklist);
var speciesProto = _prototypeManager.Index<SpeciesPrototype>(profile.Species);
var humanoid = Spawn(speciesProto.Prototype, coordinates);
MetaData(humanoid).EntityName = prototype.RandomizeName
? profile.Name
: name;
_humanoid.LoadProfile(humanoid, profile);
if (prototype.Components == null)
{
return humanoid;
}
foreach (var entry in prototype.Components.Values)
{
var comp = (Component) _serialization.Copy(entry.Component);
comp.Owner = humanoid;
EntityManager.AddComponent(humanoid, comp, true);
}
return humanoid;
}
}

View File

@@ -0,0 +1,37 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
namespace Content.Shared.Humanoid.Prototypes;
/// <summary>
/// This is what is used to change a humanoid spawned by RandomHumanoidSystem in Content.Server.
/// </summary>
[Prototype("randomHumanoidSettings")]
public sealed class RandomHumanoidSettingsPrototype : IPrototype, IInheritingPrototype
{
[IdDataField] public string ID { get; } = default!;
[ParentDataField(typeof(PrototypeIdArraySerializer<RandomHumanoidSettingsPrototype>))]
public string[]? Parents { get; }
[AbstractDataField]
public bool Abstract { get; }
/// <summary>
/// Whether the humanoid's name should take from the randomized profile or not.
/// </summary>
[DataField("randomizeName")]
public bool RandomizeName { get; } = true;
/// <summary>
/// Species that will be ignored by the randomizer.
/// </summary>
[DataField("speciesBlacklist")]
public HashSet<string> SpeciesBlacklist { get; } = new();
/// <summary>
/// Extra components to add to this entity.
/// </summary>
[DataField("components")]
public EntityPrototype.ComponentRegistry? Components { get; }
}

View File

@@ -26,20 +26,6 @@
- type: HTN - type: HTN
rootTask: RangedCombatCompound rootTask: RangedCombatCompound
- type: entity
parent: MobHuman
id: MobCBURNUnit
name: CBURN Agent
description: A miserable pile of secrets
components:
- type: RandomHumanoidAppearance
- type: Loadout
prototypes: [CBURNGear]
- type: GhostTakeoverAvailable
makeSentient: false
name: CBURN Agent
description: A highly trained CentCom agent, capable of dealing with various threats.
- type: entity - type: entity
parent: BaseMobHuman parent: BaseMobHuman
suffix: Dead suffix: Dead

View File

@@ -34,160 +34,6 @@
factions: factions:
- NanoTrasen - NanoTrasen
- type: entity
name: CentCom official
parent: MobHuman
id: MobHumanCentcomOfficial
components:
- type: Icon
sprite: Markers/jobs.rsi
state: centcom
- type: GhostTakeoverAvailable
name: CentCom official
description: Inspect the station, jot down performance reviews for heads of staff, bug the Captain.
- type: Loadout
prototypes: [CentcomGear]
- type: RandomHumanoidAppearance
# ERT Leader
- type: entity
name: ERT leader
parent: MobHuman
id: MobHumanERTLeader
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertleader
- type: GhostTakeoverAvailable
name: ERT Leader
description: Lead a team of specialists to resolve the stations issues.
- type: Loadout
prototypes: [ERTLeaderGear]
- type: RandomMetadata
nameSegments: [NamesFirstMilitaryLeader]
- type: RandomHumanoidAppearance
randomizeName: false
- type: entity
name: ERT leader
suffix: EVA
parent: MobHumanERTLeader
id: MobHumanERTLeaderEVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertleadereva
- type: Loadout
prototypes: [ERTLeaderGearEVA]
# ERT Engineer
- type: entity
name: ERT engineer
parent: MobHumanERTLeader
id: MobHumanERTEngineer
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertengineer
- type: GhostTakeoverAvailable
name: ERT Engineer
description: Assist with engineering efforts to resolve the stations issues.
- type: Loadout
prototypes: [ERTEngineerGear]
- type: entity
name: ERT engineer
suffix: EVA
parent: MobHumanERTEngineer
id: MobHumanERTEngineerEVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertengineereva
- type: Loadout
prototypes: [ERTEngineerGearEVA]
# ERT Security
- type: entity
name: ERT security
parent: MobHumanERTLeader
id: MobHumanERTSecurity
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertsecurity
- type: GhostTakeoverAvailable
name: ERT Security
description: Assist with security efforts to resolve the stations issues.
- type: Loadout
prototypes: [ERTSecurityGear]
- type: entity
name: ERT security
suffix: EVA
parent: MobHumanERTEngineer
id: MobHumanERTSecurityEVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertsecurityeva
- type: Loadout
prototypes: [ERTSecurityGearEVA]
# ERT Medical
- type: entity
name: ERT medic
parent: MobHumanERTLeader
id: MobHumanERTMedical
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertmedical
- type: GhostTakeoverAvailable
name: ERT Medic
description: Assist with medical efforts to resolve the stations issues.
- type: Loadout
prototypes: [ERTMedicalGear]
- type: entity
name: ERT medic
suffix: EVA
parent: MobHumanERTMedical
id: MobHumanERTMedicalEVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertmedicaleva
- type: Loadout
prototypes: [ERTMedicalGearEVA]
# ERT Janitor
- type: entity
name: ERT janitor
parent: MobHumanERTLeader
id: MobHumanERTJanitor
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertjanitor
- type: GhostTakeoverAvailable
name: ERT Janitor
description: Assist with custodial efforts to resolve the stations issues.
- type: Loadout
prototypes: [ERTJanitorGear]
- type: entity
name: ERT janitor
suffix: EVA
parent: MobHumanERTJanitor
id: MobHumanERTJanitorEVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertjanitoreva
- type: Loadout
prototypes: [ERTJanitorGearEVA]
#Syndie #Syndie
- type: entity - type: entity
parent: MobHuman parent: MobHuman
@@ -195,6 +41,7 @@
name: Syndicate Agent name: Syndicate Agent
components: components:
- type: Loadout - type: Loadout
prototype: SyndicateOperativeGearExtremelyBasic
prototypes: [SyndicateOperativeGearExtremelyBasic] prototypes: [SyndicateOperativeGearExtremelyBasic]
- type: RandomMetadata - type: RandomMetadata
nameSegments: [names_death_commando] nameSegments: [names_death_commando]

View File

@@ -0,0 +1,288 @@
# Random humanoids
## ERT Leader
- type: entity
id: RandomHumanoidSpawnerERTLeader
name: ERT leader
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertleader
- type: RandomMetadata
nameSegments: [ NamesFirstMilitaryLeader ]
- type: RandomHumanoidSpawner
settings: ERTLeader
- type: randomHumanoidSettings
id: ERTLeader
randomizeName: false
components:
- type: GhostTakeoverAvailable
name: ERT Leader
description: Lead a team of specialists to resolve the stations issues.
- type: Loadout
prototypes: [ ERTLeaderGear ]
- type: RandomMetadata
nameSegments: [ NamesFirstMilitaryLeader ]
- type: entity
id: RandomHumanoidSpawnerERTLeaderEVA
parent: RandomHumanoidSpawnerERTLeader
name: ERT leader
suffix: EVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertleadereva
- type: RandomHumanoidSpawner
settings: ERTLeaderEVA
- type: randomHumanoidSettings
id: ERTLeaderEVA
parent: ERTLeader
components:
- type: Loadout
prototypes: [ ERTLeaderGearEVA ]
## ERT Janitor
- type: entity
id: RandomHumanoidSpawnerERTJanitor
parent: RandomHumanoidSpawnerERTLeader
name: ERT janitor
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertjanitor
- type: RandomHumanoidSpawner
settings: ERTJanitor
- type: randomHumanoidSettings
id: ERTJanitor
parent: ERTLeader
components:
- type: GhostTakeoverAvailable
name: ERT Janitor
description: Assist with custodial efforts to resolve the stations issues.
- type: Loadout
prototypes: [ ERTJanitorGear ]
- type: entity
id: RandomHumanoidSpawnerERTJanitorEVA
parent: RandomHumanoidSpawnerERTJanitor
name: ERT janitor
suffix: EVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertjanitoreva
- type: RandomHumanoidSpawner
settings: ERTJanitorEVA
- type: randomHumanoidSettings
id: ERTJanitorEVA
parent: ERTJanitor
components:
- type: Loadout
prototypes: [ ERTJanitorGearEVA ]
## ERT Engineer
- type: entity
id: RandomHumanoidSpawnerERTEngineer
parent: RandomHumanoidSpawnerERTLeader
name: ERT engineer
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertengineer
- type: RandomHumanoidSpawner
settings: ERTEngineer
- type: randomHumanoidSettings
id: ERTEngineer
parent: ERTLeader
components:
- type: GhostTakeoverAvailable
name: ERT Engineer
description: Assist with engineering efforts to resolve the stations issues.
- type: Loadout
prototypes: [ ERTEngineerGear ]
- type: entity
id: RandomHumanoidSpawnerERTEngineerEVA
parent: RandomHumanoidSpawnerERTEngineer
name: ERT engineer
suffix: EVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertengineereva
- type: RandomHumanoidSpawner
settings: ERTEngineerEVA
- type: randomHumanoidSettings
id: ERTEngineerEVA
parent: ERTEngineer
components:
- type: Loadout
prototypes: [ ERTEngineerGearEVA ]
## ERT Security
- type: entity
id: RandomHumanoidSpawnerERTSecurity
parent: RandomHumanoidSpawnerERTLeader
name: ERT security
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertsecurity
- type: RandomHumanoidSpawner
settings: ERTSecurity
- type: randomHumanoidSettings
id: ERTSecurity
parent: ERTLeader
components:
- type: GhostTakeoverAvailable
name: ERT Security
description: Assist with security efforts to resolve the stations issues.
- type: Loadout
prototypes: [ ERTSecurityGear ]
- type: entity
id: RandomHumanoidSpawnerERTSecurityEVA
parent: RandomHumanoidSpawnerERTSecurity
name: ERT security
suffix: EVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertsecurityeva
- type: RandomHumanoidSpawner
settings: ERTSecurityEVA
- type: randomHumanoidSettings
id: ERTSecurityEVA
parent: ERTSecurity
components:
- type: Loadout
prototypes: [ ERTSecurityGearEVA ]
## ERT Medic
- type: entity
id: RandomHumanoidSpawnerERTMedical
parent: RandomHumanoidSpawnerERTLeader
name: ERT medic
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertmedical
- type: RandomHumanoidSpawner
settings: ERTMedical
- type: randomHumanoidSettings
id: ERTMedical
parent: ERTLeader
components:
- type: GhostTakeoverAvailable
name: ERT Medical
description: Assist with medicaling efforts to resolve the stations issues.
- type: Loadout
prototypes: [ ERTMedicalGear ]
- type: entity
id: RandomHumanoidSpawnerERTMedicalEVA
parent: RandomHumanoidSpawnerERTMedical
name: ERT medic
suffix: EVA
components:
- type: Icon
sprite: Markers/jobs.rsi
state: ertmedicaleva
- type: RandomHumanoidSpawner
settings: ERTMedicalEVA
- type: randomHumanoidSettings
id: ERTMedicalEVA
parent: ERTMedical
components:
- type: Loadout
prototypes: [ ERTMedicalGearEVA ]
## CBURN
- type: entity
id: RandomHumanoidSpawnerCBURNUnit
name: CBURN Agent
components:
- type: RandomHumanoidSpawner
settings: CBURNAgent
- type: randomHumanoidSettings
id: CBURNAgent
components:
- type: Loadout
prototypes: [CBURNGear]
- type: GhostTakeoverAvailable
name: CBURN Agent
description: A highly trained CentCom agent, capable of dealing with various threats.
## Central Command
- type: entity
name: CentCom official
id: RandomHumanoidSpawnerCentcomOfficial
components:
- type: Icon
sprite: Markers/jobs.rsi
state: centcom
- type: RandomHumanoidSpawner
settings: CentcomOfficial
- type: randomHumanoidSettings
id: CentcomOfficial
components:
- type: GhostTakeoverAvailable
name: CentCom official
description: Inspect the station, jot down performance reviews for heads of staff, bug the Captain.
- type: Loadout
prototypes: [ CentcomGear ]
## Syndicate
- type: entity
id: RandomHumanoidSpawnerSyndicateAgent
name: Syndicate Agent
components:
- type: Icon
sprite: Mobs/Species/Human/parts.rsi
state: full
- type: RandomMetadata
nameSegments: [ names_death_commando ]
- type: RandomHumanoidSpawner
settings: SyndicateAgent
- type: randomHumanoidSettings
id: SyndicateAgent
components:
- type: Loadout
prototypes: [SyndicateOperativeGearExtremelyBasic]
- type: entity
id: RandomHumanoidSpawnerNukeOp
name: Nuclear Operative
components:
- type: Icon
sprite: Mobs/Species/Human/parts.rsi
state: full
- type: RandomHumanoidSpawner
settings: NukeOp
- type: randomHumanoidSettings
id: NukeOp
components:
- type: NukeOperative