diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm
index 9a29754381f3..078ccbdc2d94 100644
--- a/code/__DEFINES/chemistry.dm
+++ b/code/__DEFINES/chemistry.dm
@@ -49,6 +49,7 @@
// Nutrition levels
#define NUTRITION_MAX 550
+#define NUTRITION_HIGH 540
#define NUTRITION_NORMAL 400
#define NUTRITION_LOW 250
#define NUTRITION_VERYLOW 50
diff --git a/code/__DEFINES/conflict.dm b/code/__DEFINES/conflict.dm
index 7a1b322a19ee..30b2627bb1b0 100644
--- a/code/__DEFINES/conflict.dm
+++ b/code/__DEFINES/conflict.dm
@@ -68,7 +68,7 @@
#define GUN_ANTIQUE (1<<13)
/// Whether the gun has been fired by its current user (reset upon `dropped()`)
#define GUN_RECOIL_BUILDUP (1<<14)
-/// support weapon, bipod will grant IFF
+/// support weapon, bipod will grant autofire
#define GUN_SUPPORT_PLATFORM (1<<15)
/// No gun description, only base desc
#define GUN_NO_DESCRIPTION (1<<16)
@@ -99,6 +99,8 @@
#define AMMUNITION_HANDFUL_BOX (1<<2)
#define AMMUNITION_HIDE_AMMO (1<<3)
#define AMMUNITION_CANNOT_REMOVE_BULLETS (1<<4)
+/// If this magazine can transfer to other magazines of the same type by slapping one with the other
+#define AMMUNITION_SLAP_TRANSFER (1<<5)
//Slowdown from various armors.
/// How much shoes slow you down by default. Negative values speed you up
diff --git a/code/__DEFINES/dcs/signals/atom/signals_item.dm b/code/__DEFINES/dcs/signals/atom/signals_item.dm
index 138e88d21746..b7bbca9f64a3 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_item.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_item.dm
@@ -54,3 +54,9 @@
#define COMSIG_GUN_AUTOFIREDELAY_MODIFIED "gun_autofiredelay_modified"
#define COMSIG_GUN_BURST_SHOTS_TO_FIRE_MODIFIED "gun_burst_shots_to_fire_modified"
#define COMSIG_GUN_BURST_SHOT_DELAY_MODIFIED "gun_burst_shot_delay_modified"
+
+/// from /obj/item/weapon/gun/proc/recalculate_attachment_bonuses() : ()
+#define COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES "gun_recalculate_attachment_bonuses"
+
+/// from /obj/item/weapon/gun/proc/load_into_chamber() : ()
+#define COMSIG_GUN_INTERRUPT_FIRE "gun_interrupt_fire"
diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm
index a288ac2c8be7..e33a75aee132 100644
--- a/code/__DEFINES/dcs/signals/signals_global.dm
+++ b/code/__DEFINES/dcs/signals/signals_global.dm
@@ -59,3 +59,7 @@
/// From
#define COMSIG_GLOB_YAUTJA_ARMORY_OPENED "yautja_armory_opened"
+
+/// From /proc/biohazard_lockdown()
+#define COMSIG_GLOB_RESEARCH_LOCKDOWN "research_lockdown_closed"
+#define COMSIG_GLOB_RESEARCH_LIFT "research_lockdown_opened"
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 3a25d865fb60..8a65a4b961ff 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -113,6 +113,7 @@
#define SS_INIT_INPUT 85
#define SS_INIT_FAIL_TO_TOPIC 84
#define SS_INIT_TOPIC 83
+#define SS_INIT_LOBBYART 82
#define SS_INIT_RUST 30
#define SS_INIT_INFLUXDRIVER 28
#define SS_INIT_SUPPLY_SHUTTLE 25
@@ -162,7 +163,6 @@
#define SS_INIT_PLAYTIME -29
#define SS_INIT_PREDSHIPS -30
#define SS_INIT_OBJECTIVES -31
-#define SS_INIT_LOBBYART -33
#define SS_INIT_MINIMAP -34
#define SS_INIT_STATPANELS -98
#define SS_INIT_CHAT -100 //Should be last to ensure chat remains smooth during init.
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 4936609d892e..d71125c318f6 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -128,6 +128,7 @@ DEFINE_BITFIELD(flags_magazine, list(
"AMMUNITION_HANDFUL_BOX" = AMMUNITION_HANDFUL_BOX,
"AMMUNITION_HIDE_AMMO" = AMMUNITION_HIDE_AMMO,
"AMMUNITION_CANNOT_REMOVE_BULLETS" = AMMUNITION_CANNOT_REMOVE_BULLETS,
+ "AMMUNITION_SLAP_TRANSFER" = AMMUNITION_SLAP_TRANSFER,
))
DEFINE_BITFIELD(flags_atom, list(
diff --git a/code/datums/components/autofire/autofire.dm b/code/datums/components/autofire/autofire.dm
index 31ca255f1b88..2b9401e8d346 100644
--- a/code/datums/components/autofire/autofire.dm
+++ b/code/datums/components/autofire/autofire.dm
@@ -15,6 +15,8 @@
var/have_to_reset_at_burst_end = FALSE
///If we are in a burst
var/bursting = FALSE
+ /// The multiplier for how much slower the parent should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc.
+ var/automatic_delay_mult = 1
///Callback to set bursting mode on the parent
var/datum/callback/callback_bursting
///Callback to ask the parent to reset its firing vars
@@ -26,7 +28,7 @@
///Callback to set parent's fa_firing
var/datum/callback/callback_set_firing
-/datum/component/automatedfire/autofire/Initialize(auto_fire_shot_delay = 0.3 SECONDS, burstfire_shot_delay, burst_shots_to_fire = 3, fire_mode = GUN_FIREMODE_SEMIAUTO, datum/callback/callback_bursting, datum/callback/callback_reset_fire, datum/callback/callback_fire, datum/callback/callback_display_ammo, datum/callback/callback_set_firing)
+/datum/component/automatedfire/autofire/Initialize(auto_fire_shot_delay = 0.3 SECONDS, burstfire_shot_delay, burst_shots_to_fire = 3, fire_mode = GUN_FIREMODE_SEMIAUTO, automatic_delay_mult = 1, datum/callback/callback_bursting, datum/callback/callback_reset_fire, datum/callback/callback_fire, datum/callback/callback_display_ammo, datum/callback/callback_set_firing)
. = ..()
RegisterSignal(parent, COMSIG_GUN_FIRE_MODE_TOGGLE, PROC_REF(modify_fire_mode))
@@ -35,11 +37,13 @@
RegisterSignal(parent, COMSIG_GUN_BURST_SHOT_DELAY_MODIFIED, PROC_REF(modify_burstfire_shot_delay))
RegisterSignal(parent, COMSIG_GUN_FIRE, PROC_REF(initiate_shot))
RegisterSignal(parent, COMSIG_GUN_STOP_FIRE, PROC_REF(stop_firing))
+ RegisterSignal(parent, COMSIG_GUN_INTERRUPT_FIRE, PROC_REF(hard_reset))
src.auto_fire_shot_delay = auto_fire_shot_delay
src.burstfire_shot_delay = burstfire_shot_delay
src.burst_shots_to_fire = burst_shots_to_fire
src.fire_mode = fire_mode
+ src.automatic_delay_mult = automatic_delay_mult
src.callback_bursting = callback_bursting
src.callback_reset_fire = callback_reset_fire
src.callback_fire = callback_fire
@@ -96,6 +100,7 @@
///Hard reset the autofire, happens when the shooter fall/is thrown, at the end of a burst or when it runs out of ammunition
/datum/component/automatedfire/autofire/proc/hard_reset()
+ SIGNAL_HANDLER
callback_reset_fire.Invoke() //resets the gun
shots_fired = 0
have_to_reset_at_burst_end = FALSE
@@ -131,7 +136,7 @@
next_fire = world.time + burstfire_shot_delay
if(GUN_FIREMODE_AUTOMATIC)
callback_set_firing.Invoke(TRUE)
- next_fire = world.time + auto_fire_shot_delay
+ next_fire = world.time + (auto_fire_shot_delay * automatic_delay_mult)
if(GUN_FIREMODE_SEMIAUTO)
return
schedule_shot()
diff --git a/code/datums/supply_packs/ammo.dm b/code/datums/supply_packs/ammo.dm
index e598a11be5e0..164511c25cc0 100644
--- a/code/datums/supply_packs/ammo.dm
+++ b/code/datums/supply_packs/ammo.dm
@@ -122,16 +122,6 @@
containername = "\improper M39 AP magazines crate"
group = "Ammo"
-/datum/supply_packs/ammo_smg_mag_box_ext
- name = "Magazine box (M39, 10x extended mags)"
- contains = list(
- /obj/item/ammo_box/magazine/m39/ext,
- )
- cost = 30
- containertype = /obj/structure/closet/crate/ammo
- containername = "\improper M39 extended magazines crate"
- group = "Ammo"
-
//------------------------For M4RA----------------
/datum/supply_packs/ammo_m4ra_mag_box
diff --git a/code/datums/supply_packs/black_market.dm b/code/datums/supply_packs/black_market.dm
index 65b15997d1b4..3f4453d03f32 100644
--- a/code/datums/supply_packs/black_market.dm
+++ b/code/datums/supply_packs/black_market.dm
@@ -184,10 +184,9 @@ Non-USCM items, from CLF, UPP, colonies, etc. Mostly combat-related.
new /obj/item/ammo_magazine/rifle/mar40/extended(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
else
- new /obj/item/weapon/gun/rifle/m41aMK1/tactical(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1/ap(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1(src)
+ new /obj/item/weapon/gun/rifle/mar40/lmg(src)
+ new /obj/item/ammo_magazine/rifle/mar40/lmg(src)
+ new /obj/item/ammo_magazine/rifle/mar40/lmg(src)
/* Misc. Individual Guns */
diff --git a/code/game/machinery/biohazard_lockdown.dm b/code/game/machinery/biohazard_lockdown.dm
new file mode 100644
index 000000000000..fd6205baa1d9
--- /dev/null
+++ b/code/game/machinery/biohazard_lockdown.dm
@@ -0,0 +1,109 @@
+#define LOCKDOWN_READY 0
+#define LOCKDOWN_ACTIVE 1
+GLOBAL_VAR_INIT(lockdown_state, LOCKDOWN_READY)
+
+/obj/structure/machinery/biohazard_lockdown
+ name = "Emergency Containment Breach"
+ icon_state = "big_red_button_tablev"
+ unslashable = TRUE
+ unacidable = TRUE
+ COOLDOWN_DECLARE(containment_lockdown)
+
+/obj/structure/machinery/biohazard_lockdown/ex_act(severity)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attack_remote(mob/user as mob)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attack_alien(mob/user as mob)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attackby(obj/item/attacking_item, mob/user)
+ return attack_hand(user)
+
+/obj/structure/machinery/biohazard_lockdown/attack_hand(mob/living/user)
+ if(isxeno(user))
+ return FALSE
+ if(!allowed(user))
+ to_chat(user, SPAN_DANGER("Access Denied"))
+ flick(initial(icon_state) + "-denied", src)
+ return FALSE
+
+ if(!COOLDOWN_FINISHED(src, containment_lockdown))
+ to_chat(user, SPAN_BOLDWARNING("Biohazard Lockdown procedures are on cooldown! They will be ready in [COOLDOWN_SECONDSLEFT(src, containment_lockdown)] seconds!"))
+ return FALSE
+
+ add_fingerprint(user)
+ biohazard_lockdown(user)
+ COOLDOWN_START(src, containment_lockdown, 5 MINUTES)
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard
+ name = "Biohazard Containment Airlock"
+ density = FALSE
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard/Initialize()
+ . = ..()
+ RegisterSignal(SSdcs, COMSIG_GLOB_RESEARCH_LOCKDOWN, PROC_REF(close))
+ RegisterSignal(SSdcs, COMSIG_GLOB_RESEARCH_LIFT, PROC_REF(open))
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white
+ icon_state = "w_almayer_pdoor1"
+ base_icon_state = "w_almayer_pdoor"
+
+/client/proc/admin_biohazard_alert()
+ set name = "Containment Breach Alert"
+ set category = "Admin.Ship"
+
+ if(!admin_holder ||!check_rights(R_EVENT))
+ return FALSE
+
+ var/prompt = tgui_alert(src, "Are you sure you want to trigger a containment breach alert? This will force red alert, and lockdown research.", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt != "Yes")
+ return FALSE
+
+ prompt = tgui_alert(src, "Do you want to use a custom announcement?", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt == "Yes")
+ var/whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
+ biohazard_lockdown(usr, whattoannounce, TRUE)
+ else
+ biohazard_lockdown(usr, admin = TRUE)
+ return TRUE
+
+/proc/biohazard_lockdown(mob/user, message, admin = FALSE)
+ if(IsAdminAdvancedProcCall())
+ return PROC_BLOCKED
+
+ var/log = "[key_name(user)] triggered research bio lockdown!"
+ var/ares_log = "[user.name] triggered Medical Research Biohazard Containment Lockdown."
+ if(!message)
+ message = "ATTENTION! \n\nBIOHAZARD CONTAINMENT BREACH. \n\nRESEARCH DEPARTMENT UNDER LOCKDOWN."
+ else
+ log = "[key_name(user)] triggered research bio lockdown! (Using a custom announcement)."
+ if(admin)
+ log += " (Admin Triggered)."
+ ares_log = "[MAIN_AI_SYSTEM] triggered Medical Research Biohazard Containment Lockdown."
+
+ switch(GLOB.lockdown_state)
+ if(LOCKDOWN_READY)
+ GLOB.lockdown_state = LOCKDOWN_ACTIVE
+ set_security_level(SEC_LEVEL_RED, TRUE, FALSE)
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_RESEARCH_LOCKDOWN)
+ if(LOCKDOWN_ACTIVE)
+ GLOB.lockdown_state = LOCKDOWN_READY
+ message = "ATTENTION! \n\nBIOHAZARD CONTAINMENT LOCKDOWN LIFTED."
+ log = "[key_name(user)] lifted research bio lockdown!"
+ ares_log = "[user.name] lifted Medical Research Biohazard Containment Lockdown."
+ if(admin)
+ log += " (Admin Triggered)."
+ ares_log = "[MAIN_AI_SYSTEM] lifted Medical Research Biohazard Containment Lockdown."
+
+ set_security_level(SEC_LEVEL_BLUE, TRUE, FALSE)
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_RESEARCH_LIFT)
+
+ shipwide_ai_announcement(message, MAIN_AI_SYSTEM, 'sound/effects/biohazard.ogg')
+ message_admins(log)
+ var/datum/ares_link/link = GLOB.ares_link
+ link.log_ares_security("Containment Lockdown", ares_log)
+
+#undef LOCKDOWN_READY
+#undef LOCKDOWN_ACTIVE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index dd5e99545d11..a98a9c25d1aa 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -829,6 +829,7 @@ cases. Override_icon_state should be a list.*/
UnregisterSignal(src, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_UNWIELD,
+ COMSIG_PARENT_QDELETING,
))
UnregisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK)
//General reset in case anything goes wrong, the view will always reset to default unless zooming in.
@@ -861,6 +862,7 @@ cases. Override_icon_state should be a list.*/
RegisterSignal(src, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_UNWIELD,
+ COMSIG_PARENT_QDELETING,
), PROC_REF(unzoom_dropped_callback))
RegisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(zoom_handle_mob_move_or_look))
diff --git a/code/game/objects/items/reagent_containers/food/snacks.dm b/code/game/objects/items/reagent_containers/food/snacks.dm
index c0e11dac8eb3..06a4d785e677 100644
--- a/code/game/objects/items/reagent_containers/food/snacks.dm
+++ b/code/game/objects/items/reagent_containers/food/snacks.dm
@@ -60,7 +60,7 @@
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)
- if(fullness > 540 && world.time < C.overeat_cooldown)
+ if(fullness > NUTRITION_HIGH && world.time < C.overeat_cooldown)
to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now."))
return
if(issynth(C))
@@ -70,22 +70,22 @@
to_chat(user, SPAN_DANGER("[user == M ? "You are" : "[M] is"] unable to eat!"))
return
- if(fullness > 540)
+ if(fullness > NUTRITION_HIGH)
C.overeat_cooldown = world.time + OVEREAT_TIME
if(M == user)//If you're eating it yourself
- if (fullness <= 50)
+ if (fullness <= NUTRITION_VERYLOW)
to_chat(M, SPAN_WARNING("You hungrily chew out a piece of [src] and gobble it!"))
- if (fullness > 50 && fullness <= 150)
+ if (fullness > NUTRITION_VERYLOW && fullness <= NUTRITION_LOW)
to_chat(M, SPAN_NOTICE(" You hungrily begin to eat [src]."))
- if (fullness > 150 && fullness <= 350)
+ if (fullness > NUTRITION_LOW && fullness <= NUTRITION_NORMAL)
to_chat(M, SPAN_NOTICE(" You take a bite of [src]."))
- if (fullness > 350 && fullness <= 540)
+ if (fullness > NUTRITION_NORMAL && fullness <= NUTRITION_HIGH)
to_chat(M, SPAN_NOTICE(" You unwillingly chew a bit of [src]."))
- if (fullness > 540)
+ if (fullness > NUTRITION_HIGH)
to_chat(M, SPAN_WARNING("You reluctantly force more of [src] to go down your throat."))
else
- if (fullness <= 540)
+ if (fullness <= NUTRITION_HIGH)
user.affected_message(M,
SPAN_HELPFUL("You start feeding [user == M ? "yourself" : "[M]"] [src]."),
SPAN_HELPFUL("[user] starts feeding you [src]."),
diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm
index 98974f25be29..bb763ada9911 100644
--- a/code/game/objects/items/tools/kitchen_tools.dm
+++ b/code/game/objects/items/tools/kitchen_tools.dm
@@ -45,6 +45,10 @@
return ..()
if (reagents.total_volume > 0)
+ var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)
+ if(fullness > NUTRITION_HIGH)
+ to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now."))
+ return ..()
reagents.set_source_mob(user)
reagents.trans_to_ingest(M, reagents.total_volume)
if(M == user)
diff --git a/code/game/turfs/walls/wall_types.dm b/code/game/turfs/walls/wall_types.dm
index 04c5a0735824..5338ae26c000 100644
--- a/code/game/turfs/walls/wall_types.dm
+++ b/code/game/turfs/walls/wall_types.dm
@@ -239,6 +239,8 @@
icon_state = "fakewindows"
opacity = FALSE
+INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen)
+
/turf/closed/wall/indestructible/splashscreen
name = "Lobby Art"
desc = "Assorted artworks."
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 368e2766ccfc..5e527e6a5442 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -133,7 +133,8 @@ var/list/admin_verbs_minor_event = list(
/client/proc/toggle_shipside_sd,
/client/proc/shakeshipverb,
/client/proc/adminpanelweapons,
- /client/proc/adminpanelgq,
+ /client/proc/admin_general_quarters,
+ /client/proc/admin_biohazard_alert,
/client/proc/toggle_hardcore_perma
)
diff --git a/code/modules/admin/verbs/adminpanelgq.dm b/code/modules/admin/verbs/adminpanelgq.dm
index 13b6e329aa69..8ef1ed869661 100644
--- a/code/modules/admin/verbs/adminpanelgq.dm
+++ b/code/modules/admin/verbs/adminpanelgq.dm
@@ -1,22 +1,24 @@
-/client/proc/adminpanelgq()
+/client/proc/admin_general_quarters()
set name = "Call General Quarters"
set category = "Admin.Ship"
if(security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA)
tgui_alert(src, "Security is already red or above, General Quarters cannot be called.", "Acknowledge!", list("ok."), 10 SECONDS)
- else
- var/whattoannounce = "ATTENTION! GENERAL QUARTERS. ALL HANDS, MAN YOUR BATTLESTATIONS."
- var/prompt = tgui_alert(src, "Do you want to leave the announcement as the default one?", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "No")
- whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
- prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "Yes")
- set_security_level(2, no_sound=1, announce=0)
- shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
- message_admins("[key_name_admin(src)] Sent General Quarters with a custom announcement!")
- else
- prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "Yes")
- set_security_level(2, no_sound=1, announce=0)
- shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
- message_admins("[key_name_admin(src)] Sent General Quarters!")
+ return FALSE
+
+ var/prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt != "Yes")
+ return FALSE
+
+ var/whattoannounce = "ATTENTION! GENERAL QUARTERS. ALL HANDS, MAN YOUR BATTLESTATIONS."
+ var/log = "[key_name_admin(src)] Sent General Quarters!"
+
+ prompt = tgui_alert(src, "Do you want to use a custom announcement?", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt == "Yes")
+ whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
+ log = "[key_name_admin(src)] Sent General Quarters! (Using a custom announcement)"
+
+ set_security_level(SEC_LEVEL_RED, TRUE, FALSE)
+ shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
+ message_admins(log)
+ return TRUE
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 9d53ac1103c0..e3b07a76a2ff 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -159,8 +159,8 @@
max_heat_protection_temperature = SHOE_MAX_HEAT_PROT
/obj/item/clothing/shoes/souto
- name = "\improper Souto Man's boots. Harder than the kick of Souto Red."
- desc = "Souto Man boots"
+ name = "Souto Man boots"
+ desc = "\improper Souto Man's boots. Harder than the kick of Souto Red"
icon_state = "souto_man"
item_state = "souto_man"
flags_inventory = CANTSTRIP|NOSLIPPING
diff --git a/code/modules/gear_presets/uscm_ship.dm b/code/modules/gear_presets/uscm_ship.dm
index 578114222c01..f3129acb23d2 100644
--- a/code/modules/gear_presets/uscm_ship.dm
+++ b/code/modules/gear_presets/uscm_ship.dm
@@ -320,7 +320,6 @@
ACCESS_MARINE_CARGO,
ACCESS_MARINE_RO,
ACCESS_MARINE_COMMAND,
- ACCESS_MARINE_DATABASE,
ACCESS_MARINE_ALPHA,
ACCESS_MARINE_BRAVO,
ACCESS_MARINE_CHARLIE,
@@ -637,6 +636,7 @@
. = ..()
access = list(
ACCESS_MARINE_SENIOR,
+ ACCESS_MARINE_DATABASE,
ACCESS_MARINE_ASO,
ACCESS_MARINE_COMMAND,
ACCESS_MARINE_BRIG,
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index dd53868caf36..cc0c12bd1cc8 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -755,6 +755,9 @@
/mob/living/carbon/xenomorph/start_pulling(atom/movable/AM, lunge, no_msg)
+ if(next_move >= world.time)
+ return FALSE
+
if(SEND_SIGNAL(AM, COMSIG_MOVABLE_XENO_START_PULLING, src) & COMPONENT_ALLOW_PULL)
return do_pull(AM, lunge, no_msg)
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 1947f87c574a..d747525f3feb 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -116,14 +116,17 @@ They're all essentially identical when it comes to getting the job done.
/obj/item/ammo_magazine/attackby(obj/item/I, mob/living/user, bypass_hold_check = 0)
if(istype(I, /obj/item/ammo_magazine))
var/obj/item/ammo_magazine/MG = I
- if(MG.flags_magazine & AMMUNITION_HANDFUL) //got a handful of bullets
+ if((MG.flags_magazine & AMMUNITION_HANDFUL) || (MG.flags_magazine & AMMUNITION_SLAP_TRANSFER)) //got a handful of bullets
if(flags_magazine & AMMUNITION_REFILLABLE) //and a refillable magazine
var/obj/item/ammo_magazine/handful/transfer_from = I
if(src == user.get_inactive_hand() || bypass_hold_check) //It has to be held.
if(default_ammo == transfer_from.default_ammo)
- transfer_ammo(transfer_from,user,transfer_from.current_rounds) // This takes care of the rest.
- else to_chat(user, "Those aren't the same rounds. Better not mix them up.")
- else to_chat(user, "Try holding [src] before you attempt to restock it.")
+ if(transfer_ammo(transfer_from,user,transfer_from.current_rounds)) // This takes care of the rest.
+ to_chat(user, SPAN_NOTICE("You transfer rounds to [src] from [transfer_from]."))
+ else
+ to_chat(user, SPAN_NOTICE("Those aren't the same rounds. Better not mix them up."))
+ else
+ to_chat(user, SPAN_NOTICE("Try holding [src] before you attempt to restock it."))
//Generic proc to transfer ammo between ammo mags. Can work for anything, mags, handfuls, etc.
/obj/item/ammo_magazine/proc/transfer_ammo(obj/item/ammo_magazine/source, mob/user, transfer_amount = 1)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 832f243a9602..257edd9a7720 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -127,7 +127,7 @@
///How many full-auto shots to get to max scatter?
var/fa_scatter_peak = 4
///How bad does the scatter get on full auto?
- var/fa_max_scatter = 8.5
+ var/fa_max_scatter = 6.5
///Click parameters to use when firing full-auto
var/fa_params = null
@@ -228,6 +228,8 @@
VAR_PROTECTED/start_semiauto = TRUE
/// If this gun should spawn with automatic fire. Protected due to it never needing to be edited.
VAR_PROTECTED/start_automatic = FALSE
+ /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited.
+ VAR_PROTECTED/autofire_slow_mult = 1
/**
@@ -274,7 +276,7 @@
AddElement(/datum/element/drop_retrieval/gun, auto_retrieval_slot)
update_icon() //for things like magazine overlays
gun_firemode = gun_firemode_list[1] || GUN_FIREMODE_SEMIAUTO
- AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set.
+ AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set.
/obj/item/weapon/gun/proc/set_gun_attachment_offsets()
attachable_offset = null
@@ -425,6 +427,10 @@
else if(M.r_hand == src)
M.update_inv_r_hand()
+ setup_firemodes()
+
+ SEND_SIGNAL(src, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES)
+
/obj/item/weapon/gun/proc/handle_random_attachments()
var/attachmentchoice
@@ -939,6 +945,10 @@ and you're good to go.
//Let's check on the active attachable. It loads ammo on the go, so it never chambers anything
if(active_attachable)
+ if(shots_fired >= 1) // This is what you'll want to remove if you want automatic underbarrel guns in the future
+ SEND_SIGNAL(src, COMSIG_GUN_INTERRUPT_FIRE)
+ return
+
if(active_attachable.current_rounds > 0) //If it's still got ammo and stuff.
active_attachable.current_rounds--
var/obj/item/projectile/bullet = create_bullet(active_attachable.ammo, initial(name))
@@ -1073,10 +1083,10 @@ and you're good to go.
This is where the grenade launcher and flame thrower function as attachments.
This is also a general check to see if the attachment can fire in the first place.
*/
- var/check_for_attachment_fire = 0
+ var/check_for_attachment_fire = FALSE
if(active_attachable?.flags_attach_features & ATTACH_WEAPON) //Attachment activated and is a weapon.
- check_for_attachment_fire = 1
+ check_for_attachment_fire = TRUE
if(!(active_attachable.flags_attach_features & ATTACH_PROJECTILE)) //If it's unique projectile, this is where we fire it.
if((active_attachable.current_rounds <= 0) && !(active_attachable.flags_attach_features & ATTACH_IGNORE_EMPTY))
click_empty(user) //If it's empty, let them know.
@@ -1202,8 +1212,7 @@ and you're good to go.
shots_fired++
- else // This happens in very rare circumstances when you're moving a lot while burst firing, so I'm going to toss it up to guns jamming.
- clear_jam(projectile_to_fire,user)
+ else
return TRUE
//>>POST PROCESSING AND CLEANUP BEGIN HERE.<<
@@ -1892,7 +1901,7 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
if(!target)
target = src.target
if(!user)
- user = src.gun_user
+ user = gun_user
return Fire(target, user, params, reflex, dual_wield)
/// Setter proc for fa_firing
diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm
index 7d2dbf5288be..eb0e53986f9d 100644
--- a/code/modules/projectiles/gun_attachables.dm
+++ b/code/modules/projectiles/gun_attachables.dm
@@ -852,6 +852,28 @@ Defined in conflicts.dm of the #defines folder.
delay_scoped_nerf = FIRE_DELAY_TIER_11 //to compensate initial debuff. We want "high_fire_delay"
damage_falloff_scoped_buff = -0.4 //has to be negative
+/obj/item/attachable/scope/Attach(obj/item/weapon/gun/gun)
+ . = ..()
+ RegisterSignal(gun, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES, PROC_REF(handle_attachment_recalc))
+
+/obj/item/attachable/scope/Detach(mob/user, obj/item/weapon/gun/detaching_gub)
+ . = ..()
+ UnregisterSignal(detaching_gub, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES)
+
+
+/// Due to the bipod's interesting way of handling stat modifications, this is necessary to prevent exploits.
+/obj/item/attachable/scope/proc/handle_attachment_recalc(obj/item/weapon/gun/source)
+ SIGNAL_HANDLER
+
+ if(!source.zoom)
+ return
+
+ if(using_scope)
+ source.accuracy_mult += accuracy_scoped_buff
+ source.modify_fire_delay(delay_scoped_nerf)
+ source.damage_falloff_mult += damage_falloff_scoped_buff
+
+
/obj/item/attachable/scope/proc/apply_scoped_buff(obj/item/weapon/gun/G, mob/living/carbon/user)
if(G.zoom)
G.accuracy_mult += accuracy_scoped_buff
@@ -1976,6 +1998,8 @@ Defined in conflicts.dm of the #defines folder.
G.damage_mult = 1
icon_state += "-on"
+ SEND_SIGNAL(G, COMSIG_GUN_INTERRUPT_FIRE)
+
for(var/X in G.actions)
var/datum/action/A = X
A.update_button_icon()
@@ -2646,13 +2670,14 @@ Defined in conflicts.dm of the #defines folder.
burst_scatter_mod = 0
delay_mod = FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
+ G.stop_fire()
var/mob/living/user
if(isliving(G.loc))
user = G.loc
UnregisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK)
if(G.flags_gun_features & GUN_SUPPORT_PLATFORM)
- G.remove_bullet_trait("iff")
+ G.remove_firemode(GUN_FIREMODE_AUTOMATIC)
if(!QDELETED(G))
playsound(user,'sound/items/m56dauto_rotate.ogg', 55, 1)
@@ -2683,12 +2708,13 @@ Defined in conflicts.dm of the #defines folder.
else
delay_mod = -FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
+ G.stop_fire()
initial_mob_dir = user.dir
RegisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(handle_mob_move_or_look))
if(G.flags_gun_features & GUN_SUPPORT_PLATFORM)
- G.add_bullet_trait(BULLET_TRAIT_ENTRY_ID("iff", /datum/element/bullet_trait_iff))
+ G.add_firemode(GUN_FIREMODE_AUTOMATIC)
else
to_chat(user, SPAN_NOTICE("You retract [src]."))
diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm
index a60773c88be7..e86801c9d8c1 100644
--- a/code/modules/projectiles/gun_helpers.dm
+++ b/code/modules/projectiles/gun_helpers.dm
@@ -700,6 +700,9 @@ DEFINES in setup.dm, referenced here.
CRASH("add_firemode called with a resulting gun_firemode_list length of [length(gun_firemode_list)].")
/obj/item/weapon/gun/proc/remove_firemode(removed_firemode, mob/user)
+ if(!(removed_firemode in gun_firemode_list))
+ return
+
if(!length(gun_firemode_list) || (length(gun_firemode_list) == 1))
CRASH("remove_firemode called with gun_firemode_list length [length(gun_firemode_list)].")
@@ -710,7 +713,9 @@ DEFINES in setup.dm, referenced here.
do_toggle_firemode(user, gun_firemode)
/obj/item/weapon/gun/proc/setup_firemodes()
+ var/old_firemode = gun_firemode
gun_firemode_list.len = 0
+
if(start_semiauto)
gun_firemode_list |= GUN_FIREMODE_SEMIAUTO
@@ -722,6 +727,10 @@ DEFINES in setup.dm, referenced here.
if(!length(gun_firemode_list))
CRASH("[src] called setup_firemodes() with an empty gun_firemode_list")
+
+ else if(old_firemode in gun_firemode_list)
+ gun_firemode = old_firemode
+
else
gun_firemode = gun_firemode_list[1]
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 61ea0442a427..5733b01195ff 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -181,6 +181,7 @@
fire_sound = 'sound/weapons/Laser4.ogg'
has_charge_meter = FALSE
charge_icon = "+laz_uzi_empty"
+ start_automatic = TRUE
/obj/item/weapon/gun/energy/laz_uzi/set_gun_config_values()
..()
@@ -194,6 +195,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_6
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_scatter_peak = SCATTER_AMOUNT_TIER_8
//############################ Taser ##################
// Lots of bits for it so splitting off an area
diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm
index a108b3a9948f..ee08fee0f845 100644
--- a/code/modules/projectiles/guns/flamer/flamer.dm
+++ b/code/modules/projectiles/guns/flamer/flamer.dm
@@ -370,7 +370,7 @@
/obj/item/weapon/gun/flamer/M240T/auto/set_gun_config_values()
. = ..()
- set_fire_delay(FIRE_DELAY_TIER_3)
+ set_fire_delay(FIRE_DELAY_TIER_7)
GLOBAL_LIST_EMPTY(flamer_particles)
/particles/flamer_fire
diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm
index 18ffb082217c..70c1709e9e67 100644
--- a/code/modules/projectiles/guns/rifles.dm
+++ b/code/modules/projectiles/guns/rifles.dm
@@ -75,6 +75,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
starting_attachment_types = list(/obj/item/attachable/attached_gun/grenade, /obj/item/attachable/stock/rifle/collapsible)
map_specific_decoration = TRUE
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/m41a/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 12, "rail_y" = 23, "under_x" = 24, "under_y" = 13, "stock_x" = 24, "stock_y" = 13)
@@ -88,7 +89,6 @@
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4 + 2*HIT_ACCURACY_MULT_TIER_1
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_8
- //fa_scatter_peak = FULL_AUTO_SCATTER_PEAK_TIER_8 //Zonenote
burst_scatter_mult = SCATTER_AMOUNT_TIER_10
scatter_unwielded = SCATTER_AMOUNT_TIER_2
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_2
@@ -150,6 +150,7 @@
/obj/item/attachable/attached_gun/flamer/advanced,
)
start_semiauto = FALSE
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/nsg23/Initialize(mapload, spawn_empty)
. = ..()
@@ -171,6 +172,7 @@
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_8
recoil_unwielded = RECOIL_AMOUNT_TIER_2
damage_falloff_mult = 0
+ fa_max_scatter = SCATTER_AMOUNT_TIER_5
/obj/item/weapon/gun/rifle/nsg23/handle_starting_attachment()
..()
@@ -383,6 +385,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
starting_attachment_types = list(/obj/item/attachable/attached_gun/grenade/mk1, /obj/item/attachable/stock/rifle/collapsible)
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/m41aMK1/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 12, "rail_y" = 23, "under_x" = 23, "under_y" = 13, "stock_x" = 24, "stock_y" = 14)
@@ -528,6 +531,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_2
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_3
recoil_unwielded = RECOIL_AMOUNT_TIER_2
+ fa_max_scatter = SCATTER_AMOUNT_TIER_7
/obj/item/weapon/gun/rifle/m46c/able_to_fire(mob/user)
. = ..()
@@ -633,9 +637,11 @@
if(iff_enabled)
modify_fire_delay(FIRE_DELAY_TIER_12)
remove_firemode(GUN_FIREMODE_BURSTFIRE)
+ remove_firemode(GUN_FIREMODE_AUTOMATIC)
else
add_firemode(GUN_FIREMODE_BURSTFIRE)
+ add_firemode(GUN_FIREMODE_AUTOMATIC)
/obj/item/weapon/gun/rifle/m46c/proc/name_after_co(mob/living/carbon/human/H)
@@ -719,6 +725,7 @@
)
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
+ start_automatic = TRUE
@@ -1232,7 +1239,7 @@
/obj/item/attachable/magnetic_harness,
)
- flags_gun_features = GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_WIELDED_FIRING_ONLY
+ flags_gun_features = GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_WIELDED_FIRING_ONLY|GUN_SUPPORT_PLATFORM
gun_category = GUN_CATEGORY_HEAVY
/obj/item/weapon/gun/rifle/lmg/set_gun_attachment_offsets()
@@ -1297,6 +1304,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
flags_equip_slot = SLOT_BACK
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/type71/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 18, "rail_y" = 23, "under_x" = 20, "under_y" = 13, "stock_x" = 24, "stock_y" = 13)
@@ -1534,7 +1542,7 @@
set_burst_amount(0)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
- damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_6
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_8
recoil_unwielded = RECOIL_AMOUNT_TIER_4
damage_falloff_mult = 0
scatter = SCATTER_AMOUNT_TIER_8
diff --git a/code/modules/projectiles/guns/shotguns.dm b/code/modules/projectiles/guns/shotguns.dm
index a154062c9d10..3c366df40b57 100644
--- a/code/modules/projectiles/guns/shotguns.dm
+++ b/code/modules/projectiles/guns/shotguns.dm
@@ -1186,7 +1186,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube
name = "generic dual-tube pump shotgun"
- desc = "A twenty-round pump action shotgun with dual internal tube magazines. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A twenty-round pump action shotgun with dual internal tube magazines. You can switch the active internal magazine by toggling the shotgun tube."
current_mag = /obj/item/ammo_magazine/internal/shotgun
var/obj/item/ammo_magazine/internal/shotgun/primary_tube
var/obj/item/ammo_magazine/internal/shotgun/secondary_tube
@@ -1220,7 +1220,12 @@ can cause issues with ammo types getting mixed up during the burst.
playsound(src, 'sound/machines/switch.ogg', 15, TRUE)
return TRUE
-/obj/item/weapon/gun/shotgun/pump/dual_tube/set_bursting()
+/obj/item/weapon/gun/shotgun/pump/dual_tube/verb/toggle_tube()
+ set category = "Weapons"
+ set name = "Toggle Shotgun Tube"
+ set desc = "Toggles which shotgun tube your gun loads from."
+ set src = usr.contents
+
var/obj/item/weapon/gun/shotgun/pump/dual_tube/shotgun = get_active_firearm(usr)
if(shotgun == src)
swap_tube(usr)
@@ -1229,7 +1234,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube/cmb
name = "\improper HG 37-12 pump shotgun"
- desc = "A eight-round pump action shotgun with four-round capacity dual internal tube magazines allowing for quick reloading and highly accurate fire. Used exclusively by Colonial Marshals. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A eight-round pump action shotgun with four-round capacity dual internal tube magazines allowing for quick reloading and highly accurate fire. Used exclusively by Colonial Marshals. You can switch the active internal magazine by toggling the shotgun tube."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/colony.dmi'
icon_state = "hg3712"
item_state = "hg3712"
@@ -1269,7 +1274,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube/cmb/m3717
name = "\improper M37-17 pump shotgun"
- desc = "A military version of the iconic HG 37-12, this design can fit one extra shell in each of its dual-tube internal magazines, and fires shells with increased velocity, resulting in more damage. Issued to select USCM vessels out on the rim. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A military version of the iconic HG 37-12, this design can fit one extra shell in each of its dual-tube internal magazines, and fires shells with increased velocity, resulting in more damage. Issued to select USCM vessels out on the rim. You can switch the active internal magazine by toggling the shotgun tube."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/uscm.dmi'
icon_state = "m3717"
item_state = "m3717"
diff --git a/code/modules/projectiles/guns/smgs.dm b/code/modules/projectiles/guns/smgs.dm
index 70b0acb3f2c8..b9c2b9c3514d 100644
--- a/code/modules/projectiles/guns/smgs.dm
+++ b/code/modules/projectiles/guns/smgs.dm
@@ -20,6 +20,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
gun_category = GUN_CATEGORY_SMG
+ start_automatic = TRUE
/obj/item/weapon/gun/smg/Initialize(mapload, spawn_empty)
. = ..()
@@ -32,6 +33,7 @@
/obj/item/weapon/gun/smg/set_gun_config_values()
..()
movement_onehanded_acc_penalty_mult = 4
+ fa_max_scatter = SCATTER_AMOUNT_TIER_5
//-------------------------------------------------------
//M39 SMG
@@ -85,6 +87,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_max_scatter = SCATTER_AMOUNT_TIER_10 + 0.5
/obj/item/weapon/gun/smg/m39/training
@@ -270,6 +273,8 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_max_scatter = SCATTER_AMOUNT_TIER_9
+ fa_scatter_peak = 1 // Seems a bit funny, but it works pretty well in the end
/obj/item/weapon/gun/smg/ppsh/with_drum_mag
current_mag = /obj/item/ammo_magazine/smg/ppsh/extended
@@ -361,7 +366,6 @@
)
wield_delay = WIELD_DELAY_NONE
aim_slowdown = SLOWDOWN_ADS_NONE
- start_automatic = TRUE
/obj/item/weapon/gun/smg/mac15/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 20,"rail_x" = 16, "rail_y" = 22, "under_x" = 22, "under_y" = 16, "stock_x" = 22, "stock_y" = 16)
@@ -410,7 +414,6 @@
)
wield_delay = WIELD_DELAY_MIN
aim_slowdown = SLOWDOWN_ADS_QUICK
- start_automatic = TRUE
var/jammed = FALSE
/obj/item/weapon/gun/smg/uzi/set_gun_attachment_offsets()
@@ -567,6 +570,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
gun_category = GUN_CATEGORY_SMG
civilian_usable_override = TRUE
+ start_automatic = FALSE
var/nailing_speed = 2 SECONDS //Time to apply a sheet for patching. Also haha name. Try to keep sync with soundbyte duration
var/repair_sound = 'sound/weapons/nailgun_repair_long.ogg'
diff --git a/code/modules/projectiles/guns/souto.dm b/code/modules/projectiles/guns/souto.dm
index 8d7a1b2550a4..6f45f57e1d61 100644
--- a/code/modules/projectiles/guns/souto.dm
+++ b/code/modules/projectiles/guns/souto.dm
@@ -14,6 +14,8 @@
var/obj/item/storage/backpack/souto/soutopack
current_mag = null
auto_retrieval_slot = WEAR_IN_BACK
+ start_automatic = TRUE
+ autofire_slow_mult = 0.8 //Fires FASTER when in Full Auto, that is the power of Souta
/obj/item/weapon/gun/souto/set_gun_config_values()
. = ..()
diff --git a/code/modules/projectiles/guns/specialist.dm b/code/modules/projectiles/guns/specialist.dm
index 7152106869a9..a73335971ffa 100644
--- a/code/modules/projectiles/guns/specialist.dm
+++ b/code/modules/projectiles/guns/specialist.dm
@@ -267,11 +267,15 @@
if(toggling_action)
toggling_action.update_button_icon()
-/obj/item/weapon/gun/rifle/sniper/set_bursting(mob/user)
- if(has_aimed_shot)
- toggle_laser(user)
- else
- ..()
+/obj/item/weapon/gun/rifle/sniper/verb/toggle_gun_laser()
+ set category = "Weapons"
+ set name = "Toggle Laser"
+ set desc = "Toggles your laser on or off."
+ set src = usr.contents
+
+ var/obj/item/weapon/gun/rifle/sniper/sniper = get_active_firearm(usr)
+ if((sniper == src) && has_aimed_shot)
+ toggle_laser(usr)
//Pow! Headshot.
/obj/item/weapon/gun/rifle/sniper/M42A
diff --git a/code/modules/projectiles/magazines/rifles.dm b/code/modules/projectiles/magazines/rifles.dm
index ca008c2d1376..57bcd7f0a563 100644
--- a/code/modules/projectiles/magazines/rifles.dm
+++ b/code/modules/projectiles/magazines/rifles.dm
@@ -263,7 +263,7 @@
icon_state = "m41ae2"
max_rounds = 300
gun_type = /obj/item/weapon/gun/rifle/lmg
- flags_magazine = AMMUNITION_CANNOT_REMOVE_BULLETS|AMMUNITION_REFILLABLE
+ flags_magazine = AMMUNITION_CANNOT_REMOVE_BULLETS|AMMUNITION_REFILLABLE|AMMUNITION_SLAP_TRANSFER
ammo_band_icon = "+m41ae2_band"
ammo_band_icon_empty = "+m41ae2_band_e"
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index e4251f5f6b31..eccba14a442a 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -110,7 +110,7 @@
/obj/item/projectile/Crossed(atom/movable/AM)
/* Fun fact: Crossed is called for any contents involving operations.
* This notably means, inserting a magazing in a gun Crossed() it with the bullets in the gun. */
- if(!loc.z)
+ if(!loc?.z)
return // Not on the map. Don't scan a turf. Don't shoot the poor guy reloading his gun.
if(AM && !(AM in permutated))
if(scan_a_turf(get_turf(AM)))
@@ -1143,11 +1143,16 @@
// Need to do this in order to prevent the ping from being deleted
addtimer(CALLBACK(I, TYPE_PROC_REF(/image, flick_overlay), src, 3), 1)
+/// People getting shot by a large amount of bullets in a very short period of time can lag them out, with chat messages being one cause, so a 1s cooldown per hit message is introduced to assuage that
+/mob/var/shot_cooldown = 0
+
/mob/proc/bullet_message(obj/item/projectile/P)
if(!P)
return
- visible_message(SPAN_DANGER("[src] is hit by the [P.name] in the [parse_zone(P.def_zone)]!"), \
- SPAN_HIGHDANGER("You are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT)
+ if(COOLDOWN_FINISHED(src, shot_cooldown))
+ visible_message(SPAN_DANGER("[src] is hit by the [P.name] in the [parse_zone(P.def_zone)]!"), \
+ SPAN_HIGHDANGER("You are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT)
+ COOLDOWN_START(src, shot_cooldown, 1 SECONDS)
last_damage_data = P.weapon_cause_data
if(P.firer && ismob(P.firer))
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 42e7880bd313..43a250b7b091 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -741,6 +741,7 @@
#include "code\game\machinery\autolathe_datums.dm"
#include "code\game\machinery\Beacon.dm"
#include "code\game\machinery\bio-dome_floodlights.dm"
+#include "code\game\machinery\biohazard_lockdown.dm"
#include "code\game\machinery\bioprinter.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\cell_charger.dm"
diff --git a/config/example/custom_items.txt b/config/example/custom_items.txt
index 64a4bc648d7f..f4bb1a7028b7 100644
--- a/config/example/custom_items.txt
+++ b/config/example/custom_items.txt
@@ -1 +1 @@
-ckey: name: /path/to/obj
+ckey: name: /path/to/obj
diff --git a/config/example/forumdbconfig.txt b/config/example/forumdbconfig.txt
index 61a2a2d6ecdc..0335ef90693d 100644
--- a/config/example/forumdbconfig.txt
+++ b/config/example/forumdbconfig.txt
@@ -1,19 +1,19 @@
-# This configuration file is for the forum database, if you need to set up
-# population, death, etc. tracking see 'dbconfig.txt'
-# The login credentials for this will likely differ from those in dbconfig.txt!
-
-# Server the MySQL database can be found at
-# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc.
-ADDRESS localhost
-
-# MySQL server port (default is 3306)
-PORT 3306
-
-# Database the forum data may be found in
-DATABASE tgstation13
-
-# Username/Login used to access the database
-LOGIN mylogin
-
-# Password used to access the database
+# This configuration file is for the forum database, if you need to set up
+# population, death, etc. tracking see 'dbconfig.txt'
+# The login credentials for this will likely differ from those in dbconfig.txt!
+
+# Server the MySQL database can be found at
+# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc.
+ADDRESS localhost
+
+# MySQL server port (default is 3306)
+PORT 3306
+
+# Database the forum data may be found in
+DATABASE tgstation13
+
+# Username/Login used to access the database
+LOGIN mylogin
+
+# Password used to access the database
PASSWORD mypassword
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4035.yml b/html/changelogs/AutoChangeLog-pr-4035.yml
deleted file mode 100644
index 90ffb5a71740..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4035.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - code_imp: "Overhauled how ID accesses are assigned via proc, compiling all the many different procs we used into one."
- - rscadd: "Added faction specific accesses to all major factions."
- - rscdel: "Removed almost all marine accesses from non marine presets. No more free CIC access to CLF."
- - code_imp: "Removed duplicate code in the VAI file."
- - rscadd: "Adds a mapping var to indicate a door has non-standard access tags. This is to make it significantly easier for any future access changes to know if they need to look somewhere."
- - maptweak: "Applied this var to every door I could find on the Almayer that has non-standard access. Colonies and other stuff to come in a future update."
- - rscadd: "Added various new accesses to colonial doors, added WY_SECURITY and WY_RESEARCH to marine research doors."
- - maptweak: "Added reinforced piping to lifeboats area. Didn't make much sense for a cruicial part of the evacuation procedures to be prone to spontaneous explosions that can singlehandedly end a marine evacuation without hostiles ever seeing it."
- - maptweak: "Added reinforced piping to the research closed loop (it's a closed loop). Also removed CIC access from containment shutters as CIC access can't open the doors."
- - maptweak: "Changed a couple walls around research from standard to reinforced, to fit with the containment breach shutters."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4067.yml b/html/changelogs/AutoChangeLog-pr-4067.yml
new file mode 100644
index 000000000000..e0a9e4b383ef
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4067.yml
@@ -0,0 +1,5 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - rscadd: "Added a new lockdown system to research."
+ - rscadd: "Added an admin button to interact with above."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4226.yml b/html/changelogs/AutoChangeLog-pr-4226.yml
deleted file mode 100644
index 781b47852cf1..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4226.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CapCamIII"
-delete-after: True
-changes:
- - bugfix: "UPP soldier preset works again"
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml
index ee712fb75694..92158fdf3668 100644
--- a/html/changelogs/archive/2023-08.yml
+++ b/html/changelogs/archive/2023-08.yml
@@ -287,3 +287,55 @@
CapCamIII:
- bugfix: fixes the offset on m4ra custom barrel, it should appropriately be sat
right on the gun sprite
+2023-08-23:
+ CapCamIII:
+ - bugfix: UPP soldier preset works again
+ Drathek:
+ - bugfix: Fixed a cade attack exploit
+ Huffie56:
+ - bugfix: you will no longer be able to feed without any limit with the fork.
+ - bugfix: Whiskey Outpost Chem master will now be connected to the smartfridge.
+ harryob:
+ - rscadd: you always see lobby art while the world is setting up
+ realforest2001:
+ - code_imp: Overhauled how ID accesses are assigned via proc, compiling all the
+ many different procs we used into one.
+ - rscadd: Added faction specific accesses to all major factions.
+ - rscdel: Removed almost all marine accesses from non marine presets. No more free
+ CIC access to CLF.
+ - code_imp: Removed duplicate code in the VAI file.
+ - rscadd: Adds a mapping var to indicate a door has non-standard access tags. This
+ is to make it significantly easier for any future access changes to know if
+ they need to look somewhere.
+ - maptweak: Applied this var to every door I could find on the Almayer that has
+ non-standard access. Colonies and other stuff to come in a future update.
+ - rscadd: Added various new accesses to colonial doors, added WY_SECURITY and WY_RESEARCH
+ to marine research doors.
+ - maptweak: Added reinforced piping to lifeboats area. Didn't make much sense for
+ a cruicial part of the evacuation procedures to be prone to spontaneous explosions
+ that can singlehandedly end a marine evacuation without hostiles ever seeing
+ it.
+ - maptweak: Added reinforced piping to the research closed loop (it's a closed loop).
+ Also removed CIC access from containment shutters as CIC access can't open the
+ doors.
+ - maptweak: Changed a couple walls around research from standard to reinforced,
+ to fit with the containment breach shutters.
+2023-08-24:
+ Morrow:
+ - bugfix: Possible fix for binoc perma zoom
+ - balance: M4RA damage buffed by 10%
+ Zonespace27:
+ - balance: The M41A, M41Amk1, m39, m46c (iff off), mar-30/40/60, type 71, laser
+ uzi, and every SMG now has automatic fire. To compensate for the ability to
+ re-aim (unlike burst), the guns fire 20% slower while automatic. This does not
+ apply to already-existing automatic weaponry.
+ - balance: The HPR can now fire in full auto when bipodded.
+ - bugfix: Adding/removing attachments now keeps the current firemode, if possible.
+ - bugfix: The dualtube and spec sniper now can switch tubes/toggle laser again
+ - bugfix: Fixed a long-standing exploit with bipods and scopes.
+ - bugfix: Fixed guns jamming when shooting UI elements.
+ - bugfix: Fixed a bunch of guns unintentionally having burst.
+ - balance: You can transfer ammo between HPR ammo boxes by hitting one with another.
+ realforest2001:
+ - rscadd: Gave the ASO ability to modify IDs.
+ - rscdel: Removed this from the QM.
diff --git a/icons/obj/structures/doors/blastdoors_shutters.dmi b/icons/obj/structures/doors/blastdoors_shutters.dmi
index 0c91c00f0f79..c5ec97be49b8 100644
Binary files a/icons/obj/structures/doors/blastdoors_shutters.dmi and b/icons/obj/structures/doors/blastdoors_shutters.dmi differ
diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm
index 92b4422aeebe..186aa61b7835 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -3500,10 +3500,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple,
/area/almayer/medical/containment/cell)
@@ -4496,10 +4494,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 1
@@ -4946,10 +4942,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 8
@@ -5266,10 +5260,7 @@
icon_state = "E";
pixel_x = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -5744,10 +5735,7 @@
/obj/structure/machinery/door/firedoor/border_only/almayer{
dir = 2
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/plating,
/area/almayer/medical/upper_medical)
"aso" = (
@@ -8150,13 +8138,15 @@
},
/area/almayer/medical/medical_science)
"ayZ" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
/obj/structure/machinery/light{
dir = 1
},
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 10
+ },
/turf/open/floor/almayer{
icon_state = "dark_sterile"
},
@@ -8828,10 +8818,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 4
@@ -10577,10 +10565,8 @@
id = "researchlockdownext_windoor";
name = "\improper Research Windoor Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/open/floor/plating,
/area/almayer/medical/medical_science)
@@ -12412,10 +12398,8 @@
id = "researchlockdownext_windoor";
name = "\improper Research Windoor Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -32059,10 +32043,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 4
@@ -33438,7 +33420,6 @@
/turf/open/floor/plating/plating_catwalk,
/area/almayer/hallways/starboard_umbilical)
"eBO" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
/obj/structure/bed,
/turf/open/floor/almayer{
icon_state = "mono"
@@ -39761,14 +39742,15 @@
/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
name = "\improper Research Reception Laboratory"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 8;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -40681,10 +40663,7 @@
id = "researchlockdownext_door";
name = "\improper Research Doorway Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -41013,8 +40992,8 @@
/turf/open/floor/plating/plating_catwalk,
/area/almayer/shipboard/brig/cic_hallway)
"hVf" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 1
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 10
},
/turf/open/floor/almayer{
dir = 6;
@@ -44642,10 +44621,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 8
@@ -45070,10 +45047,8 @@
icon_state = "N";
pixel_y = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
dir = 4
@@ -45938,10 +45913,7 @@
/obj/structure/machinery/door/firedoor/border_only/almayer{
dir = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/plating,
/area/almayer/medical/medical_science)
"khd" = (
@@ -48546,12 +48518,12 @@
},
/area/almayer/squads/charlie)
"lou" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 8
- },
/obj/effect/decal/warning_stripes{
icon_state = "S"
},
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 5
+ },
/turf/open/floor/almayer{
icon_state = "sterile_green_side"
},
@@ -49687,10 +49659,7 @@
id = "researchlockdownext";
name = "\improper Research Window Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/plating,
/area/almayer/medical/medical_science)
"lJG" = (
@@ -49916,10 +49885,7 @@
id = "researchlockdownext_door";
name = "\improper Research Doorway Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -50748,11 +50714,8 @@
id = "researchlockdownext_se_2";
name = "\improper Research Window Shutter"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/plating,
/area/almayer/medical/medical_science)
"mnf" = (
@@ -52333,12 +52296,12 @@
},
/area/almayer/shipboard/brig/general_equipment)
"mWs" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
/obj/effect/decal/warning_stripes{
icon_state = "S"
},
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "sterile_green_side"
},
@@ -52547,9 +52510,6 @@
},
/area/almayer/engineering/upper_engineering/port)
"naR" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
/obj/structure/machinery/iv_drip,
/obj/effect/decal/warning_stripes{
icon_state = "E";
@@ -53553,10 +53513,6 @@
},
/turf/open/floor/plating,
/area/almayer/shipboard/brig/main_office)
-"nxF" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/turf/closed/wall/almayer/white/reinforced,
-/area/almayer/medical/medical_science)
"nxK" = (
/obj/structure/sign/safety/high_voltage{
pixel_y = -32
@@ -56296,10 +56252,8 @@
dir = 8;
name = "\improper Containment Airlock"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -58490,10 +58444,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple{
dir = 1
@@ -58757,9 +58709,6 @@
},
/area/almayer/living/offices)
"pRn" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 4
- },
/obj/structure/bed,
/obj/structure/machinery/power/apc/almayer{
dir = 4
@@ -60208,10 +60157,8 @@
name = "\improper Containment Cell 5";
unacidable = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/closed/wall/almayer/research/containment/wall/purple,
/area/almayer/medical/containment/cell)
@@ -60517,10 +60464,7 @@
/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor/research{
name = "\improper Research Hydroponics Workshop"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -62028,10 +61972,12 @@
},
/area/almayer/medical/lower_medical_medbay)
"rmc" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/pipes/standard/manifold/hidden/supply{
+ dir = 8
+ },
/turf/open/floor/almayer{
dir = 4;
icon_state = "sterile_green_side"
@@ -65967,10 +65913,8 @@
icon_state = "N";
pixel_y = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
dir = 4
@@ -69010,12 +68954,12 @@
/turf/open/floor/plating/plating_catwalk,
/area/almayer/engineering/engine_core)
"usy" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 9
- },
/obj/effect/decal/warning_stripes{
icon_state = "S"
},
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 9
+ },
/turf/open/floor/almayer{
icon_state = "sterile_green_side"
},
@@ -72394,10 +72338,7 @@
},
/obj/structure/disposalpipe/segment,
/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -72504,10 +72445,7 @@
/obj/structure/machinery/door/firedoor/border_only/almayer{
dir = 2
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -73089,16 +73027,14 @@
/obj/item/tool/pen{
pixel_y = -2
},
-/obj/structure/machinery/door_control/brbutton/alt{
- id = "Containment Breach";
- name = "Emergency Containment Breach";
- pixel_x = 8;
- pixel_y = 10
- },
/obj/item/reagent_container/dropper{
pixel_x = -1;
pixel_y = 9
},
+/obj/structure/machinery/biohazard_lockdown{
+ pixel_x = 8;
+ pixel_y = 10
+ },
/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
/turf/open/floor/almayer{
icon_state = "sterile_green"
@@ -73311,21 +73247,19 @@
/turf/open/floor/almayer,
/area/almayer/living/auxiliary_officer_office)
"wdo" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
/obj/structure/machinery/door/airlock/almayer/research/reinforced{
dir = 8;
name = "\improper Containment Airlock"
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
/obj/effect/decal/warning_stripes{
icon_state = "S"
},
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -73365,14 +73299,11 @@
},
/area/almayer/engineering/upper_engineering/starboard)
"wei" = (
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
/obj/effect/decal/warning_stripes{
icon_state = "E";
pixel_x = 1
},
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -73687,10 +73618,8 @@
/obj/structure/pipes/standard/simple/hidden/supply{
dir = 4
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -74816,12 +74745,10 @@
icon_state = "W";
pixel_x = -1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/almayer/medical/containment)
"wLi" = (
@@ -74939,10 +74866,8 @@
},
/area/almayer/squads/alpha)
"wMO" = (
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
},
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -76525,10 +76450,7 @@
icon_state = "E";
pixel_x = 1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
/turf/open/floor/almayer{
icon_state = "test_floor4"
@@ -78591,15 +78513,13 @@
icon_state = "W";
pixel_x = -1
},
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
/obj/structure/machinery/door/airlock/almayer/research/reinforced{
dir = 8;
name = "\improper Containment Airlock"
},
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -110583,7 +110503,7 @@ jUM
lou
eBO
pRn
-nxF
+vOy
ayZ
aCD
hFC
diff --git a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
index a39d7d7fffba..6a0e8b169fea 100644
--- a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
+++ b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
@@ -868,6 +868,9 @@
"dl" = (
/turf/closed/wall/r_wall/unmeltable,
/area/whiskey_outpost/inside/hospital)
+"dn" = (
+/turf/open/space/basic,
+/area/whiskey_outpost/inside/caves)
"dr" = (
/obj/structure/window/reinforced{
dir = 4;
@@ -1062,7 +1065,7 @@
/turf/open/gm/dirt,
/area/whiskey_outpost/inside/caves/tunnel)
"dV" = (
-/obj/structure/machinery/chem_master,
+/obj/structure/machinery/chem_dispenser,
/turf/open/floor{
dir = 9;
icon_state = "whitegreen"
@@ -1203,9 +1206,8 @@
/turf/open/gm/dirt,
/area/whiskey_outpost/inside/caves/tunnel)
"ez" = (
-/obj/structure/machinery/chem_dispenser,
-/obj/structure/machinery/light/small{
- dir = 8
+/obj/structure/machinery/chem_master{
+ tether_range = 4
},
/turf/open/floor{
dir = 1;
@@ -1959,7 +1961,9 @@
/turf/open/gm/dirt,
/area/whiskey_outpost/outside/lane/four_north)
"he" = (
-/obj/structure/machinery/chem_dispenser,
+/obj/structure/machinery/chem_master{
+ tether_range = 4
+ },
/turf/open/floor{
dir = 6;
icon_state = "whitegreen"
@@ -2426,7 +2430,10 @@
},
/area/whiskey_outpost/outside/north/northeast)
"ix" = (
-/obj/structure/machinery/chem_master,
+/obj/structure/machinery/chem_dispenser,
+/obj/structure/machinery/light/small{
+ dir = 8
+ },
/turf/open/floor{
dir = 10;
icon_state = "whitegreen"
@@ -22662,7 +22669,7 @@ mT
mT
mT
mT
-mT
+dn
mT
mT
dl
@@ -23061,12 +23068,12 @@ mT
mT
mT
mT
+dn
mT
mT
mT
mT
-mT
-mT
+dn
mT
mT
qz
diff --git a/sound/effects/biohazard.ogg b/sound/effects/biohazard.ogg
new file mode 100644
index 000000000000..b6528f9311ca
Binary files /dev/null and b/sound/effects/biohazard.ogg differ