using Content.Server.Shuttles.Components;
using Content.Server.Station.Systems;
using Content.Shared.Antag;
+using Content.Shared.Clothing;
using Content.Shared.GameTicking;
using Content.Shared.GameTicking.Components;
using Content.Shared.Ghost;
using Content.Shared.Humanoid;
using Content.Shared.Players;
+using Content.Shared.Preferences.Loadouts;
+using Content.Shared.Roles;
using Content.Shared.Whitelist;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IServerPreferencesManager _pref = default!;
+ [Dependency] private readonly ActorSystem _actors = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly GhostRoleSystem _ghostRole = default!;
[Dependency] private readonly JobSystem _jobs = default!;
+ [Dependency] private readonly LoadoutSystem _loadout = default!;
[Dependency] private readonly MindSystem _mind = default!;
+ [Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly RoleSystem _role = default!;
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
[Dependency] private readonly TransformSystem _transform = default!;
// The following is where we apply components, equipment, and other changes to our antagonist entity.
EntityManager.AddComponents(player, def.Components);
- _stationSpawning.EquipStartingGear(player, def.StartingGear);
+
+ // Equip the entity's RoleLoadout and LoadoutGroup
+ List<ProtoId<StartingGearPrototype>>? gear = new();
+ if (def.StartingGear is not null)
+ gear.Add(def.StartingGear.Value);
+
+ _loadout.Equip(player, gear, def.RoleLoadout);
if (session != null)
{
using Content.Server.Administration.Systems;
using Content.Shared.Antag;
using Content.Shared.Destructible.Thresholds;
+using Content.Shared.Preferences.Loadouts;
using Content.Shared.Roles;
using Content.Shared.Storage;
using Content.Shared.Whitelist;
[DataField]
public ProtoId<StartingGearPrototype>? StartingGear;
+ /// <summary>
+ /// A list of role loadouts, from which a randomly selected one will be equipped.
+ /// </summary>
+ [DataField]
+ public List<ProtoId<RoleLoadoutPrototype>>? RoleLoadout;
+
/// <summary>
/// A briefing shown to the player.
/// </summary>
private void OnMapInit(EntityUid uid, LoadoutComponent component, MapInitEvent args)
{
- // Use starting gear if specified
- if (component.StartingGear != null)
+ Equip(uid, component.StartingGear, component.RoleLoadout);
+ }
+
+ public void Equip(EntityUid uid, List<ProtoId<StartingGearPrototype>>? startingGear,
+ List<ProtoId<RoleLoadoutPrototype>>? loadoutGroups)
+ {
+ // First, randomly pick a startingGear profile from those specified, and equip it.
+ if (startingGear != null && startingGear.Count > 0)
+ _station.EquipStartingGear(uid, _random.Pick(startingGear));
+
+ if (loadoutGroups == null)
{
- _station.EquipStartingGear(uid, _random.Pick(component.StartingGear));
+ GearEquipped(uid);
return;
}
- if (component.RoleLoadout == null)
- return;
-
- // ...otherwise equip from role loadout
- var id = _random.Pick(component.RoleLoadout);
+ // Then, randomly pick a RoleLoadout profile from those specified, and process/equip all LoadoutGroups from it.
+ // For non-roundstart mobs there is no SelectedLoadout data, so minValue must be set in each LoadoutGroup to force selection.
+ var id = _random.Pick(loadoutGroups);
var proto = _protoMan.Index(id);
var loadout = new RoleLoadout(id);
loadout.SetDefault(GetProfile(uid), _actors.GetSession(uid), _protoMan, true);
_station.EquipRoleLoadout(uid, loadout, proto);
+
+ GearEquipped(uid);
+ }
+
+ public void GearEquipped(EntityUid uid)
+ {
+ var ev = new StartingGearEquippedEvent(uid);
+ RaiseLocalEvent(uid, ref ev);
}
public HumanoidCharacterProfile GetProfile(EntityUid? uid)
loadout-group-survival-syndicate = Github is forcing me to write text that is literally twice-impossible for the player to ever see, send help
loadout-group-breath-tool = Species-dependent breath tools
loadout-group-tank-harness = Species-specific survival equipment
+loadout-group-EVA-tank = Species-specific gas tank
# Command
loadout-group-captain-head = Captain head
minimumPlayers: 30
- type: SpaceSpawnRule
- type: AntagLoadProfileRule
- # Vox disabled until loadouts work on AntagSelection-based spawns
- speciesOverride: Human
- speciesOverrideBlacklist:
- - Vox
- type: AntagObjectives
objectives:
- StealResearchObjective
max: 1
pickPlayer: false
startingGear: SpaceNinjaGear
+ roleLoadout:
+ - RoleSurvivalEVA
briefing:
text: ninja-role-greeting
color: Green
#Species that do not work with nukies should be included in this list.
#Once the issues are fixed the species should be removed from this list to be enabled.
#Balance concerns are not a valid reason to disable a species, except for high-impact Nukie-specific exploits.
- - Vox
+ #- Vox
- type: entity
parent: BaseNukeopsRule
fallbackRoles: [ Nukeops, NukeopsMedic ]
spawnerPrototype: SpawnPointNukeopsCommander
startingGear: SyndicateCommanderGearFull
+ roleLoadout:
+ - RoleSurvivalSyndicate
components:
- type: NukeOperative
- type: RandomMetadata
fallbackRoles: [ Nukeops, NukeopsCommander ]
spawnerPrototype: SpawnPointNukeopsMedic
startingGear: SyndicateOperativeMedicFull
+ roleLoadout:
+ - RoleSurvivalSyndicate
components:
- type: NukeOperative
- type: RandomMetadata
max: 3
playerRatio: 10
startingGear: SyndicateOperativeGearFull
+ roleLoadout:
+ - RoleSurvivalSyndicate
components:
- type: NukeOperative
- type: RandomMetadata
# Pre-equipped species gear
-# Full Tank Equipped
+# Full tank for vox as part of any Survival loadout
- type: loadout
- id: LoadoutSpeciesEVANitrogen
+ id: LoadoutSpeciesVoxNitrogen
effects:
- !type:GroupLoadoutEffect
proto: EffectSpeciesVox
equipment:
suitstorage: NitrogenTankFilled
+# Full EVA Tank, Any Species
+- type: loadout
+ id: LoadoutSpeciesEVANitrogen
+ effects:
+ - !type:GroupLoadoutEffect
+ proto: NitrogenBreather
+ equipment:
+ suitstorage: NitrogenTankFilled
+
+- type: loadout
+ id: LoadoutSpeciesEVAOxygen
+ effects:
+ - !type:GroupLoadoutEffect
+ proto: OxygenBreather
+ equipment:
+ suitstorage: OxygenTankFilled
+
# Tank Harness
- type: loadout
id: LoadoutTankHarness
loadouts:
- EmergencyNitrogen
- EmergencyOxygen
+ - LoadoutSpeciesVoxNitrogen
+
+- type: loadoutGroup
+ id: GroupEVATank
+ name: loadout-group-EVA-tank
+ hidden: true
+ loadouts:
- LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesEVAOxygen
# Command
- type: loadoutGroup
loadouts:
- EmergencyNitrogenClown
- EmergencyOxygenClown
- - LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesVoxNitrogen
- type: loadoutGroup
id: MimeHead
loadouts:
- EmergencyNitrogenExtended
- EmergencyOxygenExtended
- - LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesVoxNitrogen
# Science
- type: loadoutGroup
loadouts:
- EmergencyNitrogenSecurity
- EmergencyOxygenSecurity
- - LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesVoxNitrogen
# Medical
- type: loadoutGroup
loadouts:
- EmergencyNitrogenMedical
- EmergencyOxygenMedical
- - LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesVoxNitrogen
# Wildcards
- type: loadoutGroup
loadouts:
- EmergencyNitrogenSyndicate
- EmergencyOxygenSyndicate
- - LoadoutSpeciesEVANitrogen
+ - LoadoutSpeciesVoxNitrogen
- type: loadoutGroup
id: GroupSpeciesBreathTool
- SurvivalSyndicate
- GroupSpeciesBreathTool
- GroupTankHarness
+
+- type: roleLoadout
+ id: RoleSurvivalEVA
+ groups:
+ - GroupEVATank
+ - SurvivalExtended
pocket1: SpiderCharge
pocket2: PinpointerStation
belt: EnergyKatana
- suitstorage: OxygenTankFilled
inhand:
- JetpackBlackFilled
storage:
back: # belt holds katana so satchel has the tools for sabotaging things
- - BoxSurvival
- Crowbar
- Wrench
- Screwdriver
belt: ClothingBeltMilitaryWebbing
storage:
back:
- - BoxSurvivalSyndicate
- WeaponPistolViper
- PinpointerSyndicateNuclear
- DeathAcidifierImplanter
storage:
back:
- SyndiHypo
- - BoxSurvivalSyndicate
- SawAdvanced
- Cautery
- CombatKnife