Skip to content

Commit

Permalink
Adds CBRN ERT (#4337)
Browse files Browse the repository at this point in the history
# About the pull request

Adds the CBRN ERT, with a 10/120 chance of responding to distress
signals.


# Explain why it's good for the game

It is a USCM-aligned ERT that could be used for events

# Changelog

:cl:
add: Added CBRN ERT with new CBRN MOPP equipment. (Sprites by DrMacCool
and Esselnek, names and descriptions by TopHatPenguin and Kaga)
add: ERT Squads (Marine Raider and new CBRN) get assigned to their squad
even if spawned as an ERT, and do not automatically unlock it for
overwatch
balance: Tool Webbing can now only hold tools, instead of just being a
better webbing
spellcheck: Corrected spelling of "Intercepted Transmission" for ERTs
fix: USCM faction squads that are not default marine squads should no
longer cause a crew manifest runtime
/:cl:

---------

Co-authored-by: harryob <[email protected]>
  • Loading branch information
BeagleGaming1 and harryob committed Nov 7, 2023
1 parent 3f12d8b commit 05eaa34
Show file tree
Hide file tree
Showing 40 changed files with 725 additions and 22 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define SQUAD_MARINE_CRYO "Foxtrot"
#define SQUAD_MARINE_INTEL "Intel"
#define SQUAD_SOF "SOF"
#define SQUAD_CBRN "CBRN"

// Job name defines
#define JOB_SQUAD_MARINE "Rifleman"
Expand Down
3 changes: 3 additions & 0 deletions code/controllers/subsystem/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ var/const/MAX_FREQ = 1468 // ---------------------------------------------------
var/const/HC_FREQ = 1471
var/const/SOF_FREQ = 1472
var/const/PVST_FREQ = 1473
var/const/CBRN_FREQ = 1474

//Ship department channels
var/const/SENTRY_FREQ = 1480
Expand Down Expand Up @@ -162,6 +163,7 @@ var/list/radiochannels = list(
SQUAD_MARINE_5 = ECHO_FREQ,
SQUAD_MARINE_CRYO = CRYO_FREQ,
SQUAD_SOF = SOF_FREQ,
SQUAD_CBRN = CBRN_FREQ,

RADIO_CHANNEL_ALAMO = DS1_FREQ,
RADIO_CHANNEL_NORMANDY = DS2_FREQ,
Expand Down Expand Up @@ -262,6 +264,7 @@ SUBSYSTEM_DEF(radio)
"[DELTA_FREQ]" = "deltaradio",
"[ECHO_FREQ]" = "echoradio",
"[CRYO_FREQ]" = "cryoradio",
"[CBRN_FREQ]" = "hcradio",
"[SOF_FREQ]" = "hcradio",
"[HC_FREQ]" = "hcradio",
"[PVST_FREQ]" = "pvstradio",
Expand Down
3 changes: 3 additions & 0 deletions code/datums/datacore.dm
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
continue
dept_flags |= FLAG_SHOW_MARINES
squad_sublists[squad_name] = TRUE
///If it is a real squad in the USCM squad list to prevent the crew manifest from breaking
if(!(squad_name in ROLES_SQUAD_ALL))
continue
LAZYSET(marines_by_squad[squad_name][real_rank], name, rank)

//here we fill manifest
Expand Down
9 changes: 9 additions & 0 deletions code/datums/diseases/black_goo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@
. = ..()
reagents.add_reagent("antiZed", 30)

/obj/item/reagent_container/glass/bottle/labeled_black_goo_cure
name = "\"Pathogen\" cure bottle"
desc = "The bottle has a biohazard symbol on the front, and has a label, designating its use against Agent A0-3959X.91–15, colloquially known as the \"Black Goo\"."
icon_state = "bottle20"

/obj/item/reagent_container/glass/bottle/labeled_black_goo_cure/Initialize()
. = ..()
reagents.add_reagent("antiZed", 60)

/datum/language/zombie
name = "Zombie"
desc = "A growling, guttural method of communication, only Zombies seem to be capable of producing these sounds."
Expand Down
80 changes: 80 additions & 0 deletions code/datums/emergency_calls/cbrn.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/datum/emergency_call/cbrn
name = "CBRN (Squad)"
arrival_message = "A CBRN squad has been dispatched to your ship. Stand by."
objectives = "Handle the chemical, biological, radiological, or nuclear threat. Further orders may be provided."
mob_min = 3
mob_max = 5
max_heavies = 0
max_smartgunners = 0

/datum/emergency_call/cbrn/create_member(datum/mind/new_mind, turf/override_spawn_loc)
var/turf/spawn_loc = override_spawn_loc ? override_spawn_loc : get_spawn_point()

if(!istype(spawn_loc))
return //Didn't find a useable spawn point.

var/mob/living/carbon/human/mob = new(spawn_loc)
new_mind.transfer_to(mob, TRUE)

if(!leader && HAS_FLAG(mob.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(mob.client, JOB_SQUAD_LEADER, time_required_for_job))
leader = mob
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/leader, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are the CBRN Fireteam Leader!"))

else if(medics < max_medics && HAS_FLAG(mob.client.prefs.toggles_ert, PLAY_MEDIC) && check_timelock(mob.client, JOB_SQUAD_MEDIC, time_required_for_job))
medics++
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/medic, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are the CBRN Squad Medic!"))

else if(engineers < max_engineers && HAS_FLAG(mob.client.prefs.toggles_ert, PLAY_ENGINEER) && check_timelock(mob.client, JOB_SQUAD_ENGI, time_required_for_job))
engineers++
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/engineer, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are the CBRN Squad Engineer!"))

else
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/standard, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are a CBRN Squad Rifleman!"))

to_chat(mob, SPAN_ROLE_BODY("You are a member of the USCM's CBRN. The CBRN is a force that specializes in handling chemical, biological, radiological, and nuclear threats."))
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), mob, SPAN_BOLD("Objectives:</b> [objectives]")), 1 SECONDS)

/datum/emergency_call/cbrn/ert
name = "CBRN (Distress)"
arrival_message = "Your distress signal has been received and we are dispatching the nearest CBRN squad to board with you now. Stand by."
probability = 10

/datum/emergency_call/cbrn/ert/New()
..()
objectives = "Investigate the distress signal aboard the [MAIN_SHIP_NAME]."

/datum/emergency_call/cbrn/specialists
name = "CBRN (Specialists)"
mob_min = 2
mob_max = 5
max_engineers = 0
max_medics = 0

/datum/emergency_call/cbrn/specialists/New()
var/cbrn_ship_name = "Unit [pick(nato_phonetic_alphabet)]-[rand(1, 99)]"
arrival_message = "[MAIN_SHIP_NAME], CBRN [cbrn_ship_name] has been dispatched. Follow all orders provided by [cbrn_ship_name]."
objectives = "You are a specialist team in [cbrn_ship_name] dispatched to quell a threat to [MAIN_SHIP_NAME]. Further orders may be provided."

/datum/emergency_call/cbrn/specialists/create_member(datum/mind/new_mind, turf/override_spawn_loc)
var/turf/spawn_loc = override_spawn_loc ? override_spawn_loc : get_spawn_point()

if(!istype(spawn_loc))
return //Didn't find a useable spawn point.

var/mob/living/carbon/human/mob = new(spawn_loc)
new_mind.transfer_to(mob, TRUE)

if(!leader && HAS_FLAG(mob.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(mob.client, JOB_SQUAD_LEADER, time_required_for_job))
leader = mob
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/specialist/lead, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are the CBRN Specialist Squad Leader!"))
else
arm_equipment(mob, /datum/equipment_preset/uscm/cbrn/specialist, TRUE, TRUE)
to_chat(mob, SPAN_ROLE_HEADER("You are a CBRN Specialist!"))

to_chat(mob, SPAN_ROLE_BODY("You are a member of the USCM's CBRN. The CBRN is a force that specializes in handling chemical, biological, radiological, and nuclear threats."))
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), mob, SPAN_BOLD("Objectives:</b> [objectives]")), 1 SECONDS)
2 changes: 1 addition & 1 deletion code/datums/emergency_calls/emergency_call.dm
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@

candidates = list()
if(arrival_message && announce_incoming)
marine_announcement(arrival_message, "Intercepted Tranmission:")
marine_announcement(arrival_message, "Intercepted Transmission:")

/datum/emergency_call/proc/add_candidate(mob/M)
if(!M.client || (M.mind && (M.mind in candidates)) || istype(M, /mob/living/carbon/xenomorph))
Expand Down
13 changes: 13 additions & 0 deletions code/datums/factions/uscm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@
if(JOB_CMB_OBS)
marine_rk = "obs"
icon_prefix = "cmb_"
// Check squad marines here too, for the unique ones
if(JOB_SQUAD_ENGI)
marine_rk = "engi"
if(JOB_SQUAD_MEDIC)
marine_rk = "med"
if(JOB_SQUAD_SPECIALIST)
marine_rk = "spec"
if(JOB_SQUAD_SMARTGUN)
marine_rk = "gun"
if(JOB_SQUAD_TEAM_LEADER)
marine_rk = "tl"
if(JOB_SQUAD_LEADER)
marine_rk = "leader"

if(marine_rk)
var/image/I = image('icons/mob/hud/marine_hud.dmi', current_human, "hudsquad")
Expand Down
11 changes: 11 additions & 0 deletions code/game/jobs/job/marine/squads.dm
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@
roundstart = FALSE
locked = TRUE

/datum/squad/marine/cbrn
name = SQUAD_CBRN
equipment_color = "#3B2A7B" //Chemical Corps Purple
chat_color = "#553EB2"
radio_freq = CBRN_FREQ
minimap_color = "#3B2A7B"

active = FALSE
roundstart = FALSE
locked = TRUE

//############################### UPP Squads
/datum/squad/upp
name = "Root"
Expand Down
12 changes: 5 additions & 7 deletions code/game/machinery/telecomms/presets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,7 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
id = "CentComm Receiver"
network = "tcommsat"
autolinkers = list("receiverCent")
freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ)

freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ, CBRN_FREQ)

//Buses

Expand All @@ -469,7 +468,7 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
/obj/structure/machinery/telecomms/bus/preset_three
id = "Bus 3"
network = "tcommsat"
freq_listening = list(SEC_FREQ, COMM_FREQ, WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, JTAC_FREQ, INTEL_FREQ, WY_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ)
freq_listening = list(SEC_FREQ, COMM_FREQ, WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, JTAC_FREQ, INTEL_FREQ, WY_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ, CBRN_FREQ)
autolinkers = list("processor3", "security", "command", "JTAC")

/obj/structure/machinery/telecomms/bus/preset_four
Expand All @@ -485,7 +484,7 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
/obj/structure/machinery/telecomms/bus/preset_cent
id = "CentComm Bus"
network = "tcommsat"
freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ)
freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ, CBRN_FREQ)
autolinkers = list("processorCent", "centcomm")

//Processors
Expand Down Expand Up @@ -550,7 +549,7 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)

/obj/structure/machinery/telecomms/server/presets/command
id = "Command Server"
freq_listening = list(COMM_FREQ, WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, JTAC_FREQ, INTEL_FREQ, WY_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ)
freq_listening = list(COMM_FREQ, WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, JTAC_FREQ, INTEL_FREQ, WY_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ, CBRN_FREQ)
autolinkers = list("command")

/obj/structure/machinery/telecomms/server/presets/engineering
Expand All @@ -565,10 +564,9 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)

/obj/structure/machinery/telecomms/server/presets/centcomm
id = "CentComm Server"
freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ)
freq_listening = list(WY_WO_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, HC_FREQ, PVST_FREQ, SOF_FREQ, CBRN_FREQ)
autolinkers = list("centcomm")


//Broadcasters

//--PRESET LEFT--//
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/vending/vendor_types/crew/synthetic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth, list(
list("Surgical Drop Pouch", 0, /obj/item/clothing/accessory/storage/surg_vest/drop_green, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Surgical Drop Pouch (Blue)", 0, /obj/item/clothing/accessory/storage/surg_vest/drop_blue, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Surgical Drop Pouch (Black)", 0, /obj/item/clothing/accessory/storage/surg_vest/drop_black, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Tool Webbing", 0, /obj/item/clothing/accessory/storage/black_vest/tool_webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Tool Webbing", 0, /obj/item/clothing/accessory/storage/tool_webbing/equipped, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Drop Pouch", 0, /obj/item/clothing/accessory/storage/droppouch, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),

list("SHOES (CHOOSE 1)", 0, null, null, null),
Expand Down
8 changes: 8 additions & 0 deletions code/game/objects/items/devices/radio/headset.dm
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,14 @@
"Corporate Liaison" = TRACKER_CL
)

/obj/item/device/radio/headset/distress/cbrn
name = "\improper CBRN headset"
desc = "A headset given to CBRN marines. Channels are as follows: :g - public, :v - marine command, :a - alpha squad, :b - bravo squad, :c - charlie squad, :d - delta squad, :n - engineering, :m - medbay, :u - requisitions, :j - JTAC, :t - intel"
frequency = CBRN_FREQ
initial_keys = list(/obj/item/device/encryptionkey/public, /obj/item/device/encryptionkey/mcom)
ignore_z = TRUE
has_hud = TRUE

/obj/item/device/radio/headset/distress/pmc/hvh
desc = "A special headset used by corporate personnel. Channels are as follows: :o - colony."
initial_keys = list(/obj/item/device/encryptionkey/colony, /obj/item/device/encryptionkey/WY)
Expand Down
9 changes: 9 additions & 0 deletions code/game/objects/items/storage/pouch.dm
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,15 @@
new /obj/item/stack/medical/advanced/ointment(src)
new /obj/item/stack/medical/splint(src)

/obj/item/storage/pouch/medkit/full/toxin/fill_preset_inventory()
new /obj/item/device/healthanalyzer(src)
new /obj/item/storage/pill_bottle/antitox(src)
new /obj/item/storage/pill_bottle/antitox(src)
new /obj/item/roller(src)
new /obj/item/stack/medical/splint(src)
new /obj/item/stack/medical/advanced/bruise_pack(src)
new /obj/item/stack/medical/advanced/ointment(src)

/obj/item/storage/pouch/pressurized_reagent_canister
name = "Pressurized Reagent Canister Pouch"
max_w_class = SIZE_SMALL
Expand Down
60 changes: 60 additions & 0 deletions code/game/objects/prop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,66 @@
w_class = SIZE_SMALL
garbage = TRUE

/obj/item/prop/geiger_counter
name = "geiger counter"
desc = "A geiger counter measures the radiation it receives. This type automatically records and transfers any information it reads, provided it has a battery, with no user input required beyond being enabled."
icon = 'icons/obj/items/devices.dmi'
icon_state = "geiger"
item_state = ""
w_class = SIZE_SMALL
flags_equip_slot = SLOT_WAIST
///Whether the geiger counter is on or off
var/toggled_on = FALSE
///Iconstate of geiger counter when on
var/enabled_state = "geiger_on"
///Iconstate of geiger counter when off
var/disabled_state = "geiger"
///New battery it will spawn with
var/starting_battery = /obj/item/cell/crap
///Battery inside geiger counter
var/obj/item/cell/battery //It doesn't drain the battery, but it has a battery for emergency use

/obj/item/prop/geiger_counter/Initialize(mapload, ...)
. = ..()
if(!starting_battery)
return
battery = new starting_battery(src)

/obj/item/prop/geiger_counter/Destroy()
. = ..()
if(battery)
qdel(battery)

/obj/item/prop/geiger_counter/attack_self(mob/user)
. = ..()
toggled_on = !toggled_on
if(!battery)
to_chat(user, SPAN_NOTICE("[src] is missing a battery."))
return
to_chat(user, SPAN_NOTICE("You [toggled_on ? "enable" : "disable"] [src]."))
update_icon()

/obj/item/prop/geiger_counter/attackby(obj/item/attacking_item, mob/user)
. = ..()
if(!HAS_TRAIT(attacking_item, TRAIT_TOOL_SCREWDRIVER) && !HAS_TRAIT(attacking_item, TRAIT_TOOL_CROWBAR))
return

if(!battery)
to_chat(user, SPAN_NOTICE("There is no battery for you to remove."))
return
to_chat(user, SPAN_NOTICE("You jam [battery] out of [src] with [attacking_item], prying it out irreversibly."))
user.put_in_hands(battery)
battery = null
update_icon()

/obj/item/prop/geiger_counter/update_icon()
. = ..()

if(battery && toggled_on)
icon_state = enabled_state
return
icon_state = disabled_state

/obj/item/prop/tableflag
name = "United Americas table flag"
icon = 'icons/obj/items/items.dmi'
Expand Down
6 changes: 6 additions & 0 deletions code/modules/clothing/glasses/glasses.dm
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,12 @@
vision_impair_on = VISION_IMPAIR_WEAK
vision_impair_off = VISION_IMPAIR_NONE

/obj/item/clothing/glasses/welding/superior/alt
desc = "Welding goggles made from more expensive materials."

/obj/item/clothing/glasses/welding/superior/prescription
desc = "Welding goggles made from more expensive materials. There are barely visible prescription lenses connected to the frame, allowing vision even when the goggles are raised."
prescription = TRUE
//sunglasses

/obj/item/clothing/glasses/sunglasses
Expand Down
8 changes: 8 additions & 0 deletions code/modules/clothing/gloves/marine_gloves.dm
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,11 @@
desc = "Standard issue tactical gloves used by the royal marines."
icon_state = "rmc_gloves"
flags_atom = NO_NAME_OVERRIDE|NO_SNOW_TYPE

/obj/item/clothing/gloves/marine/veteran/cbrn
name = "\improper M3 MOPP gloves"
desc = "M3 MOPP gloves are made of treated venlar designed to protect the user’s hands against contamination whilst working in CBRN environments. Special care has been taken to give the user’s hands enough dexterity to fully service a rifle or utilize most handheld tools, while circular adhesive patterns on the fingers provide the user with enhanced grips. Standard CBRN protocol dictates that the gloves are expected to have a lifespan of maximum effectiveness of around twenty-four hours once exposed to moderate levels of contamination and that users are recommended to discard and replace them afterwards."
icon_state = "cbrn"
item_state = "cbrn"
armor_bio = CLOTHING_ARMOR_GIGAHIGHPLUS
armor_rad = CLOTHING_ARMOR_GIGAHIGHPLUS
Loading

0 comments on commit 05eaa34

Please sign in to comment.