Basis for the job system (#434)
* Add basic yaml Jobs file * Add Job Prototype * Rename Jobs to Job * Remove BaseJob * Add the Job class child of Role * Add code for spawning as an assistant. Not actually working, the job prototype can't be found. * Fix role instead of job left in yaml * Add starting gear support for job and the starting gear for assistant as an exemple * Link job with starting gear in yaml * Better naming and some error handling * Tweak error handling
This commit is contained in:
committed by
Pieter-Jan Briers
parent
480d3b26c4
commit
447db2e458
@@ -7,9 +7,11 @@ using Content.Server.GameTicking.GamePresets;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Interfaces.GameTicking;
|
||||
using Content.Server.Mobs;
|
||||
using Content.Server.Mobs.Roles;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Content.Shared.Jobs;
|
||||
using Robust.Server.Interfaces.Maps;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Server.Player;
|
||||
@@ -27,6 +29,7 @@ using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -91,6 +94,7 @@ namespace Content.Server.GameTicking
|
||||
[Dependency] private IChatManager _chatManager;
|
||||
[Dependency] private IServerNetManager _netManager;
|
||||
[Dependency] private IDynamicTypeFactory _dynamicTypeFactory;
|
||||
[Dependency] private IPrototypeManager _prototypeManager;
|
||||
[Dependency] private readonly ILocalizationManager _localization;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom;
|
||||
#pragma warning restore 649
|
||||
@@ -260,16 +264,23 @@ namespace Content.Server.GameTicking
|
||||
UpdateInfoText();
|
||||
}
|
||||
|
||||
private IEntity _spawnPlayerMob()
|
||||
private IEntity _spawnPlayerMob(Job job)
|
||||
{
|
||||
var entity = _entityManager.SpawnEntityAt(PlayerPrototypeName, _getLateJoinSpawnPoint());
|
||||
if (entity.TryGetComponent(out InventoryComponent inventory))
|
||||
{
|
||||
var uniform = _entityManager.SpawnEntity("UniformAssistant");
|
||||
inventory.Equip(EquipmentSlotDefines.Slots.INNERCLOTHING, uniform.GetComponent<ClothingComponent>());
|
||||
var gear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear).Equipment;
|
||||
|
||||
var shoes = _entityManager.SpawnEntity("ShoesBlack");
|
||||
inventory.Equip(EquipmentSlotDefines.Slots.SHOES, shoes.GetComponent<ClothingComponent>());
|
||||
foreach (var (slotStr, equipmentStr) in gear)
|
||||
{
|
||||
if (!Enum.TryParse(slotStr.ToUpper(), out EquipmentSlotDefines.Slots slot))
|
||||
{
|
||||
Logger.Error("{0} is an invalid equipment slot.", slotStr);
|
||||
continue;
|
||||
}
|
||||
var equipmentEntity = _entityManager.SpawnEntity(equipmentStr);
|
||||
inventory.Equip(slot, equipmentEntity.GetComponent<ClothingComponent>());
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
@@ -441,8 +452,11 @@ namespace Content.Server.GameTicking
|
||||
var data = session.ContentData();
|
||||
data.WipeMind();
|
||||
data.Mind = new Mind(session.SessionId);
|
||||
//TODO Replace "Assistant" with the job when char preference are done
|
||||
var job = new Job(data.Mind, _prototypeManager.Index<JobPrototype>("Assistant"));
|
||||
data.Mind.AddRole(job);
|
||||
|
||||
var mob = _spawnPlayerMob();
|
||||
var mob = _spawnPlayerMob(job);
|
||||
data.Mind.TransferTo(mob);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using System.Text;
|
||||
using Content.Server.Mobs.Roles;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared.Jobs;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Mobs
|
||||
{
|
||||
|
||||
public class MindInfoCommand : IClientCommand
|
||||
{
|
||||
public string Command => "mindinfo";
|
||||
@@ -47,6 +51,10 @@ namespace Content.Server.Mobs
|
||||
|
||||
public class AddRoleCommand : IClientCommand
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private IPrototypeManager _prototypeManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public string Command => "addrole";
|
||||
|
||||
public string Description => "Adds a role to a player's mind.";
|
||||
@@ -65,9 +73,8 @@ namespace Content.Server.Mobs
|
||||
if (mgr.TryGetPlayerData(new NetSessionId(args[0]), out var data))
|
||||
{
|
||||
var mind = data.ContentData().Mind;
|
||||
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||
var type = refl.LooseGetType(args[1]);
|
||||
mind.AddRole(type);
|
||||
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
|
||||
mind.AddRole(role);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -78,6 +85,11 @@ namespace Content.Server.Mobs
|
||||
|
||||
public class RemoveRoleCommand : IClientCommand
|
||||
{
|
||||
|
||||
#pragma warning disable 649
|
||||
[Dependency] private IPrototypeManager _prototypeManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public string Command => "rmrole";
|
||||
|
||||
public string Description => "Removes a role from a player's mind.";
|
||||
@@ -96,9 +108,8 @@ namespace Content.Server.Mobs
|
||||
if (mgr.TryGetPlayerData(new NetSessionId(args[0]), out var data))
|
||||
{
|
||||
var mind = data.ContentData().Mind;
|
||||
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||
var type = refl.LooseGetType(args[1]);
|
||||
mind.RemoveRole(type);
|
||||
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
|
||||
mind.RemoveRole(role);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Content.Server.Mobs
|
||||
/// </remarks>
|
||||
public sealed class Mind
|
||||
{
|
||||
private readonly Dictionary<Type, Role> _roles = new Dictionary<Type, Role>();
|
||||
private readonly ISet<Role> _roles = new HashSet<Role>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the new mind attached to a specific player session.
|
||||
@@ -66,7 +66,7 @@ namespace Content.Server.Mobs
|
||||
/// An enumerable over all the roles this mind has.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public IEnumerable<Role> AllRoles => _roles.Values;
|
||||
public IEnumerable<Role> AllRoles => _roles;
|
||||
|
||||
/// <summary>
|
||||
/// The session of the player owning this mind.
|
||||
@@ -87,19 +87,6 @@ namespace Content.Server.Mobs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives this mind a new role.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the role to give.</typeparam>
|
||||
/// <returns>The instance of the role.</returns>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if we already have a role with this type.
|
||||
/// </exception>
|
||||
public T AddRole<T>() where T : Role
|
||||
{
|
||||
return (T)AddRole(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives this mind a new role.
|
||||
/// </summary>
|
||||
@@ -108,31 +95,18 @@ namespace Content.Server.Mobs
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if we already have a role with this type.
|
||||
/// </exception>
|
||||
public Role AddRole(Type t)
|
||||
public Role AddRole(Role role)
|
||||
{
|
||||
if (_roles.ContainsKey(t))
|
||||
if (_roles.Contains(role))
|
||||
{
|
||||
throw new ArgumentException($"We already have this role: {t}");
|
||||
throw new ArgumentException($"We already have this role: {role}");
|
||||
}
|
||||
|
||||
var role = (Role)Activator.CreateInstance(t, this);
|
||||
_roles[t] = role;
|
||||
_roles.Add(role);
|
||||
role.Greet();
|
||||
return role;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a role from this mind.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the role to remove.</typeparam>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if we do not have this role.
|
||||
/// </exception>
|
||||
public void RemoveRole<T>() where T : Role
|
||||
{
|
||||
RemoveRole(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a role from this mind.
|
||||
/// </summary>
|
||||
@@ -140,42 +114,16 @@ namespace Content.Server.Mobs
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if we do not have this role.
|
||||
/// </exception>
|
||||
public void RemoveRole(Type t)
|
||||
public void RemoveRole(Role role)
|
||||
{
|
||||
if (!_roles.ContainsKey(t))
|
||||
if (!_roles.Contains(role))
|
||||
{
|
||||
throw new ArgumentException($"We do not have this role: {t}");
|
||||
throw new ArgumentException($"We do not have this role: {role}");
|
||||
}
|
||||
|
||||
// This can definitely get more complex removal hooks later,
|
||||
// when we need it.
|
||||
_roles.Remove(t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a role of a certain type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the role to get.</typeparam>
|
||||
/// <returns>The role's instance.</returns>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if we do not have a role of this type.
|
||||
/// </exception>
|
||||
public T GetRole<T>() where T : Role
|
||||
{
|
||||
return (T)_roles[typeof(T)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a role of a certain type.
|
||||
/// </summary>
|
||||
/// <param name="t">The type of the role to get.</param>
|
||||
/// <returns>The role's instance.</returns>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if we do not have a role of this type.
|
||||
/// </exception>
|
||||
public Role GetRole(Type t)
|
||||
{
|
||||
return _roles[t];
|
||||
_roles.Remove(role);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
35
Content.Server/Mobs/Roles/Job.cs
Normal file
35
Content.Server/Mobs/Roles/Job.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Shared.Jobs;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.Mobs.Roles
|
||||
{
|
||||
public class Job : Role
|
||||
{
|
||||
private readonly JobPrototype _jobPrototype;
|
||||
|
||||
public override string Name { get; }
|
||||
|
||||
public String StartingGear => _jobPrototype.StartingGear;
|
||||
|
||||
public Job(Mind mind, JobPrototype jobPrototype) : base(mind)
|
||||
{
|
||||
_jobPrototype = jobPrototype;
|
||||
Name = jobPrototype.Name;
|
||||
}
|
||||
|
||||
public override void Greet()
|
||||
{
|
||||
base.Greet();
|
||||
|
||||
var chat = IoCManager.Resolve<IChatManager>();
|
||||
chat.DispatchServerMessage(
|
||||
Mind.Session,
|
||||
String.Format("You're a new {0}. Do your best!", Name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
27
Content.Shared/Jobs/JobPrototype.cs
Normal file
27
Content.Shared/Jobs/JobPrototype.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Shared.Jobs
|
||||
{
|
||||
[Prototype("job")]
|
||||
public class JobPrototype : IPrototype, IIndexedPrototype
|
||||
{
|
||||
public string ID { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
|
||||
public string StartingGear { get; private set; }
|
||||
public IEnumerable<string> Department { get; private set; }
|
||||
|
||||
public void LoadFrom(YamlMappingNode mapping)
|
||||
{
|
||||
ID = mapping.GetNode("id").AsString();
|
||||
Name = mapping.GetNode("name").ToString();
|
||||
StartingGear = mapping.GetNode("startingGear").ToString();
|
||||
Department = mapping.GetNode("department").AllNodes.Select(i => i.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Content.Shared/Jobs/StartingGearPrototype.cs
Normal file
30
Content.Shared/Jobs/StartingGearPrototype.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Shared.Jobs
|
||||
{
|
||||
[Prototype("startingGear")]
|
||||
public class StartingGearPrototype : IPrototype, IIndexedPrototype
|
||||
{
|
||||
private string _id;
|
||||
private Dictionary<string, string> _equipment;
|
||||
|
||||
[ViewVariables]
|
||||
public string ID => _id;
|
||||
|
||||
[ViewVariables]
|
||||
public Dictionary<string, string> Equipment => _equipment;
|
||||
|
||||
public void LoadFrom(YamlMappingNode mapping)
|
||||
{
|
||||
var serializer = YamlObjectSerializer.NewReader(mapping);
|
||||
|
||||
serializer.DataField(ref _id, "id", string.Empty);
|
||||
serializer.DataField(ref _equipment, "equipment", new Dictionary<string, string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Resources/Prototypes/Jobs/StartingGear/assistantGear.yml
Normal file
6
Resources/Prototypes/Jobs/StartingGear/assistantGear.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- type: startingGear
|
||||
id: AssistantGear
|
||||
equipment:
|
||||
innerclothing: UniformAssistant
|
||||
backpack: BackpackClothing
|
||||
shoes: ShoesBlack
|
||||
231
Resources/Prototypes/Jobs/job.yml
Normal file
231
Resources/Prototypes/Jobs/job.yml
Normal file
@@ -0,0 +1,231 @@
|
||||
- type: job
|
||||
id: Captain
|
||||
name: "Captain"
|
||||
startingGear: CaptainGear
|
||||
department:
|
||||
- Command
|
||||
|
||||
- type: job
|
||||
id: HeadOfPersonnel
|
||||
name: "Head Of Personnel"
|
||||
startingGear: HeadOfPersonnelGear
|
||||
department:
|
||||
- Command
|
||||
- Civilian
|
||||
- Cargo
|
||||
|
||||
- type: job
|
||||
id: HeadOfSecurity
|
||||
name: "Head Of Security"
|
||||
startingGear: HeadOfSecurityGear
|
||||
department:
|
||||
- Command
|
||||
- Security
|
||||
|
||||
- type: job
|
||||
id: ChiefEngineer
|
||||
name: "Chief Engineer"
|
||||
startingGear: ChiefEngineerGear
|
||||
department:
|
||||
- Command
|
||||
- Engineering
|
||||
|
||||
- type: job
|
||||
id: ResearchDirector
|
||||
name: "Research Director"
|
||||
startingGear: ResearchDirectorGear
|
||||
department:
|
||||
- Command
|
||||
- Science
|
||||
|
||||
- type: job
|
||||
id: ChiefMedicalOfficer
|
||||
name: "Chief Medical Officer"
|
||||
startingGear: ChiefMedicalOfficerGear
|
||||
department:
|
||||
- Command
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: StationEngineer
|
||||
name: "Station Engineer"
|
||||
startingGear: StationEngineerGear
|
||||
department:
|
||||
- Engineering
|
||||
|
||||
- type: job
|
||||
id: AtmosphericTechnician
|
||||
name: "Atmospheric Technician"
|
||||
startingGear: AtmosphericTechnicianGear
|
||||
department:
|
||||
- Engineering
|
||||
|
||||
- type: job
|
||||
id: Mechanic
|
||||
name: "Mechanic"
|
||||
startingGear: MechanicGear
|
||||
department:
|
||||
- Engineering
|
||||
- Science
|
||||
|
||||
- type: job
|
||||
id: MedicalDoctor
|
||||
name: "Medical Doctor"
|
||||
startingGear: MedicalDoctorGear
|
||||
department:
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: Geneticist
|
||||
name: "Geneticist"
|
||||
startingGear: GeneticistGear
|
||||
department:
|
||||
- Science
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: Virologist
|
||||
name: "Virologist"
|
||||
startingGear: VirologistGear
|
||||
department:
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: Paramedic
|
||||
name: "Paramedic"
|
||||
startingGear: ParamedicGear
|
||||
department:
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: Chemist
|
||||
name: "Chemist"
|
||||
startingGear: ChemistGear
|
||||
department:
|
||||
- Medical
|
||||
|
||||
- type: job
|
||||
id: Scientist
|
||||
name: "Scientist"
|
||||
startingGear: ScientistGear
|
||||
department:
|
||||
- Science
|
||||
|
||||
- type: job
|
||||
id: Roboticist
|
||||
name: "Roboticist"
|
||||
startingGear: RoboticistGear
|
||||
department:
|
||||
- Science
|
||||
|
||||
- type: job
|
||||
id: Bartender
|
||||
name: "Bartender"
|
||||
startingGear: BartenderGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Botanist
|
||||
name: "Botanist"
|
||||
startingGear: BotanistGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Chef
|
||||
name: "Chef"
|
||||
startingGear: ChefGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Janitor
|
||||
name: "Janitor"
|
||||
startingGear: JanitorGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Librarian
|
||||
name: "Librarian"
|
||||
startingGear: LibrarianGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: InternalAffairsAgent
|
||||
name: "Internal Affairs Agent"
|
||||
startingGear: InternalAffairsAgentGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Chaplain
|
||||
name: "Chaplain"
|
||||
startingGear: ChaplainGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Clown
|
||||
name: "Clown"
|
||||
startingGear: ClownGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Mime
|
||||
name: "Mime"
|
||||
startingGear: MimeGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Assistant
|
||||
name: "Assistant"
|
||||
startingGear: AssistantGear
|
||||
department:
|
||||
- Civilian
|
||||
|
||||
- type: job
|
||||
id: Quartermaster
|
||||
name: "Quartermaster"
|
||||
startingGear: QuartermasterGear
|
||||
department:
|
||||
- Cargo
|
||||
|
||||
- type: job
|
||||
id: CargoTechnician
|
||||
name: "Cargo Technician"
|
||||
startingGear: CargoTechnicianGear
|
||||
department:
|
||||
- Cargo
|
||||
|
||||
- type: job
|
||||
id: ShaftMiner
|
||||
name: "Shaft Miner"
|
||||
startingGear: ShaftMinerGear
|
||||
department:
|
||||
- Cargo
|
||||
|
||||
- type: job
|
||||
id: Warden
|
||||
name: "Warden"
|
||||
startingGear: WardenGear
|
||||
department:
|
||||
- Security
|
||||
|
||||
- type: job
|
||||
id: Detective
|
||||
name: "Detective"
|
||||
startingGear: DetectiveGear
|
||||
department:
|
||||
- Security
|
||||
|
||||
- type: job
|
||||
id: SecurityOfficer
|
||||
name: "Security Officer"
|
||||
startingGear: SecurityOfficerGear
|
||||
department:
|
||||
- Security
|
||||
Reference in New Issue
Block a user