monkey reinforcement teleporters can now select between kobold or monkey with a verb (#25982)
* inital * Update animals.yml * Update animals.yml * Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * selecting different role will change the description and name * fix name * gargh * the review Hello * e --------- Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Ghost.Roles.Components
|
||||
{
|
||||
@@ -10,17 +9,22 @@ namespace Content.Server.Ghost.Roles.Components
|
||||
[Access(typeof(GhostRoleSystem))]
|
||||
public sealed partial class GhostRoleMobSpawnerComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("deleteOnSpawn")]
|
||||
[DataField]
|
||||
public bool DeleteOnSpawn = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("availableTakeovers")]
|
||||
[DataField]
|
||||
public int AvailableTakeovers = 1;
|
||||
|
||||
[ViewVariables]
|
||||
public int CurrentTakeovers = 0;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string? Prototype { get; private set; }
|
||||
[DataField]
|
||||
public EntProtoId? Prototype;
|
||||
|
||||
/// <summary>
|
||||
/// If this ghostrole spawner has multiple selectable ghostrole prototypes.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<string> SelectablePrototypes = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ using Robust.Shared.Enums;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Collections;
|
||||
|
||||
namespace Content.Server.Ghost.Roles
|
||||
{
|
||||
@@ -37,6 +41,8 @@ namespace Content.Server.Ghost.Roles
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roleSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
private uint _nextRoleIdentifier;
|
||||
private bool _needsUpdateGhostRoleCount = true;
|
||||
@@ -63,6 +69,7 @@ namespace Content.Server.Ghost.Roles
|
||||
SubscribeLocalEvent<GhostRoleComponent, EntityUnpausedEvent>(OnUnpaused);
|
||||
SubscribeLocalEvent<GhostRoleMobSpawnerComponent, TakeGhostRoleEvent>(OnSpawnerTakeRole);
|
||||
SubscribeLocalEvent<GhostTakeoverAvailableComponent, TakeGhostRoleEvent>(OnTakeoverTakeRole);
|
||||
SubscribeLocalEvent<GhostRoleMobSpawnerComponent, GetVerbsEvent<Verb>>(OnVerb);
|
||||
_playerManager.PlayerStatusChanged += PlayerStatusChanged;
|
||||
}
|
||||
|
||||
@@ -100,11 +107,11 @@ namespace Content.Server.Ghost.Roles
|
||||
|
||||
public void OpenEui(ICommonSession session)
|
||||
{
|
||||
if (session.AttachedEntity is not {Valid: true} attached ||
|
||||
if (session.AttachedEntity is not { Valid: true } attached ||
|
||||
!EntityManager.HasComponent<GhostComponent>(attached))
|
||||
return;
|
||||
|
||||
if(_openUis.ContainsKey(session))
|
||||
if (_openUis.ContainsKey(session))
|
||||
CloseEui(session);
|
||||
|
||||
var eui = _openUis[session] = new GhostRolesEui();
|
||||
@@ -250,7 +257,7 @@ namespace Content.Server.Ghost.Roles
|
||||
if (metaQuery.GetComponent(uid).EntityPaused)
|
||||
continue;
|
||||
|
||||
roles.Add(new GhostRoleInfo {Identifier = id, Name = role.RoleName, Description = role.RoleDescription, Rules = role.RoleRules, Requirements = role.Requirements});
|
||||
roles.Add(new GhostRoleInfo { Identifier = id, Name = role.RoleName, Description = role.RoleDescription, Rules = role.RoleRules, Requirements = role.Requirements });
|
||||
}
|
||||
|
||||
return roles.ToArray();
|
||||
@@ -407,6 +414,63 @@ namespace Content.Server.Ghost.Roles
|
||||
|
||||
args.TookRole = true;
|
||||
}
|
||||
|
||||
private void OnVerb(EntityUid uid, GhostRoleMobSpawnerComponent component, GetVerbsEvent<Verb> args)
|
||||
{
|
||||
var prototypes = component.SelectablePrototypes;
|
||||
if (prototypes.Count < 1)
|
||||
return;
|
||||
|
||||
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
|
||||
return;
|
||||
|
||||
var verbs = new ValueList<Verb>();
|
||||
|
||||
foreach (var prototypeID in prototypes)
|
||||
{
|
||||
if (_prototype.TryIndex<GhostRolePrototype>(prototypeID, out var prototype))
|
||||
{
|
||||
var verb = CreateVerb(uid, component, args.User, prototype);
|
||||
verbs.Add(verb);
|
||||
}
|
||||
}
|
||||
|
||||
args.Verbs.UnionWith(verbs);
|
||||
}
|
||||
|
||||
private Verb CreateVerb(EntityUid uid, GhostRoleMobSpawnerComponent component, EntityUid userUid, GhostRolePrototype prototype)
|
||||
{
|
||||
var verbText = Loc.GetString(prototype.Name);
|
||||
|
||||
return new Verb()
|
||||
{
|
||||
Text = verbText,
|
||||
Disabled = component.Prototype == prototype.EntityPrototype,
|
||||
Category = VerbCategory.SelectType,
|
||||
Act = () => SetMode(uid, prototype, verbText, component, userUid)
|
||||
};
|
||||
}
|
||||
|
||||
public void SetMode(EntityUid uid, GhostRolePrototype prototype, string verbText, GhostRoleMobSpawnerComponent? component, EntityUid? userUid = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
var ghostrolecomp = EnsureComp<GhostRoleComponent>(uid);
|
||||
|
||||
component.Prototype = prototype.EntityPrototype;
|
||||
ghostrolecomp.RoleName = verbText;
|
||||
ghostrolecomp.RoleDescription = prototype.Description;
|
||||
ghostrolecomp.RoleRules = prototype.Rules;
|
||||
|
||||
// Dirty(ghostrolecomp);
|
||||
|
||||
if (userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("ghostrole-spawner-select", ("mode", verbText));
|
||||
_popupSystem.PopupEntity(msg, uid, userUid.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AnyCommand]
|
||||
@@ -417,7 +481,7 @@ namespace Content.Server.Ghost.Roles
|
||||
public string Help => $"{Command}";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if(shell.Player != null)
|
||||
if (shell.Player != null)
|
||||
EntitySystem.Get<GhostRoleSystem>().OpenEui(shell.Player);
|
||||
else
|
||||
shell.WriteLine("You can only open the ghost roles UI on a client.");
|
||||
|
||||
38
Content.Shared/Ghost/Roles/GhostRolePrototype.cs
Normal file
38
Content.Shared/Ghost/Roles/GhostRolePrototype.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Ghost.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// For selectable ghostrole prototypes in ghostrole spawners.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class GhostRolePrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the ghostrole.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The description of the ghostrole.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Description { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The entity prototype of the ghostrole
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string EntityPrototype = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Rules of the ghostrole
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Rules = default!;
|
||||
}
|
||||
@@ -228,6 +228,10 @@ ghost-role-information-syndicate-monkey-reinforcement-name = Syndicate Monkey Ag
|
||||
ghost-role-information-syndicate-monkey-reinforcement-description = Someone needs reinforcements. You, a trained monkey, will help them.
|
||||
ghost-role-information-syndicate-monkey-reinforcement-rules = Normal syndicate antagonist rules apply. Work with whoever called you in, and don't harm them.
|
||||
|
||||
ghost-role-information-syndicate-kobold-reinforcement-name = Syndicate Kobold Agent
|
||||
ghost-role-information-syndicate-kobold-reinforcement-description = Someone needs reinforcements. You, a trained kobold, will help them.
|
||||
ghost-role-information-syndicate-kobold-reinforcement-rules = Normal syndicate antagonist rules apply. Work with whoever called you in, and don't harm them.
|
||||
|
||||
ghost-role-information-artifact-name = Sentient Artifact
|
||||
ghost-role-information-artifact-description =
|
||||
Enact your eldritch whims.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ghostrole-spawner-select = Selected: {$mode}
|
||||
@@ -121,8 +121,8 @@ uplink-agent-id-card-desc = A modified ID card that can copy accesses from other
|
||||
uplink-black-jetpack-name = Black Jetpack
|
||||
uplink-black-jetpack-desc = A black jetpack. It allows you to fly around in space. Refills not included, use your fuel wisely.
|
||||
|
||||
uplink-reinforcement-radio-monkey-name = Monkey Reinforcement Teleporter
|
||||
uplink-reinforcement-radio-monkey-desc = Call in a trained monkey to assist you. Comes with a single syndicate cigarette.
|
||||
uplink-reinforcement-radio-ancestor-name = Genetic Ancestor Reinforcement Teleporter
|
||||
uplink-reinforcement-radio-ancestor-desc = Call in a trained ancestor of your choosing to assist you. Comes with a single syndicate cigarette.
|
||||
|
||||
uplink-reinforcement-radio-name = Reinforcement Teleporter
|
||||
uplink-reinforcement-radio-desc = Radio in a reinforcement agent of extremely questionable quality. No off button, buy this if you're ready to party. They have a pistol with no reserve ammo, and a knife. That's it.
|
||||
|
||||
@@ -937,10 +937,10 @@
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkReinforcementRadioSyndicateMonkey
|
||||
name: uplink-reinforcement-radio-monkey-name
|
||||
description: uplink-reinforcement-radio-monkey-desc
|
||||
productEntity: ReinforcementRadioSyndicateMonkey
|
||||
id: UplinkReinforcementRadioSyndicateAncestor
|
||||
name: uplink-reinforcement-radio-ancestor-name
|
||||
description: uplink-reinforcement-radio-ancestor-desc
|
||||
productEntity: ReinforcementRadioSyndicateAncestor
|
||||
icon: { sprite: Objects/Devices/communication.rsi, state: old-radio }
|
||||
cost:
|
||||
Telecrystal: 6
|
||||
@@ -953,10 +953,10 @@
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkReinforcementRadioSyndicateMonkeyNukeops # Version for Nukeops that spawns a syndicate monkey with the NukeOperative component.
|
||||
name: uplink-reinforcement-radio-monkey-name
|
||||
description: uplink-reinforcement-radio-monkey-desc
|
||||
productEntity: ReinforcementRadioSyndicateMonkeyNukeops
|
||||
id: UplinkReinforcementRadioSyndicateAncestorNukeops # Version for Nukeops that spawns a syndicate monkey with the NukeOperative component.
|
||||
name: uplink-reinforcement-radio-ancestor-name
|
||||
description: uplink-reinforcement-radio-ancestor-desc
|
||||
productEntity: ReinforcementRadioSyndicateAncestorNukeops
|
||||
icon: { sprite: Objects/Devices/communication.rsi, state: old-radio }
|
||||
cost:
|
||||
Telecrystal: 6
|
||||
|
||||
@@ -1324,9 +1324,10 @@
|
||||
|
||||
- type: entity
|
||||
name: kobold
|
||||
id: MobKobold
|
||||
id: MobBaseKobold
|
||||
parent: MobBaseAncestor
|
||||
description: Cousins to the sentient race of lizard people, kobolds blend in with their natural habitat and are as nasty as monkeys; ready to pull out your hair and stab you to death.
|
||||
abstract: true
|
||||
components:
|
||||
- type: NameIdentifier
|
||||
group: Kobold
|
||||
@@ -1420,15 +1421,6 @@
|
||||
spawned:
|
||||
- id: FoodMeat
|
||||
amount: 2
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
types:
|
||||
Blunt: 2
|
||||
Piercing: 7
|
||||
groups:
|
||||
Burn: 3
|
||||
clumsySound:
|
||||
path: /Audio/Voice/Reptilian/reptilian_scream.ogg
|
||||
- type: AlwaysRevolutionaryConvertible
|
||||
- type: GhostTakeoverAvailable
|
||||
- type: SentienceTarget
|
||||
@@ -1439,6 +1431,55 @@
|
||||
name: ghost-role-information-kobold-name
|
||||
description: ghost-role-information-kobold-description
|
||||
|
||||
- type: entity
|
||||
name: kobold
|
||||
id: MobKobold
|
||||
parent: MobBaseKobold
|
||||
description: Cousins to the sentient race of lizard people, kobolds blend in with their natural habitat and are as nasty as monkeys; ready to pull out your hair and stab you to death.
|
||||
components:
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
types:
|
||||
Blunt: 2
|
||||
Piercing: 7
|
||||
groups:
|
||||
Burn: 3
|
||||
clumsySound:
|
||||
path: /Audio/Voice/Reptilian/reptilian_scream.ogg
|
||||
|
||||
- type: entity
|
||||
id: MobBaseSyndicateKobold
|
||||
parent: MobBaseKobold
|
||||
suffix: syndicate base
|
||||
components:
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
75: Critical
|
||||
200: Dead
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
- Syndicate
|
||||
- type: Loadout
|
||||
prototypes: [SyndicateOperativeGearMonkey]
|
||||
|
||||
- type: entity
|
||||
id: MobKoboldSyndicateAgent
|
||||
parent: MobBaseSyndicateKobold
|
||||
suffix: syndicate agent
|
||||
components:
|
||||
# make the player a traitor once its taken
|
||||
- type: AutoTraitor
|
||||
giveUplink: false
|
||||
giveObjectives: false
|
||||
|
||||
- type: entity
|
||||
id: MobKoboldSyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink
|
||||
parent: MobBaseSyndicateKobold
|
||||
suffix: NukeOps
|
||||
components:
|
||||
- type: NukeOperative
|
||||
|
||||
- type: entity
|
||||
name: guidebook monkey
|
||||
parent: MobMonkey
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
- type: entity
|
||||
parent: ReinforcementRadioSyndicate
|
||||
id: ReinforcementRadioSyndicateMonkey
|
||||
name: syndicate monkey reinforcement radio
|
||||
description: Calls in a specially trained monkey to assist you.
|
||||
id: ReinforcementRadioSyndicateAncestor
|
||||
name: syndicate genetic ancestor reinforcement radio
|
||||
description: Calls in a specially trained ancestor of your choosing to assist you.
|
||||
components:
|
||||
- type: GhostRole
|
||||
name: ghost-role-information-syndicate-monkey-reinforcement-name
|
||||
@@ -39,14 +39,16 @@
|
||||
rules: ghost-role-information-syndicate-monkey-reinforcement-rules
|
||||
- type: GhostRoleMobSpawner
|
||||
prototype: MobMonkeySyndicateAgent
|
||||
selectablePrototypes: ["SyndicateMonkey", "SyndicateKobold"]
|
||||
|
||||
- type: entity
|
||||
parent: ReinforcementRadioSyndicateMonkey
|
||||
id: ReinforcementRadioSyndicateMonkeyNukeops # Reinforcement radio exclusive to nukeops uplink
|
||||
parent: ReinforcementRadioSyndicateAncestor
|
||||
id: ReinforcementRadioSyndicateAncestorNukeops # Reinforcement radio exclusive to nukeops uplink
|
||||
suffix: NukeOps
|
||||
components:
|
||||
- type: GhostRoleMobSpawner
|
||||
prototype: MobMonkeySyndicateAgentNukeops
|
||||
selectablePrototypes: ["SyndicateMonkeyNukeops", "SyndicateKoboldNukeops"]
|
||||
|
||||
- type: entity
|
||||
parent: ReinforcementRadioSyndicate
|
||||
|
||||
27
Resources/Prototypes/Roles/Ghostroles/syndicate.yml
Normal file
27
Resources/Prototypes/Roles/Ghostroles/syndicate.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
- type: ghostRole
|
||||
id: SyndicateKobold
|
||||
name: ghost-role-information-syndicate-kobold-reinforcement-name
|
||||
description: ghost-role-information-syndicate-kobold-reinforcement-description
|
||||
rules: ghost-role-information-syndicate-kobold-reinforcement-rules
|
||||
entityPrototype: MobKoboldSyndicateAgent
|
||||
|
||||
- type: ghostRole
|
||||
id: SyndicateKoboldNukeops
|
||||
name: ghost-role-information-syndicate-kobold-reinforcement-name
|
||||
description: ghost-role-information-syndicate-kobold-reinforcement-description
|
||||
rules: ghost-role-information-syndicate-kobold-reinforcement-rules
|
||||
entityPrototype: MobKoboldSyndicateAgentNukeops
|
||||
|
||||
- type: ghostRole
|
||||
id: SyndicateMonkey
|
||||
name: ghost-role-information-syndicate-monkey-reinforcement-name
|
||||
description: ghost-role-information-syndicate-monkey-reinforcement-description
|
||||
rules: ghost-role-information-syndicate-monkey-reinforcement-name
|
||||
entityPrototype: MobMonkeySyndicateAgent
|
||||
|
||||
- type: ghostRole
|
||||
id: SyndicateMonkeyNukeops
|
||||
name: ghost-role-information-syndicate-monkey-reinforcement-name
|
||||
description: ghost-role-information-syndicate-monkey-reinforcement-description
|
||||
rules: ghost-role-information-syndicate-monkey-reinforcement-name
|
||||
entityPrototype: MobMonkeySyndicateAgentNukeops
|
||||
@@ -327,3 +327,5 @@ WeaponPistolN1984Nonlethal: WeaponPistolN1984
|
||||
WeaponSubMachineGunVectorRubber: WeaponSubMachineGunVector
|
||||
WeaponSubMachineGunDrozdRubber: WeaponSubMachineGunDrozd
|
||||
WeaponRifleLecterRubber: WeaponRifleLecter
|
||||
ReinforcementRadioSyndicateMonkey: ReinforcementRadioSyndicateAncestor
|
||||
ReinforcementRadioSyndicateMonkeyNukeops: ReinforcementRadioSyndicateAncestorNukeops
|
||||
|
||||
Reference in New Issue
Block a user