diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 9ee9f0e14738..3adb22909582 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -26,6 +26,7 @@ new /obj/item/clothing/under/syndicate(src) new /obj/item/clothing/under/syndicate/skirt(src) new /obj/item/clothing/shoes/sneakers/black(src) + new /obj/item/mod/module/plasma_stabilizer(src) /obj/structure/closet/syndicate/nuclear desc = "It's a storage unit for a Syndicate boarding party." diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index d3e72238879b..bca7ccb34f9e 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -104,7 +104,9 @@ var/special_role_name = ROLE_NUCLEAR_OPERATIVE /// The applied outfit var/datum/outfit/syndicate/outfit = /datum/outfit/syndicate/reinforcement - /// The antag datam applied + /// The outfit given to plasmaman operatives + var/datum/outfit/syndicate/plasma_outfit = /datum/outfit/syndicate/reinforcement/plasmaman + /// The antag datum applied var/datum/antagonist/nukeop/antag_datum = /datum/antagonist/nukeop /// Style used by the droppod var/pod_style = STYLE_SYNDICATE diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm index 2b21764e0835..b94c33d326ad 100644 --- a/code/modules/antagonists/nukeop/nukeop.dm +++ b/code/modules/antagonists/nukeop/nukeop.dm @@ -8,9 +8,13 @@ show_to_ghosts = TRUE hijack_speed = 2 //If you can't take out the station, take the shuttle instead. suicide_cry = "FOR THE SYNDICATE!!" + /// Which nukie team are we on? var/datum/team/nuclear/nuke_team - var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. - var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + /// If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/always_new_team = FALSE + /// Should the user be moved to default spawnpoint after being granted this datum. + var/send_to_spawnpoint = TRUE + /// The DEFAULT outfit we will give to players granted this datum var/nukeop_outfit = /datum/outfit/syndicate preview_outfit = /datum/outfit/nuclear_operative_elite @@ -34,9 +38,12 @@ if(!nukeop_outfit) // this variable is null in instances where an antagonist datum is granted via enslaving the mind (/datum/mind/proc/enslave_mind_to_creator), like in golems. return - operative.set_species(/datum/species/human) //Plasmamen burn up otherwise, and besides, all other species are vulnerable to asimov AIs. Let's standardize all operatives being human. + // If our nuke_ops_species pref is set to TRUE, (or we have no client) make us a human + if(isnull(operative.client) || operative.client.prefs.read_preference(/datum/preference/toggle/nuke_ops_species)) + operative.set_species(/datum/species/human) + + operative.equip_species_outfit(nukeop_outfit) - operative.equipOutfit(nukeop_outfit) return TRUE /datum/antagonist/nukeop/greet() @@ -233,7 +240,9 @@ name = "Nuclear Operative Leader" nukeop_outfit = /datum/outfit/syndicate/leader always_new_team = TRUE + /// Randomly chosen honorific, for distinction var/title + /// The nuclear challenge remote we will spawn this player with. var/challengeitem = /obj/item/nuclear_challenge /datum/antagonist/nukeop/leader/memorize_code() diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 4b8560dc9186..28ba70e13ceb 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -13,18 +13,33 @@ skillchips = list(/obj/item/skillchip/disk_verifier) box = /obj/item/storage/box/survival/syndie + /// Amount of TC to automatically store in this outfit's uplink. var/tc = 25 + /// Enables big voice on this outfit's headset, used for nukie leaders. var/command_radio = FALSE + /// The type of uplink to be given on equip. var/uplink_type = /obj/item/uplink/nuclear id_trim = /datum/id_trim/chameleon/operative +/datum/outfit/syndicate/plasmaman + name = "Syndicate Operative - Basic (Plasmaman)" + head = /obj/item/clothing/head/helmet/space/plasmaman/syndie + uniform = /obj/item/clothing/under/plasmaman/syndicate + r_hand = /obj/item/tank/internals/plasmaman/belt/full + /datum/outfit/syndicate/leader name = "Syndicate Leader - Basic" command_radio = TRUE id_trim = /datum/id_trim/chameleon/operative/nuke_leader +/datum/outfit/syndicate/leader/plasmaman + name = "Syndicate Leader - Basic (Plasmaman)" + head = /obj/item/clothing/head/helmet/space/plasmaman/syndie + uniform = /obj/item/clothing/under/plasmaman/syndicate + r_hand = /obj/item/tank/internals/plasmaman/belt/full + /datum/outfit/syndicate/post_equip(mob/living/carbon/human/nukie, visualsOnly = FALSE) if(visualsOnly) return @@ -64,6 +79,17 @@ /obj/item/pen/edagger = 1, ) +/datum/outfit/syndicate/full/plasmaman + name = "Syndicate Operative - Full Kit (Plasmaman)" + back = /obj/item/mod/control/pre_equipped/nuclear/plasmaman + uniform = /obj/item/clothing/under/plasmaman/syndicate + r_pocket = /obj/item/tank/internals/plasmaman/belt/full + mask = null + +/datum/outfit/syndicate/full/plasmaman/New() + backpack_contents += /obj/item/clothing/head/helmet/space/plasmaman/syndie + return ..() + /datum/outfit/syndicate/reinforcement name = "Syndicate Operative - Reinforcement" tc = 0 @@ -80,6 +106,13 @@ to_chat(H, span_notice("You're an agent of [faction], sent to accompany the nuclear squad on their mission. \ Support your allies, and remember: Down with Nanotrasen.")) +/datum/outfit/syndicate/reinforcement/plasmaman + name = "Syndicate Operative - Reinforcement (Plasmaman)" + head = /obj/item/clothing/head/helmet/space/plasmaman/syndie + uniform = /obj/item/clothing/under/plasmaman/syndicate + r_hand = /obj/item/tank/internals/plasmaman/belt/full + tc = 0 + /datum/outfit/syndicate/reinforcement/gorlex name = "Syndicate Operative - Gorlex Reinforcement" suit = /obj/item/clothing/suit/armor/vest/alt diff --git a/code/modules/client/preferences/operative_species.dm b/code/modules/client/preferences/operative_species.dm new file mode 100644 index 000000000000..0b55bc23b52f --- /dev/null +++ b/code/modules/client/preferences/operative_species.dm @@ -0,0 +1,23 @@ +/// When TRUE, will spawn you as a human when selected for an operative role +/// When FALSE, players will be placed into the game as their character's species +/datum/preference/toggle/nuke_ops_species + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + can_randomize = FALSE + default_value = TRUE + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "operative_species" + +/datum/preference/toggle/nuke_ops_species/is_accessible(datum/preferences/preferences) + . = ..() + if(!.) + return FALSE + + // If one of the roles is ticked in the antag prefs menu, this option will show. + var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE) + if(length(ops_roles & preferences.be_special)) + return TRUE + + return FALSE + +/datum/preference/toggle/nuke_ops_species/apply_to_human(mob/living/carbon/human/target, value) + return diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 8379c817144e..00bf14bcf603 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -379,3 +379,10 @@ desc = "A special containment helmet designed for CentCom Staff. You know, so any coffee spills don't kill the poor sod." icon_state = "intern_envirohelm" inhand_icon_state = null + +/obj/item/clothing/head/helmet/space/plasmaman/syndie + name = "tacticool envirosuit helmet" + desc = "There's no doubt about it, this helmet puts you above ALL of the other plasmamen. If you see another plasmaman wearing a helmet like this, it's either because they're a fellow badass, \ + or they've murdered one of your fellow badasses and have taken it from them as a trophy. Either way, anyone wearing this deserves at least a cursory nod of respect." + icon_state = "syndie_envirohelm" + inhand_icon_state = null diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index c70f80985ff0..403493216e76 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -168,3 +168,11 @@ bio = 50 fire = 50 acid = 40 + +/obj/item/clothing/under/plasmaman/syndicate + name = "tacticool envirosuit" + desc = "A sinister looking envirosuit, for the boniest of operatives." + icon_state = "syndie_envirosuit" + has_sensor = NO_SENSORS + resistance_flags = FIRE_PROOF + inhand_icon_state = null diff --git a/code/modules/events/ghost_role/operative.dm b/code/modules/events/ghost_role/operative.dm index 33cd9e059f09..4cf8da639bb5 100644 --- a/code/modules/events/ghost_role/operative.dm +++ b/code/modules/events/ghost_role/operative.dm @@ -30,6 +30,10 @@ Mind.special_role = ROLE_LONE_OPERATIVE Mind.active = TRUE Mind.transfer_to(operative) + if(!operative.client?.prefs.read_preference(/datum/preference/toggle/nuke_ops_species)) + var/species_type = operative.client.prefs.read_preference(/datum/preference/choiced/species) + operative.set_species(species_type) //Apply the preferred species to our freshly-made body. + Mind.add_antag_datum(/datum/antagonist/nukeop/lone) message_admins("[ADMIN_LOOKUPFLW(operative)] has been made into lone operative by an event.") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/_species.dm similarity index 99% rename from code/modules/mob/living/carbon/human/species.dm rename to code/modules/mob/living/carbon/human/_species.dm index 337ab1664201..583d61223b31 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -237,6 +237,10 @@ GLOBAL_LIST_EMPTY(features_by_species) /// Was on_species_gain ever actually called? /// Species code is really odd... var/properly_gained = FALSE + + ///A list containing outfits that will be overridden in the species_equip_outfit proc. [Key = Typepath passed in] [Value = Typepath of outfit you want to equip for this specific species instead]. + var/list/outfit_override_registry = list() + ///are we furry little creatures var/use_fur = FALSE ///health mod of a species diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 467bf69a6171..8583a5beb56e 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -386,6 +386,22 @@ return O.equip(src, visualsOnly) +///A version of equipOutfit that overrides passed in outfits with their entry on the species' outfit override registry +/mob/living/carbon/human/proc/equip_species_outfit(outfit, visualsOnly = FALSE) + var/datum/outfit/outfit_to_equip + + var/override_outfit_path = dna?.species.outfit_override_registry[outfit] + if(override_outfit_path) + outfit_to_equip = new override_outfit_path + else + outfit_to_equip = new outfit + + if(isnull(outfit_to_equip)) + return FALSE + + return outfit_to_equip.equip(src, visualsOnly) + + //delete all equipment without dropping anything /mob/living/carbon/human/proc/delete_equipment() for(var/slot in get_all_worn_items())//order matters, dependant slots go first diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 16cb62941e6a..2b83f8455e69 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -56,6 +56,13 @@ ass_image = 'icons/ass/assplasma.png' + outfit_override_registry = list( + /datum/outfit/syndicate = /datum/outfit/syndicate/plasmaman, + /datum/outfit/syndicate/full = /datum/outfit/syndicate/full/plasmaman, + /datum/outfit/syndicate/leader = /datum/outfit/syndicate/leader/plasmaman, + /datum/outfit/syndicate/reinforcement = /datum/outfit/syndicate/reinforcement/plasmaman, + ) + /// If the bones themselves are burning clothes won't help you much var/internal_fire = FALSE diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index f0a5085f4ec7..e33472006c4b 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -241,6 +241,12 @@ /obj/item/mod/module/jetpack/advanced, ) +/obj/item/mod/control/pre_equipped/nuclear/plasmaman + +/obj/item/mod/control/pre_equipped/nuclear/plasmaman/Initialize(mapload, new_theme, new_skin, new_core) + applied_modules += /obj/item/mod/module/plasma_stabilizer + return ..() + /obj/item/mod/control/pre_equipped/elite theme = /datum/mod_theme/elite applied_cell = /obj/item/stock_parts/cell/bluespace diff --git a/icons/mob/clothing/head/plasmaman_head.dmi b/icons/mob/clothing/head/plasmaman_head.dmi index c01492ae8b65..49f8c58a15ee 100644 Binary files a/icons/mob/clothing/head/plasmaman_head.dmi and b/icons/mob/clothing/head/plasmaman_head.dmi differ diff --git a/icons/mob/clothing/under/plasmaman.dmi b/icons/mob/clothing/under/plasmaman.dmi index c220a357269b..e529065c905c 100644 Binary files a/icons/mob/clothing/under/plasmaman.dmi and b/icons/mob/clothing/under/plasmaman.dmi differ diff --git a/icons/obj/clothing/head/plasmaman_hats.dmi b/icons/obj/clothing/head/plasmaman_hats.dmi index 8a50d0ea040c..a6e148e09bc5 100644 Binary files a/icons/obj/clothing/head/plasmaman_hats.dmi and b/icons/obj/clothing/head/plasmaman_hats.dmi differ diff --git a/icons/obj/clothing/under/plasmaman.dmi b/icons/obj/clothing/under/plasmaman.dmi index 55c94df5f235..84d33aa3ca71 100644 Binary files a/icons/obj/clothing/under/plasmaman.dmi and b/icons/obj/clothing/under/plasmaman.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 46c16219451b..420606037b3e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3135,6 +3135,7 @@ #include "code\modules\client\preferences\multiz_performance.dm" #include "code\modules\client\preferences\names.dm" #include "code\modules\client\preferences\ooc.dm" +#include "code\modules\client\preferences\operative_species.dm" #include "code\modules\client\preferences\paint_color.dm" #include "code\modules\client\preferences\parallax.dm" #include "code\modules\client\preferences\pda.dm" @@ -4186,6 +4187,7 @@ #include "code\modules\mob\living\carbon\alien\larva\powers.dm" #include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm" #include "code\modules\mob\living\carbon\alien\special\facehugger.dm" +#include "code\modules\mob\living\carbon\human\_species.dm" #include "code\modules\mob\living\carbon\human\damage_procs.dm" #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\dummy.dm" @@ -4206,7 +4208,6 @@ #include "code\modules\mob\living\carbon\human\life.dm" #include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\physiology.dm" -#include "code\modules\mob\living\carbon\human\species.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\suicides.dm" #include "code\modules\mob\living\carbon\human\monkey\monkey.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/operative_species.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/operative_species.tsx new file mode 100644 index 000000000000..82042b8efba1 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/operative_species.tsx @@ -0,0 +1,6 @@ +import { CheckboxInput, FeatureToggle } from '../base'; + +export const operative_species: FeatureToggle = { + name: 'Always Human as Operative', + component: CheckboxInput, +};