diff --git a/code/__DEFINES/client_prefs.dm b/code/__DEFINES/client_prefs.dm
index ef5ff00e4ed6..b1e194354555 100644
--- a/code/__DEFINES/client_prefs.dm
+++ b/code/__DEFINES/client_prefs.dm
@@ -22,6 +22,7 @@
#define TOGGLE_VEND_ITEM_TO_HAND (1<<15) // This toggles whether items from vendors will be automatically put into your hand.
#define TOGGLE_START_JOIN_CURRENT_SLOT (1<<16) // Whether joining at roundstart ignores assigned character slot for the job and uses currently selected slot.
#define TOGGLE_LATE_JOIN_CURRENT_SLOT (1<<17) //Whether joining during the round ignores assigned character slot for the job and uses currently selected slot.
+#define TOGGLE_ABILITY_DEACTIVATION_OFF (1<<18) // This toggles whether selecting the same ability again can toggle it off
#define JOB_SLOT_RANDOMISED_SLOT -1
#define JOB_SLOT_CURRENT_SLOT 0
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 89976c498422..22c3827022ff 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "6.5.0"
+#define TGS_DMAPI_VERSION "6.5.2"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm
index 4b45c660feab..ac783b6f426e 100644
--- a/code/__DEFINES/xeno.dm
+++ b/code/__DEFINES/xeno.dm
@@ -168,6 +168,8 @@
#define XENO_LEAVE_TIMER_LARVA 80 //80 seconds
/// The time against away_timer when an AFK xeno (not larva) can be replaced
#define XENO_LEAVE_TIMER 300 //300 seconds
+/// The time against away_timer when an AFK facehugger converts to a npc
+#define XENO_FACEHUGGER_LEAVE_TIMER 420 //420 seconds
/// The time against away_timer when an AFK xeno gets listed in the available list so ghosts can get ready
#define XENO_AVAILABLE_TIMER 60 //60 seconds
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 0132a31d0b50..cca3edda464e 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -241,8 +241,14 @@
else
return get_step(start, EAST)
-/// Get a list of observers that can be alien candidates, optionally sorted by larva_queue_time
-/proc/get_alien_candidates(sorted = TRUE)
+/**
+ * Get a list of observers that can be alien candidates.
+ *
+ * Arguments:
+ * * hive - The hive we're filling a slot for to check if the player is banished
+ * * sorted - Whether to sort by larva_queue_time (default TRUE) or leave unsorted
+ */
+/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE)
var/list/candidates = list()
for(var/mob/dead/observer/cur_obs as anything in GLOB.observer_list)
@@ -273,6 +279,15 @@
if((cur_obs.client.admin_holder && (cur_obs.client.admin_holder.rights & R_MOD)) && !cur_obs.adminlarva)
continue
+ if(hive)
+ var/banished = FALSE
+ for(var/mob_name in hive.banished_ckeys)
+ if(hive.banished_ckeys[mob_name] == cur_obs.ckey)
+ banished = TRUE
+ break
+ if(banished)
+ continue
+
candidates += cur_obs
// Optionally sort by larva_queue_time
diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm
index 18b11dde030e..a42ff3f22e59 100644
--- a/code/game/gamemodes/cm_initialize.dm
+++ b/code/game/gamemodes/cm_initialize.dm
@@ -333,23 +333,28 @@ Additional game mode variables.
/datum/game_mode/proc/check_xeno_late_join(mob/xeno_candidate)
if(jobban_isbanned(xeno_candidate, JOB_XENOMORPH)) // User is jobbanned
to_chat(xeno_candidate, SPAN_WARNING("You are banned from playing aliens and cannot spawn as a xenomorph."))
- return
- return 1
+ return FALSE
+ return TRUE
-/datum/game_mode/proc/attempt_to_join_as_xeno(mob/xeno_candidate, instant_join = 0)
+/datum/game_mode/proc/attempt_to_join_as_xeno(mob/xeno_candidate, instant_join = FALSE)
var/list/available_xenos = list()
var/list/available_xenos_non_ssd = list()
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- var/area/A = get_area(X)
- if(is_admin_level(X.z) && (!A || !(A.flags_area & AREA_ALLOW_XENO_JOIN)) || X.aghosted)
- continue //xenos on admin z level and aghosted ones don't count
- if(istype(X) && ((!islarva(X) && (XENO_LEAVE_TIMER - X.away_timer < XENO_AVAILABLE_TIMER)) || (islarva(X) && (XENO_LEAVE_TIMER_LARVA - X.away_timer < XENO_AVAILABLE_TIMER))))
- if(!X.client)
- available_xenos += X
- else
- available_xenos_non_ssd += X
-
+ for(var/mob/living/carbon/xenomorph/cur_xeno as anything in GLOB.living_xeno_list)
+ if(cur_xeno.aghosted)
+ continue //aghosted xenos don't count
+ var/area/area = get_area(cur_xeno)
+ if(is_admin_level(cur_xeno.z) && (!area || !(area.flags_area & AREA_ALLOW_XENO_JOIN)))
+ continue //xenos on admin z level don't count
+ if(!istype(cur_xeno))
+ continue
+ var/required_time = islarva(cur_xeno) ? XENO_LEAVE_TIMER_LARVA - cur_xeno.away_timer : XENO_LEAVE_TIMER - cur_xeno.away_timer
+ if(required_time > XENO_AVAILABLE_TIMER)
+ continue
+ if(!cur_xeno.client)
+ available_xenos += cur_xeno
+ else
+ available_xenos_non_ssd += cur_xeno
var/datum/hive_status/hive
for(var/hivenumber in GLOB.hive_datum)
@@ -379,6 +384,13 @@ Additional game mode variables.
// No cache, lets check now then
message_alien_candidates(get_alien_candidates(), dequeued = 0, cache_only = TRUE)
if(candidate_observer.larva_queue_cached_message)
+ var/datum/hive_status/cur_hive
+ for(var/hive_num in GLOB.hive_datum)
+ cur_hive = GLOB.hive_datum[hive_num]
+ for(var/mob_name in cur_hive.banished_ckeys)
+ if(cur_hive.banished_ckeys[mob_name] == xeno_candidate.ckey)
+ candidate_observer.larva_queue_cached_message += "\n" + SPAN_WARNING("NOTE: You are banished from the [cur_hive] and you may not rejoin unless the Queen re-admits you or dies. Your queue number won't update until there is a hive you aren't banished from.")
+ break
to_chat(xeno_candidate, candidate_observer.larva_queue_cached_message)
return FALSE
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index ed06c0117f33..9c0a227008c3 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -503,23 +503,25 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
add_fingerprint(usr)
-/obj/structure/machinery/cryopod/proc/go_in_cryopod(mob/M, silent = FALSE)
+/obj/structure/machinery/cryopod/proc/go_in_cryopod(mob/mob, silent = FALSE)
if(occupant)
return
- M.forceMove(src)
- occupant = M
+ mob.forceMove(src)
+ occupant = mob
icon_state = "body_scanner_closed"
SetLuminosity(2)
time_entered = world.time
start_processing()
if(!silent)
- if(M.client)
- to_chat(M, SPAN_NOTICE("You feel cool air surround you. You go numb as your senses turn inward."))
- to_chat(M, SPAN_BOLDNOTICE("If you log out or close your client now, your character will permanently removed from the round in 10 minutes. If you ghost, timer will be decreased to 2 minutes."))
+ if(mob.client)
+ to_chat(mob, SPAN_NOTICE("You feel cool air surround you. You go numb as your senses turn inward."))
+ to_chat(mob, SPAN_BOLDNOTICE("If you log out or close your client now, your character will permanently removed from the round in 10 minutes. If you ghost, timer will be decreased to 2 minutes."))
+ if(!is_admin_level(src.z)) // Set their queue time now because the client has to actually leave to despawn and at that point the client is lost
+ mob.client.player_details.larva_queue_time = max(mob.client.player_details.larva_queue_time, world.time)
var/area/location = get_area(src)
- if(M.job != GET_MAPPED_ROLE(JOB_SQUAD_MARINE))
- message_admins("[key_name_admin(M)], [M.job], has entered \a [src] at [location] after playing for [duration2text(world.time - M.life_time_start)].")
+ if(mob.job != GET_MAPPED_ROLE(JOB_SQUAD_MARINE))
+ message_admins("[key_name_admin(mob)], [mob.job], has entered \a [src] at [location] after playing for [duration2text(world.time - mob.life_time_start)].")
playsound(src, 'sound/machines/hydraulics_3.ogg', 30)
silent_exit = silent
diff --git a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
index 5b0324edc2a2..103efeedde61 100644
--- a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
@@ -11,11 +11,21 @@
GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer, list(
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
+ list("Uniform", 0, /obj/item/clothing/under/marine/officer/bridge, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/mcom, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
+ list("JACKET (CHOOSE 1)", 0, null, null, null),
+ list("Service Jacket", 0, /obj/item/clothing/suit/storage/jacket/marine/service, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_RECOMMENDED),
+
+ list("HAT (CHOOSE 1)", 0, null, null, null),
+ list("Beret, Green", 0, /obj/item/clothing/head/beret/cm, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+ list("Beret, Tan", 0, /obj/item/clothing/head/beret/cm/tan, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+ list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+
+
list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M4A3 Pistol", 0, /obj/item/storage/belt/gun/m4a3/commander, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm
index 838b21a00e6f..b8e3e55f1d89 100644
--- a/code/game/machinery/vending/vendor_types/requisitions.dm
+++ b/code/game/machinery/vending/vendor_types/requisitions.dm
@@ -92,6 +92,7 @@
list("POUCHES", -1, null, null),
list("Autoinjector Pouch", round(scale * 2), /obj/item/storage/pouch/autoinjector, VENDOR_ITEM_REGULAR),
+ list("Bayonet Pouch", round(scale * 2), /obj/item/storage/pouch/bayonet, VENDOR_ITEM_REGULAR),
list("Construction Pouch", round(scale * 2), /obj/item/storage/pouch/construction, VENDOR_ITEM_REGULAR),
list("Document Pouch", round(scale * 2), /obj/item/storage/pouch/document/small, VENDOR_ITEM_REGULAR),
list("Electronics Pouch", round(scale * 2), /obj/item/storage/pouch/electronics, VENDOR_ITEM_REGULAR),
diff --git a/code/game/objects/effects/landmarks/landmarks.dm b/code/game/objects/effects/landmarks/landmarks.dm
index 64a5025794e3..1cbe10c497f6 100644
--- a/code/game/objects/effects/landmarks/landmarks.dm
+++ b/code/game/objects/effects/landmarks/landmarks.dm
@@ -216,23 +216,25 @@
/obj/effect/landmark/yautja_teleport
name = "yautja_teleport"
+ /// The index we registered as in mainship_yautja_desc or yautja_teleport_descs
+ var/desc_index
/obj/effect/landmark/yautja_teleport/Initialize(mapload, ...)
. = ..()
- var/turf/T = get_turf(src)
+ var/turf/turf = get_turf(src)
+ desc_index = turf.loc.name + turf.loc_to_string()
if(is_mainship_level(z))
GLOB.mainship_yautja_teleports += src
- GLOB.mainship_yautja_desc[T.loc.name + T.loc_to_string()] = src
+ GLOB.mainship_yautja_desc[desc_index] = src
else
GLOB.yautja_teleports += src
- GLOB.yautja_teleport_descs[T.loc.name + T.loc_to_string()] = src
+ GLOB.yautja_teleport_descs[desc_index] = src
/obj/effect/landmark/yautja_teleport/Destroy()
- var/turf/T = get_turf(src)
GLOB.mainship_yautja_teleports -= src
GLOB.yautja_teleports -= src
- GLOB.mainship_yautja_desc -= T.loc.name + T.loc_to_string()
- GLOB.yautja_teleport_descs -= T.loc.name + T.loc_to_string()
+ GLOB.mainship_yautja_desc -= desc_index
+ GLOB.yautja_teleport_descs -= desc_index
return ..()
diff --git a/code/game/objects/items/pamphlets.dm b/code/game/objects/items/pamphlets.dm
index 683fbb2540f4..dd96f275ef17 100644
--- a/code/game/objects/items/pamphlets.dm
+++ b/code/game/objects/items/pamphlets.dm
@@ -96,8 +96,8 @@
user.hud_set_squad()
var/obj/item/card/id/ID = user.wear_id
- ID.set_assignment((user.assigned_squad ? (user.assigned_squad.name + " ") : "") + "Squad Spotter")
- GLOB.data_core.manifest_modify(user.real_name, WEAKREF(user), "Squad Spotter")
+ ID.set_assignment((user.assigned_squad ? (user.assigned_squad.name + " ") : "") + "Spotter")
+ GLOB.data_core.manifest_modify(user.real_name, WEAKREF(user), "Spotter")
/obj/item/pamphlet/skill/machinegunner
name = "heavy machinegunner instructional pamphlet"
diff --git a/code/game/objects/items/storage/pouch.dm b/code/game/objects/items/storage/pouch.dm
index 198e5b3b9960..02e4b3866271 100644
--- a/code/game/objects/items/storage/pouch.dm
+++ b/code/game/objects/items/storage/pouch.dm
@@ -612,13 +612,12 @@
name = "explosive pouch"
desc = "It can carry grenades, plastic explosives, mine boxes, and other explosives."
icon_state = "large_explosive"
- storage_slots = 3
+ storage_slots = 6
max_w_class = SIZE_MEDIUM
can_hold = list(
/obj/item/explosive/plastic,
/obj/item/explosive/mine,
/obj/item/explosive/grenade,
- /obj/item/storage/box/explosive_mines,
)
/obj/item/storage/pouch/explosive/attackby(obj/item/W, mob/user)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 730263ad7a3e..db3ce98339a3 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -326,11 +326,13 @@
/// Checks whether a table is a straight line along a given axis
/obj/structure/surface/table/proc/straight_table_check(direction)
var/obj/structure/surface/table/table = src
- while(table)
+ var/obj/structure/surface/table/side_table
+ var/tables_count = 7 // Lazy extra safety against infinite loops. If table big, can't flip, i guess.
+ while(--tables_count)
// Check whether there are connected tables perpendicular to the axis
for(var/angle in list(-90, 90))
- table = locate() in get_step(loc, turn(direction, angle))
- if(table && !table.flipped)
+ side_table = locate() in get_step(table, turn(direction, angle))
+ if(side_table && !side_table.flipped)
return FALSE
table = locate() in get_step(table, direction)
if(!table || table.flipped)
@@ -339,6 +341,8 @@
var/obj/structure/surface/table/reinforced/reinforced_table = table
if(reinforced_table.status == RTABLE_NORMAL)
return FALSE
+ if(!tables_count)
+ return FALSE
return TRUE
/obj/structure/surface/table/verb/do_flip()
@@ -421,7 +425,7 @@
to_chat(usr, SPAN_WARNING("You have moved a table too recently."))
return FALSE
- if(!skip_straight_check && (!straight_table_check(turn(direction, 90)) || !straight_table_check(turn(direction, -90))))
+ if(!skip_straight_check && !(straight_table_check(turn(direction, 90)) && straight_table_check(turn(direction, -90))))
to_chat(usr, SPAN_WARNING("[src] is too wide to be flipped."))
return FALSE
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index c700a226295e..f42f350eea16 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -46,6 +46,7 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list(
/client/proc/toggle_eject_to_hand,
/client/proc/toggle_automatic_punctuation,
/client/proc/toggle_middle_mouse_click,
+ /client/proc/toggle_ability_deactivation,
/client/proc/toggle_clickdrag_override,
/client/proc/toggle_dualwield,
/client/proc/toggle_middle_mouse_swap_hands,
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index d2d69d095dbd..5698c30c0acf 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -595,6 +595,8 @@ var/const/MAX_SAVE_SLOTS = 10
[toggle_prefs & TOGGLE_HELP_INTENT_SAFETY ? "On" : "Off"]
"
dat += "Toggle Middle Mouse Ability Activation: \
[toggle_prefs & TOGGLE_MIDDLE_MOUSE_CLICK ? "On" : "Off"]
"
+ dat += "Toggle Ability Deactivation: \
+ [toggle_prefs & TOGGLE_ABILITY_DEACTIVATION_OFF ? "Off" : "On"]
"
dat += "Toggle Directional Assist: \
[toggle_prefs & TOGGLE_DIRECTIONAL_ATTACK ? "On" : "Off"]
"
dat += "Toggle Magazine Auto-Ejection: \
@@ -1229,7 +1231,7 @@ var/const/MAX_SAVE_SLOTS = 10
predator_gender = predator_gender == MALE ? FEMALE : MALE
if("pred_age")
var/new_predator_age = tgui_input_number(user, "Choose your Predator's age(175 to 3000):", "Character Preference", 1234, 3000, 175)
- if(new_predator_age)
+ if(new_predator_age)
predator_age = max(min( round(text2num(new_predator_age)), 3000),175)
if("pred_trans_type")
var/new_translator_type = tgui_input_list(user, "Choose your translator type.", "Translator Type", PRED_TRANSLATORS)
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index 9e3d9eb33766..b81411a26440 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -205,7 +205,7 @@
set name = "Toggle SpecialRole Candidacy"
set category = "Preferences"
set desc = "Toggles which special roles you would like to be a candidate for, during events."
-
+
var/list/be_special_flags = list(
"Xenomorph after unrevivable death" = BE_ALIEN_AFTER_DEATH,
"Agent" = BE_AGENT,
@@ -274,6 +274,7 @@
"Toggle 'Unload Weapon' Ejecting Magazines to Your Hands
",
"Toggle Automatic Punctuation
",
"Toggle Middle Mouse Ability Activation
",
+ "Toggle Ability Deactivation
",
"Toggle Combat Click-Drag Override
",
"Toggle Alternate-Fire Dual Wielding
",
"Toggle Middle Mouse Swapping Hands
",
@@ -287,7 +288,7 @@
for (var/pref_button in pref_buttons)
dat += "[pref_button]\n"
- var/height = 50+22*length(pref_buttons)
+ var/height = 50+24*length(pref_buttons)
show_browser(src, dat, "Toggle Preferences", "togglepreferences", "size=475x[height]")
@@ -355,6 +356,14 @@
to_chat(src, SPAN_NOTICE("Your selected ability will now be activated with shift clicking."))
prefs.save_preferences()
+/client/proc/toggle_ability_deactivation() // Toggle whether the current ability can be deactivated when re-selected
+ prefs.toggle_prefs ^= TOGGLE_ABILITY_DEACTIVATION_OFF
+ if (prefs.toggle_prefs & TOGGLE_ABILITY_DEACTIVATION_OFF)
+ to_chat(src, SPAN_NOTICE("Your current ability can no longer be toggled off when re-selected."))
+ else
+ to_chat(src, SPAN_NOTICE("Your current ability can be toggled off when re-selected."))
+ prefs.save_preferences()
+
/client/proc/toggle_clickdrag_override() //Toggle whether mousedown clicks immediately when on disarm or harm intent to prevent click-dragging from 'eating' attacks.
prefs.toggle_prefs ^= TOGGLE_COMBAT_CLICKDRAG_OVERRIDE
if(prefs.toggle_prefs & TOGGLE_COMBAT_CLICKDRAG_OVERRIDE)
diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm
index c38e540efb30..a29b49b7745a 100644
--- a/code/modules/cm_aliens/structures/special/pylon_core.dm
+++ b/code/modules/cm_aliens/structures/special/pylon_core.dm
@@ -150,7 +150,7 @@
last_larva_time = world.time
if(spawning_larva || (last_larva_queue_time + spawn_cooldown * 4) < world.time)
last_larva_queue_time = world.time
- var/list/players_with_xeno_pref = get_alien_candidates()
+ var/list/players_with_xeno_pref = get_alien_candidates(linked_hive)
if(players_with_xeno_pref && players_with_xeno_pref.len)
if(spawning_larva && spawn_burrowed_larva(players_with_xeno_pref[1]))
// We were in spawning_larva mode and successfully spawned someone
diff --git a/code/modules/gear_presets/synths.dm b/code/modules/gear_presets/synths.dm
index b7749f54c386..8ac227e9a0bb 100644
--- a/code/modules/gear_presets/synths.dm
+++ b/code/modules/gear_presets/synths.dm
@@ -394,7 +394,7 @@
idtype = /obj/item/card/id/pmc
equipment_to_spawn = list(
WEAR_HEAD = /obj/item/clothing/head/helmet/marine/veteran/pmc,
- WEAR_L_EAR = /obj/item/device/radio/headset/distress/pmc,
+ WEAR_L_EAR = /obj/item/device/radio/headset/distress/pmc/hvh,
WEAR_EYES = /obj/item/clothing/glasses/sunglasses/sechud,
WEAR_BODY = /obj/item/clothing/under/marine/veteran/pmc,
WEAR_ACCESSORY = /obj/item/clothing/accessory/storage/droppouch,
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index dbe00407d7ef..3896cd1f9ded 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -48,6 +48,10 @@
if(HAS_TRAIT(src, TRAIT_HARDCORE) || MODE_HAS_TOGGLEABLE_FLAG(MODE_HARDCORE_PERMA))
if(!(species.flags & IS_SYNTHETIC)) // Synths wont perma
status_flags |= PERMANENTLY_DEAD
+ if(HAS_TRAIT(src, TRAIT_INTENT_EYES)) //their eyes need to be 'offline'
+ r_eyes = 0
+ g_eyes = 0
+ b_eyes = 0
disable_special_flags()
disable_lights()
disable_special_items()
@@ -59,6 +63,7 @@
//Handle species-specific deaths.
if(species)
species.handle_death(src, gibbed)
+ update_body() //if species handle_death or other procs change body in some way after death, this is what will update the body.
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MARINE_DEATH, src, gibbed)
diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
index 874684480d15..b9044becb6f5 100644
--- a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
@@ -1,6 +1,7 @@
/datum/species/synthetic/colonial/working_joe
name = SYNTH_WORKING_JOE
name_plural = "Working Joes"
+ death_message = "violently gargles fluid and seizes up, the glow in their eyes dimming..."
uses_ethnicity = FALSE
burn_mod = 0.65 // made for hazardous environments, withstanding temperatures up to 1210 degrees
mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT, TRAIT_CANNOT_EAT)
@@ -14,6 +15,11 @@
. = ..()
give_action(joe, /datum/action/joe_emote_panel)
+// Special death noise for Working Joe
+/datum/species/synthetic/colonial/working_joe/handle_death(mob/living/carbon/human/dying_joe, gibbed)
+ if(!gibbed) //A gibbed Joe won't have a death rattle
+ playsound(dying_joe.loc, pick_weight(list('sound/voice/joe/death_normal.ogg' = 75, 'sound/voice/joe/death_silence.ogg' = 10, 'sound/voice/joe/death_tomorrow.ogg' = 10,'sound/voice/joe/death_dream.ogg' = 5)), 25, FALSE)
+ return ..()
/// Open the WJ's emote panel, which allows them to use voicelines
/datum/species/synthetic/colonial/working_joe/proc/open_emote_panel()
diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm
index 01f6c1a3c238..3ba42650e49c 100644
--- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm
@@ -163,7 +163,7 @@
if(!picked)
// Get a candidate from observers
- var/list/candidates = get_alien_candidates()
+ var/list/candidates = get_alien_candidates(hive)
if(candidates && candidates.len)
// If they were facehugged by a player thats still in queue, they get second dibs on the new larva.
if(hugger_ckey)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
index 60fdda450df3..f4d4628e41f2 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
@@ -158,6 +158,8 @@
if(xeno.selected_ability == src)
if(xeno.deselect_timer > world.time)
return // We clicked the same ability in a very short time
+ if(xeno.client && xeno.client.prefs && xeno.client.prefs.toggle_prefs & TOGGLE_ABILITY_DEACTIVATION_OFF)
+ return
to_chat(xeno, "You will no longer use [ability_name] with \
[xeno.client && xeno.client.prefs && xeno.client.prefs.toggle_prefs & TOGGLE_MIDDLE_MOUSE_CLICK ? "middle-click" : "shift-click"].")
button.icon_state = "template"
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
index 1ad171ec5c93..08566a6e9af3 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
@@ -67,6 +67,11 @@
PF.flags_can_pass_all = PASS_ALL^PASS_OVER_THROW_ITEM
/mob/living/carbon/xenomorph/facehugger/Life(delta_time)
+ if(!client && !aghosted && away_timer > XENO_FACEHUGGER_LEAVE_TIMER)
+ // Become a npc once again
+ new /obj/item/clothing/mask/facehugger(loc, hivenumber)
+ qdel(src)
+ return
if(stat != DEAD && !lying && !(locate(/obj/effect/alien/weeds) in get_turf(src)))
adjustBruteLoss(1)
return ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm
index e3a69da23262..12c9b3e37c9b 100644
--- a/code/modules/mob/living/carbon/xenomorph/death.dm
+++ b/code/modules/mob/living/carbon/xenomorph/death.dm
@@ -38,7 +38,7 @@
if(GLOB.hive_datum[hivenumber].stored_larva)
GLOB.hive_datum[hivenumber].stored_larva = round(GLOB.hive_datum[hivenumber].stored_larva * 0.5) //Lose half on dead queen
- var/list/players_with_xeno_pref = get_alien_candidates()
+ var/list/players_with_xeno_pref = get_alien_candidates(GLOB.hive_datum[hivenumber])
if(players_with_xeno_pref && istype(GLOB.hive_datum[hivenumber].hive_location, /obj/effect/alien/resin/special/pylon/core))
var/turf/larva_spawn = get_turf(GLOB.hive_datum[hivenumber].hive_location)
var/count = 0
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
index 20c170b72e4e..6b37145ad7a1 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
@@ -111,6 +111,21 @@
else
to_chat(src, SPAN_NOTICE("The selected xeno ability will now be activated with shift clicking."))
+/mob/living/carbon/xenomorph/verb/ability_deactivation_toggle()
+ set name = "Toggle Ability Deactivation"
+ set desc = "Toggles whether you can deactivate your currently active ability when re-selecting it."
+ set category = "Alien"
+
+ if (!client || !client.prefs)
+ return
+
+ client.prefs.toggle_prefs ^= TOGGLE_ABILITY_DEACTIVATION_OFF
+ client.prefs.save_preferences()
+ if (client.prefs.toggle_prefs & TOGGLE_ABILITY_DEACTIVATION_OFF)
+ to_chat(src, SPAN_NOTICE("Your current ability can no longer be toggled off when re-selected."))
+ else
+ to_chat(src, SPAN_NOTICE("Your current ability can be toggled off when re-selected."))
+
/mob/living/carbon/xenomorph/verb/directional_attack_toggle()
set name = "Toggle Directional Attacks"
set desc = "Toggles the use of directional assist attacks."
diff --git a/code/modules/projectiles/ammo_datums.dm b/code/modules/projectiles/ammo_datums.dm
index 14eb6a120886..d794b725b044 100644
--- a/code/modules/projectiles/ammo_datums.dm
+++ b/code/modules/projectiles/ammo_datums.dm
@@ -309,6 +309,7 @@
name = "tranquilizer bullet"
flags_ammo_behavior = AMMO_BALLISTIC|AMMO_IGNORE_RESIST
stamina_damage = 30
+ damage = 15
//2020 rebalance: is supposed to counter runners and lurkers, dealing high damage to the only castes with no armor.
//Limited by its lack of versatility and lower supply, so marines finally have an answer for flanker castes that isn't just buckshot.
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 6d3465ee8747..983fffeb2634 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -635,7 +635,7 @@
var/mob/dead/observer/obs = mob.ghostize(FALSE)
if(obs)
obs.timeofdeath = world.time
- obs.client?.player_details.larva_queue_time = world.time
+ obs.client?.player_details.larva_queue_time = max(obs.client.player_details.larva_queue_time, world.time)
mob.moveToNullspace()
// Now that mobs are stowed, delete the shuttle
diff --git a/code/modules/tgs/core/_definitions.dm b/code/modules/tgs/core/_definitions.dm
index ebf6d17c2a07..fd98034eb716 100644
--- a/code/modules/tgs/core/_definitions.dm
+++ b/code/modules/tgs/core/_definitions.dm
@@ -1,2 +1,10 @@
+#if DM_VERSION < 510
+#error The TGS DMAPI does not support BYOND versions < 510!
+#endif
+
#define TGS_UNIMPLEMENTED "___unimplemented"
#define TGS_VERSION_PARAMETER "server_service_version"
+
+#ifndef TGS_DEBUG_LOG
+#define TGS_DEBUG_LOG(message)
+#endif
diff --git a/code/modules/tgs/v3210/commands.dm b/code/modules/tgs/v3210/commands.dm
index d9bd287465b9..e65c816320dc 100644
--- a/code/modules/tgs/v3210/commands.dm
+++ b/code/modules/tgs/v3210/commands.dm
@@ -47,7 +47,7 @@
user.friendly_name = sender
// Discord hack, fix the mention if it's only numbers (fuck you IRC trolls)
- var/regex/discord_id_regex = regex(@"^[0-9]+$")
+ var/regex/discord_id_regex = regex("^\[0-9\]+$")
if(findtext(sender, discord_id_regex))
sender = "<@[sender]>"
@@ -55,4 +55,4 @@
var/datum/tgs_message_content/result = stc.Run(user, params)
result = UpgradeDeprecatedCommandResponse(result, command)
- return result?.text || TRUE
+ return result ? result.text : TRUE
diff --git a/code/modules/tgs/v4/commands.dm b/code/modules/tgs/v4/commands.dm
index d6d3d718d471..25dd6740e3af 100644
--- a/code/modules/tgs/v4/commands.dm
+++ b/code/modules/tgs/v4/commands.dm
@@ -40,5 +40,5 @@
var/datum/tgs_message_content/result = sc.Run(u, params)
result = UpgradeDeprecatedCommandResponse(result, command)
- return result?.text
+ return result ? result.text : TRUE
return "Unknown command: [command]!"
diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm
index c7213cc24699..f973338daa03 100644
--- a/code/modules/tgs/v5/_defines.dm
+++ b/code/modules/tgs/v5/_defines.dm
@@ -5,8 +5,8 @@
#define DMAPI5_TOPIC_DATA "tgs_data"
#define DMAPI5_BRIDGE_REQUEST_LIMIT 8198
-#define DMAPI5_TOPIC_REQUEST_LIMIT 65529
-#define DMAPI5_TOPIC_RESPONSE_LIMIT 65528
+#define DMAPI5_TOPIC_REQUEST_LIMIT 65528
+#define DMAPI5_TOPIC_RESPONSE_LIMIT 65529
#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0
#define DMAPI5_BRIDGE_COMMAND_STARTUP 1
diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm
index 926ea10a8f27..34cc43f8762f 100644
--- a/code/modules/tgs/v5/api.dm
+++ b/code/modules/tgs/v5/api.dm
@@ -22,12 +22,17 @@
var/detached = FALSE
+/datum/tgs_api/v5/New()
+ . = ..()
+ TGS_DEBUG_LOG("V5 API created")
+
/datum/tgs_api/v5/ApiVersion()
return new /datum/tgs_version(
#include "__interop_version.dm"
)
/datum/tgs_api/v5/OnWorldNew(minimum_required_security_level)
+ TGS_DEBUG_LOG("OnWorldNew()")
server_port = world.params[DMAPI5_PARAM_SERVER_PORT]
access_identifier = world.params[DMAPI5_PARAM_ACCESS_IDENTIFIER]
@@ -96,17 +101,28 @@
return TRUE
/datum/tgs_api/v5/proc/RequireInitialBridgeResponse()
+ TGS_DEBUG_LOG("RequireInitialBridgeResponse()")
+ var/logged = FALSE
while(!version)
+ if(!logged)
+ TGS_DEBUG_LOG("RequireInitialBridgeResponse: Starting sleep")
+ logged = TRUE
+
sleep(1)
+ TGS_DEBUG_LOG("RequireInitialBridgeResponse: Passed")
+
/datum/tgs_api/v5/OnInitializationComplete()
Bridge(DMAPI5_BRIDGE_COMMAND_PRIME)
/datum/tgs_api/v5/OnTopic(T)
+ TGS_DEBUG_LOG("OnTopic()")
RequireInitialBridgeResponse()
+ TGS_DEBUG_LOG("OnTopic passed bridge request gate")
var/list/params = params2list(T)
var/json = params[DMAPI5_TOPIC_DATA]
if(!json)
+ TGS_DEBUG_LOG("No \"[DMAPI5_TOPIC_DATA]\" entry found, ignoring...")
return FALSE // continue to /world/Topic
if(!initialized)
@@ -156,7 +172,7 @@
TGS_WARNING_LOG("Received legacy string when a [/datum/tgs_message_content] was expected. Please audit all calls to TgsChatBroadcast, TgsChatTargetedBroadcast, and TgsChatPrivateMessage to ensure they use the new /datum.")
return new /datum/tgs_message_content(message)
-/datum/tgs_api/v5/ChatBroadcast(datum/tgs_message_content/message, list/channels)
+/datum/tgs_api/v5/ChatBroadcast(datum/tgs_message_content/message2, list/channels)
if(!length(channels))
channels = ChatChannelInfo()
@@ -165,45 +181,45 @@
var/datum/tgs_chat_channel/channel = I
ids += channel.id
- message = UpgradeDeprecatedChatMessage(message)
+ message2 = UpgradeDeprecatedChatMessage(message2)
if (!length(channels))
return
- message = message._interop_serialize()
- message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = ids
+ var/list/data = message2._interop_serialize()
+ data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = ids
if(intercepted_message_queue)
- intercepted_message_queue += list(message)
+ intercepted_message_queue += list(data)
else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
+ Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
-/datum/tgs_api/v5/ChatTargetedBroadcast(datum/tgs_message_content/message, admin_only)
+/datum/tgs_api/v5/ChatTargetedBroadcast(datum/tgs_message_content/message2, admin_only)
var/list/channels = list()
for(var/I in ChatChannelInfo())
var/datum/tgs_chat_channel/channel = I
if (!channel.is_private_channel && ((channel.is_admin_channel && admin_only) || (!channel.is_admin_channel && !admin_only)))
channels += channel.id
- message = UpgradeDeprecatedChatMessage(message)
+ message2 = UpgradeDeprecatedChatMessage(message2)
if (!length(channels))
return
- message = message._interop_serialize()
- message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channels
+ var/list/data = message2._interop_serialize()
+ data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channels
if(intercepted_message_queue)
- intercepted_message_queue += list(message)
+ intercepted_message_queue += list(data)
else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
+ Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
-/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
- message = UpgradeDeprecatedChatMessage(message)
- message = message._interop_serialize()
- message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = list(user.channel.id)
+/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message2, datum/tgs_chat_user/user)
+ message2 = UpgradeDeprecatedChatMessage(message2)
+ var/list/data = message2._interop_serialize()
+ data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = list(user.channel.id)
if(intercepted_message_queue)
- intercepted_message_queue += list(message)
+ intercepted_message_queue += list(data)
else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
+ Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
/datum/tgs_api/v5/ChatChannelInfo()
RequireInitialBridgeResponse()
@@ -211,6 +227,7 @@
return chat_channels.Copy()
/datum/tgs_api/v5/proc/DecodeChannels(chat_update_json)
+ TGS_DEBUG_LOG("DecodeChannels()")
var/list/chat_channels_json = chat_update_json[DMAPI5_CHAT_UPDATE_CHANNELS]
if(istype(chat_channels_json))
chat_channels.Cut()
diff --git a/code/modules/tgs/v5/commands.dm b/code/modules/tgs/v5/commands.dm
index a832c81f172d..9557f8a08ed5 100644
--- a/code/modules/tgs/v5/commands.dm
+++ b/code/modules/tgs/v5/commands.dm
@@ -35,10 +35,10 @@
if(sc)
var/datum/tgs_message_content/response = sc.Run(u, params)
response = UpgradeDeprecatedCommandResponse(response, command)
-
+
var/list/topic_response = TopicResponse()
- topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = response?.text
- topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE] = response?._interop_serialize()
+ topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = response ? response.text : null
+ topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE] = response ? response._interop_serialize() : null
return topic_response
return TopicResponse("Unknown custom chat command: [command]!")
diff --git a/code/modules/tgs/v5/serializers.dm b/code/modules/tgs/v5/serializers.dm
index 7f9bc731b792..3a32848ad512 100644
--- a/code/modules/tgs/v5/serializers.dm
+++ b/code/modules/tgs/v5/serializers.dm
@@ -1,12 +1,12 @@
/datum/tgs_message_content/proc/_interop_serialize()
- return list("text" = text, "embed" = embed?._interop_serialize())
+ return list("text" = text, "embed" = embed ? embed._interop_serialize() : null)
/datum/tgs_chat_embed/proc/_interop_serialize()
CRASH("Base /proc/interop_serialize called on [type]!")
/datum/tgs_chat_embed/structure/_interop_serialize()
var/list/serialized_fields
- if(islist(fields))
+ if(istype(fields, /list))
serialized_fields = list()
for(var/datum/tgs_chat_embed/field/field as anything in fields)
serialized_fields += list(field._interop_serialize())
@@ -16,12 +16,12 @@
"url" = url,
"timestamp" = timestamp,
"colour" = colour,
- "image" = image?._interop_serialize(),
- "thumbnail" = thumbnail?._interop_serialize(),
- "video" = video?._interop_serialize(),
- "footer" = footer?._interop_serialize(),
- "provider" = provider?._interop_serialize(),
- "author" = author?._interop_serialize(),
+ "image" = src.image ? src.image._interop_serialize() : null,
+ "thumbnail" = thumbnail ? thumbnail._interop_serialize() : null,
+ "video" = video ? video._interop_serialize() : null,
+ "footer" = footer ? footer._interop_serialize() : null,
+ "provider" = provider ? provider._interop_serialize() : null,
+ "author" = author ? author._interop_serialize() : null,
"fields" = serialized_fields
)
@@ -43,7 +43,7 @@
. = ..()
.["iconUrl"] = icon_url
.["proxyIconUrl"] = proxy_icon_url
-
+
/datum/tgs_chat_embed/footer/_interop_serialize()
return list(
"text" = text,
diff --git a/code/modules/tgs/v5/topic.dm b/code/modules/tgs/v5/topic.dm
index 56c1824fd97d..d7d471213813 100644
--- a/code/modules/tgs/v5/topic.dm
+++ b/code/modules/tgs/v5/topic.dm
@@ -5,6 +5,7 @@
return response
/datum/tgs_api/v5/proc/ProcessTopicJson(json, check_access_identifier)
+ TGS_DEBUG_LOG("ProcessTopicJson(..., [check_access_identifier])")
var/list/result = ProcessRawTopic(json, check_access_identifier)
if(!result)
result = TopicResponse("Runtime error!")
@@ -25,16 +26,20 @@
return response_json
/datum/tgs_api/v5/proc/ProcessRawTopic(json, check_access_identifier)
+ TGS_DEBUG_LOG("ProcessRawTopic(..., [check_access_identifier])")
var/list/topic_parameters = json_decode(json)
if(!topic_parameters)
+ TGS_DEBUG_LOG("ProcessRawTopic: json_decode failed")
return TopicResponse("Invalid topic parameters json: [json]!");
var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
if(check_access_identifier && their_sCK != access_identifier)
- return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER]!")
+ TGS_DEBUG_LOG("ProcessRawTopic: access identifier check failed")
+ return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] or it does not match!")
var/command = topic_parameters[DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE]
if(!isnum(command))
+ TGS_DEBUG_LOG("ProcessRawTopic: command type check failed")
return TopicResponse("Failed to decode [DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE]!")
return ProcessTopicCommand(command, topic_parameters)
@@ -43,6 +48,7 @@
return "response[payload_id]"
/datum/tgs_api/v5/proc/ProcessTopicCommand(command, list/topic_parameters)
+ TGS_DEBUG_LOG("ProcessTopicCommand([command], ...)")
switch(command)
if(DMAPI5_TOPIC_COMMAND_CHAT_COMMAND)
@@ -55,7 +61,6 @@
return result
if(DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION)
- intercepted_message_queue = list()
var/list/event_notification = topic_parameters[DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]
if(!istype(event_notification))
return TopicResponse("Invalid [DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]!")
@@ -66,23 +71,25 @@
var/list/event_parameters = event_notification[DMAPI5_EVENT_NOTIFICATION_PARAMETERS]
if(event_parameters && !istype(event_parameters))
- return TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_PARAMETERS]!")
+ . = TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_PARAMETERS]!")
+ else
+ var/list/response = TopicResponse()
+ . = response
+ if(event_handler != null)
+ var/list/event_call = list(event_type)
+ if(event_parameters)
+ event_call += event_parameters
+
+ intercepted_message_queue = list()
+ event_handler.HandleEvent(arglist(event_call))
+ response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue
+ intercepted_message_queue = null
- var/list/event_call = list(event_type)
if (event_type == TGS_EVENT_WATCHDOG_DETACH)
detached = TRUE
chat_channels.Cut() // https://github.com/tgstation/tgstation-server/issues/1490
- if(event_parameters)
- event_call += event_parameters
-
- if(event_handler != null)
- event_handler.HandleEvent(arglist(event_call))
-
- var/list/response = TopicResponse()
- response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue
- intercepted_message_queue = null
- return response
+ return
if(DMAPI5_TOPIC_COMMAND_CHANGE_PORT)
var/new_port = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT]
@@ -122,8 +129,10 @@
return TopicResponse()
if(DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE)
+ TGS_DEBUG_LOG("ProcessTopicCommand: It's a chat update")
var/list/chat_update_json = topic_parameters[DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]
if(!istype(chat_update_json))
+ TGS_DEBUG_LOG("ProcessTopicCommand: failed \"[DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]\" check")
return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]!")
DecodeChannels(chat_update_json)
@@ -138,7 +147,7 @@
return TopicResponse()
if(DMAPI5_TOPIC_COMMAND_HEALTHCHECK)
- if(event_handler?.receive_health_checks)
+ if(event_handler && event_handler.receive_health_checks)
event_handler.HandleEvent(TGS_EVENT_HEALTH_CHECK)
return TopicResponse()
diff --git a/code/modules/vehicles/interior/interior.dm b/code/modules/vehicles/interior/interior.dm
index b56de4bfe16b..046b42495ac7 100644
--- a/code/modules/vehicles/interior/interior.dm
+++ b/code/modules/vehicles/interior/interior.dm
@@ -72,6 +72,7 @@
entrance_markers = null
QDEL_NULL(reservation)
+ SSinterior.interiors -= src
return ..()
diff --git a/html/changelogs/AutoChangeLog-pr-3798.yml b/html/changelogs/AutoChangeLog-pr-3798.yml
new file mode 100644
index 000000000000..0cf3ed169ecd
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3798.yml
@@ -0,0 +1,6 @@
+author: "Ben10083"
+delete-after: True
+changes:
+ - rscadd: "Working Joes now have a unique death message. Credit to Quickload for the message."
+ - soundadd: "Working Joes now have a death rattle. Credit to Quickload for shifting through Alien Isolation audio files."
+ - qol: "Things that die with intent eyes now lose color in their eyes on death."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3816.yml b/html/changelogs/AutoChangeLog-pr-3816.yml
deleted file mode 100644
index 94b1da5bec33..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3816.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - bugfix: "You can no longer weld non metal containers closed."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3830.yml b/html/changelogs/AutoChangeLog-pr-3830.yml
deleted file mode 100644
index 89a5541d9ade..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3830.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BeagleGaming1"
-delete-after: True
-changes:
- - code_imp: "Messed with chem and drink dispenser code"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3831.yml b/html/changelogs/AutoChangeLog-pr-3831.yml
deleted file mode 100644
index 073d35899894..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3831.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ben10083"
-delete-after: True
-changes:
- - mapadd: "Combat Information Center Reception now has a telephone"
- - maptweak: "Medical Lower telephone shifted to the left"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3841.yml b/html/changelogs/AutoChangeLog-pr-3841.yml
deleted file mode 100644
index 90292a845422..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3841.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Drathek"
-delete-after: True
-changes:
- - bugfix: "Fix morpher ejected items and dumped objectives not restoring their mouse_opacity setting."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3849.yml b/html/changelogs/AutoChangeLog-pr-3849.yml
deleted file mode 100644
index bf5c9c9813f6..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3849.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - rscadd: "Added a PMC Synth Survivor preset, and stopped PMC Synth Survivor using the ERT set."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3851.yml b/html/changelogs/AutoChangeLog-pr-3851.yml
deleted file mode 100644
index 2066366eb549..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3851.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Zonespace27"
-delete-after: True
-changes:
- - admin: "Removed msay. All staff now have access to asay"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3854.yml b/html/changelogs/AutoChangeLog-pr-3854.yml
deleted file mode 100644
index 651976126290..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3854.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - soundadd: "Added a drag sound for footstep component"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3857.yml b/html/changelogs/AutoChangeLog-pr-3857.yml
deleted file mode 100644
index e9729283ea34..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3857.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Morrow"
-delete-after: True
-changes:
- - balance: "Lurkers now lose their invisibility when they run into a person"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3864.yml b/html/changelogs/AutoChangeLog-pr-3864.yml
deleted file mode 100644
index 01e5ed5e7c73..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3864.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ondrej008"
-delete-after: True
-changes:
- - bugfix: "The HE OB now deals the correct amount of damage to xenos, before it dealt half damage caused by xenos being forced to rest before it hit."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3866.yml b/html/changelogs/AutoChangeLog-pr-3866.yml
deleted file mode 100644
index 49809e7e7dc3..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3866.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - bugfix: "Carbon copies can no longer infinitely breed."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3870.yml b/html/changelogs/AutoChangeLog-pr-3870.yml
deleted file mode 100644
index 34bba780f492..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3870.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - bugfix: "Fixes the icon on the alien blade on LV."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3871.yml b/html/changelogs/AutoChangeLog-pr-3871.yml
deleted file mode 100644
index 76cdd0ebb9ca..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3871.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ben10083"
-delete-after: True
-changes:
- - spellcheck: "Fixed typos relating to M74 airburst packets."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3878.yml b/html/changelogs/AutoChangeLog-pr-3878.yml
deleted file mode 100644
index bef90fd797f5..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3878.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - bugfix: "Fixes the toggle notification sound verb for Yautja bracers not working."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3881.yml b/html/changelogs/AutoChangeLog-pr-3881.yml
deleted file mode 100644
index e7228482ba13..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3881.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Steelpoint"
-delete-after: True
-changes:
- - ui: "Predator Ship is now called 'Yautja Ship\" for teleporting Predators"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3885.yml b/html/changelogs/AutoChangeLog-pr-3885.yml
new file mode 100644
index 000000000000..f3d6528be66b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3885.yml
@@ -0,0 +1,6 @@
+author: "Drathek"
+delete-after: True
+changes:
+ - bugfix: "Banished players will no longer be candidates for hives they are banished from."
+ - bugfix: "Cryoing will now set your larva queue time so you don't get prioritized over others that have been waiting."
+ - admin: "Shuttle intoTheSunset will set larva queue time the same as other situations."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3892.yml b/html/changelogs/AutoChangeLog-pr-3892.yml
new file mode 100644
index 000000000000..5973b1b11324
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3892.yml
@@ -0,0 +1,4 @@
+author: "theselfish"
+delete-after: True
+changes:
+ - spellcheck: "Goodbye Squad Spotter, hello regular non-squaded Spotter."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3897.yml b/html/changelogs/AutoChangeLog-pr-3897.yml
new file mode 100644
index 000000000000..5c4c45410146
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3897.yml
@@ -0,0 +1,5 @@
+author: "Morrow"
+delete-after: True
+changes:
+ - balance: "Explosive pouch inventory size from 3 to 6"
+ - balance: "Explosive pouch can no longer hold mine boxes"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3874.yml b/html/changelogs/AutoChangeLog-pr-3898.yml
similarity index 52%
rename from html/changelogs/AutoChangeLog-pr-3874.yml
rename to html/changelogs/AutoChangeLog-pr-3898.yml
index 83311c453f97..abda91f2b52b 100644
--- a/html/changelogs/AutoChangeLog-pr-3874.yml
+++ b/html/changelogs/AutoChangeLog-pr-3898.yml
@@ -1,4 +1,4 @@
author: "Morrow"
delete-after: True
changes:
- - admin: "VV Jump To Fix"
\ No newline at end of file
+ - rscadd: "Added bayonet pouch to req"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3900.yml b/html/changelogs/AutoChangeLog-pr-3900.yml
new file mode 100644
index 000000000000..9f5a7f4cacf2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3900.yml
@@ -0,0 +1,4 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - balance: "Reduced tranq pistol bullet damage from 40 to 15"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3901.yml b/html/changelogs/AutoChangeLog-pr-3901.yml
new file mode 100644
index 000000000000..cbf4cc58a410
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3901.yml
@@ -0,0 +1,4 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - bugfix: "Fixes another synth survivor variant having marine comms."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-3904.yml b/html/changelogs/AutoChangeLog-pr-3904.yml
new file mode 100644
index 000000000000..e3c1a56fa7ae
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3904.yml
@@ -0,0 +1,4 @@
+author: "Drathek"
+delete-after: True
+changes:
+ - qol: "Added a preference to disable xeno ability deactivation when re-selecting the same ability"
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-07.yml b/html/changelogs/archive/2023-07.yml
index 923af7d86a7b..db8b80db6820 100644
--- a/html/changelogs/archive/2023-07.yml
+++ b/html/changelogs/archive/2023-07.yml
@@ -166,3 +166,57 @@
- bugfix: Fixed burrowers being able to get slashed from enemy Xenos on the surface.
- bugfix: Fixed burrowers unburrow stun to now properly target and stun enemy Xenos.
- soundadd: Added sounds for the Burrower when they are burrowing and unburrowing.
+2023-07-15:
+ BeagleGaming1:
+ - code_imp: Messed with chem and drink dispenser code
+ Ben10083:
+ - spellcheck: Fixed typos relating to M74 airburst packets.
+ - mapadd: Combat Information Center Reception now has a telephone
+ - maptweak: Medical Lower telephone shifted to the left
+ Drathek:
+ - bugfix: Fix morpher ejected items and dumped objectives not restoring their mouse_opacity
+ setting.
+ Morrow:
+ - admin: VV Jump To Fix
+ - balance: Lurkers now lose their invisibility when they run into a person
+ Steelpoint:
+ - ui: Predator Ship is now called 'Yautja Ship" for teleporting Predators
+ Zonespace27:
+ - admin: Removed msay. All staff now have access to asay
+ ondrej008:
+ - bugfix: The HE OB now deals the correct amount of damage to xenos, before it dealt
+ half damage caused by xenos being forced to rest before it hit.
+ realforest2001:
+ - soundadd: Added a drag sound for footstep component
+ - bugfix: Fixes the icon on the alien blade on LV.
+ - bugfix: Carbon copies can no longer infinitely breed.
+ - rscadd: Added a PMC Synth Survivor preset, and stopped PMC Synth Survivor using
+ the ERT set.
+ - bugfix: You can no longer weld non metal containers closed.
+ - bugfix: Fixes the toggle notification sound verb for Yautja bracers not working.
+2023-07-16:
+ Drathek:
+ - rscadd: Facehuggers now convert to their NPC version after 7 minutes of inactivity
+ and no client.
+ - code_imp: Cleanup join as xeno button code somewhat.
+ Drathek, Fira:
+ - bugfix: Fixed an issue with table flips that could make some tables incorrectly
+ unflippable, and cause infinite loops. It is no longer possible to flip tables
+ that t-shape or cross, or spans more than 5 tiles away from you.
+ Drathek, Steelpoint:
+ - bugfix: Fixed possible hardeletes for predator landmarks and vehicles. Predator
+ teleporation descriptions now do not change if the area is altered at runtime
+ so they can still be found correctly.
+ theselfish:
+ - rscadd: SOs may now get coats in their vendor.
+2023-07-17:
+ Puckaboo2:
+ - spellcheck: Some duplicate icon states have been differentiated to prevent future
+ missing icon state errors.
+ - imageadd: Added new icon states for chemical and virology dispensers.
+ - rscdel: Removed dozens of duplicate icon states from over 50 files to reduce bloat.
+ - rscdel: Removed duplicate empty icon states.
+ realforest2001:
+ - maptweak: Added Apollo Maintenance Controllers to the following locations.
+ - maptweak: Astronavigation, CIC Substation, Brig Substation, Req Aux Storage, Hangar
+ & OT & Engineering workshops, Reactor Core Room and Lifeboat Control Ring.
diff --git a/icons/effects/genetics.dmi b/icons/effects/genetics.dmi
index 8e31fea96135..fa46a2d6c094 100644
Binary files a/icons/effects/genetics.dmi and b/icons/effects/genetics.dmi differ
diff --git a/icons/mob/hud/alien_standard.dmi b/icons/mob/hud/alien_standard.dmi
index 7e339ec5e83d..8bad0b44acc9 100644
Binary files a/icons/mob/hud/alien_standard.dmi and b/icons/mob/hud/alien_standard.dmi differ
diff --git a/icons/mob/hud/hud.dmi b/icons/mob/hud/hud.dmi
index 91fd9e92b5fa..f8ea98d01e53 100644
Binary files a/icons/mob/hud/hud.dmi and b/icons/mob/hud/hud.dmi differ
diff --git a/icons/mob/hud/human_bronze.dmi b/icons/mob/hud/human_bronze.dmi
index 4f2ee88d1da5..11a724057245 100644
Binary files a/icons/mob/hud/human_bronze.dmi and b/icons/mob/hud/human_bronze.dmi differ
diff --git a/icons/mob/hud/human_old.dmi b/icons/mob/hud/human_old.dmi
index 2e29c09411b7..194206d4de16 100644
Binary files a/icons/mob/hud/human_old.dmi and b/icons/mob/hud/human_old.dmi differ
diff --git a/icons/mob/hud/human_orange.dmi b/icons/mob/hud/human_orange.dmi
index 420fb3e8ea3e..8a46dad89ed5 100644
Binary files a/icons/mob/hud/human_orange.dmi and b/icons/mob/hud/human_orange.dmi differ
diff --git a/icons/mob/hud/screen1.dmi b/icons/mob/hud/screen1.dmi
index df8475ef0ebd..fd4cf8188579 100644
Binary files a/icons/mob/hud/screen1.dmi and b/icons/mob/hud/screen1.dmi differ
diff --git a/icons/mob/hud/screen1_robot.dmi b/icons/mob/hud/screen1_robot.dmi
index a54b0a34b392..679a555c97a6 100644
Binary files a/icons/mob/hud/screen1_robot.dmi and b/icons/mob/hud/screen1_robot.dmi differ
diff --git a/icons/mob/hud/talk.dmi b/icons/mob/hud/talk.dmi
index 52255e1094f9..c6f043bfd781 100644
Binary files a/icons/mob/hud/talk.dmi and b/icons/mob/hud/talk.dmi differ
diff --git a/icons/mob/humans/green_armors.dmi b/icons/mob/humans/green_armors.dmi
index e1a5aaf8c13f..5022b6c4bbc7 100644
Binary files a/icons/mob/humans/green_armors.dmi and b/icons/mob/humans/green_armors.dmi differ
diff --git a/icons/mob/humans/human.dmi b/icons/mob/humans/human.dmi
index f98eb58f08ff..7bcd1e9796cc 100644
Binary files a/icons/mob/humans/human.dmi and b/icons/mob/humans/human.dmi differ
diff --git a/icons/mob/humans/onmob/belt.dmi b/icons/mob/humans/onmob/belt.dmi
index 1d5ed650b6f9..f95ba65ece52 100644
Binary files a/icons/mob/humans/onmob/belt.dmi and b/icons/mob/humans/onmob/belt.dmi differ
diff --git a/icons/mob/humans/species/monkeys/onmob/suit_monkey_0.dmi b/icons/mob/humans/species/monkeys/onmob/suit_monkey_0.dmi
index 3083c943c761..6d05304ef8d9 100644
Binary files a/icons/mob/humans/species/monkeys/onmob/suit_monkey_0.dmi and b/icons/mob/humans/species/monkeys/onmob/suit_monkey_0.dmi differ
diff --git a/icons/mob/humans/species/monkeys/onmob/uniform_monkey_0.dmi b/icons/mob/humans/species/monkeys/onmob/uniform_monkey_0.dmi
index 730ee28ff467..cc6fb5d13b03 100644
Binary files a/icons/mob/humans/species/monkeys/onmob/uniform_monkey_0.dmi and b/icons/mob/humans/species/monkeys/onmob/uniform_monkey_0.dmi differ
diff --git a/icons/mob/xenonids/lurker.dmi b/icons/mob/xenonids/lurker.dmi
index bc2c3aa06837..45a04ac68446 100644
Binary files a/icons/mob/xenonids/lurker.dmi and b/icons/mob/xenonids/lurker.dmi differ
diff --git a/icons/obj/bodybag.dmi b/icons/obj/bodybag.dmi
index 9084afd56f63..157a7692b2a8 100644
Binary files a/icons/obj/bodybag.dmi and b/icons/obj/bodybag.dmi differ
diff --git a/icons/obj/items/black_goo_stuff.dmi b/icons/obj/items/black_goo_stuff.dmi
index 2d7b063bc4b8..b40461a40101 100644
Binary files a/icons/obj/items/black_goo_stuff.dmi and b/icons/obj/items/black_goo_stuff.dmi differ
diff --git a/icons/obj/items/clothing/halloween_clothes.dmi b/icons/obj/items/clothing/halloween_clothes.dmi
index 3de24560ec9d..530b7cf5a905 100644
Binary files a/icons/obj/items/clothing/halloween_clothes.dmi and b/icons/obj/items/clothing/halloween_clothes.dmi differ
diff --git a/icons/obj/items/food.dmi b/icons/obj/items/food.dmi
index ac802dc66a9a..6e2c86aa4999 100644
Binary files a/icons/obj/items/food.dmi and b/icons/obj/items/food.dmi differ
diff --git a/icons/obj/items/hunter/pred_gear.dmi b/icons/obj/items/hunter/pred_gear.dmi
index 5587cc685bec..ab034d7ec48a 100644
Binary files a/icons/obj/items/hunter/pred_gear.dmi and b/icons/obj/items/hunter/pred_gear.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/barrel.dmi b/icons/obj/items/weapons/guns/attachments/barrel.dmi
index 41231e81b975..d040aa85fd5d 100644
Binary files a/icons/obj/items/weapons/guns/attachments/barrel.dmi and b/icons/obj/items/weapons/guns/attachments/barrel.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/rail.dmi b/icons/obj/items/weapons/guns/attachments/rail.dmi
index 10e3cbe99a8c..315005696ba8 100644
Binary files a/icons/obj/items/weapons/guns/attachments/rail.dmi and b/icons/obj/items/weapons/guns/attachments/rail.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/stock.dmi b/icons/obj/items/weapons/guns/attachments/stock.dmi
index 481710383a14..8eb95d15770f 100644
Binary files a/icons/obj/items/weapons/guns/attachments/stock.dmi and b/icons/obj/items/weapons/guns/attachments/stock.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/under.dmi b/icons/obj/items/weapons/guns/attachments/under.dmi
index 8cbf735ac96b..1a55ea7e215f 100644
Binary files a/icons/obj/items/weapons/guns/attachments/under.dmi and b/icons/obj/items/weapons/guns/attachments/under.dmi differ
diff --git a/icons/obj/items/weapons/guns/legacy/old_bayguns.dmi b/icons/obj/items/weapons/guns/legacy/old_bayguns.dmi
index d1bdb7d3b0c9..568bfd0ee456 100644
Binary files a/icons/obj/items/weapons/guns/legacy/old_bayguns.dmi and b/icons/obj/items/weapons/guns/legacy/old_bayguns.dmi differ
diff --git a/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi b/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi
index bf67ed68502c..24cade43454f 100644
Binary files a/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi and b/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi differ
diff --git a/icons/obj/structures/doors/mineral_doors.dmi b/icons/obj/structures/doors/mineral_doors.dmi
index 1613f466d523..f9e025ccf0e9 100644
Binary files a/icons/obj/structures/doors/mineral_doors.dmi and b/icons/obj/structures/doors/mineral_doors.dmi differ
diff --git a/icons/obj/structures/doors/prison_FOP/prison_hatches.dmi b/icons/obj/structures/doors/prison_FOP/prison_hatches.dmi
index 489d2333f2a6..23864a1065d1 100644
Binary files a/icons/obj/structures/doors/prison_FOP/prison_hatches.dmi and b/icons/obj/structures/doors/prison_FOP/prison_hatches.dmi differ
diff --git a/icons/obj/structures/machinery/computer3.dmi b/icons/obj/structures/machinery/computer3.dmi
index 4735cfc5a1a4..047417f303f3 100644
Binary files a/icons/obj/structures/machinery/computer3.dmi and b/icons/obj/structures/machinery/computer3.dmi differ
diff --git a/icons/obj/structures/machinery/cryogenics.dmi b/icons/obj/structures/machinery/cryogenics.dmi
index b2c5d2e0c5ce..dc061195583f 100644
Binary files a/icons/obj/structures/machinery/cryogenics.dmi and b/icons/obj/structures/machinery/cryogenics.dmi differ
diff --git a/icons/obj/structures/machinery/shuttle-parts.dmi b/icons/obj/structures/machinery/shuttle-parts.dmi
index 1ec8a07e6b3f..7db27387e7c1 100644
Binary files a/icons/obj/structures/machinery/shuttle-parts.dmi and b/icons/obj/structures/machinery/shuttle-parts.dmi differ
diff --git a/icons/obj/structures/machinery/vending.dmi b/icons/obj/structures/machinery/vending.dmi
index ecc570680a74..3098aadca8be 100644
Binary files a/icons/obj/structures/machinery/vending.dmi and b/icons/obj/structures/machinery/vending.dmi differ
diff --git a/icons/obj/structures/props/dam.dmi b/icons/obj/structures/props/dam.dmi
index 3541b2412e13..76f67514c2ea 100644
Binary files a/icons/obj/structures/props/dam.dmi and b/icons/obj/structures/props/dam.dmi differ
diff --git a/icons/obj/structures/props/fence.dmi b/icons/obj/structures/props/fence.dmi
index 9ed9d1f7fc20..016aab562777 100644
Binary files a/icons/obj/structures/props/fence.dmi and b/icons/obj/structures/props/fence.dmi differ
diff --git a/icons/obj/structures/stairs/perspective_stairs_ice.dmi b/icons/obj/structures/stairs/perspective_stairs_ice.dmi
index 8f5bf6935d7b..3311adfc11dd 100644
Binary files a/icons/obj/structures/stairs/perspective_stairs_ice.dmi and b/icons/obj/structures/stairs/perspective_stairs_ice.dmi differ
diff --git a/icons/obj/structures/stairs/perspective_stairs_kutjevo.dmi b/icons/obj/structures/stairs/perspective_stairs_kutjevo.dmi
index 86a2cfde6339..f9c759a32d12 100644
Binary files a/icons/obj/structures/stairs/perspective_stairs_kutjevo.dmi and b/icons/obj/structures/stairs/perspective_stairs_kutjevo.dmi differ
diff --git a/icons/old_stuff/Seasonal/xmas.dmi b/icons/old_stuff/Seasonal/xmas.dmi
index 8dd25fd4b6d4..9669a6034b9c 100644
Binary files a/icons/old_stuff/Seasonal/xmas.dmi and b/icons/old_stuff/Seasonal/xmas.dmi differ
diff --git a/icons/rebase_icons.dmi b/icons/rebase_icons.dmi
index aaf92453b29a..2d394cef793d 100644
Binary files a/icons/rebase_icons.dmi and b/icons/rebase_icons.dmi differ
diff --git a/icons/turf/almayer.dmi b/icons/turf/almayer.dmi
index a90940470acf..07f771ec78c7 100644
Binary files a/icons/turf/almayer.dmi and b/icons/turf/almayer.dmi differ
diff --git a/icons/turf/area_strata.dmi b/icons/turf/area_strata.dmi
index 54b90d0a8f92..8c9791522989 100644
Binary files a/icons/turf/area_strata.dmi and b/icons/turf/area_strata.dmi differ
diff --git a/icons/turf/floors/asphalt.dmi b/icons/turf/floors/asphalt.dmi
index ef4f07d5f374..57b807b1c3f4 100644
Binary files a/icons/turf/floors/asphalt.dmi and b/icons/turf/floors/asphalt.dmi differ
diff --git a/icons/turf/floors/concrete.dmi b/icons/turf/floors/concrete.dmi
index d3aa3a1fa7ee..54d7dd3aaaef 100644
Binary files a/icons/turf/floors/concrete.dmi and b/icons/turf/floors/concrete.dmi differ
diff --git a/icons/turf/floors/floors.dmi b/icons/turf/floors/floors.dmi
index 681ffa537aa4..7b68cbb2b6b2 100644
Binary files a/icons/turf/floors/floors.dmi and b/icons/turf/floors/floors.dmi differ
diff --git a/icons/turf/walls/bunker.dmi b/icons/turf/walls/bunker.dmi
index 6f7537e20f7c..d9d4f8a080cb 100644
Binary files a/icons/turf/walls/bunker.dmi and b/icons/turf/walls/bunker.dmi differ
diff --git a/icons/turf/walls/dev/dev.dmi b/icons/turf/walls/dev/dev.dmi
index 0c6025876b2e..4a1eaf6f7b6a 100644
Binary files a/icons/turf/walls/dev/dev.dmi and b/icons/turf/walls/dev/dev.dmi differ
diff --git a/icons/turf/walls/floodgate.dmi b/icons/turf/walls/floodgate.dmi
index 5b3f00abb597..f67e5a7a3fcc 100644
Binary files a/icons/turf/walls/floodgate.dmi and b/icons/turf/walls/floodgate.dmi differ
diff --git a/icons/turf/walls/kutjevo/kutjevo.dmi b/icons/turf/walls/kutjevo/kutjevo.dmi
index 5c8c0053e1bf..3aba82409af6 100644
Binary files a/icons/turf/walls/kutjevo/kutjevo.dmi and b/icons/turf/walls/kutjevo/kutjevo.dmi differ
diff --git a/icons/turf/walls/solaris/solaris.dmi b/icons/turf/walls/solaris/solaris.dmi
index 85d5c118a901..96865710abd7 100644
Binary files a/icons/turf/walls/solaris/solaris.dmi and b/icons/turf/walls/solaris/solaris.dmi differ
diff --git a/icons/turf/walls/solaris/solaris_old.dmi b/icons/turf/walls/solaris/solaris_old.dmi
index 59846bf0ad1c..2aca7b187508 100644
Binary files a/icons/turf/walls/solaris/solaris_old.dmi and b/icons/turf/walls/solaris/solaris_old.dmi differ
diff --git a/icons/turf/walls/strata_outpost.dmi b/icons/turf/walls/strata_outpost.dmi
index 36e20bdd176a..6043f7c32d8d 100644
Binary files a/icons/turf/walls/strata_outpost.dmi and b/icons/turf/walls/strata_outpost.dmi differ
diff --git a/icons/turf/walls/windows.dmi b/icons/turf/walls/windows.dmi
index b1b7c7ebfbe9..85f822873e68 100644
Binary files a/icons/turf/walls/windows.dmi and b/icons/turf/walls/windows.dmi differ
diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm
index 1eb738588f80..15f92fe53502 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -2839,6 +2839,10 @@
pixel_y = 7
},
/obj/effect/decal/cleanable/blood/oil,
+/obj/structure/machinery/computer/working_joe{
+ dir = 4;
+ pixel_x = -17
+ },
/turf/open/floor/almayer{
dir = 8;
icon_state = "silver"
@@ -5322,7 +5326,13 @@
"are" = (
/obj/structure/machinery/computer/demo_sim{
dir = 4;
- pixel_x = -16
+ pixel_x = -17;
+ pixel_y = 8
+ },
+/obj/structure/machinery/computer/working_joe{
+ dir = 4;
+ pixel_x = -17;
+ pixel_y = -8
},
/turf/open/floor/almayer,
/area/almayer/engineering/engineering_workshop/hangar)
@@ -9677,6 +9687,9 @@
/area/almayer/shipboard/brig/main_office)
"aEm" = (
/obj/structure/surface/table/almayer,
+/obj/structure/machinery/computer/working_joe{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "plate"
},
@@ -10322,6 +10335,10 @@
},
/area/almayer/living/numbertwobunks)
"aHo" = (
+/obj/structure/machinery/computer/working_joe{
+ dir = 4;
+ pixel_x = -17
+ },
/turf/open/floor/almayer{
dir = 8;
icon_state = "orange"
@@ -18126,7 +18143,7 @@
/area/almayer/squads/bravo)
"buQ" = (
/obj/structure/surface/table/almayer,
-/obj/structure/machinery/computer/station_alert{
+/obj/structure/machinery/computer/working_joe{
dir = 8
},
/turf/open/floor/almayer{
@@ -21033,11 +21050,11 @@
},
/area/almayer/squads/req)
"bIw" = (
-/obj/structure/machinery/prop/almayer/computer,
/obj/structure/surface/table/almayer,
/obj/structure/machinery/light{
dir = 1
},
+/obj/structure/machinery/computer/working_joe,
/turf/open/floor/almayer{
dir = 1;
icon_state = "red"
@@ -38933,12 +38950,12 @@
/area/almayer/medical/upper_medical)
"hbZ" = (
/obj/structure/surface/table/almayer,
-/obj/structure/machinery/computer/station_alert{
- dir = 4
- },
/obj/structure/sign/safety/terminal{
pixel_x = -17
},
+/obj/structure/machinery/computer/working_joe{
+ dir = 4
+ },
/turf/open/floor/almayer{
dir = 8;
icon_state = "orange"
@@ -49735,6 +49752,9 @@
"lXg" = (
/obj/structure/surface/table/almayer,
/obj/structure/machinery/recharger,
+/obj/structure/machinery/computer/working_joe{
+ pixel_y = 16
+ },
/turf/open/floor/almayer{
icon_state = "plate"
},
@@ -56146,6 +56166,10 @@
},
/obj/effect/decal/cleanable/cobweb2/dynamic,
/obj/item/packageWrap,
+/obj/structure/machinery/computer/working_joe{
+ dir = 8;
+ pixel_x = 17
+ },
/turf/open/floor/almayer{
icon_state = "test_floor5"
},
@@ -76731,6 +76755,11 @@
},
/obj/structure/surface/rack,
/obj/effect/spawner/random/toolbox,
+/obj/structure/machinery/computer/working_joe{
+ dir = 4;
+ pixel_y = 14;
+ pixel_x = -17
+ },
/turf/open/floor/almayer{
dir = 10;
icon_state = "orange"
diff --git a/sound/voice/joe/death_dream.ogg b/sound/voice/joe/death_dream.ogg
new file mode 100644
index 000000000000..366890711fe4
Binary files /dev/null and b/sound/voice/joe/death_dream.ogg differ
diff --git a/sound/voice/joe/death_normal.ogg b/sound/voice/joe/death_normal.ogg
new file mode 100644
index 000000000000..b1afd713e094
Binary files /dev/null and b/sound/voice/joe/death_normal.ogg differ
diff --git a/sound/voice/joe/death_silence.ogg b/sound/voice/joe/death_silence.ogg
new file mode 100644
index 000000000000..fea5080ccc99
Binary files /dev/null and b/sound/voice/joe/death_silence.ogg differ
diff --git a/sound/voice/joe/death_tomorrow.ogg b/sound/voice/joe/death_tomorrow.ogg
new file mode 100644
index 000000000000..dbb134005e5e
Binary files /dev/null and b/sound/voice/joe/death_tomorrow.ogg differ
diff --git a/tools/requirements.txt b/tools/requirements.txt
index abd6a512a222..316d7d2fe18d 100644
--- a/tools/requirements.txt
+++ b/tools/requirements.txt
@@ -3,5 +3,5 @@ bidict==0.22.0
Pillow==9.3.0
# changelogs
-PyYaml==5.4
+PyYaml==6.0.1
beautifulsoup4==4.9.3