From 4ea62745cfeabbb570b37a501e6c7ccea51d55ee Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Thu, 21 Nov 2024 20:09:44 +0100 Subject: [PATCH 01/25] Fixes ckey transfers making keys lowercase --- code/modules/admin/admin.dm | 2 +- code/modules/mob/dead/observer/respawn.dm | 2 +- code/modules/mob/mob.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 891f6250da..b529c0ed01 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1001,7 +1001,7 @@ log_admin("[key_name(usr)] stuffed [frommob.key] into [tomob.name].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag Control") - tomob.ckey = frommob.ckey + tomob.key = frommob.key qdel(frommob) return TRUE diff --git a/code/modules/mob/dead/observer/respawn.dm b/code/modules/mob/dead/observer/respawn.dm index 5d1f65311d..2390e6fd1e 100644 --- a/code/modules/mob/dead/observer/respawn.dm +++ b/code/modules/mob/dead/observer/respawn.dm @@ -180,5 +180,5 @@ client.view_size.resetToDefault() var/mob/dead/new_player/M = new /mob/dead/new_player - M.ckey = ckey + M.key = key return M diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e9bb92516c..8109301238 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -461,7 +461,7 @@ client.prefs.chat_toggles ^= CHAT_OOC if (!(client.prefs.chat_toggles & CHAT_OOC) && isdead(new_mob)) client.prefs.chat_toggles ^= CHAT_OOC - new_mob.ckey = ckey + new_mob.key = key if(send_signal) SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src) return TRUE From e23b1f84fdf77d3591169c3eb17bbf190f572c8f Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Sat, 30 Nov 2024 15:43:37 +0100 Subject: [PATCH 02/25] BEESTATION PORT PR#4567: Filters + plane_master atomized --- code/__DEFINES/layers_planes.dm | 3 + code/_onclick/hud/hud.dm | 8 +- code/_onclick/hud/plane_master_controller.dm | 87 +++++++++++++++++++ code/game/objects/items.dm | 3 - code/modules/mob/living/life.dm | 5 +- code/modules/mob/status_procs.dm | 32 ++----- .../chemistry/reagents/toxin_reagents.dm | 20 ++--- tgstation.dme | 1 + 8 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 code/_onclick/hud/plane_master_controller.dm diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index 578dfe87e5..81374cee21 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -200,5 +200,8 @@ #define SPLASHSCREEN_PLANE 90 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" +///Plane master controller keys +#define PLANE_MASTERS_GAME "plane_masters_game" + ///Layer for screentips #define SCREENTIP_LAYER 40 diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 53d69fe01e..c10e781833 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -57,7 +57,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/list/inv_slots[SLOTS_AMT] // /atom/movable/screen/inventory objects, ordered by their slot ID. var/list/hand_slots // /atom/movable/screen/inventory/hand objects, assoc list of "[held_index]" = object var/list/atom/movable/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object - + ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref + var/list/atom/movable/plane_master_controller/plane_master_controllers = list() ///UI for screentips that appear when you mouse over things var/atom/movable/screen/screentip/screentip_text @@ -113,6 +114,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( plane_masters["[instance.plane]"] = instance instance.backdrop(mymob) + for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) + var/atom/movable/plane_master_controller/controller_instance = new mytype(src) + plane_master_controllers[controller_instance.name] = controller_instance + screentip_text = new(null, src) static_inventory += screentip_text @@ -153,6 +158,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( combo_display = null QDEL_LIST_ASSOC_VAL(plane_masters) + QDEL_LIST_ASSOC_VAL(plane_master_controllers) QDEL_LIST(screenoverlays) mymob = null diff --git a/code/_onclick/hud/plane_master_controller.dm b/code/_onclick/hud/plane_master_controller.dm new file mode 100644 index 0000000000..e27bd3bc55 --- /dev/null +++ b/code/_onclick/hud/plane_master_controller.dm @@ -0,0 +1,87 @@ +///Atom that manages and controls multiple planes. It's an atom so we can hook into add_filter etc. Multiple controllers can control one plane. +/atom/movable/plane_master_controller + ///List of planes in this controllers control. Initially this is a normal list, but becomes an assoc list of plane numbers as strings | plane instance + var/list/controlled_planes = list() + ///hud that owns this controller + var/datum/hud/owner_hud + +///Ensures that all the planes are correctly in the controlled_planes list. +/atom/movable/plane_master_controller/New(hud) + . = ..() + owner_hud = hud + var/assoc_controlled_planes = list() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/instance = owner_hud.plane_masters["[i]"] + if(!instance) //If we looked for a hud that isn't instanced, just keep going + stack_trace("[i] isn't a valid plane master layer for [owner_hud.type], are you sure it exists in the first place?") + continue + assoc_controlled_planes["[i]"] = instance + controlled_planes = assoc_controlled_planes + +// From BeeStation +/atom/movable/plane_master_controller/Destroy() + if(owner_hud) + owner_hud.plane_master_controllers -= src + controlled_planes.Cut() + return ..() + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_filter(name, priority, list/params) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.add_filter(name, priority, params) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/remove_filter(name_or_names) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.remove_filter(name_or_names) + +/atom/movable/plane_master_controller/update_filters() + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.update_filters() + +///Gets all filters for this controllers plane masters +/atom/movable/plane_master_controller/proc/get_filters(name) + . = list() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + . += pm_iterator.get_filter(name) + +///Transitions all filters owned by this plane master controller +/atom/movable/plane_master_controller/transition_filter(name, time, list/new_params, easing, loop) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.transition_filter(name, time, new_params, easing, loop) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_atom_colour(coloration, colour_priority) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.add_atom_colour(coloration, colour_priority) + + +///Removes an instance of colour_type from the atom's atom_colours list +/atom/movable/plane_master_controller/remove_atom_colour(colour_priority, coloration) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.remove_atom_colour(colour_priority, coloration) + + +///Resets the atom's color to null, and then sets it to the highest priority colour available +/atom/movable/plane_master_controller/update_atom_colour() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.update_atom_colour() + + +/atom/movable/plane_master_controller/game + name = PLANE_MASTERS_GAME + controlled_planes = list(FLOOR_PLANE, GAME_PLANE, WALL_PLANE, ABOVE_WALL_PLANE, LIGHTING_PLANE, EMISSIVE_PLANE) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e437ac5c8b..0a11ae69da 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -160,9 +160,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! - //the outline filter on hover - var/outline_filter - /* Our block parry data. Should be set in init, or something if you are using it. * This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory. * If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy. diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index bfad3339f1..7fd8bb5317 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -182,10 +182,7 @@ else if(eye_blurry) //blurry eyes heal slowly eye_blurry = max(eye_blurry-1, 0) if(client) - if(!eye_blurry) - remove_eyeblur() - else - update_eyeblur() + update_eye_blur() /mob/living/proc/update_damage_hud() return diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index da1919443a..28431b805b 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -66,42 +66,26 @@ /mob/proc/blur_eyes(amount) if(amount>0) eye_blurry = max(amount, eye_blurry) - update_eyeblur() + update_eye_blur() /** * Adjust the current blurriness of the mobs vision by amount */ /mob/proc/adjust_blurriness(amount) eye_blurry = max(eye_blurry+amount, 0) - update_eyeblur() + update_eye_blur() ///Set the mobs blurriness of vision to an amount /mob/proc/set_blurriness(amount) eye_blurry = max(amount, 0) - update_eyeblur() + update_eye_blur() -/mob/proc/update_eyeblur() - remove_eyeblur() +/mob/proc/update_eye_blur() + var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used.plane_master_controllers[PLANE_MASTERS_GAME] if(eye_blurry) - add_eyeblur() - -/mob/proc/add_eyeblur() - if(!client) - return - var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"], - hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) - for(var/A in screens) - var/atom/movable/screen/plane_master/P = A - P.add_filter("blurry_eyes", 2, EYE_BLUR(clamp(eye_blurry*0.1,0.6,3))) - -/mob/proc/remove_eyeblur() - if(!client) - return - var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"], - hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) - for(var/A in screens) - var/atom/movable/screen/plane_master/P = A - P.remove_filter("blurry_eyes") + game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * 0.1, 0.6, 3))) + else + game_plane_master_controller.remove_filter("eye_blur") ///Adjust the drugginess of a mob /mob/proc/adjust_drugginess(amount) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 106de64746..786b3add53 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -786,26 +786,22 @@ value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/rotatium/on_mob_life(mob/living/carbon/M) - return ..() // until fixed - the rotations never stop -/* if(M.hud_used) if(current_cycle >= 20 && current_cycle%20 == 0) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], - M.hud_used.plane_masters["[LIGHTING_PLANE]"], M.hud_used.plane_masters["[WALL_PLANE]"], - M.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + var/rotation = min(round(current_cycle/20), 89) // By this point the player is probably puking and quitting anyway - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() /datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/M) - if(M && M.hud_used) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING) + if(M?.hud_used) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(), time = 5, easing = QUAD_EASING) ..() -*/ /datum/reagent/toxin/skewium name = "Skewium" diff --git a/tgstation.dme b/tgstation.dme index 0d49f689c2..6adf6658d6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -315,6 +315,7 @@ #include "code\_onclick\hud\new_player.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" +#include "code\_onclick\hud\plane_master_controller.dm" #include "code\_onclick\hud\radial.dm" #include "code\_onclick\hud\radial_persistent.dm" #include "code\_onclick\hud\revenanthud.dm" From 77aa15c4c2494d29db5201045d1062bf176cebdb Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:40:41 +0100 Subject: [PATCH 03/25] 515.1543+ compatibility --- .../debug_variable_appearance.dm | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index 3ceaf2a50b..8bc9979a7d 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -59,25 +59,23 @@ GLOBAL_DATUM_INIT(pluto, /atom/movable, new /atom/movable(null)) if(beloved.vars.Find(var_name)) // If datums have it, get out return FALSE // If it is one of the two args on /image, yeet (I am sorry) - if(var_name == NAMEOF(src, realized_overlays)) + if(var_name == "realized_overlays") return FALSE - if(var_name == NAMEOF(src, realized_underlays)) + if(var_name == "realized_underlays") return FALSE // Filtering out the stuff I know we don't care about - if(var_name == NAMEOF(src, x)) + if(var_name == "x") return FALSE - if(var_name == NAMEOF(src, y)) + if(var_name == "y") return FALSE - if(var_name == NAMEOF(src, z)) + if(var_name == "z") return FALSE // Could make an argument for these but I think they will just confuse people, so yeeet -#ifndef SPACEMAN_DMM // Spaceman doesn't believe in contents on appearances, sorry lads - if(var_name == NAMEOF(src, contents)) + if(var_name == "contents") return FALSE -#endif - if(var_name == NAMEOF(src, loc)) + if(var_name == "loc") return FALSE - if(var_name == NAMEOF(src, vis_contents)) + if(var_name == "vis_contents") return FALSE return ..() From 12767b3942a879dbfcf3dd79a0552fed9d8aa531 Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:56:28 +0100 Subject: [PATCH 04/25] I forgor (fix compilation test) --- code/modules/mob/status_procs.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 28431b805b..6b47d016e5 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -81,6 +81,8 @@ update_eye_blur() /mob/proc/update_eye_blur() + if(!hud_used) + return var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used.plane_master_controllers[PLANE_MASTERS_GAME] if(eye_blurry) game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * 0.1, 0.6, 3))) From caec26cd205e89775982519c562e7ba87936fcdf Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Wed, 4 Dec 2024 23:05:09 +0800 Subject: [PATCH 05/25] buh --- code/datums/world_topic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 679d2faf11..154b735c02 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -26,7 +26,7 @@ var/require_comms_key = FALSE /datum/world_topic/proc/TryRun(list/input, addr) - key_valid = config && (CONFIG_GET(string/comms_key) == input["key"]) + key_valid = (CONFIG_GET(string/comms_key) == input["key"]) && CONFIG_GET(string/comms_key) && input["key"] if(require_comms_key && !key_valid) return "Bad Key" input -= "key" From b55fb91d6cd26559c6b90ccdd41586a671021767 Mon Sep 17 00:00:00 2001 From: AbsFree Date: Mon, 23 Dec 2024 13:29:50 +0100 Subject: [PATCH 06/25] medi belt can hold chemical analyzer. also removed redundant line --- code/game/objects/items/storage/belt.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index a8342b87bd..371d6ff771 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -149,7 +149,6 @@ /obj/item/storage/belt/medical/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_w_class = WEIGHT_CLASS_BULKY STR.max_items = 11 STR.max_w_class = WEIGHT_CLASS_NORMAL STR.max_combined_w_class = 24 @@ -202,7 +201,8 @@ /obj/item/implanter, /obj/item/pinpointer/crew, /obj/item/reagent_containers/chem_pack, - /obj/item/stack/sticky_tape //surgical tape + /obj/item/stack/sticky_tape, //surgical tape + /obj/item/fermichem/pHmeter // chemical analyzer )) /obj/item/storage/belt/medical/surgery_belt_adv From 9e2111472da5da3ff8c01e53f3cc5efb50600ae2 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Tue, 24 Dec 2024 19:12:48 -0300 Subject: [PATCH 07/25] thanks tg --- .../debug_variable_appearance.dm | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index 8bc9979a7d..444fb39110 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -59,23 +59,33 @@ GLOBAL_DATUM_INIT(pluto, /atom/movable, new /atom/movable(null)) if(beloved.vars.Find(var_name)) // If datums have it, get out return FALSE // If it is one of the two args on /image, yeet (I am sorry) - if(var_name == "realized_overlays") + if(var_name == NAMEOF(src, realized_overlays)) return FALSE - if(var_name == "realized_underlays") + if(var_name == NAMEOF(src, realized_underlays)) return FALSE + +#if (MIN_COMPILER_VERSION >= 515 && MIN_COMPILER_BUILD >= 1643) +#warn X/Y/Z and contents are now fully unviewable on our supported versions, remove the below check +#endif + +// lummy removed these from the the MA/image type +#if (DM_VERSION <= 515 && DM_BUILD < 1643) // Filtering out the stuff I know we don't care about - if(var_name == "x") + if(var_name == NAMEOF(src, x)) return FALSE - if(var_name == "y") + if(var_name == NAMEOF(src, y)) return FALSE - if(var_name == "z") + if(var_name == NAMEOF(src, z)) return FALSE - // Could make an argument for these but I think they will just confuse people, so yeeet - if(var_name == "contents") + #ifndef SPACEMAN_DMM // Spaceman doesn't believe in contents on appearances, sorry lads + if(var_name == NAMEOF(src, contents)) return FALSE - if(var_name == "loc") + #endif + if(var_name == NAMEOF(src, loc)) return FALSE - if(var_name == "vis_contents") +#endif + // Could make an argument for this but I think they will just confuse people, so yeeet + if(var_name == NAMEOF(src, vis_contents)) return FALSE return ..() From 66cc8cf50fc7e5ec0f758e75f4e82da61f4a2147 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 1 Jan 2025 20:20:16 -0300 Subject: [PATCH 08/25] push --- code/game/objects/items/devices/radio/headset.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 8403ea30e7..15bd2f5151 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -81,6 +81,12 @@ GLOBAL_LIST_INIT(channel_tokens, list( return ..(freq, level) return FALSE +/obj/item/radio/headset/MouseDrop(mob/over, src_location, over_location) + var/mob/headset_user = usr + if((headset_user == over) && headset_user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return attack_self(headset_user) + return ..() + /obj/item/radio/headset/syndicate //disguised to look like a normal headset for stealth ops /obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection From ba85afe8957ae688f952cbed0c1f570101eb059d Mon Sep 17 00:00:00 2001 From: Jerry Wester Date: Tue, 14 Jan 2025 20:23:28 -0700 Subject: [PATCH 09/25] give autolathe rpd a unique id --- .../autolathe_desings/autolathe_designs_sec_and_hacked.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm index bf9d5886a0..bc0dd1e79e 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm @@ -50,7 +50,7 @@ build_path = /obj/item/flamethrower/full category = list("hacked", "Security") -/datum/design/rcd +/datum/design/rcd_autolathe name = "Rapid Construction Device (RCD)" id = "rcd" build_type = AUTOLATHE | NO_PUBLIC_LATHE @@ -58,7 +58,7 @@ build_path = /obj/item/construction/rcd category = list("hacked", "Construction") -/datum/design/rpd +/datum/design/rpd_autolathe name = "Rapid Pipe Dispenser (RPD)" id = "rpd" build_type = AUTOLATHE | NO_PUBLIC_LATHE From fbd3438b5e3a178b6d051701fd93c6bcb83ea923 Mon Sep 17 00:00:00 2001 From: Jerry Wester Date: Wed, 15 Jan 2025 14:32:55 -0700 Subject: [PATCH 10/25] guess I gotta update the id field too or there's a runtime or smth --- .../autolathe_desings/autolathe_designs_sec_and_hacked.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm index bc0dd1e79e..1c8bd86a31 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm @@ -50,7 +50,7 @@ build_path = /obj/item/flamethrower/full category = list("hacked", "Security") -/datum/design/rcd_autolathe +/datum/design/rcd name = "Rapid Construction Device (RCD)" id = "rcd" build_type = AUTOLATHE | NO_PUBLIC_LATHE @@ -60,7 +60,7 @@ /datum/design/rpd_autolathe name = "Rapid Pipe Dispenser (RPD)" - id = "rpd" + id = "rpd_autolathe" build_type = AUTOLATHE | NO_PUBLIC_LATHE materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) build_path = /obj/item/pipe_dispenser From 44e507dfef70e74c3d45c971b56899b329e9d1d4 Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Fri, 24 Jan 2025 05:47:50 +0100 Subject: [PATCH 11/25] [BEESTATION PORT] Semi-Port of Beestation Decal Fixes, Fixes turf decals disappearing on shuttle movements (#16119) * SEMI-PORT OF BEESTATION PR #3111: Decal fixes * Forgot this, rotate flag --- code/__DEFINES/dcs/signals.dm | 2 + code/datums/elements/decal.dm | 113 ++++++++++++---------- code/game/objects/effects/decals/decal.dm | 2 +- code/modules/shuttle/on_move.dm | 1 + 4 files changed, 68 insertions(+), 50 deletions(-) diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index de4bd46139..f216a416c5 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -214,6 +214,8 @@ #define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del" ///from base of turf/multiz_turf_new: (turf/source, direction) #define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" +/// from base of turf/proc/afterShuttleMove: (turf/new_turf) +#define COMSIG_TURF_AFTER_SHUTTLE_MOVE "turf_after_shuttle_move" // /atom/movable signals #define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" ///from base of atom/movable/Moved(): (/atom) diff --git a/code/datums/elements/decal.dm b/code/datums/elements/decal.dm index c3f9f1bd17..e3baf9aafa 100644 --- a/code/datums/elements/decal.dm +++ b/code/datums/elements/decal.dm @@ -4,75 +4,90 @@ var/cleanable var/description var/mutable_appearance/pic - var/list/num_decals_per_atom + /** + * A short lecture on decal element collision on rotation + * If a given decal's rotated version is identical to one of existing (at a same target), pre-rotation decals, + * then the rotated decal won't stay after when the colliding pre-rotation decal gets rotated, + * resulting in some decal elements colliding into nonexistence. This internal tick-tock prevents + * such collision by forcing a non-collision. + */ + var/rotated - var/first_dir // This stores the direction of the decal compared to the parent facing NORTH - -/datum/element/decal/Attach(datum/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255) +/datum/element/decal/Attach(atom/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255, _rotated=FALSE) . = ..() - if(. == ELEMENT_INCOMPATIBLE || !_icon || !_icon_state || !isatom(target)) + if(!isatom(target) || (pic ? FALSE : !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, target))) return ELEMENT_INCOMPATIBLE - var/atom/A = target - if(!pic) - // It has to be made from an image or dir breaks because of a byond bug - var/temp_image = image(_icon, null, _icon_state, _layer, _dir) - pic = new(temp_image) - pic.color = _color - pic.alpha = _alpha - first_dir = _dir description = _description cleanable = _cleanable + rotated = _rotated - LAZYINITLIST(num_decals_per_atom) - - if(!num_decals_per_atom[A]) - if(first_dir) - RegisterSignal(A, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_react)) - if(cleanable) - RegisterSignal(A, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react)) - if(description) - RegisterSignal(A, COMSIG_PARENT_EXAMINE, PROC_REF(examine)) - RegisterSignal(A, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_overlay), TRUE) - - num_decals_per_atom[A]++ - apply(A) - -/datum/element/decal/Detach(datum/target) - var/atom/A = target - num_decals_per_atom[A]-- - if(!num_decals_per_atom[A]) - UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, - COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS)) - LAZYREMOVE(num_decals_per_atom, A) - apply(A) - return ..() - -/datum/element/decal/proc/apply(atom/target) + RegisterSignal(target,COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_overlay), TRUE) + if(isturf(target)) + RegisterSignal(target,COMSIG_TURF_AFTER_SHUTTLE_MOVE, PROC_REF(shuttlemove_react), TRUE) if(target.flags_1 & INITIALIZED_1) target.update_icon() //could use some queuing here now maybe. - else if(!QDELETED(target) && num_decals_per_atom[target] == 1) - RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, PROC_REF(late_update_icon)) + else + RegisterSignal(target,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE,PROC_REF(late_update_icon), TRUE) if(isitem(target)) - addtimer(CALLBACK(target, TYPE_PROC_REF(/obj/item, update_slot_icon)), 0, TIMER_UNIQUE) + INVOKE_ASYNC(target, TYPE_PROC_REF(/obj/item, update_slot_icon), TRUE) + if(_dir) + RegisterSignal(target, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_react),TRUE) + if(_cleanable) + RegisterSignal(target, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react),TRUE) + if(_description) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(examine),TRUE) + +/datum/element/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source) + if(!_icon || !_icon_state) + return FALSE + var/temp_image = image(_icon, null, _icon_state, _layer, _dir) + pic = new(temp_image) + pic.color = _color + pic.alpha = _alpha + return TRUE + +/datum/element/decal/Detach(atom/source, force) + UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS,COMSIG_TURF_AFTER_SHUTTLE_MOVE)) + source.update_icon() + if(isitem(source)) + INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, update_slot_icon)) + return ..() /datum/element/decal/proc/late_update_icon(atom/source) - source.update_icon() - UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) + SIGNAL_HANDLER + + if(source && istype(source)) + source.update_icon() + UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) + /datum/element/decal/proc/apply_overlay(atom/source, list/overlay_list) - if(first_dir) - pic.dir = first_dir == SOUTH ? source.dir : turn(first_dir, dir2angle(source.dir)-180) //Never turn a dir by 0. - for(var/i in 1 to num_decals_per_atom[source]) - overlay_list += pic + SIGNAL_HANDLER + + overlay_list += pic + +/datum/element/decal/proc/shuttlemove_react(datum/source, turf/newT) + SIGNAL_HANDLER + Detach(source) + newT.AddElement(/datum/element/decal, pic.icon, pic.icon_state, pic.dir, cleanable, pic.color, pic.layer, description, pic.alpha, rotated) + +/datum/element/decal/proc/rotate_react(datum/source, old_dir, new_dir) + SIGNAL_HANDLER -/datum/element/decal/proc/rotate_react(atom/source, old_dir, new_dir) if(old_dir == new_dir) return - source.update_icon() + Detach(source) + source.AddElement(/datum/element/decal, pic.icon, pic.icon_state, angle2dir(dir2angle(pic.dir)+dir2angle(new_dir)-dir2angle(old_dir)), cleanable, pic.color, pic.layer, description, pic.alpha, !rotated) /datum/element/decal/proc/clean_react(datum/source, strength) + SIGNAL_HANDLER + if(strength >= cleanable) Detach(source) + return TRUE + return NONE /datum/element/decal/proc/examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += description diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index 2e1cc2b606..27b84c152c 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -47,4 +47,4 @@ if(!istype(T)) //you know this will happen somehow CRASH("Turf decal initialized in an object/nullspace") var/turn_dir = 180 - dir2angle(T.dir) //Turning a dir by 0 results in a roulette of random dirs. - T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha) + T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha, FALSE) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 032687bd25..2f16402b0f 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -69,6 +69,7 @@ All ShuttleMove procs go here /turf/proc/afterShuttleMove(turf/oldT, rotation) //Dealing with the turf we left behind oldT.TransferComponents(src) + SEND_SIGNAL(oldT, COMSIG_TURF_AFTER_SHUTTLE_MOVE, src) //Mostly for decals var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle) if(shuttle_boundary) oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1) From cae94afdb7217b0ec0061be02fe26767cf3b10db Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sun, 26 Jan 2025 18:06:36 -0300 Subject: [PATCH 12/25] push --- code/__DEFINES/color/colors.dm | 1 + code/__DEFINES/hud.dm | 14 +-- code/_onclick/hud/action_button.dm | 5 +- code/_onclick/hud/ai.dm | 1 + code/_onclick/hud/alert.dm | 75 +++++++++++-- code/_onclick/hud/blob_overmind.dm | 1 + code/_onclick/hud/ghost.dm | 1 + code/_onclick/hud/guardian.dm | 1 + code/_onclick/hud/hud.dm | 5 +- code/_onclick/hud/human.dm | 7 +- code/_onclick/hud/monkey.dm | 4 - code/_onclick/hud/new_player.dm | 8 +- code/_onclick/hud/robot.dm | 1 + code/_onclick/hud/screen_objects.dm | 101 +++++------------- code/_onclick/hud/screen_objects/sprint.dm | 3 +- code/_onclick/hud/screen_objects/stamina.dm | 11 +- code/_onclick/hud/screen_objects/vore.dm | 1 + code/datums/action.dm | 8 ++ code/datums/components/combat_mode.dm | 1 + code/datums/status_effects/debuffs.dm | 1 + code/datums/status_effects/wound_effects.dm | 1 + code/game/atoms_movable.dm | 5 + code/game/gamemodes/clock_cult/clock_cult.dm | 1 - code/game/gamemodes/sandbox/h_sandbox.dm | 1 - code/game/machinery/buttons.dm | 1 + .../embedded_controller/access_controller.dm | 1 + code/game/machinery/firealarm.dm | 1 + code/game/machinery/lightswitch.dm | 1 + code/game/objects/items/tanks/tanks.dm | 2 - .../objects/structures/ghost_role_spawners.dm | 1 - code/modules/buildmode/buttons.dm | 1 + code/modules/mob/living/carbon/carbon.dm | 4 - .../living/carbon/human/human_stripping.dm | 3 - .../mob/living/carbon/human/inventory.dm | 1 - .../carbon/human/species_types/plasmamen.dm | 1 - code/modules/mob/living/carbon/life.dm | 3 - icons/mob/actions.dmi | Bin 9992 -> 9419 bytes 37 files changed, 152 insertions(+), 126 deletions(-) diff --git a/code/__DEFINES/color/colors.dm b/code/__DEFINES/color/colors.dm index d88320d094..ca2d0fe496 100644 --- a/code/__DEFINES/color/colors.dm +++ b/code/__DEFINES/color/colors.dm @@ -30,6 +30,7 @@ #define COLOR_YELLOW "#FFFF00" #define COLOR_VIVID_YELLOW "#FBFF23" #define COLOR_VERY_SOFT_YELLOW "#FAE48E" +#define COLOR_GOLD "#FFD700" #define COLOR_OLIVE "#808000" #define COLOR_VIBRANT_LIME "#00FF00" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 14a3b7dc49..f5676b626c 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -94,11 +94,12 @@ #define ui_palette_scroll_offset(north_offset) ("WEST+1:8,NORTH-[6+north_offset]:28") //Middle right (status indicators) -#define ui_healthdoll "EAST-1:28,CENTER-2:13" -#define ui_health "EAST-1:28,CENTER-1:15" -#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter -#define ui_mood "EAST-1:28,CENTER-3:10" -// #define ui_spacesuit "EAST-1:28,CENTER-4:10" +#define ui_healthdoll "EAST-1:28,CENTER-2:17" +#define ui_health "EAST-1:28,CENTER-1:19" +#define ui_internal "EAST-1:28,CENTER+1:21" // RIP, although nobody will remember this, unsmart coders have used this for other stuff. DO NOT REMOVE UNLESS RENAMING OR REPLACING. +#define ui_mood "EAST-1:28,CENTER:21" +#define ui_stamina "EAST-1:28,CENTER-3:14" +// #define ui_spacesuit "EAST-1:28,CENTER-4:14" //Pop-up inventory #define ui_shoes "WEST+1:8,SOUTH:5" @@ -208,7 +209,6 @@ #define ui_ghost_spawners "SOUTH: 6, CENTER+1:24" // LEGACY. SAME LOC AS PAI //UI position overrides for 1:1 screen layout. (default is 7:5) -#define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button #define ui_overridden_resist "EAST-3:24,SOUTH+1:7" #define ui_clickdelay "CENTER,SOUTH+1:-31" #define ui_resistdelay "EAST-3:24,SOUTH+1:4" @@ -231,6 +231,8 @@ #define SCRN_OBJ_IN_LIST "list" /// In the collapseable palette #define SCRN_OBJ_IN_PALETTE "palette" +///Inserted first in the list +#define SCRN_OBJ_INSERT_FIRST "first" /// The filter name for the hover outline #define HOVER_OUTLINE_FILTER "hover_outline" diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index f5826579c8..05c16c12ed 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -5,10 +5,11 @@ var/datum/hud/our_hud var/actiontooltipstyle = "" screen_loc = null + mouse_over_pointer = MOUSE_HAND_POINTER var/button_icon_state var/appearance_cache - + var/mutable_appearance/button_overlay /// Where we are currently placed on the hud. SCRN_OBJ_DEFAULT asks the linked action what it thinks var/location = SCRN_OBJ_DEFAULT /// A unique bitflag, combined with the name of our linked action this lets us persistently remember any user changes to our position @@ -199,6 +200,7 @@ icon = 'icons/hud/64x16_actions.dmi' icon_state = "screen_gen_palette" screen_loc = ui_action_palette + mouse_over_pointer = MOUSE_HAND_POINTER var/datum/hud/our_hud var/expanded = FALSE /// Id of any currently running timers that set our color matrix @@ -324,6 +326,7 @@ GLOBAL_LIST_INIT(palette_removed_matrix, list(1.4,0,0,0, 0.7,0.4,0,0, 0.4,0,0.6, /atom/movable/screen/palette_scroll icon = 'icons/mob/screen_gen.dmi' screen_loc = ui_palette_scroll + mouse_over_pointer = MOUSE_HAND_POINTER /// How should we move the palette's actions? /// Positive scrolls down the list, negative scrolls back var/scroll_direction = 0 diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 419de492ef..d4344b9464 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ai icon = 'icons/mob/screen_ai.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ai/Click() if(isobserver(usr) || usr.incapacitated()) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 060e44e007..815e46f9eb 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -91,6 +91,8 @@ name = "Alert" desc = "Something seems to have gone wrong with this alert, so report this bug please" mouse_opacity = MOUSE_OPACITY_ICON + /// do we glow to represent we do stuff when clicked + var/clickable_glow = FALSE var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds var/severity = 0 var/alerttooltipstyle = "" @@ -100,6 +102,12 @@ /// Boolean. If TRUE, the Click() proc will attempt to Click() on the master first if there is a master. var/click_master = TRUE +/atom/movable/screen/alert/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(clickable_glow) + add_filter("clickglow", 2, outline_filter(color = COLOR_GOLD, size = 1)) + mouse_over_pointer = MOUSE_HAND_POINTER + /atom/movable/screen/alert/MouseEntered(location,control,params) if(!QDELETED(src)) openToolTip(usr,src,params,title = name,content = desc,theme = alerttooltipstyle) @@ -247,6 +255,7 @@ or something covering your eyes." name = "Mind Control" desc = "Your mind has been hijacked! Click to view the mind control command." icon_state = "mind_control" + clickable_glow = TRUE var/command /atom/movable/screen/alert/mind_control/Click() @@ -271,6 +280,7 @@ or something covering your eyes." desc = "Something got lodged into your flesh and is causing major bleeding. It might fall out with time, but surgery is the safest way. \ If you're feeling frisky, examine yourself and click the underlined item to pull the object out." icon_state = "embeddedobject" + clickable_glow = TRUE /atom/movable/screen/alert/embeddedobject/Click() if(isliving(usr) && usr == owner) @@ -299,6 +309,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "On Fire" desc = "You're on fire. Stop, drop and roll to put the fire out or move to a vacuum area." icon_state = "fire" + clickable_glow = TRUE /atom/movable/screen/alert/fire/Click() var/mob/living/L = usr @@ -310,8 +321,29 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/give // information set when the give alert is made icon_state = "default" + clickable_glow = TRUE var/mob/living/carbon/offerer var/obj/item/receiving + /// Additional text displayed in the description of the alert. + var/additional_desc_text = "Click this alert to take it, or shift click it to examine it." + /// Text to override what appears in screentips for the alert + var/screentip_override_text + /// Whether the offered item can be examined by shift-clicking the alert + var/examinable = TRUE + +/atom/movable/screen/alert/give/Initialize(mapload, datum/hud/hud_owner) + . = ..() + register_context() + +/atom/movable/screen/alert/give/Destroy() + offerer = null + receiving = null + return ..() + +/atom/movable/screen/alert/give/add_context(atom/source, list/context, obj/item/held_item, mob/user) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, screentip_override_text || "Take [receiving.name]") + LAZYSET(context[SCREENTIP_CONTEXT_SHIFT_LMB], INTENT_ANY, "Examine") + return CONTEXTUAL_SCREENTIP_SET /** * Handles assigning most of the variables for the alert that pops up when an item is offered @@ -341,6 +373,16 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." CRASH("User for [src] is of type \[[usr.type]\]. This should never happen.") handle_transfer() +/atom/movable/screen/alert/give/examine(mob/user) + if(!examinable) + return ..() + + return list( + span_boldnotice(name), + span_info("[offerer] is offering you the following item (click the alert to take it!):"), + "
[jointext(receiving.examine(user), "\n")]", + ) + /// An overrideable proc used simply to hand over the item when claimed, this is a proc so that high-fives can override them since nothing is actually transferred /atom/movable/screen/alert/give/proc/handle_transfer() var/mob/living/carbon/taker = owner @@ -354,6 +396,11 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." to_chat(owner, span_warning("You moved out of range of [offerer]!")) owner.clear_alert("[offerer]") +/atom/movable/screen/alert/give/highfive + additional_desc_text = "Click this alert to slap it." + screentip_override_text = "High Five" + examinable = FALSE + /atom/movable/screen/alert/give/highfive/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) . = ..() name = "[offerer] is offering a high-five!" @@ -404,6 +451,9 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /// Families handshakes /atom/movable/screen/alert/give/secret_handshake icon_state = "default" + additional_desc_text = "Click this alert to accept." + screentip_override_text = "Handshake" + examinable = FALSE /atom/movable/screen/alert/give/secret_handshake/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) name = "[offerer] is offering a Handshake" @@ -666,7 +716,8 @@ so as to remain in compliance with the most up-to-date laws." complete, you will have exclusive control of it, and you will gain \ additional processing time to unlock more malfunction abilities." icon_state = "hackingapc" - timeout = 600 + timeout = 60 SECONDS + clickable_glow = TRUE var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() @@ -693,7 +744,8 @@ so as to remain in compliance with the most up-to-date laws." name = "Revival" desc = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!" icon_state = "template" - timeout = 300 + timeout = 30 SECONDS + clickable_glow = TRUE /atom/movable/screen/alert/notify_cloning/Click() if(!usr || !usr.client || usr != owner) @@ -705,7 +757,8 @@ so as to remain in compliance with the most up-to-date laws." name = "Body created" desc = "A body was created. You can enter it." icon_state = "template" - timeout = 300 + timeout = 30 SECONDS + clickable_glow = TRUE var/atom/target = null var/action = NOTIFY_JUMP @@ -729,6 +782,9 @@ so as to remain in compliance with the most up-to-date laws." //OBJECT-BASED +/atom/movable/screen/alert/restrained + clickable_glow = TRUE + /atom/movable/screen/alert/restrained/buckled name = "Buckled" desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed." @@ -765,6 +821,7 @@ so as to remain in compliance with the most up-to-date laws." name = "Knotted Shoes" desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot." icon_state = "shoealert" + clickable_glow = TRUE /atom/movable/screen/alert/shoes/Click() var/mob/living/carbon/C = usr @@ -814,9 +871,9 @@ so as to remain in compliance with the most up-to-date laws." return FALSE if(usr != owner) return FALSE - var/paramslist = params2list(params) - if(paramslist["shift"]) // screen objects don't do the normal Click() stuff so we'll cheat - to_chat(usr, "[name] - [desc]") + var/modifiers = params2list(params) + if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat + to_chat(usr, "
[jointext(examine(usr), "\n")]
") return FALSE if(master && click_master) return usr.client.Click(master, location, control, params) @@ -829,3 +886,9 @@ so as to remain in compliance with the most up-to-date laws." master = null owner = null screen_loc = "" + +/atom/movable/screen/alert/examine(mob/user) + return list( + span_boldnotice(name), + span_info(desc), + ) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index f4d6ffc919..8a981d5796 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -1,6 +1,7 @@ /atom/movable/screen/blob icon = 'icons/mob/blob.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/blob/MouseEntered(location,control,params) openToolTip(usr,src,params,title = name,content = desc, theme = "blob") diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index bb637ed445..f4f1f2f7b0 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ghost icon = 'icons/mob/screen_ghost.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ghost/MouseEntered() flick(icon_state + "_anim", src) diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 2af02d8437..09ec5d925c 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -93,6 +93,7 @@ /atom/movable/screen/guardian icon = 'icons/mob/guardian.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/guardian/Manifest icon_state = "manifest" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index c10e781833..52397c3036 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -87,7 +87,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/healths var/atom/movable/screen/healthdoll - var/atom/movable/screen/internals var/atom/movable/screen/wanted/wanted_lvl // subtypes can override this to force a specific UI style @@ -148,7 +147,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( healths = null healthdoll = null wanted_lvl = null - internals = null lingchemdisplay = null devilsouldisplay = null lingstingdisplay = null @@ -365,6 +363,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( listed_actions.insert_action(button) if(SCRN_OBJ_IN_PALETTE) palette_actions.insert_action(button) + if(SCRN_OBJ_INSERT_FIRST) + listed_actions.insert_action(button, index = 1) + position = SCRN_OBJ_IN_LIST else // If we don't have it as a define, this is a screen_loc, and we should be floating floating_actions += button button.screen_loc = position diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 27989f3bb1..c8b7b3327d 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -4,6 +4,7 @@ /atom/movable/screen/human/toggle name = "toggle" icon_state = "toggle" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/human/toggle/Click() @@ -26,6 +27,7 @@ /atom/movable/screen/human/equip name = "equip" icon_state = "act_equip" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/human/equip/Click() if(ismecha(usr.loc)) // stops inventory actions in a mech @@ -68,6 +70,7 @@ /atom/movable/screen/ling/sting name = "current sting" screen_loc = ui_lingstingdisplay + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ling/sting/Click() if(isobserver(usr)) @@ -412,10 +415,6 @@ throw_icon.hud = src hotkeybuttons += throw_icon - internals = new /atom/movable/screen/internals() - internals.hud = src - infodisplay += internals - healths = new /atom/movable/screen/healths() healths.hud = src infodisplay += healths diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index b63f8241cb..9ee795a745 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -85,10 +85,6 @@ throw_icon.hud = src hotkeybuttons += throw_icon - internals = new /atom/movable/screen/internals() - internals.hud = src - infodisplay += internals - healths = new /atom/movable/screen/healths() healths.hud = src infodisplay += healths diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index 539b842375..c7f40e4dcc 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -62,8 +62,9 @@ screen_loc = "TOP,CENTER:-61" /atom/movable/screen/lobby/button + mouse_over_pointer = MOUSE_HAND_POINTER ///Is the button currently enabled? - var/enabled = TRUE + VAR_PROTECTED/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE /// The ref of the mob that owns this button. Only the owner can click on it. @@ -113,6 +114,7 @@ return FALSE enabled = status update_appearance(UPDATE_ICON) + mouse_over_pointer = enabled ? MOUSE_HAND_POINTER : MOUSE_INACTIVE_POINTER return TRUE ///Prefs menu @@ -184,10 +186,10 @@ icon = 'icons/hud/lobby/join.dmi' icon_state = "" //Default to not visible base_icon_state = "join_game" - enabled = FALSE /atom/movable/screen/lobby/button/join/Initialize(mapload) . = ..() + set_button_status(FALSE) switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) @@ -248,13 +250,13 @@ icon = 'icons/hud/lobby/observe.dmi' icon_state = "observe_disabled" base_icon_state = "observe" - enabled = FALSE /atom/movable/screen/lobby/button/observe/Initialize(mapload) . = ..() if(SSticker.current_state > GAME_STATE_STARTUP) set_button_status(TRUE) else + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(enable_observing)) /atom/movable/screen/lobby/button/observe/Click(location, control, params) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 35fd31cbdb..58b52dea49 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,5 +1,6 @@ /atom/movable/screen/robot icon = 'icons/mob/screen_cyborg.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/robot/module name = "cyborg module" diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c0d500511f..8e3dd1ccce 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -57,6 +57,7 @@ /atom/movable/screen/swap_hand plane = HUD_PLANE name = "swap hand" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/swap_hand/Click() // At this point in client Click() code we have passed the 1/10 sec check and little else @@ -85,12 +86,14 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "craft" screen_loc = ui_crafting + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/area_creator name = "create new area" icon = 'icons/mob/screen_midnight.dmi' icon_state = "area_edit" screen_loc = ui_building + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/area_creator/Click() if(usr.incapacitated() || (isobserver(usr) && !IsAdminGhost(usr))) @@ -106,11 +109,11 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "talk_wheel" screen_loc = ui_language_menu + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/language_menu/Click() - var/mob/M = usr - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) + + usr.get_language_holder().open_language_menu(usr) /atom/movable/screen/inventory /// The identifier for the slot. It has nothing to do with ID cards. @@ -172,7 +175,7 @@ var/image/item_overlay = image(holding) item_overlay.alpha = 92 - if(!user.can_equip(holding, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) + if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) item_overlay.color = "#FF0000" else item_overlay.color = "#00ff00" @@ -247,6 +250,7 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_drop" plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/drop/Click() if(usr.stat == CONSCIOUS) @@ -256,6 +260,7 @@ name = "intent" icon_state = "help" screen_loc = ui_acti + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/act_intent/Click(location, control, params) usr.a_intent_change(INTENT_HOTKEY_RIGHT) @@ -287,76 +292,11 @@ icon = 'icons/mob/screen_cyborg.dmi' screen_loc = ui_borg_intents -/atom/movable/screen/internals - name = "toggle internals" - icon_state = "internal0" - screen_loc = ui_internal - -/atom/movable/screen/internals/Click() - if(!iscarbon(usr)) - return - var/mob/living/carbon/C = usr - if(C.incapacitated()) - return - - if(C.internal) - C.internal = null - to_chat(C, span_notice("You are no longer running on internals.")) - icon_state = "internal0" - else - if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - if(HAS_TRAIT(C, TRAIT_NO_INTERNALS)) - to_chat(C, span_warning("Due to cumbersome equipment or anatomy, you are currently unable to use internals!")) - return - var/obj/item/clothing/check - var/internals = FALSE - - for(check in GET_INTERNAL_SLOTS(C)) - if(istype(check, /obj/item/clothing/mask)) - var/obj/item/clothing/mask/M = check - if(M.mask_adjusted) - M.adjustmask(C) - if((check.clothing_flags & ALLOWINTERNALS)) - internals = TRUE - if(!internals) - to_chat(C, span_warning("You are not wearing an internals mask!")) - return - - var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) - if(I) - to_chat(C, span_notice("You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].")) - C.internal = I - else if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.s_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.s_store] on your [H.wear_suit.name].")) - H.internal = H.s_store - else if(istype(H.belt, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.belt] on your belt.")) - H.internal = H.belt - else if(istype(H.l_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.l_store] in your left pocket.")) - H.internal = H.l_store - else if(istype(H.r_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.r_store] in your right pocket.")) - H.internal = H.r_store - - //Separate so CO2 jetpacks are a little less cumbersome. - if(!C.internal && istype(C.back, /obj/item/tank)) - to_chat(C, span_notice("You are now running on internals from [C.back] on your back.")) - C.internal = C.back - - if(C.internal) - icon_state = "internal1" - else - to_chat(C, span_warning("You don't have an oxygen tank!")) - return - C.update_action_buttons_icon() - /atom/movable/screen/mov_intent name = "run/walk toggle" icon = 'icons/mob/screen_midnight.dmi' icon_state = "running" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/mov_intent/Initialize(mapload) . = ..() @@ -366,7 +306,10 @@ toggle(usr) /atom/movable/screen/mov_intent/update_icon_state() - switch(hud?.mymob?.m_intent) + if(!hud || !hud.mymob || !isliving(hud.mymob)) + return + var/mob/living/living_hud_owner = hud.mymob + switch(living_hud_owner.m_intent) if(MOVE_INTENT_WALK) icon_state = CONFIG_GET(flag/sprint_enabled)? "walking" : "walking_nosprint" if(MOVE_INTENT_RUN) @@ -382,6 +325,8 @@ name = "stop pulling" icon = 'icons/mob/screen_midnight.dmi' icon_state = "pull" + base_icon_state = "pull" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/pull/Click() if(isobserver(usr)) @@ -389,17 +334,14 @@ usr.stop_pulling() /atom/movable/screen/pull/update_icon_state() - if(hud?.mymob?.pulling) - icon_state = "pull" - else - icon_state = "pull0" + icon_state = "[base_icon_state][hud?.mymob?.pulling ? null : 0]" return ..() /atom/movable/screen/resist name = "resist" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_resist" - plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/resist/Click() if(isliving(usr)) @@ -411,7 +353,7 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_rest" base_icon_state = "act_rest" - plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/rest/Click() if(isliving(usr)) @@ -429,6 +371,7 @@ name = "throw/catch" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_throw_off" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/throw_catch/Click() if(iscarbon(usr)) @@ -439,6 +382,7 @@ name = "damage zone" icon_state = "zone_sel" screen_loc = ui_zonesel + mouse_over_pointer = MOUSE_HAND_POINTER var/overlay_icon = 'icons/mob/screen_gen.dmi' var/static/list/hover_overlays_cache = list() var/hovering @@ -641,6 +585,7 @@ /atom/movable/screen/healthdoll name = "health doll" screen_loc = ui_healthdoll + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/healthdoll/Click() if (iscarbon(usr)) @@ -656,6 +601,7 @@ name = "mood" icon_state = "mood5" screen_loc = ui_mood + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/mood/attack_tk() return @@ -708,6 +654,7 @@ /atom/movable/screen/component_button + mouse_over_pointer = MOUSE_HAND_POINTER var/atom/movable/screen/parent /atom/movable/screen/component_button/Initialize(mapload, atom/movable/screen/parent) diff --git a/code/_onclick/hud/screen_objects/sprint.dm b/code/_onclick/hud/screen_objects/sprint.dm index b32973f2dd..1a655a4db6 100644 --- a/code/_onclick/hud/screen_objects/sprint.dm +++ b/code/_onclick/hud/screen_objects/sprint.dm @@ -5,7 +5,7 @@ name = "toggle sprint" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "act_sprint" - layer = ABOVE_HUD_LAYER - 0.1 + mouse_over_pointer = MOUSE_HAND_POINTER var/mutable_appearance/flashy /atom/movable/screen/sprintbutton/Click() @@ -44,6 +44,7 @@ name = "sprint buffer" icon = 'icons/effects/progessbar.dmi' icon_state = "prog_bar_100" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/sprint_buffer/Click() if(isliving(usr)) diff --git a/code/_onclick/hud/screen_objects/stamina.dm b/code/_onclick/hud/screen_objects/stamina.dm index b4c4807ec8..967bdb4f1f 100644 --- a/code/_onclick/hud/screen_objects/stamina.dm +++ b/code/_onclick/hud/screen_objects/stamina.dm @@ -1,19 +1,20 @@ -/datum/hud/var/atom/movable/screen/staminas/staminas -/datum/hud/var/atom/movable/screen/staminabuffer/staminabuffer +/datum/hud + var/atom/movable/screen/staminas/staminas + var/atom/movable/screen/staminabuffer/staminabuffer /atom/movable/screen/staminas icon = 'modular_citadel/icons/ui/screen_gen.dmi' name = "stamina" icon_state = "stamina0" screen_loc = ui_stamina - mouse_opacity = 1 + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/staminas/Click(location,control,params) if(isliving(usr)) var/mob/living/L = usr CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max) - to_chat(L, "You have [L.getStaminaLoss()] stamina loss.
\ -
Your stamina buffer is [round((L.stamina_buffer / buffer_max) * 100, 0.1)]% full.
") + to_chat(L, "
You have [L.getStaminaLoss()] stamina loss.
\ +
Your stamina buffer is [round((L.stamina_buffer / buffer_max) * 100, 0.1)]% full.
") /atom/movable/screen/staminas/update_icon_state() var/mob/living/carbon/user = hud?.mymob diff --git a/code/_onclick/hud/screen_objects/vore.dm b/code/_onclick/hud/screen_objects/vore.dm index 91aa8f318c..1eea40f565 100644 --- a/code/_onclick/hud/screen_objects/vore.dm +++ b/code/_onclick/hud/screen_objects/vore.dm @@ -2,6 +2,7 @@ name = "toggle vore mode" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "nom_off" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/voretoggle/Click() if(usr != hud.mymob) diff --git a/code/datums/action.dm b/code/datums/action.dm index f7093b1ff6..e1e84c8f51 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -39,6 +39,7 @@ var/icon_icon = 'icons/mob/actions.dmi' /// This is the icon state for the icon that appears on the button var/button_icon_state = "default" + var/button_overlay_state /datum/action/New(Target) link_to(Target) @@ -177,6 +178,11 @@ ApplyIcon(button, force) + if(button_overlay_state) + button.cut_overlay(button.button_overlay) + button.button_overlay = mutable_appearance(icon = 'icons/mob/actions.dmi', icon_state = button_overlay_state) + button.add_overlay(button.button_overlay) + if(!IsAvailable(TRUE)) button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0) else @@ -362,6 +368,8 @@ /datum/action/item_action/set_internals name = "Set Internals" + default_button_position = SCRN_OBJ_INSERT_FIRST + button_overlay_state = "ab_goldborder" /datum/action/item_action/set_internals/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force) if(!..()) // no button available diff --git a/code/datums/components/combat_mode.dm b/code/datums/components/combat_mode.dm index 51661d5472..6fd2b2e4a7 100644 --- a/code/datums/components/combat_mode.dm +++ b/code/datums/components/combat_mode.dm @@ -182,6 +182,7 @@ name = "toggle combat mode" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "combat_off" + mouse_over_pointer = MOUSE_HAND_POINTER var/mutable_appearance/flashy var/combat_on = FALSE ///Wheter combat mode is enabled or not, so we don't have to store a reference. diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index bf570ca885..5bd653556c 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -971,6 +971,7 @@ desc = "A magical strand of Durathread is wrapped around your neck, preventing you from breathing! Click this icon to remove the strand." icon_state = "his_grace" alerttooltipstyle = "hisgrace" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/strandling/Click(location, control, params) . = ..() diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index f5903bbc28..f8a51d2ad2 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -102,6 +102,7 @@ /atom/movable/screen/alert/status_effect/wound name = "Wounded" desc = "Your body has sustained serious damage, click here to inspect yourself." + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/wound/Click() var/mob/living/carbon/C = usr diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 91999acac5..b672d79024 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -647,6 +647,11 @@ /// Gets or creates the relevant language holder. For mindless atoms, gets the local one. For atom with mind, gets the mind one. /atom/movable/proc/get_language_holder(get_minds = TRUE) + RETURN_TYPE(/datum/language_holder) + if(QDELING(src)) + CRASH("get_language_holder() called on a QDELing atom, \ + this will try to re-instantiate the language holder that's about to be deleted, which is bad.") + if(!language_holder) language_holder = new initial_language_holder(src) return language_holder diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index d852ce9850..8b7f265b11 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -291,7 +291,6 @@ Credit where due: W.update_label() if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that H.internal = H.get_item_for_held_index(2) - H.update_internals_hud_icon(1) PDA.owner = H.real_name PDA.ownjob = "Assistant" PDA.update_label() diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index f91a8acc60..fdcb47b275 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -176,7 +176,6 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) P.back.plane = ABOVE_HUD_PLANE P.update_inv_back() P.internal = P.back - P.update_internals_hud_icon(1) if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 8c9caaf8c8..e2c276b207 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -14,6 +14,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 2 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + mouse_over_pointer = MOUSE_HAND_POINTER /obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) if(istext(id) && mapload && id[1] == "!") diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index dcfdeca502..e197c64f62 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -10,6 +10,7 @@ idle_power_usage = 2 active_power_usage = 4 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + mouse_over_pointer = MOUSE_HAND_POINTER var/idSelf /obj/machinery/doorButtons/attackby(obj/O, mob/user) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 7959982ed0..9a096bf923 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -21,6 +21,7 @@ max_integrity = 250 integrity_failure = 0.4 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) + mouse_over_pointer = MOUSE_HAND_POINTER use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 1b7781abb8..9cc4da11b1 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -5,6 +5,7 @@ icon_state = "light1" base_icon_state = "light" desc = "Make dark." + mouse_over_pointer = MOUSE_HAND_POINTER var/area/area = null var/otherarea = null diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index ad18d1049e..0380c2d5ac 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -34,7 +34,6 @@ if(H.internal == src) to_chat(H, "You close [src] valve.") H.internal = null - H.update_internals_hud_icon(0) else if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) if(HAS_TRAIT(H, TRAIT_NO_INTERNALS)) @@ -60,7 +59,6 @@ else to_chat(H, "You open [src] valve.") H.internal = src - H.update_internals_hud_icon(1) H.update_action_buttons_icon() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 0b8a7c5a30..1752009506 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -878,7 +878,6 @@ /datum/outfit/ghostcafe/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) H.internal = H.get_item_for_held_index(1) - H.update_internals_hud_icon(1) /obj/item/storage/box/syndie_kit/chameleon/ghostcafe name = "ghost cafe costuming kit" diff --git a/code/modules/buildmode/buttons.dm b/code/modules/buildmode/buttons.dm index e29739f5ad..f3f1105a5c 100644 --- a/code/modules/buildmode/buttons.dm +++ b/code/modules/buildmode/buttons.dm @@ -1,5 +1,6 @@ /atom/movable/screen/buildmode icon = 'icons/misc/buildmode.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER var/datum/buildmode/bd // If we don't do this, we get occluded by item action buttons layer = ABOVE_HUD_LAYER diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 86dc221654..47c9c61e34 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -793,10 +793,6 @@ else hud_used.healths.icon_state = "health7" -/mob/living/carbon/proc/update_internals_hud_icon(internal_state = 0) - if(hud_used && hud_used.internals) - hud_used.internals.icon_state = "internal[internal_state]" - /mob/living/carbon/update_stat() if(status_flags & GODMODE) return diff --git a/code/modules/mob/living/carbon/human/human_stripping.dm b/code/modules/mob/living/carbon/human/human_stripping.dm index 08db3fe552..db248959b9 100644 --- a/code/modules/mob/living/carbon/human/human_stripping.dm +++ b/code/modules/mob/living/carbon/human/human_stripping.dm @@ -285,12 +285,9 @@ GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list( if(carbon_source.internal) carbon_source.internal = null - // This isn't meant to be FALSE, it correlates to the icon's name. - carbon_source.update_internals_hud_icon(0) else if (!QDELETED(item)) if(internals || carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) carbon_source.internal = item - carbon_source.update_internals_hud_icon(1) carbon_source.visible_message( span_danger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name]."), diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index ace5cbaa6f..29866459d8 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -253,7 +253,6 @@ if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR))) update_hair() if(toggle_off && internal && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - update_internals_hud_icon(0) internal = null if(C.flags_inv & HIDEEYES) update_inv_glasses() diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 0235be3268..a6670b186a 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -69,7 +69,6 @@ H.equipOutfit(O, visualsOnly) H.internal = H.get_item_for_held_index(2) - H.update_internals_hud_icon(1) return FALSE /datum/species/plasmaman/random_name(gender,unique,lastname) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 9b2db8b106..081e19b6c6 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -329,12 +329,9 @@ if(internal) if(internal.loc != src) internal = null - update_internals_hud_icon(0) else if (!internals && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) internal = null - update_internals_hud_icon(0) else - update_internals_hud_icon(1) . = internal.remove_air_volume(volume_needed) if(!.) return FALSE //to differentiate between no internals and active, but empty internals diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index e6e0abe111b393d33dde8362ecaed237fc8589dd..53648fbba6d5c7b466a87a21fd16a509bd7c2a76 100644 GIT binary patch literal 9419 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 Date: Sun, 9 Feb 2025 02:09:28 -0300 Subject: [PATCH 13/25] all sorts of fixes and updates, may break stuff --- .vscode/settings.json | 2 +- .../signals_atom/signals_atom_mouse.dm | 2 + code/__DEFINES/dcs/signals/signals_global.dm | 3 + code/__DEFINES/dcs/signals/signals_hud.dm | 2 + code/__DEFINES/language.dm | 23 +- code/__HELPERS/_lists.dm | 7 + code/_onclick/hud/ai.dm | 54 ++-- code/_onclick/hud/alert.dm | 70 ++++-- code/_onclick/hud/alien.dm | 39 +-- code/_onclick/hud/alien_larva.dm | 18 +- code/_onclick/hud/blob_overmind.dm | 33 +-- code/_onclick/hud/blobbernauthud.dm | 6 +- code/_onclick/hud/clockwork_marauder.dm | 6 +- code/_onclick/hud/constructs.dm | 6 +- code/_onclick/hud/devil.dm | 21 +- code/_onclick/hud/drones.dm | 5 +- code/_onclick/hud/families.dm | 3 - code/_onclick/hud/generic_dextrous.dm | 24 +- code/_onclick/hud/ghost.dm | 18 +- code/_onclick/hud/guardian.dm | 34 ++- code/_onclick/hud/hud.dm | 7 +- code/_onclick/hud/human.dm | 123 ++++------ code/_onclick/hud/lavaland_elite.dm | 6 +- code/_onclick/hud/monkey.dm | 48 ++-- code/_onclick/hud/new_player.dm | 199 +++++++++++++-- code/_onclick/hud/plane_master_controller.dm | 5 +- code/_onclick/hud/radial_persistent.dm | 4 +- code/_onclick/hud/revenanthud.dm | 3 +- code/_onclick/hud/robot.dm | 58 ++--- code/_onclick/hud/screen_objects.dm | 53 +++- code/_onclick/hud/simple_animal.dm | 7 +- code/_onclick/hud/swarmer.dm | 18 +- .../subsystem/processing/station.dm | 9 + code/controllers/subsystem/ticker.dm | 4 +- code/controllers/subsystem/title.dm | 2 +- code/datums/action.dm | 14 -- code/datums/brain_damage/severe.dm | 8 +- code/datums/components/combat_mode.dm | 3 +- code/datums/components/crafting/crafting.dm | 4 +- code/datums/components/mood.dm | 4 +- .../diseases/advance/symptoms/voice_change.dm | 2 +- code/datums/dna.dm | 4 +- code/datums/mind.dm | 23 +- code/datums/mutations/speech.dm | 4 +- code/datums/station_traits/_station_trait.dm | 64 ++++- code/datums/station_traits/negative_traits.dm | 4 +- code/datums/status_effects/debuffs.dm | 14 +- code/datums/status_effects/wound_effects.dm | 3 + code/datums/world_topic.dm | 2 +- code/game/atoms_movable.dm | 66 +++-- code/game/objects/buckling.dm | 2 +- code/game/objects/effects/landmarks.dm | 50 ++-- code/game/objects/items/devices/flashlight.dm | 4 +- code/game/objects/items/documents.dm | 4 +- code/game/objects/items/holy_weapons.dm | 1 - code/game/objects/structures/fireplace.dm | 4 +- .../objects/structures/ghost_role_spawners.dm | 2 +- .../objects/structures/industrial_lift.dm | 5 +- code/game/objects/structures/mirror.dm | 12 +- .../structures/transit_tubes/transit_tube.dm | 4 +- code/game/sound.dm | 4 + code/modules/admin/topic.dm | 3 +- code/modules/admin/verbs/adminhelp.dm | 4 +- .../abductor/equipment/glands/slime.dm | 4 +- .../bloodsucker/datum_bloodsucker.dm | 2 +- .../antagonists/bloodsucker/datum_vassal.dm | 2 +- .../antagonists/changeling/changeling.dm | 2 +- .../antagonists/clockcult/clockcult.dm | 2 +- code/modules/antagonists/cult/cult.dm | 4 +- code/modules/antagonists/ert/ert.dm | 3 +- code/modules/antagonists/gang/gang.dm | 3 +- .../modules/antagonists/traitor/classes/ai.dm | 2 +- .../antagonists/wizard/equipment/artefact.dm | 4 +- .../antagonists/wizard/equipment/soulstone.dm | 4 +- .../modules/atmospherics/gasmixtures/auxgm.dm | 2 +- code/modules/client/client_procs.dm | 9 + code/modules/client/preferences.dm | 2 +- code/modules/events/sentience.dm | 2 +- code/modules/jobs/job_types/curator.dm | 3 +- code/modules/language/codespeak.dm | 4 +- code/modules/language/language_holder.dm | 230 ++++++++++-------- code/modules/language/language_menu.dm | 119 +++++---- .../mining/lavaland/necropolis_chests.dm | 1 + code/modules/mob/dead/dead.dm | 12 +- code/modules/mob/dead/new_player/login.dm | 4 - .../modules/mob/dead/new_player/new_player.dm | 4 +- .../mob/living/carbon/human/human_defines.dm | 1 + .../mob/living/carbon/human/species.dm | 16 +- .../mob/living/carbon/human/status_procs.dm | 6 +- code/modules/mob/living/say.dm | 5 - code/modules/mob/living/silicon/pai/pai.dm | 2 - .../mob/living/silicon/pai/software.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 6 +- code/modules/mob/mob.dm | 5 +- code/modules/mob/transform_procs.dm | 1 - .../crossbreeding/_status_effects.dm | 1 - .../ruins/spaceruin_code/TheDerelict.dm | 4 +- code/modules/tgui/states/language_menu.dm | 4 +- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/language_transfer.dm | 191 +++++++++++++++ icons/hud/lobby/background.dmi | Bin 558 -> 565 bytes icons/hud/lobby/collapse_expand.dmi | Bin 919 -> 854 bytes icons/hud/lobby/signup_button.dmi | Bin 0 -> 2723 bytes icons/hud/lobby/start_now.dmi | Bin 0 -> 11181 bytes sound/misc/menu/attribution.txt | 6 + sound/misc/menu/menu_rolldown1.ogg | Bin 0 -> 16980 bytes sound/misc/menu/menu_rollup1.ogg | Bin 0 -> 17736 bytes sound/misc/menu/ui_select1.ogg | Bin 0 -> 8355 bytes 108 files changed, 1157 insertions(+), 758 deletions(-) create mode 100644 code/modules/unit_tests/language_transfer.dm create mode 100644 icons/hud/lobby/signup_button.dmi create mode 100644 icons/hud/lobby/start_now.dmi create mode 100644 sound/misc/menu/attribution.txt create mode 100644 sound/misc/menu/menu_rolldown1.ogg create mode 100644 sound/misc/menu/menu_rollup1.ogg create mode 100644 sound/misc/menu/ui_select1.ogg diff --git a/.vscode/settings.json b/.vscode/settings.json index 8edb013566..a11bf93e5c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "**/.pnp.*": true }, "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "workbench.editorAssociations": { "*.dmi": "dmiEditor.dmiEditor" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm index 2b0c9c297e..381367fd92 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm @@ -23,3 +23,5 @@ #define COMPONENT_NO_MOUSEDROP (1<<0) ///from base of atom/MouseDrop_T: (/atom/from, /mob/user) #define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) +/// From /atom/movable/screen/click(): (atom/target, atom/location, control, params, mob/user) +#define COMSIG_SCREEN_ELEMENT_CLICK "screen_element_click" diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index 3e0e1d2296..eeb71f90f1 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -1,2 +1,5 @@ /// a person somewhere has thrown something : (mob/living/carbon/carbon_thrower, target) #define COMSIG_GLOB_CARBON_THROW_THING "!throw_thing" + +/// Global signal sent before we decide what job everyone has +#define COMSIG_GLOB_PRE_JOBS_ASSIGNED "!pre_roles_assigned" diff --git a/code/__DEFINES/dcs/signals/signals_hud.dm b/code/__DEFINES/dcs/signals/signals_hud.dm index c771204773..63a55f95ca 100644 --- a/code/__DEFINES/dcs/signals/signals_hud.dm +++ b/code/__DEFINES/dcs/signals/signals_hud.dm @@ -2,3 +2,5 @@ #define COMSIG_HUD_LOBBY_COLLAPSED "hud_lobby_collapsed" /// Sent from /atom/movable/screen/lobby/button/collapse/proc/expand_buttons() : () #define COMSIG_HUD_LOBBY_EXPANDED "hud_lobby_expanded" +/// Sent from /atom/movable/screen/lobby/button/ready/Click() : () +#define COMSIG_HUD_PLAYER_READY_TOGGLE "hud_player_ready_toggle" diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm index 798ea478c2..91f9f8572b 100644 --- a/code/__DEFINES/language.dm +++ b/code/__DEFINES/language.dm @@ -4,10 +4,21 @@ #define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8 // LANGUAGE SOURCE DEFINES -#define LANGUAGE_ALL "all" // For use in full removal only. -#define LANGUAGE_ATOM "atom" -#define LANGUAGE_MIND "mind" +/// For use in full removal only. +#define LANGUAGE_ALL "all" +// Generic language sources. +/// Language is linked to the movable directly. +#define LANGUAGE_ATOM "atom" +/// Language is linked to the mob's mind. +/// If a mind transfer happens, language follows. +#define LANGUAGE_MIND "mind" +/// Language is linked to the mob's species. +/// If a species change happens, language goes away. +/// If applied to a non-human (no species) atom, this is effectively the same as [LANGUAGE_ATOM]. +#define LANGUAGE_SPECIES "species" +// More specific language sources. +// Only ever goes away when dismissed directly. #define LANGUAGE_ABSORB "absorb" #define LANGUAGE_APHASIA "aphasia" #define LANGUAGE_BLOODSUCKER "bloodsucker" @@ -25,3 +36,9 @@ #define LANGUAGE_VASSAL "vassal" #define LANGUAGE_VOICECHANGE "voicechange" #define LANGUAGE_MULTILINGUAL "multilingual" + +// Language flags. Used in granting and removing languages. +/// This language can be spoken. +#define SPOKEN_LANGUAGE (1<<0) +/// This language can be understood. +#define UNDERSTOOD_LANGUAGE (1<<1) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 3b092fd3b7..a8373205ca 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -743,6 +743,13 @@ else L1[key] = other_value +/// Turns an associative list into a flat list of keys +/proc/assoc_to_keys(list/input) + var/list/keys = list() + for(var/key in input) + UNTYPED_LIST_ADD(keys, key) + return keys + /proc/assoc_list_strip_value(list/input) var/list/ret = list() for(var/key in input) diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index d4344b9464..b264de2cd9 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -194,109 +194,91 @@ var/atom/movable/screen/using // Language menu - using = new /atom/movable/screen/language_menu + using = new /atom/movable/screen/language_menu(null, src) using.screen_loc = ui_ai_language_menu - using.hud = src static_inventory += using //AI core - using = new /atom/movable/screen/ai/aicore() + using = new /atom/movable/screen/ai/aicore(null, src) using.screen_loc = ui_ai_core - using.hud = src static_inventory += using //Camera list - using = new /atom/movable/screen/ai/camera_list() + using = new /atom/movable/screen/ai/camera_list(null, src) using.screen_loc = ui_ai_camera_list - using.hud = src static_inventory += using //Track - using = new /atom/movable/screen/ai/camera_track() + using = new /atom/movable/screen/ai/camera_track(null, src) using.screen_loc = ui_ai_track_with_camera - using.hud = src static_inventory += using //Camera light - using = new /atom/movable/screen/ai/camera_light() + using = new /atom/movable/screen/ai/camera_light(null, src) using.screen_loc = ui_ai_camera_light - using.hud = src static_inventory += using //Crew Monitoring - using = new /atom/movable/screen/ai/crew_monitor() + using = new /atom/movable/screen/ai/crew_monitor(null, src) using.screen_loc = ui_ai_crew_monitor - using.hud = src static_inventory += using //Crew Manifest - using = new /atom/movable/screen/ai/crew_manifest() + using = new /atom/movable/screen/ai/crew_manifest(null, src) using.screen_loc = ui_ai_crew_manifest - using.hud = src static_inventory += using //Alerts - using = new /atom/movable/screen/ai/alerts() + using = new /atom/movable/screen/ai/alerts(null, src) using.screen_loc = ui_ai_alerts - using.hud = src static_inventory += using //Announcement - using = new /atom/movable/screen/ai/announcement() + using = new /atom/movable/screen/ai/announcement(null, src) using.screen_loc = ui_ai_announcement - using.hud = src static_inventory += using //Shuttle - using = new /atom/movable/screen/ai/call_shuttle() + using = new /atom/movable/screen/ai/call_shuttle(null, src) using.screen_loc = ui_ai_shuttle - using.hud = src static_inventory += using //Laws - using = new /atom/movable/screen/ai/state_laws() + using = new /atom/movable/screen/ai/state_laws(null, src) using.screen_loc = ui_ai_state_laws - using.hud = src static_inventory += using //PDA message - using = new /atom/movable/screen/ai/pda_msg_send() + using = new /atom/movable/screen/ai/pda_msg_send(null, src) using.screen_loc = ui_ai_pda_send - using.hud = src static_inventory += using //PDA log - using = new /atom/movable/screen/ai/pda_msg_show() + using = new /atom/movable/screen/ai/pda_msg_show(null, src) using.screen_loc = ui_ai_pda_log - using.hud = src static_inventory += using //Take image - using = new /atom/movable/screen/ai/image_take() + using = new /atom/movable/screen/ai/image_take(null, src) using.screen_loc = ui_ai_take_picture - using.hud = src static_inventory += using //View images - using = new /atom/movable/screen/ai/image_view() + using = new /atom/movable/screen/ai/image_view(null, src) using.screen_loc = ui_ai_view_images - using.hud = src static_inventory += using //Medical/Security sensors - using = new /atom/movable/screen/ai/sensors() + using = new /atom/movable/screen/ai/sensors(null, src) using.screen_loc = ui_ai_sensor - using.hud = src static_inventory += using //Multicamera mode - using = new /atom/movable/screen/ai/multicam() + using = new /atom/movable/screen/ai/multicam(null, src) using.screen_loc = ui_ai_multicam - using.hud = src static_inventory += using //Add multicamera camera - using = new /atom/movable/screen/ai/add_multicam() + using = new /atom/movable/screen/ai/add_multicam(null, src) using.screen_loc = ui_ai_add_multicam - using.hud = src static_inventory += using diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 815e46f9eb..4475d2a117 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -259,10 +259,10 @@ or something covering your eyes." var/command /atom/movable/screen/alert/mind_control/Click() - var/mob/living/L = usr - if(L != owner) + . = ..() + if(!.) return - to_chat(L, "[command]") + to_chat(usr, "[command]") /atom/movable/screen/alert/hypnosis name = "Hypnosis" @@ -283,9 +283,13 @@ If you're feeling frisky, examine yourself and click the underlined item to pull clickable_glow = TRUE /atom/movable/screen/alert/embeddedobject/Click() - if(isliving(usr) && usr == owner) - var/mob/living/carbon/M = usr - return M.help_shake_act(M) + . = ..() + if(!.) + return + if(!isliving(usr)) + return + var/mob/living/carbon/M = usr + return M.help_shake_act(M) /atom/movable/screen/alert/weightless name = "Weightless" @@ -312,8 +316,11 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." clickable_glow = TRUE /atom/movable/screen/alert/fire/Click() + . = ..() + if(!.) + return var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() if(CHECK_MOBILITY(L, MOBILITY_MOVE)) @@ -721,14 +728,16 @@ so as to remain in compliance with the most up-to-date laws." var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return if(!target) return var/mob/living/silicon/ai/AI = usr var/turf/T = get_turf(target) - if(T) - AI.eyeobj.setLoc(T) + if(!T) + return + AI.eyeobj.setLoc(T) //MECHS @@ -748,10 +757,11 @@ so as to remain in compliance with the most up-to-date laws." clickable_glow = TRUE /atom/movable/screen/alert/notify_cloning/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return - var/mob/dead/observer/G = usr - G.reenter_corpse() + var/mob/dead/observer/dead_owner = usr + dead_owner.reenter_corpse() /atom/movable/screen/alert/notify_action name = "Body created" @@ -763,8 +773,10 @@ so as to remain in compliance with the most up-to-date laws." var/action = NOTIFY_JUMP /atom/movable/screen/alert/notify_action/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return + if(!target) return var/mob/dead/observer/G = usr @@ -782,32 +794,43 @@ so as to remain in compliance with the most up-to-date laws." //OBJECT-BASED -/atom/movable/screen/alert/restrained - clickable_glow = TRUE - -/atom/movable/screen/alert/restrained/buckled +/atom/movable/screen/alert/buckled name = "Buckled" desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed." icon_state = "buckled" + clickable_glow = TRUE + +/atom/movable/screen/alert/restrained + clickable_glow = TRUE /atom/movable/screen/alert/restrained/handcuffed name = "Handcuffed" desc = "You're handcuffed and can't act. If anyone drags you, you won't be able to move. Click the alert to free yourself." + click_master = FALSE /atom/movable/screen/alert/restrained/legcuffed name = "Legcuffed" desc = "You're legcuffed, which slows you down considerably. Click the alert to free yourself." + click_master = FALSE /atom/movable/screen/alert/restrained/Click() + . = ..() + if(!.) + return + var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() return L.resist_restraints() -/atom/movable/screen/alert/restrained/buckled/Click() +/atom/movable/screen/alert/buckled/Click() + . = ..() + if(!.) + return + var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() return L.resist_buckle() @@ -824,8 +847,11 @@ so as to remain in compliance with the most up-to-date laws." clickable_glow = TRUE /atom/movable/screen/alert/shoes/Click() + . = ..() + if(!.) + return var/mob/living/carbon/C = usr - if(!istype(C) || !C.can_resist() || C != owner || !C.shoes) + if(!istype(C) || !C.can_resist() || !C.shoes) return C.MarkResistTime() C.shoes.handle_tying(C) diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 8a494a05b9..49d0087a7d 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -39,84 +39,71 @@ //begin buttons - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - action_intent = new /atom/movable/screen/act_intent/alien() + action_intent = new /atom/movable/screen/act_intent/alien(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent if(isalienhunter(mymob)) var/mob/living/carbon/alien/humanoid/hunter/H = mymob - H.leap_icon = new /atom/movable/screen/alien/leap() + H.leap_icon = new /atom/movable/screen/alien/leap(null, src) H.leap_icon.screen_loc = ui_alien_storage_r static_inventory += H.leap_icon - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_alien_language_menu - using.hud = src static_inventory += using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_pull_resist - using.hud = src hotkeybuttons += using - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist static_inventory += pull_icon //begin indicators - healths = new /atom/movable/screen/healths/alien() - healths.hud = src + healths = new /atom/movable/screen/healths/alien(null, src) infodisplay += healths - alien_plasma_display = new /atom/movable/screen/alien/plasma_display() - alien_plasma_display.hud = src + alien_plasma_display = new /atom/movable/screen/alien/plasma_display(null, src) infodisplay += alien_plasma_display if(!isalienqueen(mymob)) - alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder - alien_queen_finder.hud = src + alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder(null, src) infodisplay += alien_queen_finder - zone_select = new /atom/movable/screen/zone_sel/alien() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/alien(null, src) zone_select.update_icon() static_inventory += zone_select for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 17d3ad35e4..50848bb37e 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -5,32 +5,26 @@ ..() var/atom/movable/screen/using - action_intent = new /atom/movable/screen/act_intent/alien() + action_intent = new /atom/movable/screen/act_intent/alien(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent - healths = new /atom/movable/screen/healths/alien() - healths.hud = src + healths = new /atom/movable/screen/healths/alien(null, src) infodisplay += healths - alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder() - alien_queen_finder.hud = src + alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder(null, src) infodisplay += alien_queen_finder - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = 'icons/mob/screen_alien.dmi' - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist hotkeybuttons += pull_icon - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_alien_language_menu - using.hud = src static_inventory += using - zone_select = new /atom/movable/screen/zone_sel/alien() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/alien(null, src) zone_select.update_icon() static_inventory += zone_select diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 8a981d5796..7ce0086974 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -127,61 +127,50 @@ ..() var/atom/movable/screen/using - blobpwrdisplay = new /atom/movable/screen() + blobpwrdisplay = new /atom/movable/screen(null, src) blobpwrdisplay.name = "blob power" blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health blobpwrdisplay.mouse_opacity = MOUSE_OPACITY_TRANSPARENT blobpwrdisplay.layer = ABOVE_HUD_LAYER blobpwrdisplay.plane = ABOVE_HUD_PLANE - blobpwrdisplay.hud = src infodisplay += blobpwrdisplay - healths = new /atom/movable/screen/healths/blob() - healths.hud = src + healths = new /atom/movable/screen/healths/blob(null, src) infodisplay += healths - using = new /atom/movable/screen/blob/BlobHelp() + using = new /atom/movable/screen/blob/BlobHelp(null, src) using.screen_loc = "WEST:6,NORTH:-3" - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/JumpToNode() + using = new /atom/movable/screen/blob/JumpToNode(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/JumpToCore() + using = new /atom/movable/screen/blob/JumpToCore(null, src) using.screen_loc = ui_zonesel - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/Blobbernaut() + using = new /atom/movable/screen/blob/Blobbernaut(null, src) using.screen_loc = ui_belt - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/ResourceBlob() + using = new /atom/movable/screen/blob/ResourceBlob(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/NodeBlob() + using = new /atom/movable/screen/blob/NodeBlob(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/FactoryBlob() + using = new /atom/movable/screen/blob/FactoryBlob(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/ReadaptStrain() + using = new /atom/movable/screen/blob/ReadaptStrain(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/RelocateCore() + using = new /atom/movable/screen/blob/RelocateCore(null, src) using.screen_loc = ui_storage2 - using.hud = src static_inventory += using diff --git a/code/_onclick/hud/blobbernauthud.dm b/code/_onclick/hud/blobbernauthud.dm index 430e8e81e7..f82be53afa 100644 --- a/code/_onclick/hud/blobbernauthud.dm +++ b/code/_onclick/hud/blobbernauthud.dm @@ -2,10 +2,8 @@ /datum/hud/blobbernaut/New(mob/owner) ..() - blobpwrdisplay = new /atom/movable/screen/healths/blob/naut/core() - blobpwrdisplay.hud = src + blobpwrdisplay = new /atom/movable/screen/healths/blob/naut/core(null, src) infodisplay += blobpwrdisplay - healths = new /atom/movable/screen/healths/blob/naut() - healths.hud = src + healths = new /atom/movable/screen/healths/blob/naut(null, src) infodisplay += healths diff --git a/code/_onclick/hud/clockwork_marauder.dm b/code/_onclick/hud/clockwork_marauder.dm index de9cb65c75..51d1fbb4a9 100644 --- a/code/_onclick/hud/clockwork_marauder.dm +++ b/code/_onclick/hud/clockwork_marauder.dm @@ -7,14 +7,14 @@ ..() var/atom/movable/screen/using - healths = new /atom/movable/screen/healths/clock() + healths = new /atom/movable/screen/healths/clock(null, src) infodisplay += healths - hosthealth = new /atom/movable/screen/healths/clock() + hosthealth = new /atom/movable/screen/healths/clock(null, src) hosthealth.screen_loc = ui_internal infodisplay += hosthealth - using = new /atom/movable/screen/marauder/emerge() + using = new /atom/movable/screen/marauder/emerge(null, src) using.screen_loc = ui_zonesel static_inventory += using diff --git a/code/_onclick/hud/constructs.dm b/code/_onclick/hud/constructs.dm index 31f1060f17..70f40aace3 100644 --- a/code/_onclick/hud/constructs.dm +++ b/code/_onclick/hud/constructs.dm @@ -3,13 +3,11 @@ /datum/hud/constructs/New(mob/owner) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_construct_pull static_inventory += pull_icon - healths = new /atom/movable/screen/healths/construct() - healths.hud = src + healths = new /atom/movable/screen/healths/construct(null, src) infodisplay += healths diff --git a/code/_onclick/hud/devil.dm b/code/_onclick/hud/devil.dm index 574f5dd1fd..fb5028145c 100644 --- a/code/_onclick/hud/devil.dm +++ b/code/_onclick/hud/devil.dm @@ -6,51 +6,44 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drone_drop - using.hud = src static_inventory += using - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_drone_pull static_inventory += pull_icon build_hand_slots() - using = new /atom/movable/screen/inventory() + using = new /atom/movable/screen/inventory(null, src) using.name = "hand" using.icon = ui_style using.icon_state = "swap_1_m" using.screen_loc = ui_swaphand_position(owner,1) using.layer = HUD_LAYER using.plane = HUD_PLANE - using.hud = src static_inventory += using - using = new /atom/movable/screen/inventory() + using = new /atom/movable/screen/inventory(null, src) using.name = "hand" using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) using.layer = HUD_LAYER using.plane = HUD_PLANE - using.hud = src static_inventory += using - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) - devilsouldisplay = new /atom/movable/screen/devil/soul_counter - devilsouldisplay.hud = src + devilsouldisplay = new /atom/movable/screen/devil/soul_counter(null, src) infodisplay += devilsouldisplay diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index a2cae89864..a6632b553f 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -2,7 +2,7 @@ ..() var/atom/movable/screen/inventory/inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "internal storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -11,7 +11,7 @@ inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head/mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -22,7 +22,6 @@ for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/families.dm b/code/_onclick/hud/families.dm index 6cc9f4ef32..81da541011 100644 --- a/code/_onclick/hud/families.dm +++ b/code/_onclick/hud/families.dm @@ -9,9 +9,6 @@ /// Boolean, have the cops arrived? If so, the icon stops changing and remains the same. var/cops_arrived = 0 -/atom/movable/screen/wanted/New() - return ..() - /atom/movable/screen/wanted/Initialize(mapload) . = ..() update_icon() diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index 1762bee1fc..a7cfec5a06 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -3,63 +3,55 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drone_drop - using.hud = src static_inventory += using - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_drone_pull static_inventory += pull_icon build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1_m" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using if(mymob.possible_a_intents) if(mymob.possible_a_intents.len == 4) // All possible intents - full intent selector - action_intent = new /atom/movable/screen/act_intent/segmented + action_intent = new /atom/movable/screen/act_intent/segmented(null, src) else - action_intent = new /atom/movable/screen/act_intent + action_intent = new /atom/movable/screen/act_intent(null, src) action_intent.icon = ui_style action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() static_inventory += zone_select - using = new /atom/movable/screen/area_creator + using = new /atom/movable/screen/area_creator(null, src) using.icon = ui_style - using.hud = src static_inventory += using mymob.client.screen = list() for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index f4f1f2f7b0..ea36022dfb 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -49,34 +49,28 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/ghost/jumptomob() + using = new /atom/movable/screen/ghost/jumptomob(null, src) using.screen_loc = ui_ghost_jumptomob - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/orbit() + using = new /atom/movable/screen/ghost/orbit(null, src) using.screen_loc = ui_ghost_orbit - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/reenter_corpse() + using = new /atom/movable/screen/ghost/reenter_corpse(null, src) using.screen_loc = ui_ghost_reenter_corpse - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/teleport() + using = new /atom/movable/screen/ghost/teleport(null, src) using.screen_loc = ui_ghost_teleport - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/spawners() + using = new /atom/movable/screen/ghost/spawners(null, src) using.screen_loc = ui_ghost_spawners - using.hud = src static_inventory += using - using = new /atom/movable/screen/language_menu + using = new /atom/movable/screen/language_menu(null, src) using.icon = ui_style - using.hud = src static_inventory += using /datum/hud/ghost/show_hud(version = 0, mob/viewmob) diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 09ec5d925c..0443dc3deb 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -3,33 +3,27 @@ ..() var/atom/movable/screen/using - healths = new /atom/movable/screen/healths/guardian() - healths.hud = src + healths = new /atom/movable/screen/healths/guardian(null, src) infodisplay += healths - using = new /atom/movable/screen/guardian/Manifest() + using = new /atom/movable/screen/guardian/Manifest(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/Recall() + using = new /atom/movable/screen/guardian/Recall(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new owner.toggle_button_type() + using = new owner.toggle_button_type(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/ToggleLight() + using = new /atom/movable/screen/guardian/ToggleLight(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using /datum/hud/dextrous/guardian/New(mob/living/simple_animal/hostile/guardian/owner) //for a dextrous guardian @@ -38,7 +32,7 @@ if(istype(owner, /mob/living/simple_animal/hostile/guardian/dextrous)) var/atom/movable/screen/inventory/inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "internal storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -46,32 +40,32 @@ inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_sstore1 static_inventory += using else - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_id static_inventory += using - healths = new /atom/movable/screen/healths/guardian() + healths = new /atom/movable/screen/healths/guardian(null, src) infodisplay += healths - using = new /atom/movable/screen/guardian/Manifest() + using = new /atom/movable/screen/guardian/Manifest(null, src) using.screen_loc = ui_belt static_inventory += using - using = new /atom/movable/screen/guardian/Recall() + using = new /atom/movable/screen/guardian/Recall(null, src) using.screen_loc = ui_back static_inventory += using - using = new owner.toggle_button_type() + using = new owner.toggle_button_type(null, src) using.screen_loc = ui_storage2 static_inventory += using - using = new /atom/movable/screen/guardian/ToggleLight() + using = new /atom/movable/screen/guardian/ToggleLight(null, src) using.screen_loc = ui_inventory static_inventory += using diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 52397c3036..bda691dcc9 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -109,12 +109,12 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() for(var/mytype in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/plane_master/instance = new mytype() + var/atom/movable/screen/plane_master/instance = new mytype(null, src) plane_masters["[instance.plane]"] = instance instance.backdrop(mymob) for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) - var/atom/movable/plane_master_controller/controller_instance = new mytype(src) + var/atom/movable/plane_master_controller/controller_instance = new mytype(null, src) plane_master_controllers[controller_instance.name] = controller_instance screentip_text = new(null, src) @@ -322,14 +322,13 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() var/atom/movable/screen/inventory/hand/hand_box for(var/i in 1 to mymob.held_items.len) - hand_box = new /atom/movable/screen/inventory/hand() + hand_box = new /atom/movable/screen/inventory/hand(null, src) hand_box.name = mymob.get_held_index_name(i) hand_box.icon = ui_style hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" hand_box.screen_loc = ui_hand_position(i) hand_box.held_index = i hand_slots["[i]"] = hand_box - hand_box.hud = src static_inventory += hand_box hand_box.update_icon() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index c8b7b3327d..5808dec12c 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -186,54 +186,47 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.icon = ui_style if(!widescreenlayout) // CIT CHANGE using.screen_loc = ui_boxlang // CIT CHANGE - using.hud = src static_inventory += using - using = new /atom/movable/screen/area_creator + using = new /atom/movable/screen/area_creator(null, src) using.icon = ui_style if(!widescreenlayout) // CIT CHANGE using.screen_loc = ui_boxarea // CIT CHANGE - using.hud = src static_inventory += using - using = new /atom/movable/screen/voretoggle() //We fancy Vore now + using = new /atom/movable/screen/voretoggle(null, src) //We fancy Vore now using.icon = tg_ui_icon_to_cit_ui(ui_style) using.screen_loc = ui_voremode if(!widescreenlayout) using.screen_loc = ui_boxvore - using.hud = src static_inventory += using - action_intent = new /atom/movable/screen/act_intent/segmented + action_intent = new /atom/movable/screen/act_intent/segmented(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent assert_move_intent_ui(owner, TRUE) // clickdelay - clickdelay = new - clickdelay.hud = src + clickdelay = new(null, src) clickdelay.screen_loc = ui_clickdelay static_inventory += clickdelay // resistdelay - resistdelay = new - resistdelay.hud = src + resistdelay = new(null, src) resistdelay.screen_loc = ui_resistdelay static_inventory += resistdelay - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "uniform" inv_box.icon = ui_style inv_box.slot_id = ITEM_SLOT_ICLOTHING @@ -242,7 +235,7 @@ inv_box.screen_loc = ui_iclothing toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "suit" inv_box.icon = ui_style inv_box.slot_id = ITEM_SLOT_OCLOTHING @@ -253,21 +246,19 @@ build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "id" inv_box.icon = ui_style inv_box.icon_state = "id" @@ -276,7 +267,7 @@ inv_box.slot_id = ITEM_SLOT_ID static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -285,7 +276,7 @@ inv_box.slot_id = ITEM_SLOT_MASK toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "neck" inv_box.icon = ui_style inv_box.icon_state = "neck" @@ -294,7 +285,7 @@ inv_box.slot_id = ITEM_SLOT_NECK toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "back" inv_box.icon = ui_style inv_box.icon_state = "back" @@ -303,7 +294,7 @@ inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "left pocket" inv_box.icon = ui_style inv_box.icon_state = "pocket" @@ -312,7 +303,7 @@ inv_box.slot_id = ITEM_SLOT_LPOCKET static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "right pocket" inv_box.icon = ui_style inv_box.icon_state = "pocket" @@ -321,7 +312,7 @@ inv_box.slot_id = ITEM_SLOT_RPOCKET static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "suit storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -330,32 +321,28 @@ inv_box.slot_id = ITEM_SLOT_SUITSTORE static_inventory += inv_box - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_overridden_resist // CIT CHANGE - changes this to overridden resist - using.hud = src hotkeybuttons += using - rest_icon = new /atom/movable/screen/rest() + rest_icon = new /atom/movable/screen/rest(null, src) rest_icon.icon = ui_style rest_icon.screen_loc = ui_pull_resist - rest_icon.hud = src static_inventory += rest_icon //END OF CIT CHANGES - using = new /atom/movable/screen/human/toggle() + using = new /atom/movable/screen/human/toggle(null, src) using.icon = ui_style using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/human/equip() + using = new /atom/movable/screen/human/equip(null, src) using.icon = ui_style using.screen_loc = ui_equip_position(mymob) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "gloves" inv_box.icon = ui_style inv_box.icon_state = "gloves" @@ -364,7 +351,7 @@ inv_box.slot_id = ITEM_SLOT_GLOVES toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "eyes" inv_box.icon = ui_style inv_box.icon_state = "glasses" @@ -373,7 +360,7 @@ inv_box.slot_id = ITEM_SLOT_EYES toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "ears" inv_box.icon = ui_style inv_box.icon_state = "ears" @@ -382,7 +369,7 @@ inv_box.slot_id = ITEM_SLOT_EARS toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head" inv_box.icon = ui_style inv_box.icon_state = "head" @@ -391,7 +378,7 @@ inv_box.slot_id = ITEM_SLOT_HEAD toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "shoes" inv_box.icon = ui_style inv_box.icon_state = "shoes" @@ -400,7 +387,7 @@ inv_box.slot_id = ITEM_SLOT_FEET toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "belt" inv_box.icon = ui_style inv_box.icon_state = "belt" @@ -409,77 +396,62 @@ inv_box.slot_id = ITEM_SLOT_BELT static_inventory += inv_box - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - healths = new /atom/movable/screen/healths() - healths.hud = src + healths = new /atom/movable/screen/healths(null, src) infodisplay += healths - staminas = new /atom/movable/screen/staminas() - staminas.hud = src + staminas = new /atom/movable/screen/staminas(null, src) infodisplay += staminas if(!CONFIG_GET(flag/disable_stambuffer)) - staminabuffer = new /atom/movable/screen/staminabuffer() - staminabuffer.hud = src + staminabuffer = new /atom/movable/screen/staminabuffer(null, src) infodisplay += staminabuffer //END OF CIT CHANGES - healthdoll = new /atom/movable/screen/healthdoll() - healthdoll.hud = src + healthdoll = new /atom/movable/screen/healthdoll(null, src) infodisplay += healthdoll - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist static_inventory += pull_icon - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) infodisplay += lingchemdisplay - lingstingdisplay = new /atom/movable/screen/ling/sting() - lingstingdisplay.hud = src + lingstingdisplay = new /atom/movable/screen/ling/sting(null, src) infodisplay += lingstingdisplay - devilsouldisplay = new /atom/movable/screen/devil/soul_counter - devilsouldisplay.hud = src + devilsouldisplay = new /atom/movable/screen/devil/soul_counter(null, src) infodisplay += devilsouldisplay - blood_display = new /atom/movable/screen/bloodsucker/blood_counter // Blood Volume - blood_display.hud = src + blood_display = new /atom/movable/screen/bloodsucker/blood_counter(null, src) // Blood Volume infodisplay += blood_display - vamprank_display = new /atom/movable/screen/bloodsucker/rank_counter // Bloodsucker Rank - vamprank_display.hud = src + vamprank_display = new /atom/movable/screen/bloodsucker/rank_counter(null, src) // Bloodsucker Rank infodisplay += vamprank_display - sunlight_display = new /atom/movable/screen/bloodsucker/sunlight_counter // Sunlight - sunlight_display.hud = src + sunlight_display = new /atom/movable/screen/bloodsucker/sunlight_counter(null, src) // Sunlight infodisplay += sunlight_display - coolant_display = new /atom/movable/screen/synth/coolant_counter //Coolant & cooling efficiency readouts for Synths. - coolant_display.hud = src + coolant_display = new /atom/movable/screen/synth/coolant_counter(null, src) //Coolant & cooling efficiency readouts for Synths. infodisplay += coolant_display - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() static_inventory += zone_select - combo_display = new /atom/movable/screen/combo() + combo_display = new /atom/movable/screen/combo(null, src) infodisplay += combo_display for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() @@ -500,10 +472,9 @@ // make new ones // walk/run - using = new /atom/movable/screen/mov_intent + using = new /atom/movable/screen/mov_intent(null, src) using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon using.screen_loc = ui_movi - using.hud = src using.update_icon() static_inventory += using if(!on_new) @@ -513,19 +484,17 @@ return // sprint button - using = new /atom/movable/screen/sprintbutton + using = new /atom/movable/screen/sprintbutton(null, src) using.icon = tg_ui_icon_to_cit_ui(ui_style) using.icon_state = ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint") using.screen_loc = ui_movi - using.hud = src static_inventory += using if(!on_new) owner?.client?.screen += using // same as above but buffer. - sprint_buffer = new /atom/movable/screen/sprint_buffer + sprint_buffer = new /atom/movable/screen/sprint_buffer(null, src) sprint_buffer.screen_loc = ui_sprintbufferloc - sprint_buffer.hud = src static_inventory += sprint_buffer if(!on_new) owner?.client?.screen += using diff --git a/code/_onclick/hud/lavaland_elite.dm b/code/_onclick/hud/lavaland_elite.dm index f3ca5fec32..6df374cd10 100644 --- a/code/_onclick/hud/lavaland_elite.dm +++ b/code/_onclick/hud/lavaland_elite.dm @@ -4,13 +4,11 @@ /datum/hud/lavaland_elite/New(mob/living/simple_animal/hostile/asteroid/elite) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_living_pull static_inventory += pull_icon - healths = new /atom/movable/screen/healths/lavaland_elite() - healths.hud = src + healths = new /atom/movable/screen/healths/lavaland_elite(null, src) infodisplay += healths diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 9ee795a745..ddb5662889 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -3,48 +3,42 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - action_intent = new /atom/movable/screen/act_intent() + action_intent = new /atom/movable/screen/act_intent(null, src) action_intent.icon = ui_style action_intent.icon_state = mymob.a_intent action_intent.screen_loc = ui_acti - action_intent.hud = src static_inventory += action_intent - using = new /atom/movable/screen/mov_intent() + using = new /atom/movable/screen/mov_intent(null, src) using.icon = ui_style using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") using.screen_loc = ui_movi - using.hud = src static_inventory += using - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.icon = ui_style - using.hud = src static_inventory += using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1_m" //extra wide! using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -53,7 +47,7 @@ inv_box.slot_id = ITEM_SLOT_MASK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "neck" inv_box.icon = ui_style inv_box.icon_state = "neck" @@ -62,7 +56,7 @@ inv_box.slot_id = ITEM_SLOT_NECK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head" inv_box.icon = ui_style inv_box.icon_state = "head" @@ -71,7 +65,7 @@ inv_box.slot_id = ITEM_SLOT_HEAD static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "back" inv_box.icon = ui_style inv_box.icon_state = "back" @@ -79,49 +73,41 @@ inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - healths = new /atom/movable/screen/healths() - healths.hud = src + healths = new /atom/movable/screen/healths(null, src) infodisplay += healths - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style pull_icon.screen_loc = ui_pull_resist - pull_icon.hud = src pull_icon.update_icon() static_inventory += pull_icon - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) infodisplay += lingchemdisplay - lingstingdisplay = new /atom/movable/screen/ling/sting() - lingstingdisplay.hud = src + lingstingdisplay = new /atom/movable/screen/ling/sting(null, src) infodisplay += lingstingdisplay - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() static_inventory += zone_select mymob.client.screen = list() - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_pull_resist - using.hud = src hotkeybuttons += using for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index c7f40e4dcc..e58d330eae 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -1,9 +1,12 @@ #define SHUTTER_MOVEMENT_DURATION 0.4 SECONDS #define SHUTTER_WAIT_DURATION 0.2 SECONDS +/// Maximum number of station trait buttons we will display, please think hard before creating scenarios where there are more than this +#define MAX_STATION_TRAIT_BUTTONS_VERTICAL 3 /datum/hud/new_player ///Whether the menu is currently on the client's screen or not var/menu_hud_status = TRUE + var/list/shown_station_trait_buttons /datum/hud/new_player/New(mob/dead/new_player/owner) . = ..() @@ -13,29 +16,89 @@ /datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner) var/list/buttons = subtypesof(/atom/movable/screen/lobby) - for(var/button_type in buttons) - var/atom/movable/screen/lobby/lobbyscreen = new button_type(our_hud = src) + for (var/atom/movable/screen/lobby/lobbyscreen as anything in buttons) + if (!initial(lobbyscreen.always_available)) + continue + lobbyscreen = new lobbyscreen(our_hud = src) lobbyscreen.SlowInit() - lobbyscreen.hud = src static_inventory += lobbyscreen if(!lobbyscreen.always_shown) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) - if(istype(lobbyscreen, /atom/movable/screen/lobby/button)) - var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen - lobby_button.owner = REF(owner) + + if(owner.client.is_localhost()) + var/atom/movable/screen/lobby/button/start_now/start_button = new(our_hud = src) + start_button.SlowInit() + static_inventory += start_button + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) + show_hud(hud_version) +/// Load and then display the buttons for relevant station traits +/datum/hud/new_player/proc/show_station_trait_buttons() + var/mob/dead/new_player/user = mymob + if (!user.age_verify()) + return + for (var/datum/station_trait/trait as anything in GLOB.lobby_station_traits) + if (QDELETED(trait) || !trait.can_display_lobby_button(mymob.client)) + remove_station_trait_button(trait) + continue + if(LAZYACCESS(shown_station_trait_buttons, trait)) + continue + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = new(our_hud = src) + trait.setup_lobby_button(sign_up_button) + static_inventory |= sign_up_button + LAZYSET(shown_station_trait_buttons, trait, sign_up_button) + RegisterSignal(trait, COMSIG_PARENT_QDELETING, PROC_REF(remove_station_trait_button)) + + place_station_trait_buttons() + +/// Display the buttosn for relevant station traits. +/datum/hud/new_player/proc/place_station_trait_buttons() + if(hud_version != HUD_STYLE_STANDARD || !mymob?.client) + return + + var/y_offset = 397 + var/x_offset = 233 + var/y_button_offset = 27 + var/x_button_offset = -27 + var/iteration = 0 + for(var/trait in shown_station_trait_buttons) + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = shown_station_trait_buttons[trait] + iteration++ + sign_up_button.screen_loc = offset_to_screen_loc(x_offset, y_offset, mymob.client.view) + mymob.client.screen |= sign_up_button + if (iteration >= MAX_STATION_TRAIT_BUTTONS_VERTICAL) + iteration = 0 + y_offset = 397 + x_offset += x_button_offset + else + y_offset += y_button_offset + +/// Remove a station trait button, then re-order the rest. +/datum/hud/new_player/proc/remove_station_trait_button(datum/station_trait/trait) + SIGNAL_HANDLER + var/atom/movable/screen/lobby/button/sign_up/button = LAZYACCESS(shown_station_trait_buttons, trait) + if(!button) + return + LAZYREMOVE(shown_station_trait_buttons, trait) + UnregisterSignal(trait, COMSIG_PARENT_QDELETING) + static_inventory -= button + qdel(button) + place_station_trait_buttons() + /atom/movable/screen/lobby plane = SPLASHSCREEN_PLANE layer = LOBBY_MENU_LAYER screen_loc = "TOP,CENTER" ///Whether this HUD element can be hidden from the client's "screen" (moved off-screen) or not var/always_shown = FALSE + /// If true we will create this button every time the HUD is generated + var/always_available = TRUE /atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...) - if(our_hud) - hud = our_hud + set_new_hud(our_hud) return ..() /// Run sleeping actions after initialize @@ -67,11 +130,15 @@ VAR_PROTECTED/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE - /// The ref of the mob that owns this button. Only the owner can click on it. - var/owner + ///Should this button play the select sound? + var/select_sound_play = TRUE /atom/movable/screen/lobby/button/Click(location, control, params) - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -79,11 +146,19 @@ if(!enabled) return flick("[base_icon_state]_pressed", src) + if(select_sound_play) + var/sound/ui_select_sound = sound('sound/misc/menu/ui_select1.ogg') + ui_select_sound.frequency = get_rand_frequency_low_range() + SEND_SOUND(hud.mymob, ui_select_sound) update_appearance(UPDATE_ICON) return TRUE /atom/movable/screen/lobby/button/MouseEntered(location,control,params) - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -91,7 +166,11 @@ update_appearance(UPDATE_ICON) /atom/movable/screen/lobby/button/MouseExited() - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -178,6 +257,7 @@ new_player.ready = PLAYER_NOT_READY base_icon_state = "not_ready" update_appearance(UPDATE_ICON) + SEND_SIGNAL(hud, COMSIG_HUD_PLAYER_READY_TOGGLE) ///Shown when the game has started /atom/movable/screen/lobby/button/join @@ -186,12 +266,13 @@ icon = 'icons/hud/lobby/join.dmi' icon_state = "" //Default to not visible base_icon_state = "join_game" + enabled = null // set in init /atom/movable/screen/lobby/button/join/Initialize(mapload) . = ..() - set_button_status(FALSE) switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) if(GAME_STATE_SETTING_UP) set_button_status(TRUE) @@ -250,6 +331,7 @@ icon = 'icons/hud/lobby/observe.dmi' icon_state = "observe_disabled" base_icon_state = "observe" + enabled = null // set in init /atom/movable/screen/lobby/button/observe/Initialize(mapload) . = ..() @@ -378,6 +460,23 @@ var/mob/dead/new_player/new_player = hud.mymob new_player.handle_player_polling() +/// A generic "sign up" button used by station traits +/atom/movable/screen/lobby/button/sign_up + icon = 'icons/hud/lobby/signup_button.dmi' + icon_state = "signup" + base_icon_state = "signup" + always_available = FALSE + +/atom/movable/screen/lobby/button/sign_up/MouseEntered(location, control, params) + . = ..() + if(QDELETED(src) || !desc) + return + openToolTip(usr, tip_src = src, params = params, title = name, content = desc,) + +/atom/movable/screen/lobby/button/sign_up/MouseExited() + . = ..() + closeToolTip(usr) + /atom/movable/screen/lobby/button/collapse name = "Collapse Lobby Menu" icon = 'icons/hud/lobby/collapse_expand.dmi' @@ -387,6 +486,27 @@ screen_loc = "TOP:-82,CENTER:-54" always_shown = TRUE + var/blip_enabled = TRUE + +/atom/movable/screen/lobby/button/collapse/Initialize(mapload, datum/hud/hud_owner) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(disable_blip)) + RegisterSignal(hud, COMSIG_HUD_PLAYER_READY_TOGGLE, PROC_REF(on_player_ready_toggle)) + if(GAME_STATE_SETTING_UP) + blip_enabled = FALSE + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(enable_blip)) + else + blip_enabled = FALSE + + add_overlay(get_blip_overlay()) + update_icon(UPDATE_OVERLAYS) + +/atom/movable/screen/lobby/button/collapse/update_overlays() + . = ..() + . += get_blip_overlay() + /atom/movable/screen/lobby/button/collapse/Click(location, control, params) . = ..() if(!.) @@ -416,6 +536,38 @@ sleep(2 * SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) set_button_status(TRUE) +///Proc to update the ready blip state upon new player's ready status change +/atom/movable/screen/lobby/button/collapse/proc/on_player_ready_toggle() + SIGNAL_HANDLER + update_appearance(UPDATE_ICON) + +///Returns a ready blip overlay depending on the player's ready state +/atom/movable/screen/lobby/button/collapse/proc/get_blip_overlay() + var/blip_icon_state = "ready_blip" + if(blip_enabled && hud) + var/mob/dead/new_player/new_player = hud.mymob + blip_icon_state += "_[new_player.ready ? "" : "not_"]ready" + else + blip_icon_state += "_disabled" + var/mutable_appearance/ready_blip = mutable_appearance(icon, blip_icon_state) + return ready_blip + +///Disables the ready blip; makes us listen for the setup error to re-enable the blip +/atom/movable/screen/lobby/button/collapse/proc/disable_blip() + SIGNAL_HANDLER + blip_enabled = FALSE + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(enable_blip)) + update_appearance(UPDATE_ICON) + +///Enables the ready blip; makes us listen for the setup completion and game start to disable the blip +/atom/movable/screen/lobby/button/collapse/proc/enable_blip() + SIGNAL_HANDLER + blip_enabled = TRUE + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(disable_blip)) + update_appearance(UPDATE_ICON) + ///Moves the button to the top of the screen, leaving only the screen part in view ///Sends a signal on the hud for the menu hud elements to listen to /atom/movable/screen/lobby/button/collapse/proc/collapse_menu() @@ -424,12 +576,14 @@ animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) //then pull the button up with the shutter and leave it on the edge of the screen animate(transform = transform.Translate(x = 0, y = 134), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + SEND_SOUND(hud.mymob, sound('sound/misc/menu/menu_rollup1.ogg')) ///Extends the button back to its usual spot ///Sends a signal on the hud for the menu hud elements to listen to /atom/movable/screen/lobby/button/collapse/proc/expand_menu() SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_EXPANDED) animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + SEND_SOUND(hud.mymob, sound('sound/misc/menu/menu_rolldown1.ogg')) /atom/movable/screen/lobby/shutter icon = 'icons/hud/lobby/shutter.dmi' @@ -450,5 +604,22 @@ //pull the shutter back off-screen animate(transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) +/// LOCALHOST ONLY - Start Now button +/atom/movable/screen/lobby/button/start_now + name = "Start Now (LOCALHOST ONLY)" + screen_loc = "TOP:-146,CENTER:-54" + icon = 'icons/hud/lobby/start_now.dmi' + icon_state = "start_now" + base_icon_state = "start_now" + always_available = FALSE + select_sound_play = FALSE + +/atom/movable/screen/lobby/button/start_now/Click(location, control, params) + . = ..() + if(!. || !usr.client.is_localhost() || !check_rights_for(usr.client, R_SERVER)) + return + SEND_SOUND(hud.mymob, sound('sound/effects/splat.ogg', volume = 50)) + SSticker.start_immediately = TRUE + #undef SHUTTER_MOVEMENT_DURATION #undef SHUTTER_WAIT_DURATION diff --git a/code/_onclick/hud/plane_master_controller.dm b/code/_onclick/hud/plane_master_controller.dm index e27bd3bc55..c2ec1417b2 100644 --- a/code/_onclick/hud/plane_master_controller.dm +++ b/code/_onclick/hud/plane_master_controller.dm @@ -5,8 +5,11 @@ ///hud that owns this controller var/datum/hud/owner_hud + +INITIALIZE_IMMEDIATE(/atom/movable/plane_master_controller) + ///Ensures that all the planes are correctly in the controlled_planes list. -/atom/movable/plane_master_controller/New(hud) +/atom/movable/plane_master_controller/Initialize(mapload, datum/hud/hud) . = ..() owner_hud = hud var/assoc_controlled_planes = list() diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm index e7f7c664ad..b5fa494c94 100644 --- a/code/_onclick/hud/radial_persistent.dm +++ b/code/_onclick/hud/radial_persistent.dm @@ -7,8 +7,8 @@ icon_state = "radial_center" /atom/movable/screen/radial/persistent/center/Click(location, control, params) - if(usr.client == parent.current_user) - parent.element_chosen(null,usr) + if(usr == get_mob()) + parent.element_chosen(null, usr) /atom/movable/screen/radial/persistent/center/MouseEntered(location, control, params) . = ..() diff --git a/code/_onclick/hud/revenanthud.dm b/code/_onclick/hud/revenanthud.dm index 708b1d4915..a98ef60a1a 100644 --- a/code/_onclick/hud/revenanthud.dm +++ b/code/_onclick/hud/revenanthud.dm @@ -2,6 +2,5 @@ /datum/hud/revenant/New(mob/owner) ..() - healths = new /atom/movable/screen/healths/revenant() - healths.hud = src + healths = new /atom/movable/screen/healths/revenant(null, src) infodisplay += healths diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 58b52dea49..54987d541e 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -78,64 +78,56 @@ var/mob/living/silicon/robot/robit = mymob var/atom/movable/screen/using - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_borg_language_menu static_inventory += using //Radio - using = new /atom/movable/screen/robot/radio() + using = new /atom/movable/screen/robot/radio(null, src) using.screen_loc = ui_borg_radio - using.hud = src static_inventory += using //Module select if(!robit.inv1) - robit.inv1 = new /atom/movable/screen/robot/module1() + robit.inv1 = new /atom/movable/screen/robot/module1(null, src) robit.inv1.screen_loc = ui_inv1 - robit.inv1.hud = src static_inventory += robit.inv1 if(!robit.inv2) - robit.inv2 = new /atom/movable/screen/robot/module2() + robit.inv2 = new /atom/movable/screen/robot/module2(null, src) robit.inv2.screen_loc = ui_inv2 - robit.inv2.hud = src static_inventory += robit.inv2 if(!robit.inv3) - robit.inv3 = new /atom/movable/screen/robot/module3() + robit.inv3 = new /atom/movable/screen/robot/module3(null, src) robit.inv3.screen_loc = ui_inv3 - robit.inv3.hud = src static_inventory += robit.inv3 //End of module select - using = new /atom/movable/screen/robot/lamp() + using = new /atom/movable/screen/robot/lamp(null, src) using.screen_loc = ui_borg_lamp - using.hud = src static_inventory += using robit.lampButton = using var/atom/movable/screen/robot/lamp/lampscreen = using lampscreen.robot = robit //Photography stuff - using = new /atom/movable/screen/ai/image_take() + using = new /atom/movable/screen/ai/image_take(null, src) using.screen_loc = ui_borg_camera - using.hud = src static_inventory += using //Sec/Med HUDs - using = new /atom/movable/screen/robot/sensors() + using = new /atom/movable/screen/robot/sensors(null, src) using.screen_loc = ui_borg_sensor - using.hud = src static_inventory += using //Borg Integrated Tablet - using = new /atom/movable/screen/robot/modPC() + using = new /atom/movable/screen/robot/modPC(null, src) using.screen_loc = ui_borg_tablet - using.hud = src static_inventory += using robit.interfaceButton = using if(robit.modularInterface) @@ -144,64 +136,54 @@ tabletbutton.robot = robit //Alerts - using = new /atom/movable/screen/robot/alerts() + using = new /atom/movable/screen/robot/alerts(null, src) using.screen_loc = ui_borg_alerts - using.hud = src static_inventory += using //Thrusters - using = new /atom/movable/screen/robot/thrusters() + using = new /atom/movable/screen/robot/thrusters(null, src) using.screen_loc = ui_borg_thrusters - using.hud = src static_inventory += using robit.thruster_button = using //PDA message - using = new /atom/movable/screen/robot/pda_msg_send + using = new /atom/movable/screen/robot/pda_msg_send(null, src) using.screen_loc = ui_borg_pda_send - using.hud = src static_inventory += using //PDA log - using = new /atom/movable/screen/robot/pda_msg_show + using = new /atom/movable/screen/robot/pda_msg_show(null, src) using.screen_loc = ui_borg_pda_log - using.hud = src static_inventory += using //Intent - action_intent = new /atom/movable/screen/act_intent/robot() + action_intent = new /atom/movable/screen/act_intent/robot(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent assert_move_intent_ui(owner, TRUE) //Health - healths = new /atom/movable/screen/healths/robot() - healths.hud = src + healths = new /atom/movable/screen/healths/robot(null, src) infodisplay += healths //Installed Module - robit.hands = new /atom/movable/screen/robot/module() + robit.hands = new /atom/movable/screen/robot/module(null, src) robit.hands.screen_loc = ui_borg_module - robit.hands.hud = src static_inventory += robit.hands //Store - module_store_icon = new /atom/movable/screen/robot/store() + module_store_icon = new /atom/movable/screen/robot/store(null, src) module_store_icon.screen_loc = ui_borg_store - module_store_icon.hud = src - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = 'icons/mob/screen_cyborg.dmi' pull_icon.screen_loc = ui_borg_pull - pull_icon.hud = src pull_icon.update_icon() hotkeybuttons += pull_icon - zone_select = new /atom/movable/screen/zone_sel/robot() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/robot(null, src) zone_select.update_icon() static_inventory += zone_select @@ -222,7 +204,6 @@ using = new /atom/movable/screen/mov_intent using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' using.screen_loc = ui_borg_movi - using.hud = src using.update_icon() static_inventory += using if(!on_new) @@ -236,7 +217,6 @@ using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' using.icon_state = owner.cansprint ? ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint") : "act_sprint_locked" using.screen_loc = ui_borg_movi - using.hud = src static_inventory += using if(!on_new) owner?.client?.screen += using diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 8e3dd1ccce..27d846f8fb 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -17,7 +17,7 @@ /// A reference to the object in the slot. Grabs or items, generally. var/obj/master = null /// A reference to the owner HUD, if any. - var/datum/hud/hud = null + VAR_PRIVATE/datum/hud/hud = null /** * Map name assigned to this object. * Automatically set by /client/proc/add_obj_to_map. @@ -31,12 +31,36 @@ * But for now, this works. */ var/del_on_map_removal = TRUE + /// If FALSE, this will not be cleared when calling /client/clear_screen() + // var/clear_with_screen = TRUE // Unimplemented + /// If TRUE, clicking the screen element will fall through and perform a default "Click" call + /// Obviously this requires your Click override, if any, to call parent on their own. + /// This is set to FALSE to default to dissade you from doing this. + /// Generally we don't want default Click stuff, which results in bugs like using Telekinesis on a screen element + /// or trying to point your gun at your screen. + var/default_click = FALSE + +/atom/movable/screen/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(isnull(hud_owner)) //some screens set their hud owners on /new, this prevents overriding them with null post atoms init + return + set_new_hud(hud_owner) /atom/movable/screen/Destroy() master = null hud = null return ..() +/atom/movable/screen/Click(location, control, params) + if(flags_1 & INITIALIZED_1) + SEND_SIGNAL(src, COMSIG_SCREEN_ELEMENT_CLICK, location, control, params, usr) + if(default_click) + return ..() + +///Screen elements are always on top of the players screen and don't move so yes they are adjacent +/atom/movable/screen/Adjacent(atom/neighbor, atom/target, atom/movable/mover) + return TRUE + /atom/movable/screen/examine(mob/user) return list() @@ -46,6 +70,25 @@ /atom/movable/screen/proc/component_click(atom/movable/screen/component_button/component, params) return +///setter used to set our new hud +/atom/movable/screen/proc/set_new_hud(datum/hud/hud_owner) + if(hud) + UnregisterSignal(hud, COMSIG_PARENT_QDELETING) + if(isnull(hud_owner)) + hud = null + return + hud = hud_owner + RegisterSignal(hud, COMSIG_PARENT_QDELETING, PROC_REF(on_hud_delete)) + +/// Returns the mob this is being displayed to, if any +/atom/movable/screen/proc/get_mob() + return hud?.mymob + +/atom/movable/screen/proc/on_hud_delete(datum/source) + SIGNAL_HANDLER + + set_new_hud(hud_owner = null) + /atom/movable/screen/text icon = null icon_state = null @@ -112,7 +155,6 @@ mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/language_menu/Click() - usr.get_language_holder().open_language_menu(usr) /atom/movable/screen/inventory @@ -614,7 +656,9 @@ plane = SPLASHSCREEN_PLANE var/client/holder -/atom/movable/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE, except its not easy +INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) + +/atom/movable/screen/splash/Initialize(mapload, datum/hud/hud_owner, client/C, visible, use_previous_title) . = ..() if(!istype(C)) return @@ -629,8 +673,7 @@ icon = SStitle.icon else if(!SStitle.previous_icon) - qdel(src) - return + return INITIALIZE_HINT_QDEL icon = SStitle.previous_icon holder.screen += src diff --git a/code/_onclick/hud/simple_animal.dm b/code/_onclick/hud/simple_animal.dm index 2f7902c965..3549bc38fb 100644 --- a/code/_onclick/hud/simple_animal.dm +++ b/code/_onclick/hud/simple_animal.dm @@ -1,15 +1,14 @@ /datum/hud/living/simple_animal ui_style = 'icons/mob/screen_gen.dmi' + /datum/hud/living/simple_animal/New(mob/living/owner) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style pull_icon.update_icon() pull_icon.screen_loc = ui_living_pull - pull_icon.hud = src static_inventory += pull_icon //mob health doll! assumes whatever sprite the mob is - healthdoll = new /atom/movable/screen/healthdoll/living() - healthdoll.hud = src + healthdoll = new /atom/movable/screen/healthdoll/living(null, src) infodisplay += healthdoll diff --git a/code/_onclick/hud/swarmer.dm b/code/_onclick/hud/swarmer.dm index 6aba23fab5..ca0cbc458a 100644 --- a/code/_onclick/hud/swarmer.dm +++ b/code/_onclick/hud/swarmer.dm @@ -67,32 +67,26 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/swarmer/FabricateTrap() + using = new /atom/movable/screen/swarmer/FabricateTrap(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/Barricade() + using = new /atom/movable/screen/swarmer/Barricade(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/Replicate() + using = new /atom/movable/screen/swarmer/Replicate(null, src) using.screen_loc = ui_zonesel - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/RepairSelf() + using = new /atom/movable/screen/swarmer/RepairSelf(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/ToggleLight() + using = new /atom/movable/screen/swarmer/ToggleLight(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/ContactSwarmers() + using = new /atom/movable/screen/swarmer/ContactSwarmers(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using diff --git a/code/controllers/subsystem/processing/station.dm b/code/controllers/subsystem/processing/station.dm index f812ea8c4a..c4cdfb11b4 100644 --- a/code/controllers/subsystem/processing/station.dm +++ b/code/controllers/subsystem/processing/station.dm @@ -77,8 +77,17 @@ PROCESSING_SUBSYSTEM_DEF(station) var/datum/station_trait/trait_instance = new trait_type() can_fire = can_fire || trait_instance.trait_processes station_traits += trait_instance + log_game("Station Trait: [trait_instance.name] chosen for this round.") if(!trait_instance.blacklist) return for(var/i in trait_instance.blacklist) var/datum/station_trait/trait_to_remove = i selectable_traits_by_types[initial(trait_to_remove.trait_type)] -= trait_to_remove + +/// Update station trait lobby buttons for clients who joined before we initialised this subsystem +/datum/controller/subsystem/processing/station/proc/display_lobby_traits() + for (var/mob/dead/new_player/player as anything in GLOB.new_player_list) + var/datum/hud/new_player/observer_hud = player.hud_used + if (!istype(observer_hud)) + continue + observer_hud.show_station_trait_buttons() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 9e4ca0a6c0..859eea4cd9 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -161,7 +161,7 @@ SUBSYSTEM_DEF(ticker) start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. - to_chat(world, "Welcome to [station_name()]!") + to_chat(world, span_boldnotice("Welcome to [station_name()]!")) send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game)) current_state = GAME_STATE_PREGAME SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) @@ -424,7 +424,7 @@ SUBSYSTEM_DEF(ticker) if (living.client.prefs && living.client.prefs.auto_ooc) if (living.client.prefs.chat_toggles & CHAT_OOC) living.client.prefs.chat_toggles ^= CHAT_OOC - var/atom/movable/screen/splash/S = new(living.client, TRUE) + var/atom/movable/screen/splash/S = new(null, living.client, TRUE) S.Fade(TRUE) living.client.init_verbs() livings += living diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 1dbfb1540c..f307139406 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -60,7 +60,7 @@ SUBSYSTEM_DEF(title) for(var/thing in GLOB.clients) if(!thing) continue - var/atom/movable/screen/splash/S = new(thing, FALSE) + var/atom/movable/screen/splash/S = new(null, thing, FALSE) S.Fade(FALSE,FALSE) /datum/controller/subsystem/title/Recover() diff --git a/code/datums/action.dm b/code/datums/action.dm index e1e84c8f51..77d6b78917 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -948,20 +948,6 @@ icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "jetboot" -/datum/action/language_menu - name = "Language Menu" - desc = "Open the language menu to review your languages, their keys, and select your default language." - button_icon_state = "language_menu" - check_flags = 0 - -/datum/action/language_menu/Trigger() - if(!..()) - return FALSE - if(ismob(owner)) - var/mob/M = owner - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) - /datum/action/item_action/wheelys name = "Toggle Wheely-Heel's Wheels" desc = "Pops out or in your wheely-heel's wheels." diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index f5a46eb140..ec57e4b6c0 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -28,13 +28,13 @@ lose_text = "You suddenly remember how languages work." /datum/brain_trauma/severe/aphasia/on_gain() - owner.add_blocked_language(subtypesof(/datum/language/) - /datum/language/aphasia, LANGUAGE_APHASIA) - owner.grant_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA) + owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/aphasia, LANGUAGE_APHASIA) + owner.grant_language(/datum/language/aphasia, source = LANGUAGE_APHASIA) ..() /datum/brain_trauma/severe/aphasia/on_lose() - owner.remove_blocked_language(subtypesof(/datum/language/), LANGUAGE_APHASIA) - owner.remove_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA) + owner.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_APHASIA) + owner.remove_language(/datum/language/aphasia, LANGUAGE_APHASIA) ..() /datum/brain_trauma/severe/blindness diff --git a/code/datums/components/combat_mode.dm b/code/datums/components/combat_mode.dm index 6fd2b2e4a7..a71ac3799a 100644 --- a/code/datums/components/combat_mode.dm +++ b/code/datums/components/combat_mode.dm @@ -40,8 +40,7 @@ /// Creates the hud screen object. /datum/component/combat_mode/proc/on_mob_hud_created(mob/source) - hud_icon = new - hud_icon.hud = source.hud_used + hud_icon = new(null, source.hud_used) hud_icon.icon = tg_ui_icon_to_cit_ui(source.hud_used.ui_style) hud_icon.screen_loc = hud_loc source.hud_used.static_inventory += hud_icon diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index d32caeaea9..99ad2b4ede 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -4,11 +4,11 @@ /datum/component/personal_crafting/proc/create_mob_button(mob/user) var/datum/hud/H = user.hud_used - var/atom/movable/screen/craft/C = new() + var/atom/movable/screen/craft/C = new(null, H) C.icon = H.ui_style H.static_inventory += C user.client.screen += C - RegisterSignal(C, COMSIG_CLICK, PROC_REF(component_ui_interact)) + RegisterSignal(C, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) /datum/component/personal_crafting var/busy diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index e28e108677..06c114ca55 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -298,10 +298,10 @@ /datum/component/mood/proc/modify_hud(datum/source) var/mob/living/owner = parent var/datum/hud/hud = owner.hud_used - screen_obj = new + screen_obj = new(null, hud) hud.infodisplay += screen_obj RegisterSignal(hud, COMSIG_PARENT_QDELETING, PROC_REF(unmodify_hud)) - RegisterSignal(screen_obj, COMSIG_CLICK, PROC_REF(hud_click)) + RegisterSignal(screen_obj, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(hud_click)) /datum/component/mood/proc/unmodify_hud(datum/source) if(!screen_obj || !parent) diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 9fa6ed5cc8..6cf3847ddc 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -63,7 +63,7 @@ Bonus if(scramble_language && !current_language) // Last part prevents rerolling language with small amounts of cure. current_language = pick(subtypesof(/datum/language) - /datum/language/common) H.add_blocked_language(subtypesof(/datum/language) - current_language, LANGUAGE_VOICECHANGE) - H.grant_language(current_language, TRUE, TRUE, LANGUAGE_VOICECHANGE) + H.grant_language(current_language, source = LANGUAGE_VOICECHANGE) /datum/symptom/voice_change/End(datum/disease/advance/A) ..() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index ebec1017f7..cd1499935a 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -409,9 +409,7 @@ if(H.additional_language && H.additional_language != "None") var/language_entry = GLOB.roundstart_languages[H.additional_language] if(language_entry) - grant_language(language_entry, TRUE, TRUE) - - update_atom_languages() + grant_language(language_entry) /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) ..() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c05d04ede8..89429f2824 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -64,7 +64,6 @@ var/isholy = FALSE //is this person a chaplain or admin role allowed to use bibles var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems) - var/datum/language_holder/language_holder var/unconvertable = FALSE var/late_joiner = FALSE ///has this mind ever been an AI @@ -96,7 +95,6 @@ /datum/mind/Destroy() SSticker.minds -= src QDEL_LIST(antag_datums) - QDEL_NULL(language_holder) QDEL_NULL(skill_holder) set_current(null) soulOwner = null @@ -118,12 +116,6 @@ /datum/mind/proc/set_original_character(new_original_character) original_character = WEAKREF(new_original_character) -/datum/mind/proc/get_language_holder() - if(!language_holder) - language_holder = new (src) - - return language_holder - /datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) var/old_character = current var/signals = SEND_SIGNAL(new_character, COMSIG_MOB_PRE_PLAYER_CHANGE, new_character, old_character) | SEND_SIGNAL(src, COMSIG_PRE_MIND_TRANSFER, new_character, old_character) @@ -145,7 +137,19 @@ var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list var/mob/living/old_current = current if(current) - current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one + //transfer anyone observing the old character to the new one + current.transfer_observers_to(new_character) + + // Offload all mind languages from the old holder to a temp one + var/datum/language_holder/empty/temp_holder = new() + var/datum/language_holder/old_holder = old_current.get_language_holder() + var/datum/language_holder/new_holder = new_character.get_language_holder() + // Off load mind languages to the temp holder momentarily + new_holder.transfer_mind_languages(temp_holder) + // Transfer the old holder's mind languages to the new holder + old_holder.transfer_mind_languages(new_holder) + // And finally transfer the temp holder's mind languages back to the old holder + temp_holder.transfer_mind_languages(old_holder) set_current(new_character) //associate ourself with our new body new_character.mind = src //and associate our new body with ourself for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body @@ -162,7 +166,6 @@ if(new_character.client) LAZYCLEARLIST(new_character.client.recent_examines) new_character.client.init_verbs() // re-initialize character specific verbs - current.update_atom_languages() //CIT CHANGE - makes arousal update when transfering bodies if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 0eeb387a77..4559f39b00 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -277,10 +277,10 @@ /datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner) ..() - owner.grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER) + owner.grant_language(/datum/language/beachbum, source = LANGUAGE_STONER) owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) /datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) ..() - owner.remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER) + owner.remove_language(/datum/language/beachbum, source = LANGUAGE_STONER) owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm index cb0de6afd4..6c7abcd7bf 100644 --- a/code/datums/station_traits/_station_trait.dm +++ b/code/datums/station_traits/_station_trait.dm @@ -1,3 +1,6 @@ +/// Station traits displayed in the lobby +GLOBAL_LIST_EMPTY(lobby_station_traits) + ///Base class of station traits. These are used to influence rounds in one way or the other by influencing the levers of the station. /datum/station_trait ///Name of the trait @@ -22,26 +25,30 @@ var/trait_flags /// Whether or not this trait can be reverted by an admin var/can_revert = TRUE + /// If set to true we'll show a button on the lobby to notify people about this trait + var/sign_up_button = FALSE + /// Lobby buttons controlled by this trait + var/list/lobby_buttons = list() /datum/station_trait/New() . = ..() RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, PROC_REF(on_round_start)) + if(sign_up_button) + GLOB.lobby_station_traits += src + if(SSstation.initialized) + SSstation.display_lobby_traits() if(trait_processes) START_PROCESSING(SSstation, src) if(trait_to_give) ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT) /datum/station_trait/Destroy() + destroy_lobby_buttons() SSstation.station_traits -= src return ..() -/// Proc ran when round starts. Use this for roundstart effects. -/datum/station_trait/proc/on_round_start() - SIGNAL_HANDLER - return - ///type of info the centcom report has on this trait, if any. /datum/station_trait/proc/get_report() return "[name] - [report_message]" @@ -55,3 +62,50 @@ REMOVE_TRAIT(SSstation, trait_to_give, STATION_TRAIT) qdel(src) + +/// Return TRUE if we want to show a lobby button, by default we assume we don't want it after the round begins +/datum/station_trait/proc/can_display_lobby_button(client/player) + return sign_up_button && !SSticker.HasRoundStarted() + +/// Apply any additional handling we need to our lobby button +/datum/station_trait/proc/setup_lobby_button(atom/movable/screen/lobby/button/sign_up/lobby_button) + SHOULD_CALL_PARENT(TRUE) + lobby_button.name = name + lobby_buttons |= lobby_button + RegisterSignal(lobby_button, COMSIG_ATOM_UPDATE_ICON, PROC_REF(on_lobby_button_update_icon)) + RegisterSignal(lobby_button, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(on_lobby_button_click)) + RegisterSignal(lobby_button, COMSIG_PARENT_QDELETING, PROC_REF(on_lobby_button_destroyed)) + lobby_button.update_appearance(UPDATE_ICON) + +/// Called when our lobby button is clicked on +/datum/station_trait/proc/on_lobby_button_click(atom/movable/screen/lobby/button/sign_up/lobby_button, location, control, params, mob/dead/new_player/user) + SIGNAL_HANDLER + return + +/// Called when our lobby button tries to update its appearance +/datum/station_trait/proc/on_lobby_button_update_icon(atom/movable/screen/lobby/button/sign_up/lobby_button, updates) + SIGNAL_HANDLER + return + +/// Don't hold references to deleted buttons +/datum/station_trait/proc/on_lobby_button_destroyed(atom/movable/screen/lobby/button/sign_up/lobby_button) + SIGNAL_HANDLER + lobby_buttons -= lobby_button + +/// Proc ran when round starts. Use this for roundstart effects. By default we clean up our buttons here. +/datum/station_trait/proc/on_round_start() + SIGNAL_HANDLER + destroy_lobby_buttons() + +/// Remove all of our active lobby buttons +/datum/station_trait/proc/destroy_lobby_buttons() + for (var/atom/movable/screen/button as anything in lobby_buttons) + var/mob/dead/new_player/hud_owner = button.get_mob() + if (QDELETED(hud_owner)) + qdel(button) + continue + var/datum/hud/new_player/using_hud = hud_owner.hud_used + if(!using_hud) + qdel(button) + continue + using_hud.remove_station_trait_button(src) diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm index 09be52d700..528d9a5893 100644 --- a/code/datums/station_traits/negative_traits.dm +++ b/code/datums/station_traits/negative_traits.dm @@ -152,9 +152,7 @@ . = ..() //All bots that exist round start have their set language randomized. for(var/mob/living/simple_animal/bot/found_bot in GLOB.alive_mob_list) - /// The bot's language holder - so we can randomize and change their language - var/datum/language_holder/bot_languages = found_bot.get_language_holder() - bot_languages.selected_language = bot_languages.get_random_spoken_language() + found_bot.set_active_language(found_bot.get_random_spoken_language()) /datum/station_trait/revenge_of_pun_pun name = "Revenge of Pun Pun" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 5bd653556c..789de2ef37 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -975,14 +975,16 @@ /atom/movable/screen/alert/status_effect/strandling/Click(location, control, params) . = ..() - if(usr != owner) + if(!.) return to_chat(owner, "You attempt to remove the durathread strand from around your neck.") - if(do_after(owner, 3.5 SECONDS, owner)) - if(isliving(owner)) - var/mob/living/L = owner - to_chat(owner, "You successfully remove the durathread strand.") - L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) + if(!do_after(owner, 3.5 SECONDS, owner)) + return + if(!isliving(owner)) + return + var/mob/living/L = owner + to_chat(owner, "You successfully remove the durathread strand.") + L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) /datum/status_effect/pacify diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index f8a51d2ad2..12bc58d70f 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -105,6 +105,9 @@ clickable_glow = TRUE /atom/movable/screen/alert/status_effect/wound/Click() + . = ..() + if(!.) + return var/mob/living/carbon/C = usr C.check_self_for_injuries() diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 154b735c02..62803206d4 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -124,7 +124,7 @@ for(var/mob/dead/observer/O in GLOB.player_list) if(O.key == expected_key) if(O.client?.address == addr) - new /atom/movable/screen/splash(O.client, TRUE) + new /atom/movable/screen/splash(null, O.client, TRUE) break /datum/world_topic/adminmsg diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b672d79024..df751a114a 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -12,8 +12,11 @@ var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported var/throw_range = 7 var/mob/pulledby = null + /// What language holder type to init as var/initial_language_holder = /datum/language_holder - var/datum/language_holder/language_holder // Mindless mobs and objects need language too, some times. Mind holder takes prescedence. + /// Holds all languages this mob can speak and understand + VAR_PRIVATE/datum/language_holder/language_holder + var/verb_say = "says" var/verb_ask = "asks" var/verb_exclaim = "exclaims" @@ -657,44 +660,36 @@ return language_holder /// Grants the supplied language and sets omnitongue true. -/atom/movable/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.grant_language(language, understood, spoken, source) +/atom/movable/proc/grant_language(language, language_flags = ALL, source = LANGUAGE_ATOM) + return get_language_holder().grant_language(language, language_flags, source) /// Grants every language. -/atom/movable/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND) - var/datum/language_holder/LH = get_language_holder() - return LH.grant_all_languages(understood, spoken, grant_omnitongue, source) +/atom/movable/proc/grant_all_languages(language_flags = ALL, grant_omnitongue = TRUE, source = LANGUAGE_MIND) + return get_language_holder().grant_all_languages(language_flags, grant_omnitongue, source) /// Removes a single language. -/atom/movable/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_language(language, understood, spoken, source) +/atom/movable/proc/remove_language(language, language_flags = ALL, source = LANGUAGE_ALL) + return get_language_holder().remove_language(language, language_flags, source) /// Removes every language and sets omnitongue false. /atom/movable/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_all_languages(source, remove_omnitongue) + return get_language_holder().remove_all_languages(source, remove_omnitongue) /// Adds a language to the blocked language list. Use this over remove_language in cases where you will give languages back later. /atom/movable/proc/add_blocked_language(language, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.add_blocked_language(language, source) + return get_language_holder().add_blocked_language(language, source) /// Removes a language from the blocked language list. /atom/movable/proc/remove_blocked_language(language, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_blocked_language(language, source) + return get_language_holder().remove_blocked_language(language, source) /// Checks if atom has the language. If spoken is true, only checks if atom can speak the language. -/atom/movable/proc/has_language(language, spoken = FALSE) - var/datum/language_holder/LH = get_language_holder() - return LH.has_language(language, spoken) +/atom/movable/proc/has_language(language, flags_to_check) + return get_language_holder().has_language(language, flags_to_check) /// Checks if atom can speak the language. /atom/movable/proc/can_speak_language(language) - var/datum/language_holder/LH = get_language_holder() - return LH.can_speak_language(language) + return get_language_holder().can_speak_language(language) /// Returns the result of tongue specific limitations on spoken languages. /atom/movable/proc/could_speak_language(language) @@ -702,33 +697,32 @@ /// Returns selected language, if it can be spoken, or finds, sets and returns a new selected language if possible. /atom/movable/proc/get_selected_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_selected_language() + return get_language_holder().get_selected_language() /// Gets a random understood language, useful for hallucinations and such. /atom/movable/proc/get_random_understood_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_random_understood_language() + return get_language_holder().get_random_understood_language() /// Gets a random spoken language, useful for forced speech and such. /atom/movable/proc/get_random_spoken_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_random_spoken_language() + return get_language_holder().get_random_spoken_language() /// Copies all languages into the supplied atom/language holder. Source should be overridden when you /// do not want the language overwritten by later atom updates or want to avoid blocked languages. -/atom/movable/proc/copy_languages(from_holder, source_override) - if(isatom(from_holder)) +/atom/movable/proc/copy_languages(datum/language_holder/from_holder, source_override) + if(ismovable(from_holder)) var/atom/movable/thing = from_holder from_holder = thing.get_language_holder() - var/datum/language_holder/LH = get_language_holder() - return LH.copy_languages(from_holder, source_override) -/// Empties out the atom specific languages and updates them according to the current atoms language holder. -/// As a side effect, it also creates missing language holders in the process. -/atom/movable/proc/update_atom_languages() - var/datum/language_holder/LH = get_language_holder() - return LH.update_atom_languages(src) + return get_language_holder().copy_languages(from_holder, source_override) + +/// Sets the passed path as the active language +/// Returns the currently selected language if successful, if the language was not valid, returns null +/atom/movable/proc/set_active_language(language_path) + var/datum/language_holder/our_holder = get_language_holder() + our_holder.selected_language = language_path + + return our_holder.get_selected_language() // verifies its validity, returns it if successful. /// Sets the vocal bark for the atom, using the bark's ID /atom/movable/proc/set_bark(id) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index e4be50e19c..d20f3e4803 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -94,7 +94,7 @@ M.setDir(dir) buckled_mobs |= M M.update_mobility() - M.throw_alert("buckled", /atom/movable/screen/alert/restrained/buckled) + M.throw_alert("buckled", /atom/movable/screen/alert/buckled) post_buckle_mob(M) SEND_SIGNAL(src, COMSIG_MOVABLE_BUCKLE, M, force) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 5e533888f9..573d6b7d95 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -220,8 +220,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) name = "department_sec" icon_state = "Security Officer" -/obj/effect/landmark/start/depsec/New() - ..() +/obj/effect/landmark/start/depsec/Initialize(mapload) + . = ..() GLOB.department_security_spawns += src /obj/effect/landmark/start/depsec/Destroy() @@ -246,7 +246,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "wiznerd_spawn" /obj/effect/landmark/start/wizard/Initialize(mapload) - ..() + . = ..() GLOB.wizardstart += loc return INITIALIZE_HINT_QDEL @@ -256,7 +256,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "snukeop_spawn" /obj/effect/landmark/start/nukeop/Initialize(mapload) - ..() + . = ..() GLOB.nukeop_start += loc return INITIALIZE_HINT_QDEL @@ -266,7 +266,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "snukeop_leader_spawn" /obj/effect/landmark/start/nukeop_leader/Initialize(mapload) - ..() + . = ..() GLOB.nukeop_leader_start += loc return INITIALIZE_HINT_QDEL @@ -278,7 +278,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) name = "New Player" /obj/effect/landmark/start/new_player/Initialize(mapload) - ..() + . = ..() GLOB.newplayer_start += loc return INITIALIZE_HINT_QDEL @@ -308,7 +308,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) name = "JoinLate" /obj/effect/landmark/latejoin/Initialize(mapload) - ..() + . = ..() SSjob.latejoin_trackers += loc return INITIALIZE_HINT_QDEL @@ -333,7 +333,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "xeno_spawn" /obj/effect/landmark/xeno_spawn/Initialize(mapload) - ..() + . = ..() GLOB.xeno_spawn += loc return INITIALIZE_HINT_QDEL @@ -343,7 +343,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "blob_start" /obj/effect/landmark/blobstart/Initialize(mapload) - ..() + . = ..() GLOB.blobstart += loc return INITIALIZE_HINT_QDEL @@ -352,7 +352,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "secequipment" /obj/effect/landmark/secequipment/Initialize(mapload) - ..() + . = ..() GLOB.secequipment += loc return INITIALIZE_HINT_QDEL @@ -361,7 +361,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "prisonwarp" /obj/effect/landmark/prisonwarp/Initialize(mapload) - ..() + . = ..() GLOB.prisonwarp += loc return INITIALIZE_HINT_QDEL @@ -370,7 +370,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "ert_spawn" /obj/effect/landmark/ert_spawn/Initialize(mapload) - ..() + . = ..() GLOB.emergencyresponseteamspawn += loc return INITIALIZE_HINT_QDEL @@ -379,7 +379,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "holding_facility" /obj/effect/landmark/holding_facility/Initialize(mapload) - ..() + . = ..() GLOB.holdingfacility += loc return INITIALIZE_HINT_QDEL @@ -388,7 +388,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_observer" /obj/effect/landmark/thunderdome/observe/Initialize(mapload) - ..() + . = ..() GLOB.tdomeobserve += loc return INITIALIZE_HINT_QDEL @@ -397,7 +397,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_t1" /obj/effect/landmark/thunderdome/one/Initialize(mapload) - ..() + . = ..() GLOB.tdome1 += loc return INITIALIZE_HINT_QDEL @@ -406,7 +406,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_t2" /obj/effect/landmark/thunderdome/two/Initialize(mapload) - ..() + . = ..() GLOB.tdome2 += loc return INITIALIZE_HINT_QDEL @@ -415,7 +415,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_admin" /obj/effect/landmark/thunderdome/admin/Initialize(mapload) - ..() + . = ..() GLOB.tdomeadmin += loc return INITIALIZE_HINT_QDEL @@ -426,7 +426,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) layer = MOB_LAYER /obj/effect/landmark/servant_of_ratvar/Initialize(mapload) - ..() + . = ..() GLOB.servant_spawns += loc return INITIALIZE_HINT_QDEL @@ -436,7 +436,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "city_of_cogs" /obj/effect/landmark/city_of_cogs/Initialize(mapload) - ..() + . = ..() GLOB.city_of_cogs_spawns += loc return INITIALIZE_HINT_QDEL @@ -448,7 +448,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/event_spawn/New() - ..() + . = ..() GLOB.generic_event_spawns += src /obj/effect/landmark/event_spawn/Destroy() @@ -458,9 +458,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/ruin var/datum/map_template/ruin/ruin_template -/obj/effect/landmark/ruin/New(loc, my_ruin_template) +/obj/effect/landmark/ruin/Initialize(mapload, my_ruin_template) + . = ..() name = "ruin_[GLOB.ruin_landmarks.len + 1]" - ..(loc) ruin_template = my_ruin_template GLOB.ruin_landmarks |= src @@ -475,8 +475,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) layer = BULLET_HOLE_LAYER plane = ABOVE_WALL_PLANE -/obj/effect/landmark/stationroom/New() - ..() +/obj/effect/landmark/stationroom/Initialize(mapload) + . = ..() GLOB.stationroom_landmarks += src /obj/effect/landmark/stationroom/Destroy() @@ -514,7 +514,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) templates = list("Engine SM" = 3, "Engine Singulo" = 3, "Engine Tesla" = 3) icon = 'icons/rooms/box/engine.dmi' -/obj/effect/landmark/stationroom/box/engine/New() +/obj/effect/landmark/stationroom/box/engine/Initialize(mapload) . = ..() templates = CONFIG_GET(keyed_list/box_random_engine) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 3f64be4729..5db6aead98 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -399,8 +399,8 @@ var/emp_cur_charges = 4 var/charge_tick = 0 -/obj/item/flashlight/emp/New() - ..() +/obj/item/flashlight/emp/Initialize(mapload) + . = ..() START_PROCESSING(SSobj, src) /obj/item/flashlight/emp/Destroy() diff --git a/code/game/objects/items/documents.dm b/code/game/objects/items/documents.dm index 1172b50377..9976848bdf 100644 --- a/code/game/objects/items/documents.dm +++ b/code/game/objects/items/documents.dm @@ -37,8 +37,8 @@ var/forgedseal = 0 var/copy_type = null -/obj/item/documents/photocopy/New(loc, obj/item/documents/copy=null) - ..() +/obj/item/documents/photocopy/Initialize(mapload, obj/item/documents/copy=null) + . = ..() if(copy) copy_type = copy.type if(istype(copy, /obj/item/documents/photocopy)) // Copy Of A Copy Of A Copy diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index bac3851837..7a80ae2aca 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -522,7 +522,6 @@ S.ckey = C.ckey S.status_flags |= GODMODE S.copy_languages(user, LANGUAGE_MASTER) //Make sure the sword can understand and communicate with the user. - S.update_atom_languages() grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE) START_PROCESSING(SSprocessing,src) diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index ec7db22cf0..280922364d 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -17,8 +17,8 @@ var/fuel_added = 0 var/flame_expiry_timer -/obj/structure/fireplace/New() - ..() +/obj/structure/fireplace/Initialize(mapload) + . = ..() START_PROCESSING(SSobj, src) /obj/structure/fireplace/Destroy() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 1752009506..c8fea2de4a 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -32,7 +32,7 @@ new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere? new_spawn.socks = "Nude" new_spawn.update_body(TRUE) - new_spawn.language_holder.selected_language = /datum/language/sylvan + new_spawn.set_active_language(/datum/language/sylvan) //Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers. diff --git a/code/game/objects/structures/industrial_lift.dm b/code/game/objects/structures/industrial_lift.dm index 9f04d1b710..cff9e8e2a1 100644 --- a/code/game/objects/structures/industrial_lift.dm +++ b/code/game/objects/structures/industrial_lift.dm @@ -154,12 +154,9 @@ GLOBAL_LIST_EMPTY(lifts) var/list/atom/movable/lift_load //things to move var/datum/lift_master/lift_master_datum //control from -/obj/structure/industrial_lift/New() - GLOB.lifts.Add(src) - ..() - /obj/structure/industrial_lift/Initialize(mapload) . = ..() + GLOB.lifts.Add(src) RegisterSignal(src, COMSIG_MOVABLE_CROSSED, PROC_REF(AddItemOnLift)) RegisterSignal(loc, COMSIG_ATOM_CREATED, PROC_REF(AddItemOnLift))//For atoms created on platform RegisterSignal(src, COMSIG_MOVABLE_UNCROSSED, PROC_REF(RemoveItemFromLift)) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index ffb48ce633..1acfc16962 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -118,23 +118,23 @@ var/list/races_blacklist = list("skeleton", "agent", "military_synth", "memezombies", "clockwork golem servant", "android", "synth", "mush", "zombie", "memezombie") var/list/choosable_races = list() -/obj/structure/mirror/magic/New() +/obj/structure/mirror/magic/Initialize(mapload) + . = ..() if(!choosable_races.len) for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() if(!(S.id in races_blacklist)) choosable_races += S.id - ..() -/obj/structure/mirror/magic/lesser/New() +/obj/structure/mirror/magic/lesser/Initialize(mapload) choosable_races = GLOB.roundstart_races.Copy() - ..() + return ..() -/obj/structure/mirror/magic/badmin/New() +/obj/structure/mirror/magic/badmin/Initialize(mapload) for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() choosable_races += S.id - ..() + return ..() /obj/structure/mirror/magic/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!ishuman(user)) diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index be87c97759..0e7515b273 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -15,8 +15,8 @@ var/enter_delay = 0 var/const/time_to_unwrench = 2 SECONDS -/obj/structure/transit_tube/New(loc, newdirection) - ..(loc) +/obj/structure/transit_tube/Initialize(mapload, newdirection) + . = ..() if(newdirection) setDir(newdirection) init_tube_dirs() diff --git a/code/game/sound.dm b/code/game/sound.dm index a99d9aeaa9..9412f4f788 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -232,6 +232,10 @@ distance_multiplier - Can be used to multiply the distance at which the sound is /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. +///get_rand_frequency but lower range. +/proc/get_rand_frequency_low_range() + return rand(38000, 45000) + /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c1bf537dd8..90573b44a0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2081,8 +2081,7 @@ if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") return - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) + M.get_language_holder().open_language_menu(usr) else if(href_list["traitor"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 4aba4fda00..cb568beb52 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -135,9 +135,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /obj/effect/statclick/ticket_list var/current_state -/obj/effect/statclick/ticket_list/New(loc, name, state) +/obj/effect/statclick/ticket_list/Initialize(mapload, name, state) + . = ..() current_state = state - ..() /obj/effect/statclick/ticket_list/Click() GLOB.ahelp_tickets.BrowseTickets(current_state) diff --git a/code/modules/antagonists/abductor/equipment/glands/slime.dm b/code/modules/antagonists/abductor/equipment/glands/slime.dm index 36732d5fe0..f98bb403bc 100644 --- a/code/modules/antagonists/abductor/equipment/glands/slime.dm +++ b/code/modules/antagonists/abductor/equipment/glands/slime.dm @@ -10,12 +10,12 @@ /obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE) ..() owner.faction |= "slime" - owner.grant_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND) + owner.grant_language(/datum/language/slime, source = LANGUAGE_GLAND) /obj/item/organ/heart/gland/slime/Remove(mob/living/carbon/M, special = 0) ..() owner.faction -= "slime" - owner.remove_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND) + owner.remove_language(/datum/language/slime, source = LANGUAGE_GLAND) /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseated!") diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm index 56ebb8fd87..46c4e260e3 100644 --- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm +++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm @@ -210,7 +210,7 @@ // Physiology CheckVampOrgans() // Heart, Eyes // Language - owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER) + owner.current.grant_language(/datum/language/vampiric, source = LANGUAGE_BLOODSUCKER) owner.hasSoul = FALSE // If false, renders the character unable to sell their soul. owner.isholy = FALSE // is this person a chaplain or admin role allowed to use bibles // Disabilities diff --git a/code/modules/antagonists/bloodsucker/datum_vassal.dm b/code/modules/antagonists/bloodsucker/datum_vassal.dm index 9a2e3a1ae6..3275f251a5 100644 --- a/code/modules/antagonists/bloodsucker/datum_vassal.dm +++ b/code/modules/antagonists/bloodsucker/datum_vassal.dm @@ -48,7 +48,7 @@ objectives += vassal_objective objectives_given += vassal_objective give_thrall_eyes() - owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL) + owner.current.grant_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) // Add Antag HUD update_vassal_icons_added(owner.current, "vassal") . = ..() diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 5a6a6af90b..0ed599c824 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -84,7 +84,7 @@ create_initial_profile() if(give_objectives) forge_objectives() - owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all. + owner.current.get_language_holder().omnitongue = TRUE remove_clownmut() . = ..() diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index ed2982f861..f052afc4b4 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -96,7 +96,7 @@ current = mob_override GLOB.all_clockwork_mobs += current current.faction |= "ratvar" - current.grant_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE) + current.grant_language(/datum/language/ratvar, source = LANGUAGE_CLOCKIE) current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons if(issilicon(current)) var/mob/living/silicon/S = current diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 63b82f26ce..fe9f8cbe04 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -121,7 +121,7 @@ if(mob_override) current = mob_override current.faction |= "cult" - current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) + current.grant_language(/datum/language/narsie, source = LANGUAGE_CULTIST) if(!cult_team?.cult_master) vote.Grant(current) communion.Grant(current) @@ -139,7 +139,7 @@ if(mob_override) current = mob_override current.faction -= "cult" - current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) + current.remove_language(/datum/language/narsie, source = LANGUAGE_CULTIST) vote.Remove(current) communion.Remove(current) magic.Remove(current) diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index a8e57ee08b..7f45c5099c 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -182,9 +182,8 @@ add_antag_hud(antag_hud_type, antag_hud_name, M) if(M.hud_used) var/datum/hud/H = M.hud_used - var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted(null, H) H.wanted_lvl = giving_wanted_lvl - giving_wanted_lvl.hud = H H.infodisplay += giving_wanted_lvl H.mymob.client.screen += giving_wanted_lvl diff --git a/code/modules/antagonists/gang/gang.dm b/code/modules/antagonists/gang/gang.dm index e41c7b1228..058379d96c 100644 --- a/code/modules/antagonists/gang/gang.dm +++ b/code/modules/antagonists/gang/gang.dm @@ -113,9 +113,8 @@ add_antag_hud(antag_hud_type, antag_hud_name, M) if(M.hud_used) var/datum/hud/H = M.hud_used - var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted(null, H) H.wanted_lvl = giving_wanted_lvl - giving_wanted_lvl.hud = H H.infodisplay += giving_wanted_lvl H.mymob.client.screen += giving_wanted_lvl diff --git a/code/modules/antagonists/traitor/classes/ai.dm b/code/modules/antagonists/traitor/classes/ai.dm index 0c1709ee53..8992c9ea17 100644 --- a/code/modules/antagonists/traitor/classes/ai.dm +++ b/code/modules/antagonists/traitor/classes/ai.dm @@ -65,5 +65,5 @@ /datum/traitor_class/ai/finalize_traitor(datum/antagonist/traitor/T) T.add_law_zero() T.owner.current.playsound_local(get_turf(T.owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE) - T.owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF) + T.owner.current.grant_language(/datum/language/codespeak, source = LANGUAGE_MALF) return FALSE diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 99e69e1fa1..4eab67ea34 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -41,13 +41,13 @@ var/spawn_amt_left = 20 var/spawn_fast = 0 -/obj/effect/rend/New(loc, var/spawn_type, var/spawn_amt, var/desc, var/spawn_fast) +/obj/effect/rend/Initialize(mapload, spawn_type, spawn_amt, desc, spawn_fast) + . = ..() src.spawn_path = spawn_type src.spawn_amt_left = spawn_amt src.desc = desc src.spawn_fast = spawn_fast START_PROCESSING(SSobj, src) - return /obj/effect/rend/process() if(!spawn_fast) diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index fe9770e64a..cff5260463 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -287,9 +287,7 @@ S.real_name = "Shade of [T.real_name]" T.transfer_ckey(S) S.original_mind = T.mind - S.copy_languages(T, LANGUAGE_MIND)//Copies the old mobs languages into the new mob holder. - S.update_atom_languages() - grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue + S.get_language_holder().omnitongue = TRUE //Grants omnitongue if(user) S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation if(user && iscultist(user)) diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index 0318e06abe..9c6a533646 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -186,6 +186,6 @@ GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) appearance_flags = TILE_BOUND vis_flags = NONE -/obj/effect/overlay/gas/New(state) +/obj/effect/overlay/gas/Initialize(mapload, state) . = ..() icon_state = state diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 4eb836dab5..aab2d1ec1a 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -169,6 +169,15 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( to_chat(src, "Become a BYOND member to access member-perks and features, as well as support the engine that makes this game possible. Only 10 bucks for 3 months! Click Here to find out more.") return FALSE return TRUE + +/client/proc/is_localhost() + var/static/localhost_addresses = list( + "127.0.0.1", + "::1", + null, + ) + return address in localhost_addresses + /* * Call back proc that should be checked in all paths where a client can send messages * diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 2f1234f46d..f38721671c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -3487,7 +3487,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/language_entry = GLOB.roundstart_languages[additional_language] if(language_entry) character.additional_language = language_entry - character.grant_language(language_entry, TRUE, TRUE) + character.grant_language(language_entry) character.set_bark(bark_id) character.vocal_speed = bark_speed diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 8cccaba68b..d3a9172b96 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -55,7 +55,7 @@ SG.transfer_ckey(SA, FALSE) - SA.grant_all_languages(TRUE, FALSE, FALSE) + SA.grant_all_languages(UNDERSTOOD_LANGUAGE, grant_omnitongue = FALSE, source = LANGUAGE_ATOM) SA.sentience_act() diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm index 6b5707d76f..a4dbb20c5c 100644 --- a/code/modules/jobs/job_types/curator.dm +++ b/code/modules/jobs/job_types/curator.dm @@ -50,4 +50,5 @@ if(visualsOnly) return - H.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_CURATOR) + H.grant_all_languages(source = LANGUAGE_CURATOR) + H.remove_blocked_language(GLOB.all_languages, source=LANGUAGE_ALL) diff --git a/code/modules/language/codespeak.dm b/code/modules/language/codespeak.dm index 5d658b1fce..a051422726 100644 --- a/code/modules/language/codespeak.dm +++ b/code/modules/language/codespeak.dm @@ -46,7 +46,7 @@ return to_chat(user, "You start skimming through [src], and suddenly your mind is filled with codewords and responses.") - user.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND) + user.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) use_charge(user) @@ -65,7 +65,7 @@ M.visible_message("[user] beats [M] over the head with [src]!", "[user] beats you over the head with [src]!", "You hear smacking.") else M.visible_message("[user] teaches [M] by beating [M.p_them()] over the head with [src]!", "As [user] hits you with [src], codewords and responses flow through your mind.", "You hear smacking.") - M.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND) + M.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) use_charge(user) /obj/item/codespeak_manual/proc/use_charge(mob/user) diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm index 2ad1bb762b..1c08540e31 100644 --- a/code/modules/language/language_holder.dm +++ b/code/modules/language/language_holder.dm @@ -1,23 +1,28 @@ -/*!Language holders will either exist in an atom/movable or a mind. Creation of language holders happens +/*!Language holders will either exist in an atom/movable. Creation of language holders happens automatically when they are needed, for example when something tries to speak. Where a mind is available, the mind language holder will be the one "in charge". The mind holder will update its languages based on the atom holder, and will get updated as part of transformations and other events that cause new languages to become available. + Every language holder has three lists of languages (and sources for each of them): - understood_languages - spoken_languages - blocked_languages + Understood languages let you understand them, spoken languages lets you speak them (if your tongue is compatible), and blocked languages will let you do neither no matter what the source of the language is. + Language holders are designed to mostly only ever require the use the helpers in atom/movable to achieve your goals, but it is also possible to work on them directly if needed. Any adding and removing of languages and sources should only happen through the procs, as directly changing these will mess something up somewhere down the line. + All atom movables have the initial_language_holder var which allows you to set the default language holder to create. For example, /datum/language_holder/alien will give you xenocommon and a block for galactic common. Human species also have a default language holder var that will be updated on species change, initial_species_holder. + Key procs * [grant_language](atom/movable.html#proc/grant_language) * [remove_language](atom/movable.html#proc/remove_language) @@ -28,83 +33,86 @@ Key procs * [has_language](atom/movable.html#proc/has_language) * [can_speak_language](atom/movable.html#proc/can_speak_language) * [get_selected_language](atom/movable.html#proc/get_selected_language) -* [update_atom_languages](atom/movable.html#proc/update_atom_languages) */ /datum/language_holder - /// Understood languages. - var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_MIND)) - /// A list of languages that can be spoken. Tongue organ may also set limits beyond this list. + /// Lazyassoclist of all understood languages + var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + /// Lazyassoclist of languages that can be spoken. + /// Tongue organ may also set limits beyond this list. var/list/spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) - /// A list of blocked languages. Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. - var/list/blocked_languages = list() - /// If true, overrides tongue limitations. + /// Lazyassoclist of blocked languages. + /// Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. + var/list/blocked_languages + /// If true, overrides tongue aforementioned limitations. var/omnitongue = FALSE /// Handles displaying the language menu UI. var/datum/language_menu/language_menu /// Currently spoken language var/selected_language /// Tracks the entity that owns the holder. - var/owner + var/atom/movable/owner /// Initializes, and copies in the languages from the current atom if available. -/datum/language_holder/New(_owner) - owner = _owner - if(istype(owner, /datum/mind)) - var/datum/mind/M = owner - if(M.current) - update_atom_languages(M.current) - get_selected_language() +/datum/language_holder/New(atom/new_owner) + if(new_owner) + if(QDELETED(new_owner)) + CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(new_owner)]") + if(!ismovable(new_owner)) + CRASH("Language holder being added to a non-movable thing, this is invalid (was: [new_owner] / [new_owner.type])") + + owner = new_owner + + // If we have an owner, we'll set a default selected language + if(owner) + get_selected_language() /datum/language_holder/Destroy() QDEL_NULL(language_menu) + owner = null return ..() /// Grants the supplied language. -/datum/language_holder/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_MIND) - if(understood) - if(!understood_languages[language]) - understood_languages[language] = list() - understood_languages[language] |= source +/datum/language_holder/proc/grant_language(language, language_flags = ALL, source = LANGUAGE_MIND) + if(language_flags & UNDERSTOOD_LANGUAGE) + LAZYORASSOCLIST(understood_languages, language, source) . = TRUE - if(spoken) - if(!spoken_languages[language]) - spoken_languages[language] = list() - spoken_languages[language] |= source + if(language_flags & SPOKEN_LANGUAGE) + LAZYORASSOCLIST(spoken_languages, language, source) . = TRUE + return . + /// Grants every language to understood and spoken, and gives omnitongue. -/datum/language_holder/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND) +/datum/language_holder/proc/grant_all_languages(language_flags = ALL, grant_omnitongue = TRUE, source = LANGUAGE_MIND) for(var/language in GLOB.all_languages) - grant_language(language, understood, spoken, source) - if(grant_omnitongue) // Overrides tongue limitations. + grant_language(language, language_flags, source) + if(grant_omnitongue) // Overrides tongue limitations. omnitongue = TRUE return TRUE /// Removes a single language or source, removing all sources returns the pre-removal state of the language. -/datum/language_holder/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL) - if(understood && understood_languages[language]) +/datum/language_holder/proc/remove_language(language, language_flags = ALL, source = LANGUAGE_ALL) + if(language_flags & UNDERSTOOD_LANGUAGE) if(source == LANGUAGE_ALL) - understood_languages -= language + LAZYREMOVE(understood_languages, language) else - understood_languages[language] -= source - if(!length(understood_languages[language])) - understood_languages -= language + LAZYREMOVEASSOC(understood_languages, language, source) . = TRUE - if(spoken && spoken_languages[language]) + if(language_flags & SPOKEN_LANGUAGE) if(source == LANGUAGE_ALL) - spoken_languages -= language + LAZYREMOVE(spoken_languages, language) else - spoken_languages[language] -= source - if(!length(spoken_languages[language])) - spoken_languages -= language + LAZYREMOVEASSOC(spoken_languages, language, source) . = TRUE + return . + /// Removes every language and optionally sets omnitongue false. If a non default source is supplied, only removes that source. /datum/language_holder/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE) for(var/language in GLOB.all_languages) - remove_language(language, TRUE, TRUE, source) + remove_language(language, ALL, source) if(remove_omnitongue) omnitongue = FALSE return TRUE @@ -113,41 +121,41 @@ Key procs /datum/language_holder/proc/add_blocked_language(languages, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) + for(var/language in languages) - if(!blocked_languages[language]) - blocked_languages[language] = list() - blocked_languages[language] |= source + LAZYORASSOCLIST(blocked_languages, language, source) return TRUE /// Removes a single language or list of languages from the blocked language list. /datum/language_holder/proc/remove_blocked_language(languages, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) + for(var/language in languages) - if(blocked_languages[language]) - if(source == LANGUAGE_ALL) - blocked_languages -= language - else - blocked_languages[language] -= source - if(!length(blocked_languages[language])) - blocked_languages -= language + if(source == LANGUAGE_ALL) + LAZYREMOVE(blocked_languages, language) + else + LAZYREMOVEASSOC(blocked_languages, language, source) + return TRUE -/// Checks if you have the language. If spoken is true, only checks if you can speak the language. -/datum/language_holder/proc/has_language(language, spoken = FALSE) +/// Checks if you have the language passed. +/datum/language_holder/proc/has_language(language, flag_to_check = UNDERSTOOD_LANGUAGE) if(language in blocked_languages) return FALSE - if(spoken) - return language in spoken_languages - return language in understood_languages + + var/list/langs_to_check = list() + if(flag_to_check & SPOKEN_LANGUAGE) + langs_to_check |= spoken_languages + if(flag_to_check & UNDERSTOOD_LANGUAGE) + langs_to_check |= understood_languages + + return language in langs_to_check /// Checks if you can speak the language. Tongue limitations should be supplied as an argument. /datum/language_holder/proc/can_speak_language(language) - var/atom/movable/ouratom = get_atom() - var/tongue = ouratom.could_speak_language(language) - if((omnitongue || tongue) && has_language(language, TRUE)) - return TRUE - return FALSE + var/can_speak_language_path = omnitongue || owner.could_speak_language(language) + return (can_speak_language_path && has_language(language, SPOKEN_LANGUAGE)) /// Returns selected language if it can be spoken, or decides, sets and returns a new selected language if possible. /datum/language_holder/proc/get_selected_language() @@ -172,59 +180,79 @@ Key procs /datum/language_holder/proc/get_random_spoken_language() return pick(spoken_languages) +/// Gets a random spoken language, trying to get a non-common language. +/datum/language_holder/proc/get_random_spoken_uncommon_language() + var/list/languages_minus_common = assoc_to_keys(spoken_languages) - /datum/language/common + + // They have a language other than common + if(length(languages_minus_common)) + return pick(languages_minus_common) + + // They can only speak common, oh well. + else + return /datum/language/common + /// Opens a language menu reading from the language holder. /datum/language_holder/proc/open_language_menu(mob/user) if(!language_menu) language_menu = new (src) language_menu.ui_interact(user) -/// Gets the atom, since we some times need to check if the tongue has limitations. -/datum/language_holder/proc/get_atom() - if(owner) - if(istype(owner, /datum/mind)) - var/datum/mind/M = owner - return M.current - return owner - return FALSE - -/// Empties out the atom specific languages and updates them according to the supplied atoms language holder. -/datum/language_holder/proc/update_atom_languages(atom/movable/thing) - var/datum/language_holder/from_atom = thing.get_language_holder(FALSE) //Gets the atoms language holder - if(from_atom == src) //This could happen if called on an atom without a mind. - return FALSE - for(var/language in understood_languages) - remove_language(language, TRUE, FALSE, LANGUAGE_ATOM) - for(var/language in spoken_languages) - remove_language(language, FALSE, TRUE, LANGUAGE_ATOM) - for(var/language in blocked_languages) - remove_blocked_language(language, LANGUAGE_ATOM) - - copy_languages(from_atom) - get_selected_language() - return TRUE - /// Copies all languages from the supplied atom/language holder. Source should be overridden when you /// do not want the language overwritten by later atom updates or want to avoid blocked languages. -/datum/language_holder/proc/copy_languages(var/datum/language_holder/from_holder, source_override) - if(source_override) //No blocked languages here, for now only used by ling absorb. +/datum/language_holder/proc/copy_languages(datum/language_holder/from_holder, source_override) + if(source_override) //No blocked languages here, for now only used by ling absorb. for(var/language in from_holder.understood_languages) - grant_language(language, TRUE, FALSE, source_override) + grant_language(language, UNDERSTOOD_LANGUAGE, source_override) for(var/language in from_holder.spoken_languages) - grant_language(language, FALSE, TRUE, source_override) + grant_language(language, SPOKEN_LANGUAGE, source_override) else for(var/language in from_holder.understood_languages) - grant_language(language, TRUE, FALSE, from_holder.understood_languages[language]) + grant_language(language, UNDERSTOOD_LANGUAGE, from_holder.understood_languages[language]) for(var/language in from_holder.spoken_languages) - grant_language(language, FALSE, TRUE, from_holder.spoken_languages[language]) + grant_language(language, SPOKEN_LANGUAGE, from_holder.spoken_languages[language]) for(var/language in from_holder.blocked_languages) add_blocked_language(language, from_holder.blocked_languages[language]) return TRUE +/// Transfers all mind languages to the supplied language holder. +/datum/language_holder/proc/transfer_mind_languages(datum/language_holder/to_holder) + for(var/language in understood_languages) + if(LANGUAGE_MIND in understood_languages[language]) + remove_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) + to_holder.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) + for(var/language in spoken_languages) + if(LANGUAGE_MIND in spoken_languages[language]) + remove_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + to_holder.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + for(var/language in blocked_languages) + if(LANGUAGE_MIND in blocked_languages[language]) + remove_blocked_language(language, LANGUAGE_MIND) + to_holder.add_blocked_language(language, LANGUAGE_MIND) -//************************************************ -//* Specific language holders * -//* Use atom language sources only. * -//************************************************/ + if(owner) + get_selected_language() + if(to_holder.owner) + to_holder.get_selected_language() + +/// A global assoc list containing prototypes of all language holders +/// [Language holder typepath] to [language holder instance] +/// Used for easy reference of what can speak what without needing to constantly recreate language holders. +GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) + +/// Inits the global list of language holder prototypes. +/proc/init_language_holder_prototypes() + var/list/prototypes = list() + for(var/holdertype in typesof(/datum/language_holder)) + prototypes[holdertype] = new holdertype() + + return prototypes + +/* + * Specific language holders presets + * + * Prefer to use [LANGUGAE_ATOM]. Atom languages will stick through species changes but not mindswaps. + */ /datum/language_holder/alien @@ -252,6 +280,10 @@ Key procs /datum/language_holder/drone/syndicate blocked_languages = null +/datum/language_holder/human_basic + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + /datum/language_holder/dwarf understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), /datum/language/dwarf = list(LANGUAGE_ATOM)) @@ -339,8 +371,12 @@ Key procs /datum/language/arachnid = list(LANGUAGE_ATOM)) /datum/language_holder/empty - understood_languages = list() - spoken_languages = list() + understood_languages = null + spoken_languages = null + +/datum/language_holder/universal + understood_languages = null + spoken_languages = null /datum/language_holder/universal/New() ..() diff --git a/code/modules/language/language_menu.dm b/code/modules/language/language_menu.dm index bffd3d59af..0bfb7a7997 100644 --- a/code/modules/language/language_menu.dm +++ b/code/modules/language/language_menu.dm @@ -20,109 +20,108 @@ /datum/language_menu/ui_data(mob/user) var/list/data = list() - var/atom/movable/AM = language_holder.get_atom() - if(isliving(AM)) - data["is_living"] = TRUE - else - data["is_living"] = FALSE - + var/atom/movable/speaker = language_holder.owner + data["is_living"] = isliving(speaker) data["languages"] = list() - for(var/lang in GLOB.all_languages) - var/result = language_holder.has_language(lang) || language_holder.has_language(lang, TRUE) + for(var/datum/language/language as anything in GLOB.all_languages) + var/result = language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE) if(!result) continue - var/datum/language/language = lang - var/list/L = list() + var/list/lang_data = list() - L["name"] = initial(language.name) - L["desc"] = initial(language.desc) - L["key"] = initial(language.key) - L["is_default"] = (language == language_holder.selected_language) - if(AM) - L["can_speak"] = AM.can_speak_language(language) - L["can_understand"] = AM.has_language(language) + lang_data["name"] = initial(language.name) + lang_data["desc"] = initial(language.desc) + lang_data["key"] = initial(language.key) + lang_data["is_default"] = (language == language_holder.selected_language) + if(speaker) + lang_data["can_speak"] = speaker.can_speak_language(language) + lang_data["can_understand"] = speaker.has_language(language) - data["languages"] += list(L) + UNTYPED_LIST_ADD(data["languages"], lang_data) - if(check_rights_for(user.client, R_ADMIN) || isobserver(AM)) + if(check_rights_for(user.client, R_ADMIN) || isobserver(speaker)) data["admin_mode"] = TRUE data["omnitongue"] = language_holder.omnitongue - data["unknown_languages"] = list() - for(var/lang in GLOB.all_languages) - if(language_holder.has_language(lang) || language_holder.has_language(lang, TRUE)) + for(var/datum/language/language as anything in GLOB.all_languages) + if(language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE)) continue - var/datum/language/language = lang - var/list/L = list() + var/list/lang_data = list() - L["name"] = initial(language.name) - L["desc"] = initial(language.desc) - L["key"] = initial(language.key) + lang_data["name"] = initial(language.name) + lang_data["desc"] = initial(language.desc) + lang_data["key"] = initial(language.key) + + UNTYPED_LIST_ADD(data["unknown_languages"], lang_data) - data["unknown_languages"] += list(L) return data /datum/language_menu/ui_act(action, params) - if(..()) + . = ..() + if(.) return var/mob/user = usr - var/atom/movable/AM = language_holder.get_atom() - + var/atom/movable/speaker = language_holder.owner + var/is_admin = check_rights_for(user.client, R_ADMIN) var/language_name = params["language_name"] var/datum/language/language_datum - for(var/lang in GLOB.all_languages) - var/datum/language/language = lang + for(var/datum/language/language as anything in GLOB.all_languages) if(language_name == initial(language.name)) language_datum = language - var/is_admin = check_rights_for(user.client, R_ADMIN) switch(action) if("select_default") - if(language_datum && AM.can_speak_language(language_datum)) + if(language_datum && speaker.can_speak_language(language_datum)) language_holder.selected_language = language_datum . = TRUE if("grant_language") - if((is_admin || isobserver(AM)) && language_datum) + if((is_admin || isobserver(speaker)) && language_datum) var/list/choices = list("Only Spoken", "Only Understood", "Both") - var/choice = input(user,"How do you want to add this language?","[language_datum]",null) as null|anything in choices - var/spoken = FALSE - var/understood = FALSE + var/choice = tgui_input_list(user, "How do you want to add this language?", "[language_datum]", choices) + if(isnull(choice)) + return + var/adding_flags = NONE switch(choice) if("Only Spoken") - spoken = TRUE + adding_flags |= SPOKEN_LANGUAGE if("Only Understood") - understood = TRUE + adding_flags |= UNDERSTOOD_LANGUAGE if("Both") - spoken = TRUE - understood = TRUE - language_holder.grant_language(language_datum, understood, spoken) + adding_flags |= ALL + + if(LAZYACCESS(language_holder.blocked_languages, language_datum)) + choice = tgui_alert(user, "Do you want to lift the blockage that's also preventing the language to be spoken or understood?", "[language_datum]", list("Yes", "No")) + if(choice == "Yes") + language_holder.remove_blocked_language(language_datum, LANGUAGE_ALL) + language_holder.grant_language(language_datum, adding_flags) if(is_admin) - message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(AM)].") - log_admin("[key_name(user)] granted the language [language_name] to [key_name(AM)].") + message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(speaker)].") + log_admin("[key_name(user)] granted the language [language_name] to [key_name(speaker)].") . = TRUE if("remove_language") - if((is_admin || isobserver(AM)) && language_datum) + if((is_admin || isobserver(speaker)) && language_datum) var/list/choices = list("Only Spoken", "Only Understood", "Both") - var/choice = input(user,"Which part do you wish to remove?","[language_datum]",null) as null|anything in choices - var/spoken = FALSE - var/understood = FALSE + var/choice = tgui_input_list(user, "Which part do you wish to remove?", "[language_datum]", choices) + if(isnull(choice)) + return + var/removing_flags = NONE switch(choice) if("Only Spoken") - spoken = TRUE + removing_flags |= SPOKEN_LANGUAGE if("Only Understood") - understood = TRUE + removing_flags |= UNDERSTOOD_LANGUAGE if("Both") - spoken = TRUE - understood = TRUE - language_holder.remove_language(language_datum, understood, spoken) + removing_flags |= ALL + + language_holder.remove_language(language_datum, removing_flags) if(is_admin) - message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(AM)].") - log_admin("[key_name(user)] removed the language [language_name] to [key_name(AM)].") + message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(speaker)].") + log_admin("[key_name(user)] removed the language [language_name] to [key_name(speaker)].") . = TRUE if("toggle_omnitongue") - if(is_admin || isobserver(AM)) + if(is_admin || isobserver(speaker)) language_holder.omnitongue = !language_holder.omnitongue if(is_admin) - message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(AM)].") - log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(AM)].") + message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(speaker)].") + log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(speaker)].") . = TRUE diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index efc00159ea..0475b7075a 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -666,6 +666,7 @@ /obj/item/book_of_babel/attack_self(mob/user) to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") user.grant_all_languages() + user.remove_blocked_language(GLOB.all_languages, source = LANGUAGE_ALL) new /obj/effect/decal/cleanable/ash(get_turf(user)) qdel(src) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index b455787e5c..f9631209f2 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -89,20 +89,20 @@ INITIALIZE_IMMEDIATE(/mob/dead) if(alert(src, "Jump to server [pick] ([addr])?", "Server Hop", "Yes", "No") != "Yes") return - var/client/C = client - to_chat(C, "Sending you to [pick].") - new /atom/movable/screen/splash(C) + var/client/hopper = client + to_chat(hopper, "Sending you to [pick].") + new /atom/movable/screen/splash(null, src, hopper, FALSE) mob_transforming = TRUE - sleep(29) //let the animation play + sleep(2.9 SECONDS) //let the animation play mob_transforming = FALSE - if(!C) + if(!hopper) return winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources - C << link("[addr]") + hopper << link("[addr]") /mob/dead/proc/update_z(new_z) // 1+ to register, null to unregister if (registered_z != new_z) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index e40b467a79..2253e81814 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -41,7 +41,3 @@ else postfix = "soon" to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].") - - var/datum/hud/new_player/NH = hud_used - if(istype(NH)) - NH.populate_buttons(src) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 330d9b36db..41f44d357a 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -27,7 +27,7 @@ /mob/dead/new_player/Initialize(mapload) if(client && SSticker.state == GAME_STATE_STARTUP) - var/atom/movable/screen/splash/S = new(client, TRUE, TRUE) + var/atom/movable/screen/splash/S = new(null, null, client, TRUE) S.Fade(TRUE) if(length(GLOB.newplayer_start)) @@ -491,7 +491,7 @@ if(job && !job.override_latejoin_spawn(character)) SSjob.SendToLateJoin(character) if(!arrivals_docked) - var/atom/movable/screen/splash/Spl = new(character.client, TRUE) + var/atom/movable/screen/splash/Spl = new(null, character, character.client, TRUE) Spl.Fade(TRUE) character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 6723d2d4a6..de3601aa20 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -6,6 +6,7 @@ can_buckle = TRUE buckle_lying = FALSE mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + initial_language_holder = /datum/language_holder/empty // We get stuff from our species /// Enable stamina combat combat_flags = COMBAT_FLAGS_STAMINA_COMBAT | COMBAT_FLAG_UNARMED_PARRY status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index e1af109877..e50978e9c0 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -86,8 +86,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!" ///Affects the speech message, for example: Motharula flutters, "My speech message is flutters!" var/say_mod = "says" - ///What languages this species can understand and say. Use a [language holder datum][/datum/language_holder] in this var. - var/species_language_holder = /datum/language_holder + /// What languages this species can understand and say. + /// Use a [language holder datum][/datum/language_holder] typepath in this var. + /// Should never be null. + var/datum/language_holder/species_language_holder = /datum/language_holder/human_basic /** * Visible CURRENT bodyparts that are unique to a species. * DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK @@ -544,6 +546,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/obj/item/bodypart/B in C.bodyparts) B.change_bodypart_status(BODYPART_HYBRID, FALSE, TRUE) // Makes all Bodyparts 'robotic'. + // All languages associated with this language holder are added with source [LANGUAGE_SPECIES] + // rather than source [LANGUAGE_ATOM], so we can track what to remove if our species changes again + var/datum/language_holder/gaining_holder = GLOB.prototype_language_holders[species_language_holder] + for(var/language in gaining_holder.understood_languages) + C.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in gaining_holder.spoken_languages) + C.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in gaining_holder.blocked_languages) + C.add_blocked_language(language, LANGUAGE_SPECIES) + SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) /datum/species/proc/update_species_slowdown(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index ec961da4dd..697e3a257f 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -34,11 +34,11 @@ /mob/living/carbon/human/set_drugginess(amount) ..() if(!amount) - remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + remove_language(/datum/language/beachbum, source = LANGUAGE_HIGH) /mob/living/carbon/human/adjust_drugginess(amount) ..() if(druggy) - grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + grant_language(/datum/language/beachbum, source = LANGUAGE_HIGH) else - remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + remove_language(/datum/language/beachbum, source = LANGUAGE_HIGH) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 35c8303aa1..bb72f6f9c0 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -486,8 +486,3 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced) - -/mob/living/get_language_holder(get_minds = TRUE) - if(get_minds && mind) - return mind.get_language_holder() - . = ..() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 26431ece5f..99c3eda3eb 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -139,13 +139,11 @@ var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light var/datum/action/innate/custom_holoform/custom_holoform = new /datum/action/innate/custom_holoform - var/datum/action/language_menu/ALM = new SW.Grant(src) AS.Grant(src) AC.Grant(src) AR.Grant(src) AL.Grant(src) - ALM.Grant(src) custom_holoform.Grant(src) emitter_next_use = world.time + 10 SECONDS diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index ad7bc79278..38859a7a93 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -268,7 +268,7 @@ encryptmod = TRUE if("translator") if(href_list["toggle"]) //This is permanent. - grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) + grant_all_languages(source = LANGUAGE_SOFTWARE) if("doorjack") if(href_list["jack"]) if(cable && cable.machine) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9f0596d3ea..a47cc1d181 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -24,9 +24,9 @@ robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it. robot_modules_background.plane = HUD_PLANE - inv1 = new /atom/movable/screen/robot/module1() - inv2 = new /atom/movable/screen/robot/module2() - inv3 = new /atom/movable/screen/robot/module3() + inv1 = new /atom/movable/screen/robot/module1(null, src) + inv2 = new /atom/movable/screen/robot/module2(null, src) + inv3 = new /atom/movable/screen/robot/module3(null, src) ident = rand(1, 999) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8109301238..d700de554a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -954,12 +954,11 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) //Do not do parent's actions, as we *usually* do this differently. fully_replace_character_name(real_name, new_name) -/mob/verb/open_language_menu() +/mob/verb/open_language_menu_verb() set name = "Open Language Menu" set category = "IC" - var/datum/language_holder/H = get_language_holder() - H.open_language_menu(usr) + get_language_holder().open_language_menu(usr) ///Adjust the nutrition of a mob /mob/proc/adjust_nutrition(change, max = INFINITY) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 48faeafd48..9352d191dd 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -436,7 +436,6 @@ mind.transfer_to(new_xeno) else transfer_ckey(new_xeno) - update_atom_languages() to_chat(new_xeno, "You are now an alien.") . = new_xeno diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 5d46329462..977d210bc6 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -980,7 +980,6 @@ familiar.copy_languages(owner, LANGUAGE_MASTER) if(linked.saved_mind) linked.saved_mind.transfer_to(familiar) - familiar.update_atom_languages() familiar.ckey = linked.saved_mind.key else if(familiar.mind) diff --git a/code/modules/ruins/spaceruin_code/TheDerelict.dm b/code/modules/ruins/spaceruin_code/TheDerelict.dm index d26e023df0..cae5c53090 100644 --- a/code/modules/ruins/spaceruin_code/TheDerelict.dm +++ b/code/modules/ruins/spaceruin_code/TheDerelict.dm @@ -159,7 +159,7 @@ to_chat(user, "You start skimming through [src], but you already know dronespeak.") else to_chat(user, "You start skimming through [src], and suddenly the drone chittering makes sense.") - user.grant_language(/datum/language/drone, TRUE, TRUE)//, LANGUAGE_MIND) + user.grant_language(/datum/language/drone, source = LANGUAGE_MIND) return if(user.has_language(/datum/language/drone)) @@ -180,7 +180,7 @@ M.visible_message("[user] beats [M] over the head with [src]!", "[user] beats you over the head with [src]!", "You hear smacking.") else M.visible_message("[user] teaches [M] by beating [M.p_them()] over the head with [src]!", "As [user] hits you with [src], chitters resonate in your mind.", "You hear smacking.") - M.grant_language(/datum/language/drone, TRUE, TRUE) //, LANGUAGE_MIND) + M.grant_language(/datum/language/drone, source = LANGUAGE_MIND) return /obj/structure/fluff/oldturret diff --git a/code/modules/tgui/states/language_menu.dm b/code/modules/tgui/states/language_menu.dm index eaaa125786..1786175f05 100644 --- a/code/modules/tgui/states/language_menu.dm +++ b/code/modules/tgui/states/language_menu.dm @@ -14,6 +14,6 @@ GLOBAL_DATUM_INIT(language_menu_state, /datum/ui_state/language_menu, new) if(check_rights_for(user.client, R_ADMIN)) . = UI_INTERACTIVE else if(istype(src_object, /datum/language_menu)) - var/datum/language_menu/LM = src_object - if(LM.language_holder.get_atom() == user) + var/datum/language_menu/my_languages = src_object + if(my_languages.language_holder.owner == user) . = UI_INTERACTIVE diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index c7f69fcaf1..d593f90423 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -67,6 +67,7 @@ // #include "holidays.dm" // #include "hydroponics_harvest.dm" // #include "keybinding_init.dm" +// #include "language_transfer.dm" #include "machine_disassembly.dm" #include "medical_wounds.dm" #include "merge_type.dm" diff --git a/code/modules/unit_tests/language_transfer.dm b/code/modules/unit_tests/language_transfer.dm new file mode 100644 index 0000000000..7e031f3a8b --- /dev/null +++ b/code/modules/unit_tests/language_transfer.dm @@ -0,0 +1,191 @@ +// Dedicated to testing language holders + +/// Simply tests that swapping to a new species gives you the languages of that species and removes the languages of the old species +/datum/unit_test/language_species_swap_simple + +/datum/unit_test/language_species_swap_simple/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + + var/datum/language_holder/holder = dummy.get_language_holder() + + var/list/initial_spoken = holder.spoken_languages.Copy() + var/list/initial_understood = holder.understood_languages.Copy() + + TEST_ASSERT(length(initial_spoken) == 1, \ + "Dummy should only speak one language! Instead, it knew the following: [print_language_list(initial_spoken)]") + TEST_ASSERT(length(initial_understood) == 1, \ + "Dummy should only understand one language! Instead, it knew the following: [print_language_list(initial_understood)]") + + dummy.set_species(/datum/species/lizard) + + TEST_ASSERT(length(holder.spoken_languages) == 2, \ + "Dummy should speak two languages - Common and Draconic! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(holder.understood_languages) == 2, \ + "Dummy should understand two languages - Common and Draconic! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + + dummy.set_species(/datum/species/human) + + TEST_ASSERT(length(initial_spoken & holder.spoken_languages) == 1, \ + "Dummy did not speak Common after returning to human! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(initial_understood & holder.understood_languages) == 1, \ + "Dummy did not understand Common after returning to human! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + +/// Tests species changes which are more complex are functional (e.g. from a species which speaks common to one which does not) +/datum/unit_test/language_species_swap_complex + +/datum/unit_test/language_species_swap_complex/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + + var/datum/language_holder/holder = dummy.get_language_holder() + + dummy.set_species(/datum/species/lizard/silverscale) + + TEST_ASSERT(!dummy.has_language(/datum/language/common, SPOKEN_LANGUAGE), \ + "Changing a mob's species from one which speaks common to one which does not should remove the language!") + + TEST_ASSERT(dummy.has_language(/datum/language/common, UNDERSTOOD_LANGUAGE), \ + "Changing a mob's species from one which understands common another which does should not remove the language!") + + TEST_ASSERT(length(holder.spoken_languages) == 2, \ + "Dummy should speak two languages - Uncommon and Draconic! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(holder.understood_languages) == 3, \ + "Dummy should understand two languages - Common, Uncommon and Draconic! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + +/// Test that other random languages known are not lost on species change +/datum/unit_test/language_species_change_other_known + +/datum/unit_test/language_species_change_other_known/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + dummy.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + dummy.grant_language(/datum/language/draconic, source = LANGUAGE_ATOM) + dummy.set_species(/datum/species/lizard) + + TEST_ASSERT(dummy.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy should still speak Pirate after changing species, as it's a mind language!") + + TEST_ASSERT(dummy.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Pirate after changing species, as it's a mind language!") + + dummy.set_species(/datum/species/human) + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy should still speak Draconic after changing species, as it's an atom language!") + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Draconic after changing species, as it's an atom language!") + +/// Tests that mind bound languages are not lost swapping into a new mob, but other languages are +/datum/unit_test/language_mind_transfer + +/datum/unit_test/language_mind_transfer/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + var/mob/living/basic/pet/dog/corgi/transfer_target = allocate(/mob/living/basic/pet/dog/corgi) + dummy.mind_initialize() + dummy.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + dummy.grant_language(/datum/language/draconic, source = LANGUAGE_ATOM) + dummy.set_species(/datum/species/lizard/silverscale) + + dummy.mind.transfer_to(transfer_target) + + // transfer_target should speak and understand pirate + TEST_ASSERT(!dummy.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy should no longer be speaking Pirate after losing their mind!") + TEST_ASSERT(transfer_target.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy's new mob should be capable of speaking Pirate!") + + TEST_ASSERT(!dummy.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy should no longer be understanding Pirate after losing their mind!") + TEST_ASSERT(transfer_target.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should be capable of understanding Pirate!") + + // transfer_target should NOT speak and understand draconic + TEST_ASSERT(dummy.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy should still understand Draconic after losing their mind - it's an atom language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy's new mob should not understand Draconic - it's an atom language!") + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Draconic after losing their mind - it's an atom language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should not understand Draconic - it's an atom language!") + + // transfer_target should NOT speak and understand uncommon + TEST_ASSERT(dummy.has_language(/datum/language/uncommon, SPOKEN_LANGUAGE), \ + "Dummy should still understand Uncommon after losing their mind - it's a species language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/uncommon, SPOKEN_LANGUAGE), \ + "Dummy's new mob should not understand Uncommon - it's a species language!") + + TEST_ASSERT(dummy.has_language(/datum/language/uncommon, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Uncommon after losing their mind - it's a species language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/uncommon, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should not understand Uncommon - it's a species language!") + +/// Tests that mind bound languages are not lost when swapping with another person (wiz mindswap) +/datum/unit_test/language_mind_swap + +/datum/unit_test/language_mind_swap/Run() + var/mob/living/carbon/human/dummy_A = allocate(/mob/living/carbon/human/consistent) + var/mob/living/carbon/human/dummy_B = allocate(/mob/living/carbon/human/consistent) + + dummy_A.mind_initialize() + dummy_B.mind_initialize() + + var/datum/mind/dummy_A_mind = dummy_A.mind + var/datum/mind/dummy_B_mind = dummy_B.mind + + dummy_A.set_species(/datum/species/lizard) + dummy_B.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + + dummy_A_mind.transfer_to(dummy_B) + dummy_B_mind.transfer_to(dummy_A) + + var/datum/language_holder/holder_A = dummy_A.get_language_holder() + var/datum/language_holder/holder_B = dummy_B.get_language_holder() + + // Holder A is a lizard: starts with 2 languages (common, draconic) + // Holder B is a human with a mind language: starts with 2 language (common, pirate) + // Swap occurs + // Holder A is a lizard with 2 languages, but should now also have pirate: 3 languages (common, draconic, pirate) + // Holder B is a human with just 1 language left over (common) + + TEST_ASSERT_EQUAL(length(holder_A.spoken_languages), 3, \ + "Holder A / Dummy A / Dummy B mind should speak Common, Draconic, and Pirate! \ + Instead, it knew the following: [print_language_list(holder_A.spoken_languages)]") + + TEST_ASSERT_EQUAL(length(holder_A.understood_languages), 3, \ + "Holder A / Dummy A / Dummy B mind should only understand Common, Draconic, and Pirate! \ + Instead, it knew the following: [print_language_list(holder_A.understood_languages)]") + + TEST_ASSERT_EQUAL(length(holder_B.spoken_languages), 1, \ + "Holder B / Dummy B / Dummy A mind should only speak 1 language - Common! \ + Instead, it knew the following: [print_language_list(holder_B.spoken_languages)]") + + TEST_ASSERT_EQUAL(length(holder_B.understood_languages), 1, \ + "Holder B / Dummy B / Dummy A mind only understand 1 language - Common! \ + Instead, it knew the following: [print_language_list(holder_B.understood_languages)]") + +/// Tests that the book of babel, and by extension grant_all_languages, works as intended +/datum/unit_test/book_of_babel + +/datum/unit_test/book_of_babel/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + var/obj/item/book_of_babel/book = allocate(/obj/item/book_of_babel) + var/datum/language_holder/holder = dummy.get_language_holder() + var/expected_amount = length(GLOB.all_languages) + + book.attack_self(dummy) + TEST_ASSERT_EQUAL(length(holder.spoken_languages), expected_amount, "Book of Babel failed to give all languages out!") + dummy.set_species(/datum/species/lizard) + TEST_ASSERT_EQUAL(length(holder.spoken_languages), expected_amount, "Changing species after using the Book of Bable should not remove languages!") + +/// Helper proc to print a list of languages in a human readable format +/proc/print_language_list(list/languages_to_print) + var/list/printed_languages = list() + + for(var/datum/language/language as anything in languages_to_print) + printed_languages += initial(language.name) + + return english_list(printed_languages) diff --git a/icons/hud/lobby/background.dmi b/icons/hud/lobby/background.dmi index 554543ecf3f728d6af47ef9bd33312457d93c537..5fb9085da09439fc11eb24e69b3fb30d1284e011 100644 GIT binary patch delta 346 zcmZ3-vXy1RlX@FZ7srr{#O^O_ALSQE-W+>1XUR_))QvoZWB!;ZC^7q7Up;1SnO z2eu=FhE2O1ce%XE3_?{5LI*m$5q2u6_5A*MD-s!%1w&`TQyQSr#qXsJo-vKHE;aE_{4B0o3!nDFOB?$wdcTQ}90X}r^HwQv_+ ps+qFpu;(AUBF8<+lXT8l%D;6j-v4*O+Byax@O1TaS?83{1OPHdrSAX$ delta 339 zcmdnWvW{iKlX_E67srr{#Ovkn`GuqEi)9a!v9ah|hhLG?=hgsruAn-$G9_BrWI zI9PFN+Tte+mI0qrl8<+BdFpz!{a07W@t!Z5&iQYu@}(^{Ng=Ne-%3gqckf9*w(r!Z zwJ~yrT2sHUSH$(qoSZQ0X7b9Sf3x223gUbun{c3kk(rI>#$to|Kg(I!cq9y7TenI##N2wvk@jomVS&Rwj$fn_d@uiDnPKv$)PD26 zD1*eGW!X$?a&O-)F){m-z4VO9kxz5w`95d+mB(&h{JQPF=F+9|FWMtE{i&D}U;Ovn zu_T{I^OhZY`~7pK`AWP7QI%pQetX}ShQa! zTk%y*?sJ-IGZp&J-i+2}c5?1C68xOyd{Xt4bj@@5#Q|(jQyixXTRp$!U&bq;IeeiaRLErYS_-s$r#~BW;`2TTDE_JXCe72U=3U5{I{(Bro!6Xa!+&o7!M6DI0z2h{YHD8MRvndFx^B&!$p^Ho3-ju?@2-peym^zu zky@6=Is%z72EDA0Enzhe^i~H{`o53+lN8#f7)KOXaChJRsP|s-pA`R_Ln`WKXD-Uf4jgXmgHuGiUsUN zn~F}nE?(uZ{`|{RjO)*zJf*n){7R`pB-J>^N2-_i(+j{z9n9deaJ@@E`MO#F< z!F-_bQ714TD7-O%!$gEhFFl&WZr=f*5|9vv&bD0FG}g(X%xX-Nr#h=Kz2Ch1>BoYW zGtImXto{Lt-TjQhjR%EGPCQEfxVhl8t8m})&p%6eCg#2Qy^(w3?T!DZcF$MxiPWq5 xXOy_}dTT}W&g<$-_cK;I)yb#0obdX@DwWe$`{VxgYrr(l;OXk;vd$@?2>`Uabq)Xk delta 856 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

_G<#P6WYww%+z$VsX5xfGbk`7Ab8(iG;v>S zaAf$tu%La>hSFd^74VPfZoi#C^t2(lqP?PH0)xY4!Akq>?i9Q|#byPG;zV&J+Wf9{ zb0fO{u5}=~dlGGAz;?VR#mS3e1CjduK8AMoGzhSQj&()1bNbV%0H6#2etL#VS$mue zOS6j%4(4V%u0ZXkDY@Ax?Wlk>Y{$O}w0R%`0H6TJK<-rWb0>DM!^JK?zvJhx!TDnusEq1*{OXgKN5x! z7AC;VI?;))W^*N3?pAZc;!{?y4C?#srmgPo*L;e0NG{6Br6L83YJJrH_YBlc<=xzUCOjg4UY$AG5+^ArR z@!b&{G#VQ-8hg|`_k>ULQSasxK4T|*znt(#CI6kj9-aQOl7D?V8UhsRTIM`66zFIO zo>~edlaebXfWQ@!pye`k3^R+J%J#6Ug3mXyDjLIj>Wq8p6n>$AtO8wm8=x>auk8Pq z_ju<7{rB0H)rkRYL0aC8(7YR=NA%RY8)+=_i^81%xTdzA#_f^j4pHWJqpZQ~5KZXH zcD?`6b=AKXVP)9?z!t079--LN;|BEafa9C84ti8hTnLq??(F{7TKku*mmP&cEh2`+`gSS#B=Qms_&prQZ1w(t) zpMh&>*nO_O@LYdhRIiglUg>Y>pz3)UarpzVPW?r`Qir-fh!^}IPp14K9qjAfpZ8pN z1r9BW3)2$Q3zX5Lyh(e{)}MrS3nok1e=v{$r?) zf&}!@Q_@VhcA0k8+UV0tS%uh6!;-c9QzYl|L=R8(4W-cuzrGv|07=TfxcFbiFIN7| z#U+_MOt-=1duBbxD@Emg4~-SpP^4018dgFPY3{reW{qC%W6o{a)aINlpa(ZiZ%8 zhMr5Ep4$WC`yb4=|7AX)MkJfNc_DlU5HW+uATJBwL0r%vHE1|C=wV}!Pt#HF#=iyT zx7bXN#{8S)tcZw?<*8?mnb7}`oI-oiwJKv|=^wL20TpcKhr1 zH`)w<1dS%H{`Um{fYx*cmtXq`+0$g$6F2N>LZ#UJ?~_O=>&Y}DTA#QMM>q010C@u zjUAravqBkg+mi)~)B&Zt5KT8pO&3W}@>Y`5Am9dv+*kWsowW{_+p5{vsu6#;{?AHq zB6Bhn%zqC9PBcJ)44D5t7dT7nCZer5s7e0k>A#qZjDu|dx4CT1-E1jt|MQvt-w6MY z0{<-qR%|>a@DFKMq-`X@*#ZGhKC{h4JH0dK1bDx*KA_>M_Lz>eUX>>^_%G=I73>G| z18c2UmC2=>ueu=9ml*tywF#gPf(;iyWXF|;7q|Y!*Wio1b5$#o8%SbHSPv!z-!}Ib z{nszY0RRp}2H*f{-M0U{Q?a8e0Bp$&^akw<$IKuIzzOoc09t>UK?m3V*Teju*Z!vo zAshn$I4Phb_iOe@oC@%^%`}$x^9I}`4`|rJAuGrdD{r^PTpuZ8U>>LsC`$p4_rrT0 zn3HF=EKpb?a!V-A8U7hW7Jlk58n{B8rDAXoxaFCf{aR>*F_ayC}- zV0AhJXg#3y$(Eeig8~B{Xg`U%BaD0gB9P&3UR2++&*(WXQUnHhWumJa!HN2QsVLC6 zW99u*ZSDpKcVTch_FbL#JY{7Bk*G=@#2hqt12IRX1gyNWauKLWY=0pR$M~-1uGEP@ z?IN*)MD-m#6T}Gy`(3RvmZbcCRxcEZUR|v+>H$Cl>fxCnZ|TP?Pj$us@VFHMpj&0F zx`cJIYuuXO0dS2v9e@k+LYlubwp1ZN)ectV?`r3$9q8$aF)W4IVf4><;vGv%Jk6X< zN^?A=w9jNZm!nHOJq@J*j@B0Nk1l&6xe^L|0Ij`%Z00@77kYNi*ys6Cs@kO}(7Y*! z2dvmQ*_l|-PIh!$`B|P;V4V_Za72SBCE1>KFY}{7`=bCvfdIC@sm%*@ zH&vzlA~ynPeY~<<7dC+8cFHU}cwqx*x3V)!e%It#_x(-%gBSj$ailM}8Y_g-?^#)+ za*+rIJ`I9|Ia-`M(K` zF+#)*Gyv6mLekbdiNC2*uK;mMdbLKKDj+Kdt~#EJeW{n7>FkWKOS3f4Ka<1YiS4*p z+0v3BMkp59XDL%ulFi^5Ha-Ox2&@A?g|Sm!yEL1TYSM^0AF2(mS_oJdu*tartOGwK z#Mt=?SXbMQ3gHtC&ikyihKO;7vr#U!!;FB+hV{j1nJaab4I?_)o@O0zFA&O0GVS<+ z3aG@sU}UM@{<_x71Vj!2c|kXjU*5q08AmQCjc+oX9n~uZ*xGCXZ1qw24eC^+f3e)^ zwVYoIa|QGvLDuV7;jk6H@+?6`foz6OTJgk6WPdf_LGuz^GxdOfH54UfdUk_7RvN(R z^h<|+_b^zogq_R(X(-Lk_WadX_Lqqax}qzVsw&94*`8p(6W|=bZD)`mFmR4v4bGs; z3b&K{-H@FL;+6j008Rvs|91m85jf269w4w{f}dHzT>*ZT9)0=Mi0 z0FYEMQXoFTWlTEB>tQ66cAci}yE z(Wn0YZ`aC!#H#=iKXrEv!e z_~1oo$ug)gJ~RIZp#r66x%o_){66H6=Giw=nXBFio;OGTk$z*NSnv)CiMu0ygXw!YW@d#WB2);0N)?MmEOQM$>6SE{|9xBdzL~c^@DE>VuZKN) z^aw7OleI4i8meEd66&NLD+k2|HD!*Jx-K5eIkU)aefoDlv>&I{9te{+Xjl`0Tc#g(rLJ&O(|DzQ~2G+MIP= zp}A>SH({5A1s-NQL~p|gq~>d=A@~~ePzzfkk)S&wRD-lPv40fcqXUc4W9TX-$+6M%Zz4B_c{R{om*LsxjExs!i#`_* zla23`PHr4Jw#f>1$0rNJ)$c@aNBfBx*!2}U0t~~gD256h5M8a@%*7q5cwX)6_~qcz z?MG+P>&yJ_lM)MmWIj9$q0Gh>PiTi_^!p2vk5Kn*-qxVe&e?~Kd?!O;>kyTdJpxV9 z92MLvMs&Z*jx#|H=?%I_3H5m0?;5@7jXzD?^CTrg5vj0xw>tkTihW`xIlj@!!uV{$ z&mZ+;e(6~ONz8Ei5DDMT>mUt_MAYJOAw$fs6^R&PTE*2Tv(p)0mqvQ>l7HSH%B+{v zQ;9nmx{8woch-6HVcZ6=g-r^Lx|EImBaNYzSav0SSi}J|_RlleU2MUcIsp{}6N#;g<| z;UQ#V2$@foz+e)ejf+)_jhS3=iu2 zK#bkmm3*}D`=xb9k*1wb>>P=q$_-S66uCi1C?I=;k>SxIi5#L`iyi(`?2Gr&aP4L9 zl$a@6(to;w?HkcP?G1r&(^QF9yVVB49yvRNF9SBvA8(h1z z{tEWATw_{G@adyjk8B{R)vMy0rb%|``K~Uo$c{uY zAH}F0U?l4Br1@WOhA&4OXb_7H1n|u9UCx{5T+`O7aE`xNFQ*V~;zFJn6n4e)ov!AT zau=`~Go2mjKcrKX^)}q;9GPN|k1-Uf5Hi9fp@D%vI_WP{l;~{In9cC|Bh(yee=Z#N zdLui|N7#ePx0IJ(xX42VDqM*kF~-y!h96AF&OD%sGnq9Ela5w8#lu4^MfRX7(#=o! znSYzz5M5z_B32@x8QWQ66(7B|7i0fQ9XEynq1rCNOUt$_wLRFkIknl1)2os!{E<=n z8dTMb`i=1yP|_VjI)R^n;~9(?yOFPsFVkz81GIgIoc_F~Q!Lc*k^LM@Axaf{+uG*0 z14pnuA7fjpaB6!OZ{!9YYVjS-OSycc$bYnw)_#A?(U2tnzmHKhKy5q@KI zoXZ8t1+qZ=yN*RP6QCL^E(< zSE9yA5u>XVWf}5CV`vLy*m+}nXV;Yrb|ngtsK8tW$y%mZ6!Y@p)0ByYqrDzEp5FPB zH7_Rl+p}*;S)0TiwBZAi(Vv5_^vnlCQH7V+`6cL%W=g;~FjXbpZjW~40Bj@}Bmt{N zEIQ@2Erd*{q2ah3F@zPdscET_On^2wUbBkp|c*2fx#;aAgge+w-Pta_ze4-5bq?e^4FD*avI%2x2y6fAaG_4-;gMBAM zUAxC>HT4%_J3C4~PQ?2$^Yl$?#vi5@w0ns0#k@mtqcI6cAA%9Gl9l+^2rY)*3X)is z8zV{emqHQhZ_nOqkkFjmC22iDu`o_h`0?R_su#&JCS&TK=SaAKc)QGx+Va%JrWOL(OK=Rc%iOHehw!&N0h+C@skFj1jN z>`5VW0K*(8OlZ4Eb(kzLyS+wM$HJ!uixmJA!)iDx4nSWNW$%EcZ3WV|H@TarYik=g zy1Prap>Q-Jjz=Px>(ClR@VAdztOin)C@RkHp~d8+&zExgaX)YKau5e$nvmV43tw)h z&t85m`xO&*b9J)uMO@RqKxzE8$jC^AHjc26(XJ6vvGbc3lZ=pLDC%$`C)QOIXzsvB zH4{C9zb1uB1e(Mlhm{h{RSk}(H$3vDY?XcBSor;x3~L5Vs51a6cxU$$thI`YqHHqm z&h6V0%EV&X8|0hY*Bn&N>T^dX|&?uG2w@sE$&YnABM8EKDDUbfCetcz6^mj z!!qxGSm+;>-H*^aJmS^unCF*}uK-a_#Ey8lO4cgT={wq(^@ZP~Qj~}RkXst9?1vd& zema^|3zk={BD{}%rP$K;8L6id1rNV8RpSyGj#tHQa0uk!r6mKPLsPU+F+H3SI!&^A zprZMZKl${-x0$rjznYAIBa7XK!|d1Br0>~%CSKf-D3fFvx0HQSFOP3~#W6Rk zY5PG(!9&^X)JF#Fglv?txCmZEx4O*GP<3K&KjZ8}y`)Wq>aTw?8j<5K1} zn$OFPeXS0V==W7GbHmgciCJ?`eFv};>qAr5M~#T(^zf09VG=+h>K0SJ)!fx^m6(`{ zAY89-IB5BC-=CkX?5OoTlgDsL5y@v*YUeCSSX)3b;d(bnSPq~8otTzgW2q1cb@duX zlC=bo3Kqe`yb*<{BnA-EMleXRzthQ6AK#y|d{Za<8KR>EP@cq+JMdlgmM3{al z=np=JANv49JCaDr5SBz63a!$pcW2d(kf(u%+Z^nH z&?nu&LAron)Bf4|Iu)R%X`fhDCj(_^Y{wqrim0}Ds=0+v}{{W{t580=qx2NCX*fQIg#Ar@~0V|9G$9W+) zZ&uwbc+2l#5A2&rmVWFi4#djy<_3M~#54uT zJ5%)yY7Gbzq#|pe@Q!eLz$%0S4XJ$PK_s6U`mS{Oje+j@oBQ6-q&C3iZkjLQA6$RZ zO}zcb{bT9T;msdp(CZE+C=^R5uMSd&khu~gI#$)uU(T%|Q-{$SS}x|mj(gZ z4JKNK;+evR%zzU>pjO=sU&pG_)DYKeJWn3+xTY*=M_r~kGJ22ztr;ldKhP%&$@7(*|XKO^BoeCBscIT=dk z-1+ju>S_(b!)Ru3_a*N@J(C-fNuOf5jn_4*waYT>73a^a4qfFR*OW_AdLc4NF2s9=q;g+A&=)o$G&>^FvYZ7U*M{2c z9tb_}ml@<4IKRl-Gl9-3aN`}}v_U~PUCNIH-MJRAhY)&QB;1>wtx4ORogJ*49o$J)F0O7)+nrpA_D7!ZjyAr~R@_>6 zmykB^a`P0U;WV7G=YY z?g5AbhGC7gNhJhPAriBPOR)?Dz?VRmH_Ce?>2U{2KO9HM9GUCpo!LG z&_lH>rz`XQoEVAoyNt*A&N!l@!gFvWVMB*drH08D@L&S$GED5H%L;AN5KDYcO;SuQ z6tJpBk4IdWIJnp(A2=5aYg9DbFrHgFVK`>dna>Ki8P3l)hDb_QTo?O~m#450Mj}D2 zn5RQi@i6CN?2fdHwFw5!$5M0lJu*IiqjKAO_KMQER=a=K|s z$E>T(Pp=+@QfU*l(-C~(2v@BAIYec^fTWU0I%#*A^2jxW2xU3s@nbY-TaNWhgxXXe z@;35KoIGc!>(f`UYs7ifFK$nFr`SQ8;Odc{uPND%VODYtMzmSbVLF01%p@*WUX&i7 z!>I`pim0KT8@t51vqn(;-A52fCOyG5o+TzRB_-w@)kfn>x12K?hcYrB0Nvtj96lGV zV3rmSF%qf}ZBHWc0~o*xCqhuYukSOV7gOn8H@8Nf`f%q(U*GE2fA;tQf!aM}XSHl7 z6IrKOYL0h8ua!mTqEF(J@emJf?QWiGFK96r4qw z)PXO{;lzFeo`JwXgIwZhSo-W*?eW9sr5&}6Xm!#%an)-4iN|TW1+l}|+|BnTZaNh` zE*9%&CZQGZY4LahwnH#3u!mEJ8PuKKVR7ZvFo7EN{g(C9qM_}rOmm+_< z8bxvQKVK7YMaycdG}UWt{pT zW%Lm9(j#cUliY4jcg+iVxWeqVBxsAAwuJIW`zx!oZ|$?=0??y>ngusP)h(r&rNdBo&56eLnd8OO%m4iZEAIJa$w+c9Mf0KaWNM=f)*80V;CwGtn8_ud{C8!&ABgL4xD^Y6zO_#)7z70 zj<m-2#T_CUQwS((s{b$Sl z7l7tm6%x8OXD)+xMt<$T!Jj8?LH)bxQMrxD;{iBCWrDzqLa5+$NQiFlUSBIAV)83@ zQff%bulAl7P!&W6n!esWDrr8~9ULpJJ&)b&b~Q53H{|u6d-owRJ@*vOIqL0~&<;s! z=ap=FW6U5Ei=B@OL0vdpp=JcUOc!`qPu=Y2aTIy)#=k<+5Ireti~ZwF)?z~|>Fys< ziY+1Ux&B}<55olspONLyLEJ+5e7{aLfsvNqPA^Y0rl-Fwh-bHJozg9k`S_*v(dAM} zg7)r;gWK$~?Z|@k>S613+RjA=%ezkLcXl| z&Ip&1$l7Y%y;Xn@MMb>jkNJDh=qFVN(gGr~JNcoj-|+5kK{}*7>YTC)O47sP=_Vu* zT_u2GJ1pdi2G|tsdQ~Ygy^>DsAM@A)gisd086$n_d9+#~tZi?6JP&@Dsj@OL?aP5&%$3@#KQ?Nw0cql7birL)5L5_^#$G1 zkHk}_6DjqNUIRNnIk&Y+P9+8U`2GWFd0bLe;VjnAB*>;P5CJ6yb#LB`4CR$VavKq1 zj@YXWNwuv!bHe9q%;v};nL&mEcMDW9O)l=h>&A}PcegZt)KYu%ZY+%d@N`7z+~L%5 zg>#^1K4Yq^JjCN-1oR5V_38IT91;W{LcC=-S-+`k@uJUE*Ef$m0ju`9$&n|!J}Gav zdkrJ}l>Z_+c|eu91O2V3(#v(Ww%&(0)j9sd_zk^hy`rG_=n(w&fTopz0FeQ3snO$jRm2bFoB9`ZY?1nUb6xmSA2Bh!=(H7X6^5|rynJE2*GBr$vT#@V z^kx4Sp%BG@bwEl3O0pl8u1Co>GUiBy8uuvOuba{ty&TLWnCCc(t~#a5SU-vVDtUUt zw7u%-PbCv%f!`rURA%lK-o`ftqkKJIa0c2}cUrGxYx@F>A z;3M64YLwil{pvBYwAUnYGlg5z=GTgr+}Otx!4MQ8g-Qr8#aNjG8hisD^NFm~8e&KY z73d0oan0MOw;?CB2*{p zNTpMVR0^L~%)^s$3@vc`qO?2DUH#UzAbvQSQ8454M^uPJ();fkrcmDEA%E+e(hBj+ z8@rB=8{@%{1V=lT$-u(-?Hce}QX-&X0z*od9d8 zRQa%_>*vb$55B&T(0-zEdCJwRIXG5kNKFKdO!H5dEYuNUFn<=c?1#v`?tbM)(JLH03OC z&uqZx2x>7SJe(^LPdurlax0H3mHetdrJadLMbH;K7f1YVVh}E z5qPgW_?%Mrf--u3Hx*bmR#E&oxQlK1@X!Tp%9QdXYkkYd6H8yK?jTjNG3LL zm}C=1JIo4CS=Y2Z5h4G`$2k>|%IeE!@AzwYCqH?7!%&%;-eRoRg-upV9L)Kd3Acm2 zFJDWFLMQz6I#p^Q^5;$5%KklTI;a`A9x#mG9C-iZ!to;V~rh>N7)aJznv1U zn|LyJ%6iwD5OLCE?1Kxdq}-$rcPX|kl-R6;1tq1|F?@suWDENTE4gZMlscIcC3RIo$7d_S6TIu^OPBG*jL-$wcF=cX4PY<=s##pzbkHib$l~bx5RJN>+;DE zGI(s71b-bbz9Np#*Ocy%9XlsIminnyBzrfeGkx2LLEq!c9Z&ZJnVbhgXRGiF3VZ4@ zyf#G|#VNA)nr89y^D@?R;lEV(5;N#(@QH*R ztrMH-n>Q=BBMXA0166kGV(z~infX@Jr*nfu$$KL1`sDu;Lb}k;ZY_kOH+HTLw6x|X zU`8;FBt#;qR+KP7)@(aTCD$A9_D>fVk~s)1DW8h*gL4u)Rd%~fJQ-Wn4Cns>i`tI0 zx(syIUch7+XP`GY*jD;sEo2eWPZAh70~%;?Q;0+gR)hNC4IDwNh(G$uK=NtUcWPHt z?~h1G;1lPVZu>l4Tiu)9&7K7x(!a^}_rH~K)Kkq>NR;p+sz-F!X{Iv8VjhiJnfufE zrjAH>0CBZHp(7!q+WAe{i%(7q7WJbfaMOwn0sivNDhPfwO?%68w|~{gt54}zo?K&R zc&AfdT3xztaKA6xM=TVH*bS&e5}5#>eg3>`&-ir_BV>&U9_{p3*!IkyHx`@B&M5$) zD%GRe$pfJu_&Ps*?#$y#{msu?7k5sJz3%JDtyc{UM9DI#Kq`+l?8ED0)o^*35!QlU zLyZVw-r@B&O^Com|G3uMv>k|^+f~%b6lJQ^qwc!tRI?ZD6*CdTv##A+2fB^wJw?N*fY#RCnd z0u`Tpl|PPe=Xn9YVhm7bz^@R)uNcG1%?QLxNQtqtr>mQ#vxk?*W_M>N$L&@)OIv5M z^UpPou5Pcl;5J)0dAc|*zq7O>j*qQ1m#V&mD@!t0e&=>;KA3N)tqA=tzQouQn2QE4 z2slFMX$CYhf>_Kopb;)1?r7Z1W-Iw?$lR_82#EJ6dx_35x_eu zXV*27$kY>Bo#74KxcaY)N{ionS7lG`8kkTP;WRT$TCNM4v?(E5bPms-F}n?IV3


FknX5`@Wyu9v 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 literal 0 HcmV?d00001 diff --git a/sound/misc/menu/ui_select1.ogg b/sound/misc/menu/ui_select1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d9b3ac8f61af3594adef3779ef7c51dc9c99c34e GIT binary patch literal 8355 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 Aga7~l literal 0 HcmV?d00001 From 521126f194548b11c6ed93739d64edc2f2022d37 Mon Sep 17 00:00:00 2001 From: AbsFree Date: Wed, 12 Feb 2025 19:14:59 +0100 Subject: [PATCH 14/25] added comments :D --- code/game/objects/items/storage/belt.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 371d6ff771..9fe335e1ef 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -149,6 +149,9 @@ /obj/item/storage/belt/medical/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) + // GS13 Edit + //STR.max_w_class = WEIGHT_CLASS_BULKY + // GS13 End Edit STR.max_items = 11 STR.max_w_class = WEIGHT_CLASS_NORMAL STR.max_combined_w_class = 24 @@ -201,8 +204,10 @@ /obj/item/implanter, /obj/item/pinpointer/crew, /obj/item/reagent_containers/chem_pack, + // GS13 Edit /obj/item/stack/sticky_tape, //surgical tape /obj/item/fermichem/pHmeter // chemical analyzer + // GS13 End Edit )) /obj/item/storage/belt/medical/surgery_belt_adv From fc530786b84288b175cbc85a1823cc947278ab65 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Thu, 13 Feb 2025 17:39:15 -0300 Subject: [PATCH 15/25] push --- code/_onclick/hud/screen_objects.dm | 1 + code/_onclick/hud/screen_objects/storage.dm | 20 +++++++------- code/datums/components/storage/ui.dm | 30 ++++++++++----------- code/datums/numbered_display.dm | 2 +- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 27d846f8fb..5b6d6c6387 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -82,6 +82,7 @@ /// Returns the mob this is being displayed to, if any /atom/movable/screen/proc/get_mob() + RETURN_TYPE(/mob) return hud?.mymob /atom/movable/screen/proc/on_hud_delete(datum/source) diff --git a/code/_onclick/hud/screen_objects/storage.dm b/code/_onclick/hud/screen_objects/storage.dm index 6a990dc7c8..cc96cf25e3 100644 --- a/code/_onclick/hud/screen_objects/storage.dm +++ b/code/_onclick/hud/screen_objects/storage.dm @@ -2,14 +2,14 @@ name = "storage" var/insertion_click = FALSE -/atom/movable/screen/storage/Initialize(mapload, new_master) +/atom/movable/screen/storage/Initialize(mapload, datum/hud/hud, new_master) . = ..() master = new_master /atom/movable/screen/storage/Click(location, control, params) if(!insertion_click) return ..() - if(hud?.mymob && (hud.mymob != usr)) + if(get_mob() != usr) return // just redirect clicks if(master) @@ -55,7 +55,7 @@ plane = VOLUMETRIC_STORAGE_BOX_PLANE var/obj/item/our_item -/atom/movable/screen/storage/volumetric_box/Initialize(mapload, new_master, obj/item/our_item) +/atom/movable/screen/storage/volumetric_box/Initialize(mapload, datum/hud/hud, new_master, obj/item/our_item) src.our_item = our_item RegisterSignal(our_item, COMSIG_ITEM_MOUSE_ENTER, PROC_REF(on_item_mouse_enter)) RegisterSignal(our_item, COMSIG_ITEM_MOUSE_EXIT, PROC_REF(on_item_mouse_exit)) @@ -97,9 +97,9 @@ var/atom/movable/screen/storage/item_holder/holder var/pixel_size -/atom/movable/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item) - left = new(null, src, our_item) - right = new(null, src, our_item) +/atom/movable/screen/storage/volumetric_box/center/Initialize(mapload, datum/hud/hud, new_master, our_item) + left = new(null, hud, src, our_item) + right = new(null, hud, src, our_item) return ..() /atom/movable/screen/storage/volumetric_box/center/Destroy() @@ -116,7 +116,7 @@ /** * Sets the size of this box screen object and regenerates its left/right borders. This includes the actual border's size! */ -/atom/movable/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels) +/atom/movable/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels, datum/hud/hud) if(pixel_size == pixels) return pixel_size = pixels @@ -128,7 +128,7 @@ if(our_item) if(holder) qdel(holder) - holder = new(null, src, our_item) + holder = new(null, hud, src, our_item) holder.transform = matrix(1 / multiplier, 0, 0, 0, 1, 0) holder.mouse_opacity = MOUSE_OPACITY_TRANSPARENT holder.appearance_flags &= ~RESET_TRANSFORM @@ -155,7 +155,7 @@ layer = VOLUMETRIC_STORAGE_BOX_LAYER plane = VOLUMETRIC_STORAGE_BOX_PLANE -/atom/movable/screen/storage/volumetric_edge/Initialize(mapload, master, our_item) +/atom/movable/screen/storage/volumetric_edge/Initialize(mapload, datum/hud/hud, master, our_item) src.master = master return ..() @@ -183,7 +183,7 @@ var/obj/item/our_item vis_flags = NONE -/atom/movable/screen/storage/item_holder/Initialize(mapload, new_master, obj/item/I) +/atom/movable/screen/storage/item_holder/Initialize(mapload, datum/hud/hud, new_master, obj/item/I) . = ..() our_item = I vis_contents += I diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm index c0cc03965c..841525ba79 100644 --- a/code/datums/components/storage/ui.dm +++ b/code/datums/components/storage/ui.dm @@ -33,11 +33,11 @@ var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) // First, boxes. - ui_boxes = get_ui_boxes() + ui_boxes = get_ui_boxes(user.hud_used) ui_boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_boxes // Then, closer. - ui_close = get_ui_close() + ui_close = get_ui_close(user.hud_used) ui_close.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]" . += ui_close // Then orient the actual items. @@ -62,7 +62,7 @@ for(var/obj/O in accessible_items()) if(QDELETED(O)) continue - var/atom/movable/screen/storage/item_holder/D = new(null, src, O) + var/atom/movable/screen/storage/item_holder/D = new(null, user.hud_used, src, O) // SNOWFLAKE: make O opaque too, pending storage rewrite O.mouse_opacity = MOUSE_OPACITY_OPAQUE D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" @@ -139,7 +139,7 @@ for(var/i in percentage_by_item) I = i var/percent = percentage_by_item[I] - var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I) + var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, user.hud_used, src, I) // SNOWFLAKE: force it to icon until we unfuck storage/click passing I.mouse_opacity = MOUSE_OPACITY_ICON var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM) @@ -168,15 +168,15 @@ current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING // Then, continuous section. - ui_continuous = get_ui_continuous() + ui_continuous = get_ui_continuous(user.hud_used) ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_continuous // Then, left. - ui_left = get_ui_left() + ui_left = get_ui_left(user.hud_used) ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_left // Then, closer, which is also our right element. - ui_close = get_ui_close() + ui_close = get_ui_close(user.hud_used) ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_close @@ -258,23 +258,23 @@ /** * Gets our ui_boxes, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_boxes() - return new /atom/movable/screen/storage/boxes(null, src) +/datum/component/storage/proc/get_ui_boxes(datum/hud/hud) + return new /atom/movable/screen/storage/boxes(null, hud, src) /** * Gets our ui_left, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_left() - return new /atom/movable/screen/storage/left(null, src) +/datum/component/storage/proc/get_ui_left(datum/hud/hud) + return new /atom/movable/screen/storage/left(null, hud, src) /** * Gets our ui_close, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_close() - return new /atom/movable/screen/storage/close(null, src) +/datum/component/storage/proc/get_ui_close(datum/hud/hud) + return new /atom/movable/screen/storage/close(null, hud, src) /** * Gets our ui_continuous, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_continuous() - return new /atom/movable/screen/storage/continuous(null, src) +/datum/component/storage/proc/get_ui_continuous(datum/hud/hud) + return new /atom/movable/screen/storage/continuous(null, hud, src) diff --git a/code/datums/numbered_display.dm b/code/datums/numbered_display.dm index b714be23fb..15e147463d 100644 --- a/code/datums/numbered_display.dm +++ b/code/datums/numbered_display.dm @@ -6,5 +6,5 @@ /datum/numbered_display/New(obj/item/sample, _number = 1, datum/component/storage/parent) if(!istype(sample)) qdel(src) - sample_object = new /atom/movable/screen/storage/item_holder(null, parent, sample) + sample_object = new /atom/movable/screen/storage/item_holder(null, null, parent, sample) number = _number From a59ed8afc826118f885cf84cfcb5cdcd73a60026 Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:02:41 -0500 Subject: [PATCH 16/25] updates fat damage --- GainStation13/code/mechanics/fatness.dm | 4 ++++ code/__DEFINES/combat.dm | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/GainStation13/code/mechanics/fatness.dm b/GainStation13/code/mechanics/fatness.dm index c2d2ec4c33..916e102f91 100644 --- a/GainStation13/code/mechanics/fatness.dm +++ b/GainStation13/code/mechanics/fatness.dm @@ -274,6 +274,10 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/command/bridge, /area/mainten return needed_fatness /mob/living/carbon/proc/applyFatnessDamage(amount) + if(!client?.prefs?.weight_gain_weapons) // If we can't fatten them through weapons, apply stamina damage + adjustStaminaLoss(amount) + return TRUE + var/fat_to_add = ((amount * CONFIG_GET(number/damage_multiplier)) * FAT_DAMAGE_TO_FATNESS) adjust_fatness(fat_to_add, FATTENING_TYPE_WEAPON) return fat_to_add diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 785c83c322..bd2d0844bd 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -279,5 +279,5 @@ #define FAT "fat" #define PERMA_FAT "perma_fat" /// What is the rate that one damage is converted to fatness? -#define FAT_DAMAGE_TO_FATNESS 4 -#define PERMA_FAT_DAMAGE_TO_FATNESS 4 +#define FAT_DAMAGE_TO_FATNESS 8 +#define PERMA_FAT_DAMAGE_TO_FATNESS 8 From 812398d82f2cf0045cf4f2dcc1b820584a34bfcd Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:15:53 -0500 Subject: [PATCH 17/25] Update hud.dm --- code/__DEFINES/hud.dm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index afee77c356..4c48be3fb5 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -94,13 +94,12 @@ #define ui_palette_scroll_offset(north_offset) ("WEST+1:8,NORTH-[6+north_offset]:28") //Middle right (status indicators) - -#define ui_healthdoll "EAST-1:28,CENTER-2:17" -#define ui_health "EAST-1:28,CENTER-1:19" -#define ui_internal "EAST-1:28,CENTER+1:21" // RIP, although nobody will remember this, unsmart coders have used this for other stuff. DO NOT REMOVE UNLESS RENAMING OR REPLACING. -#define ui_mood "EAST-1:28,CENTER:21" -#define ui_stamina "EAST-1:28,CENTER-3:14" -// #define ui_spacesuit "EAST-1:28,CENTER-4:14" +#define ui_healthdoll "EAST-1:28,CENTER-2:13" +#define ui_health "EAST-1:28,CENTER-1:15" +#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter +#define ui_mood "EAST-1:28,CENTER-3:10" +#define ui_arousal "EAST-1:28,CENTER-4:8" +// #define ui_spacesuit "EAST-1:28,CENTER-4:10" //Pop-up inventory #define ui_shoes "WEST+1:8,SOUTH:5" From 08f611fed834c74bf4c72efeb1ed5b9b709b9b9c Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Sun, 16 Feb 2025 20:34:17 -0500 Subject: [PATCH 18/25] fixes things --- code/__DEFINES/hud.dm | 1 + code/_onclick/hud/human.dm | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 4c48be3fb5..22971eb925 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -99,6 +99,7 @@ #define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter #define ui_mood "EAST-1:28,CENTER-3:10" #define ui_arousal "EAST-1:28,CENTER-4:8" +#define ui_stamina "EAST-1:28,CENTER-0:14" // #define ui_spacesuit "EAST-1:28,CENTER-4:10" //Pop-up inventory diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index acaa94f3ea..7e54d725d9 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -413,9 +413,8 @@ //END OF CIT CHANGES //GS13 Port - adds arousal and stamina to hud - arousal = new /atom/movable/screen/arousal() + arousal = new /atom/movable/screen/arousal(null, src) arousal.icon_state = (owner.canbearoused == 1 ? "arousal0" : "") - arousal.hud = src infodisplay += arousal healthdoll = new /atom/movable/screen/healthdoll(null, src) From d5b11405656aa189ba304b01d625b30f0f919479 Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Sun, 16 Feb 2025 21:36:02 -0500 Subject: [PATCH 19/25] Improves feeder mobs Feeder mobs now check to see if a mob is a carbon with the prefs before attempting to attack the mob. This should prevent fattening attempts on objects. --- GainStation13/code/mobs/chocoslime.dm | 49 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/GainStation13/code/mobs/chocoslime.dm b/GainStation13/code/mobs/chocoslime.dm index e9addd0cf5..fb2785a98f 100644 --- a/GainStation13/code/mobs/chocoslime.dm +++ b/GainStation13/code/mobs/chocoslime.dm @@ -2,13 +2,24 @@ var/food_per_feeding = 5 var/food_fed = /datum/reagent/consumable/nutriment +/mob/living/simple_animal/hostile/feed/CanAttack(atom/the_target) + var/mob/living/carbon/target = the_target + if(!istype(the_target)|| !check_target_prefs(target)) + return FALSE + + return ..() + +/// Called when seeing if a target can be attacked. See if the target has the pref on and return accordingly. +/mob/living/simple_animal/hostile/proc/check_target_prefs(mob/living/carbon/target) + return target?.client?.prefs?.weight_gain_weapons + /mob/living/simple_animal/hostile/feed/AttackingTarget() . = ..() var/mob/living/carbon/L = target - if(L.client?.prefs?.weight_gain_weapons) - if(L.reagents) - if(!L.is_mouth_covered(head_only = 1)) - L.reagents.add_reagent(food_fed, food_per_feeding) + if(!istype(L) || !L.reagents || !L.is_mouth_covered(head_only = 1)) + return FALSE + + L.reagents.add_reagent(food_fed, food_per_feeding) /mob/living/simple_animal/hostile/feed/chocolate_slime name = "Chocolate slime" @@ -83,13 +94,13 @@ /obj/item/projectile/beam/fattening/icecream/on_hit(atom/target, blocked) . = ..() var/mob/living/carbon/L = target - if(L.client?.prefs?.weight_gain_weapons) - if(L.reagents) - if(!L.is_mouth_covered(head_only = 1)) - L.reagents.add_reagent(food_fed, food_per_feeding) - if(HAS_TRAIT(L, TRAIT_VORACIOUS)) - fullness_add = fullness_add * 0.67 - L.fullness += (fullness_add) + if(!istype(L) || !L.reagents || L.is_mouth_covered(head_only = 1)) + return FALSE + + L.reagents.add_reagent(food_fed, food_per_feeding) + if(HAS_TRAIT(L, TRAIT_VORACIOUS)) + fullness_add = fullness_add * 0.67 + L.fullness += (fullness_add) @@ -137,5 +148,17 @@ /mob/living/simple_animal/hostile/fatten/AttackingTarget() . = ..() var/mob/living/carbon/L = target - if(L.client?.prefs?.weight_gain_magic) - L.adjust_fatness(fat_per_hit) + if(!istype(L)) + return FALSE + + L.adjust_fatness(fat_per_hit, FATTENING_TYPE_MAGIC) + +/mob/living/simple_animal/hostile/fatten/CanAttack(atom/the_target) + var/mob/living/carbon/target = the_target + if(!istype(the_target)|| !check_target_prefs(target)) + return FALSE + + return ..() + +/mob/living/simple_animal/hostile/fatten/check_target_prefs(mob/living/carbon/target) + return target?.client?.prefs?.weight_gain_magic From f78fd1e0cae60d69720629236d0c02e0b8dad285 Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Mon, 17 Feb 2025 01:33:23 -0500 Subject: [PATCH 20/25] Hot fix for a very prevalent runtime I'd normally go through and wait for the upstream PR for this to be merged, but this runtime happens enough and is enough of a issue for the server that this needs to be fixed like now. --- code/game/turfs/open/floor/catwalk_plating.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/game/turfs/open/floor/catwalk_plating.dm b/code/game/turfs/open/floor/catwalk_plating.dm index ac0f3b63de..833bcdf60b 100644 --- a/code/game/turfs/open/floor/catwalk_plating.dm +++ b/code/game/turfs/open/floor/catwalk_plating.dm @@ -13,9 +13,6 @@ desc = "Flooring that shows its contents underneath. Engineers love it!" baseturfs = /turf/open/floor/plating footstep = FOOTSTEP_CATWALK - barefootstep = FOOTSTEP_CATWALK - clawfootstep = FOOTSTEP_CATWALK - heavyfootstep = FOOTSTEP_CATWALK intact = FALSE var/covered = TRUE From 1d094fb1732b03e08de4ba25b84370fd103a1d6e Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Mon, 17 Feb 2025 01:43:41 -0500 Subject: [PATCH 21/25] Adds in variables for tracking digestion counts Adds two variables on carbons that check how many prey have been digested and also if the digested prey were human. --- GainStation13/code/mechanics/fatness.dm | 5 +++++ code/modules/vore/eating/bellymodes.dm | 3 +++ 2 files changed, 8 insertions(+) diff --git a/GainStation13/code/mechanics/fatness.dm b/GainStation13/code/mechanics/fatness.dm index 0b181d1584..a63479c582 100644 --- a/GainStation13/code/mechanics/fatness.dm +++ b/GainStation13/code/mechanics/fatness.dm @@ -26,6 +26,11 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/command/bridge, /area/mainten var/fullness = FULLNESS_LEVEL_HALF_FULL var/fullness_reduction_timer = 0 // When was the last time they emoted to reduce their fullness + /// How many mobs have been digested by this mob? + var/prey_digested = 0 + /// How many humanoid mobs have been digested by this mob? + var/human_prey_digested = 0 + /** * Adjusts the fatness level of the parent mob. * diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm index 9a5bc86a67..2f4b5dea54 100644 --- a/code/modules/vore/eating/bellymodes.dm +++ b/code/modules/vore/eating/bellymodes.dm @@ -100,6 +100,9 @@ if(iscarbon(prey) && prey.fatness_real) var/fatness_to_add = (prey.fatness_real * 0.80) gainer.adjust_fatness(fatness_to_add, FATTENING_TYPE_FOOD) + gainer.human_prey_digested += 1 + + gainer.prey_digested += 1 //GS13 edit end //Send messages From 947d997c69f59bde773b092682aa9795dae723ce Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Tue, 18 Feb 2025 11:28:29 -0500 Subject: [PATCH 22/25] Adds in the shuttle --- GainStation13/code/datums/shuttles.dm | 9 + _maps/RandomRuins/SpaceRuins/feeders_den.dmm | 62 ++--- _maps/shuttles/feeder.dmm | 236 +++++++++++++++++++ _maps/shuttles/feeder_ship_default.dmm | 214 +++++++++++++++++ tgstation.dme | 1 + 5 files changed, 492 insertions(+), 30 deletions(-) create mode 100644 GainStation13/code/datums/shuttles.dm create mode 100644 _maps/shuttles/feeder.dmm create mode 100644 _maps/shuttles/feeder_ship_default.dmm diff --git a/GainStation13/code/datums/shuttles.dm b/GainStation13/code/datums/shuttles.dm new file mode 100644 index 0000000000..f5ee937cda --- /dev/null +++ b/GainStation13/code/datums/shuttles.dm @@ -0,0 +1,9 @@ +/datum/map_template/shuttle/feeder + shuttle_id = "feeder_ship" + port_id = "feeder_ship" + suffix = "default" + name = "Mysterious Shuttle" + can_be_bought = FALSE + +/area/shuttle/feeder_shuttle + name = "Mysterious Shuttle" diff --git a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm index bfdddbe1f6..0554ca3084 100644 --- a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm +++ b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm @@ -17,19 +17,19 @@ "cw" = (/obj/machinery/light{dir = 8},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) "cx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "cy" = (/obj/structure/table/reinforced,/obj/item/reagent_containers/food/snacks/store/cake/chocolate,/obj/machinery/light/small{dir = 1},/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) -"cR" = (/obj/machinery/door/airlock/abductor,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"cV" = (/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) +"cR" = (/obj/effect/turf_decal{dir = 4},/obj/structure/fans/tiny,/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "cW" = (/obj/structure/cable{icon_state = "0-4"},/obj/machinery/power/apc{name = "Base Power Controller"; pixel_x = -28},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dd" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/disposalpipe/segment,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "de" = (/obj/structure/sign/poster/contraband/donut_corp{pixel_y = 32},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) "dl" = (/obj/structure/rack/shelf,/obj/item/stack/sheet/glass/fifty,/obj/item/stack/sheet/metal/fifty,/obj/item/stack/sheet/mineral/titanium/fifty{pixel_x = -4; pixel_y = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dr" = (/obj/machinery/door/airlock/external,/obj/effect/turf_decal{dir = 8},/obj/effect/turf_decal{dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dv" = (/obj/machinery/chem_dispenser/mutagensaltpeter,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"dz" = (/obj/structure/rack,/obj/item/mop/advanced,/obj/item/storage/bag/trash,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown,/obj/item/storage/box/lights/mixed,/obj/structure/window/reinforced/tinted{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"dz" = (/obj/structure/rack,/obj/item/mop/advanced,/obj/item/storage/bag/trash,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown,/obj/item/storage/box/lights/mixed,/obj/structure/window/reinforced/tinted{dir = 4},/obj/effect/turf_decal/tile/brown{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "dA" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 4; light_color = "#d8b1b1"},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "dC" = (/obj/machinery/deepfryer,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "dG" = (/obj/structure/flora/ausbushes/grassybush,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "dH" = (/obj/machinery/door/airlock/public/glass{name = "Cell 2"; id_tag = "feederden_cell2"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) +"dL" = (/obj/structure/lattice,/turf/closed/mineral/random,/area/ruin/space/has_grav/feedersden) "eb" = (/obj/structure/lattice,/turf/template_noop,/area/ruin/unpowered/no_grav) "ef" = (/obj/structure/table/wood,/obj/item/storage/pill_bottle/breast_enlargement{pixel_y = 5; pixel_x = -5},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) "eg" = (/obj/structure/reagent_dispensers/keg/lipoifier,/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) @@ -50,7 +50,7 @@ "fS" = (/obj/structure/table/wood,/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{dir = 1},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "ga" = (/obj/item/trash/boritos,/obj/structure/sign/poster/contraband/donut_corp{pixel_y = 32},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) "gi" = (/obj/structure/sink{dir = 4; pixel_x = 11},/obj/structure/mirror{pixel_x = 24},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) -"gk" = (/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 4},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) +"gk" = (/obj/effect/turf_decal,/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "gn" = (/obj/item/trash/can,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes{icon_state = "steel_grid"; dir = 5},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "gq" = (/obj/vehicle/ridden/wheelchair,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "gu" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/loading_area{icon_state = "steel_decals_central6"},/obj/effect/turf_decal/stripes/white/line{dir = 4; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 2; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals3"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -63,7 +63,8 @@ "hl" = (/obj/item/storage/toolbox/syndicate,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "hT" = (/obj/machinery/atmospherics/components/unary/vent_pump/on,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "ie" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/seed_extractor,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"ik" = (/obj/structure/ore_box,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"ik" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/machinery/computer/shuttle/syndicate{name = "shuttle terminal"; dir = 4; shuttleId = "feeder_ship"; possible_destinations = "feeder_home;whiteship_home;feeder_custom"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"iu" = (/obj/structure/curtain,/obj/effect/turf_decal/tile{dir = 1},/obj/effect/turf_decal/tile{dir = 4},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "iv" = (/obj/structure/chair/sofa/corner,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "iN" = (/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/processor,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "iO" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) @@ -85,7 +86,7 @@ "lQ" = (/obj/structure/chair/sofa/right,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "lR" = (/obj/machinery/iv_drip/feeding_tube,/obj/machinery/light/small{dir = 1},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) "ma" = (/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"mf" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/machinery/quantumpad/supply_only{map_pad_id = "denbase"; map_pad_link_id = "lavalandbase"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"mf" = (/obj/structure/ore_box,/obj/effect/turf_decal/tile/brown{dir = 8},/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/effect/turf_decal/tile/brown{dir = 1},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "mm" = (/obj/machinery/vending/mealdor{free = 1},/obj/machinery/light{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "mD" = (/obj/structure/closet/emcloset/anchored,/obj/effect/turf_decal/stripes/white/line{dir = 2},/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "mJ" = (/obj/structure/chair/sofa/corner{dir = 4},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) @@ -96,7 +97,6 @@ "nw" = (/obj/machinery/light/small{dir = 1},/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "nA" = (/obj/machinery/atmospherics/pipe/manifold/supply,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "nE" = (/obj/structure/flora/junglebush,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) -"nK" = (/obj/machinery/abductor/feeder_console,/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 9},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) "nQ" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate{pixel_x = -10},/obj/item/clothing/head/helmet/space/syndicate{pixel_x = -10},/obj/item/clothing/mask/gas{pixel_x = -10; pixel_y = 3},/obj/item/clothing/suit/space/syndicate/orange{pixel_x = 8; name = "extra stretchy space suit"},/obj/item/clothing/head/helmet/space/syndicate/orange{pixel_x = 10},/obj/item/clothing/mask/gas{pixel_x = 10; pixel_y = 3},/obj/item/tank/jetpack/carbondioxide/eva,/obj/effect/turf_decal/stripes/white/line{dir = 9},/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "nW" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "oF" = (/obj/structure/chair/office/dark{dir = 8},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) @@ -117,7 +117,7 @@ "qC" = (/obj/structure/falsewall/plastitanium,/obj/structure/fans/tiny/invisible,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "qD" = (/obj/machinery/computer/security/telescreen/entertainment,/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) "qF" = (/obj/structure/lattice,/turf/closed/mineral/random,/area/ruin/unpowered/no_grav) -"qM" = (/obj/structure/closet/crate/secure/weapon,/obj/item/clothing/glasses/hud/health/night,/obj/item/kitchen/knife/combat,/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown,/obj/item/gun/energy/fatoray,/obj/item/book/granter/spell/fattening,/obj/item/gun/energy/laser/alter_ray/gainrate,/obj/item/cookiesynth,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"qM" = (/obj/effect/turf_decal,/obj/effect/turf_decal{dir = 4},/obj/machinery/light{dir = 1; light_color = "#706891"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "rf" = (/obj/effect/turf_decal/stripes/white/line{dir = 8; icon_state = "steel_decals4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "ri" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/components/unary/tank/air,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "rj" = (/obj/machinery/iv_drip/feeding_tube,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) @@ -156,14 +156,16 @@ "uF" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/stock_parts/cell/high/plus,/obj/structure/cable{icon_state = "1-2"},/obj/item/gps,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "uO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "uX" = (/obj/machinery/computer/security/telescreen/entertainment,/obj/structure/disposalpipe/segment,/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) +"vf" = (/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "vk" = (/obj/item/trash/candy{pixel_x = 10; pixel_y = -3},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) -"vp" = (/obj/effect/turf_decal/stripes{icon_state = "trim"},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) +"vp" = (/obj/machinery/abductor/feeder_console,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "vt" = (/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "steel_decals9"},/obj/effect/turf_decal{dir = 4},/obj/effect/turf_decal{dir = 8},/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "vv" = (/obj/structure/table/wood,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "vw" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "vH" = (/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "vL" = (/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals1"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "vY" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) +"wk" = (/obj/effect/turf_decal,/obj/effect/turf_decal{dir = 8},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "wn" = (/obj/machinery/atmospherics/components/unary/vent_pump/on,/obj/structure/rack/shelf,/obj/item/storage/box/beakers/bluespace,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "ww" = (/obj/structure/flora/rock,/turf/open/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav) "wy" = (/obj/machinery/button/door{id = "feederden_cell1"; name = "Cell 1 Control"; normaldoorcontrol = 1; specialfunctions = 4; pixel_y = 32; pixel_x = -8},/obj/machinery/button/door{id = "feederden_cell2"; name = "Cell 2 Control"; normaldoorcontrol = 1; specialfunctions = 4; pixel_y = 32; pixel_x = 8},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -179,7 +181,7 @@ "yb" = (/obj/structure/sign/poster/contraband/eat{pixel_y = 32},/obj/structure/chair/sofachair,/obj/machinery/light/small{dir = 1},/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "yg" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "yk" = (/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central7"},/obj/effect/turf_decal/stripes/white/line{dir = 2; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 4; icon_state = "steel_decals3"},/obj/machinery/light{light_color = "#cee5d2"},/obj/item/storage/bag/plants,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"yq" = (/obj/structure/ore_box,/obj/effect/turf_decal/tile/brown,/obj/effect/turf_decal/tile/brown{dir = 8},/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"yq" = (/obj/effect/turf_decal{dir = 1},/obj/effect/turf_decal{dir = 4},/obj/machinery/light{light_color = "#c9d3e8"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "zc" = (/obj/effect/turf_decal/loading_area{icon_state = "steel_decals6"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "zg" = (/obj/machinery/airalarm/syndicate{pixel_y = 32},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "zl" = (/obj/machinery/autolathe/hacked,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -211,6 +213,7 @@ "Cu" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/obj/effect/turf_decal/stripes/red/line{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "CH" = (/obj/item/reagent_containers/food/snacks/pizzaslice/margherita,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "Dc" = (/turf/closed/wall/r_wall/syndicate/nodiagonal,/area/ruin/space/has_grav/feedersden) +"Dq" = (/obj/structure/closet/crate/secure/weapon,/obj/item/clothing/glasses/hud/health/night,/obj/item/kitchen/knife/combat,/obj/effect/turf_decal/tile/brown,/obj/item/gun/energy/fatoray,/obj/item/book/granter/spell/fattening,/obj/item/gun/energy/laser/alter_ray/gainrate,/obj/item/cookiesynth,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/structure/window/reinforced/tinted{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Ds" = (/turf/closed/mineral/random,/area/template_noop) "Dx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "DB" = (/obj/structure/cable,/obj/machinery/power/smes{charge = 5e+006},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -218,7 +221,6 @@ "DM" = (/obj/machinery/power/rtg/advanced/fullupgrade,/obj/structure/cable,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "DO" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "DU" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"Ef" = (/obj/machinery/light{dir = 1},/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) "Eh" = (/obj/structure/cable{icon_state = "1-4"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Ek" = (/obj/structure/cable,/obj/machinery/power/rtg/advanced/fullupgrade,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "En" = (/obj/item/reagent_containers/food/snacks/chocolatebar,/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) @@ -269,7 +271,6 @@ "Mi" = (/obj/structure/disposalpipe/segment{dir = 10},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Mq" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "MV" = (/obj/item/trash/boritos,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) -"MW" = (/obj/machinery/door/poddoor/shutters/old/preopen{id = "feederden_south"},/obj/effect/spawner/structure/window/plastitanium,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "MY" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/snacks/grown/corn,/obj/item/reagent_containers/food/condiment/sugar,/obj/item/reagent_containers/food/condiment/sugar,/obj/item/reagent_containers/food/condiment/sugar,/obj/item/reagent_containers/food/condiment/sugar,/obj/item/reagent_containers/food/snacks/spaghetti,/obj/item/reagent_containers/food/snacks/spaghetti,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Ng" = (/obj/structure/closet/wardrobe/mixed,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Nk" = (/obj/effect/turf_decal{dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -281,12 +282,14 @@ "NB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/stripes{icon_state = "steel_grid"; dir = 10},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "NJ" = (/obj/structure/curtain,/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "NR" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"NU" = (/obj/machinery/abductor/pad/feeder,/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 8},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) "NX" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/railing,/turf/open/floor/plasteel/stairs/left{dir = 4},/area/ruin/space/has_grav/feedersden) "Oc" = (/turf/open/floor/wood{icon_state = "wood-broken"},/area/ruin/space/has_grav/feedersden) "Ow" = (/obj/effect/turf_decal/sand/plating,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "OE" = (/obj/item/trash/can,/obj/effect/mob_spawn/human/feeders_den/victim{dir = 8},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) +"OH" = (/obj/effect/turf_decal{dir = 1},/obj/effect/turf_decal{dir = 8},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "Pg" = (/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/medkit_cabinet{pixel_y = 27},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Pk" = (/obj/effect/turf_decal{dir = 1},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"Pv" = (/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "PI" = (/obj/structure/closet/secure_closet/freezer/meat,/obj/item/reagent_containers/food/snacks/meat/slab/monkey,/obj/item/reagent_containers/food/snacks/meat/slab/monkey,/obj/item/reagent_containers/food/snacks/meat/slab/monkey,/obj/item/reagent_containers/food/snacks/meat/slab/monkey,/obj/item/reagent_containers/food/snacks/meat/slab/spider,/obj/item/reagent_containers/food/snacks/meat/slab/spider,/obj/structure/window/reinforced/tinted{dir = 8},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "PL" = (/obj/structure/sign/poster/contraband/eat{pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/structure/scale,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "PV" = (/obj/item/paper/fluff/ruins/feeder_den/hidden,/turf/open/floor/plating{icon_state = "panelscorched"},/area/ruin/space/has_grav/feedersden) @@ -294,11 +297,10 @@ "QK" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "QW" = (/obj/structure/table/wood,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "Ra" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"Rc" = (/obj/machinery/computer/camera_advanced/abductor/feeder,/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 10},/obj/item/paper/fluff/ruins/feeder_den/tool_warning,/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) +"Rc" = (/obj/docking_port/stationary{dir = 8; height = 7; name = "Outpost"; width = 7; roundstart_template = /datum/map_template/shuttle/feeder; shuttle_id = "feeder_home"; area_type = /area/ruin/space/has_grav/feedersden; dwidth = 3},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Rh" = (/obj/structure/table,/obj/machinery/microwave,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"Rp" = (/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) -"Rr" = (/obj/structure/table/abductor,/obj/item/abductor/gizmo/feeder,/obj/item/abductor/gizmo/feeder,/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 6},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) -"Ru" = (/obj/machinery/door/poddoor/shutters/old/preopen{id = "feederden_north"},/obj/effect/spawner/structure/window/plastitanium,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Rp" = (/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) +"Ru" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/shutters/old/preopen{id = "feederden_north"},/obj/effect/turf_decal/tile/red,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Rw" = (/obj/machinery/atmospherics/components/unary/outlet_injector/on{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plating/airless,/area/ruin/space/has_grav/feedersden) "Rz" = (/obj/structure/railing{dir = 1},/turf/open/floor/plasteel/stairs/left{dir = 8},/area/ruin/space/has_grav/feedersden) "RC" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -324,6 +326,7 @@ "UJ" = (/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "UZ" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/open/floor/plating/airless,/area/ruin/space/has_grav/feedersden) "Ve" = (/obj/structure/flora/junglebush,/turf/open/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav) +"Vv" = (/obj/effect/turf_decal/stripes/white/line{dir = 8; icon_state = "steel_decals4"},/obj/machinery/quantumpad/supply_only{map_pad_id = "denbase"; map_pad_link_id = "lavalandbase"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Vx" = (/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "VF" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/item/toy/plush/random,/obj/item/toy/plush/random,/obj/item/toy/plush/random,/obj/machinery/light{dir = 4},/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "VW" = (/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -332,7 +335,6 @@ "Wt" = (/obj/structure/lattice/catwalk,/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"; pixel_x = 12; pixel_y = -10},/turf/template_noop,/area/ruin/space/has_grav/feedersden) "WH" = (/obj/item/trash/plate{pixel_x = -4; pixel_y = 10},/obj/item/trash/plate{pixel_x = -5; pixel_y = -1},/obj/item/trash/plate{pixel_y = 4},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "WJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) -"WK" = (/obj/structure/table/abductor,/obj/item/paper/fluff/ruins/feeder_den/tool_warning,/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 5},/turf/open/floor/plating/abductor,/area/ruin/space/has_grav/feedersden) "WN" = (/obj/structure/rack/shelf,/obj/item/reagent_containers/food/snacks/syndicake,/obj/item/reagent_containers/food/snacks/syndicake,/obj/item/reagent_containers/food/snacks/chips,/obj/item/reagent_containers/food/snacks/chips,/obj/item/reagent_containers/food/snacks/cornchips,/obj/item/reagent_containers/food/snacks/cornchips,/obj/item/reagent_containers/food/snacks/candy,/obj/item/reagent_containers/food/snacks/candy,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown{dir = 1},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "WZ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Xa" = (/obj/structure/table/wood,/obj/item/card/id/syndicate{pixel_y = 14},/obj/item/storage/fancy/cigarettes/cigpack_syndicate{pixel_x = -3},/obj/item/lighter{pixel_x = 4},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) @@ -380,20 +382,20 @@ FEebebebqFBrBrnrfMsqelzCnrLMelwnnrSXXFXFwODcwYrWOclQeSiXGFCcoKoKoKNzItgUeZICnrhl FEFEFEFEFEBrBrDcnrnrnurkDcgUKHzYDcDcgUdHDcDccwoKoKOcoKoKoKvkrWoKoKNzItDcDcDcDcgUYkzYDcftbxnrnrDcBrBrFEFEFEFEFE FEFEFEFEFEBrBrBrnrtZlltPwyLoJWMqLoKofbcdcdzgcdRpRpqiRpRpRpXhRpRpRpjOkKkKRzKoLusabcQKzwgnLTmmnrBrBrFEFEFEFEFEFE FEFEFEFEfmBrBrBrnrZnNBLvAjNRgZKWNRAjNXTGTGTGTGBDTGXWZhZhZhqquOuOuOuOuOrJZOWrndWrsNnArBxJLfZnnrqFebebebFEFEFEFE -FEFEFEfmfmBrBrBrDcDcNJNJDcnrnrnrnrnrnrnrnrnrDcWJiONxgUgUgUuXZpTKDcnrnrQFnrnrnrnrnrnrDcNJNJDcDcBrFEFEFEFEFEFEFE -FEFEBrZCfmISBrBrBrnrMaEqnrikNggqnrWNYEfncnbanrDxvYFDLNdCsRiNvYSsnrZeIoxCkoPgnrridlkCnrfNginrBrBrBrFEFEFEFEFEFE +FEFEFEfmfmBrBrBrDcDcNJNJDcnrnrnrnrnrnrnrnrnrDcWJiONxgUgUgUuXZpTKDcnrnrQFnrnrnrnrnrnrDciuiuDcDcBrFEFEFEFEFEFEFE +FEFEBrZCfmISBrBrBrnrMaEqnrNggqvpnrWNYEfncnbanrDxvYFDLNdCsRiNvYSsnrZeIoxCkoPgnrridlkCnrfNginrBrBrBrFEFEFEFEFEFE FEFEBrBrfmfmBrBrBrnrtyEqnrIGJhJhWsDOlsuklslsvtDxvYSyBeaaaaUBvYmUnrcWmaUerscxtVbXJhkMnrfNdAnrBrBrBrFEFEFEFEFEFE FEFEFEBrwwfmeEBrBrDcnrnrDcxGHpEHNkDOtHguboygaQoYvYvYvYvYvYvwvYkdnrgFXsFHYpDBnrzlJhXPDcnrnrDcBrBrBrFEFEFEFEFEFE -FEFEFEBrxZfmfmBrBrBrBrBrDcDcnrnrDcmflsucaEBPnrvYaDMYMdRhDKjhANYUnrnrnrTPJhfKDcnrRanrDcBrEWYNxZBrBrBrFEFEFEFEFE -FEFEFEFEfmfmBrBrBrBrBrBrnrnKEfWKnrqhlslszcVFDczAnrnrnrMWnrnrnrnrDcmDnQddRCuFnrNtVWdvnrISVefmfmfxBrBrFEFEFEFEFE -FEFEFEFEFEfmBrBrBrBrBrBrnrNUcVgkcRDOrfrfYhdzPItjfhnroHoHoHdrVxnwAaYAtBTYzGzEHivLMisCkgeEfmFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrBrBrBrBrnrRcvpRrnrqMyqzJjSTUbWTxsunroHoHoHdrBVBVAaYApeWZlhFmEsieuqrEuyRwfmFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEFEBrBrBrBrBrDcnrnrnrDcnrnrnrnrnrnrnrnrpfgDoHWtpfnrnrnrnrnrnWnrnrDcaMsIaMtIUZFEFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEBrBrBrBrBrBrBrBrBrBrBrBrBrBrXLBrqFebebebebebqFXLBrBrDcEhDUUJDcaMsIaMDcqFebebqFqFFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrBrplVeFEFEFEFEFEFEVeEWVefmDcEkSpDMDcaMykaMDcDsFEFEBrBrFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrISfmFEFEFEFEFEFEfmISZCISDcDcDcDcDcDcDcDcDcDsFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrFEFEFEFEFEFEFEBrfmfmwwxZfmfmfmBrBrqFqFDsDsFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrVefmfmfmfmeEfmKuqFqFKuFEFEFEFEFEFEFEFEFEFEFEFE +FEFEFEBrxZfmfmBrDcDcDcDcDcDcnrnrDcDOlsucaEBPnrvYaDMYMdRhDKjhANYUnrnrnrTPJhfKDcnrRanrDcBrEWYNxZBrBrBrFEFEFEFEFE +FEFEFEFEfmfmBrBrDcgkgkqMJhJhJhwknrqhlslszcVFDczAnrnrnrkgnrnrnrnrDcmDnQddRCuFnrNtVWdvnrISVefmfmfxBrBrFEFEFEFEFE +FEFEFEFEFEfmBrBrDcJhJhJhJhJhJhJhnrmfrfVvYhdzPItjfhnroHoHoHdrVxnwAaYAtBTYzGzEHivLMisCkgeEfmFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhnrikrfrfYhDqbWTxsunroHoHoHdrBVBVAaYApeWZlhFmEsieuqrEuyRwfmFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhRccRvfPvzJjSTUnrnrnrpfgDoHWtpfnrnrnrnrnrnWnrnrDcaMsIaMtIUZFEFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhDcnrnrnrnrnrnrXLdLebebebebebqFXLBrBrDcEhDUUJDcaMsIaMDcqFebebqFqFFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhDcXLXLXLXLXLXLBrplVeFEFEFEFEVeEWVefmDcEkSpDMDcaMykaMDcDsFEFEBrBrFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcPkPkyqJhJhJhOHDcBrBrBrBrBrBrBrISfmFEFEFEFEfmISZCISDcDcDcDcDcDcDcDcDcDsFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrDcDcDcDcDcDcDcDcDcBrBrFEFEBrBrFEFEFEFEFEFEFEBrfmfmwwxZfmfmfmBrBrqFqFDsDsFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEFEFEBrBrBrBrBrBrBrBrBrBrBrBrFEFEFEFEFEFEFEFEFEFEFEBrBrVefmfmfmfmeEfmKuqFqFKuFEFEFEFEFEFEFEFEFEFEFEFE FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrZCZCfmFEFEFEebebFEFEFEFEFEFEFEFEFEFEFEFEFE FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrBrFEFEFEFEFEebFEFEFEFEFEFEFEFEFEFEFEFEFE FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrFEFEFEFEFEebFEFEFEFEFEFEFEFEFEFEFEFEFE diff --git a/_maps/shuttles/feeder.dmm b/_maps/shuttles/feeder.dmm new file mode 100644 index 0000000000..8b3d174fa9 --- /dev/null +++ b/_maps/shuttles/feeder.dmm @@ -0,0 +1,236 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/wall/mineral/plastitanium, +/area/space) +"c" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/space) +"g" = ( +/turf/open/floor/wood, +/area/space) +"h" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/space) +"j" = ( +/turf/open/floor/mineral/basaltstone_floor, +/area/space) +"l" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/chair/sofachair{ + dir = 8 + }, +/turf/open/floor/mineral/basaltstone_floor, +/area/space) +"n" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/loading_area{ + dir = 8; + icon_state = "drain"; + name = "drain" + }, +/obj/machinery/door/window/brigdoor/westleft, +/turf/open/floor/plasteel/dark, +/area/space) +"o" = ( +/obj/structure/chair/sofachair{ + dir = 8 + }, +/turf/open/floor/mineral/basaltstone_floor, +/area/space) +"p" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/loading_area{ + dir = 8; + icon_state = "drain"; + name = "drain" + }, +/obj/structure/window/reinforced/spawner/west, +/turf/open/floor/plasteel/dark, +/area/space) +"u" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/loading_area{ + dir = 8; + icon_state = "drain"; + name = "drain" + }, +/obj/structure/window/reinforced/spawner/west, +/obj/structure/closet/secure_closet{ + req_one_access_txt = "150" + }, +/turf/open/floor/plasteel/dark, +/area/space) +"y" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/space) +"z" = ( +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate{ + name = "shuttle navigation computer"; + desc = "Used to designate a precise transit location for the shuttle." + }, +/turf/open/floor/plasteel/dark, +/area/space) +"G" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood, +/area/space) +"H" = ( +/obj/machinery/light, +/obj/structure/chair/sofa{ + dir = 1 + }, +/turf/open/floor/wood, +/area/space) +"J" = ( +/obj/machinery/computer/shuttle/syndicate{ + name = "shuttle terminal" + }, +/turf/open/floor/plasteel/dark, +/area/space) +"K" = ( +/obj/machinery/door/airlock/abductor, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/space) +"M" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/space) +"P" = ( +/obj/item/kirbyplants/photosynthetic, +/turf/open/floor/wood, +/area/space) +"Q" = ( +/turf/open/space/basic, +/area/space) +"S" = ( +/obj/structure/falsewall/plastitanium, +/obj/machinery/door/window/brigdoor/northright{ + layer = 1 + }, +/turf/open/floor/mineral/basaltstone_floor, +/area/space) +"Y" = ( +/obj/structure/shuttle/engine/heater{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/space) +"Z" = ( +/obj/effect/spawner/structure/window/plastitanium, +/turf/open/floor/plating, +/area/space) + +(1,1,1) = {" +Q +M +M +M +Q +Q +Q +Q +"} +(2,1,1) = {" +a +Y +Y +Y +a +a +a +a +"} +(3,1,1) = {" +K +g +g +G +S +j +j +a +"} +(4,1,1) = {" +a +h +g +H +a +l +o +a +"} +(5,1,1) = {" +Z +P +g +y +a +a +a +a +"} +(6,1,1) = {" +Z +u +n +p +a +Q +Q +Q +"} +(7,1,1) = {" +a +J +c +z +a +Q +Q +Q +"} +(8,1,1) = {" +a +Z +Z +Z +a +Q +Q +Q +"} diff --git a/_maps/shuttles/feeder_ship_default.dmm b/_maps/shuttles/feeder_ship_default.dmm new file mode 100644 index 0000000000..4ffbc3137a --- /dev/null +++ b/_maps/shuttles/feeder_ship_default.dmm @@ -0,0 +1,214 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"g" = ( +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate{ + name = "shuttle navigation computer"; + desc = "Used to designate a precise transit location for the shuttle."; + dir = 4; + shuttleId = "feeder_ship"; + shuttlePortId = "feeder_custom"; + jump_to_ports = list("whiteship_home" = 1, "feeder_home" = 1) + }, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"j" = ( +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/feeder_shuttle) +"k" = ( +/obj/structure/shuttle/engine/heater{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod{ + dir = 1 + }, +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/turf/open/floor/plating, +/area/shuttle/feeder_shuttle) +"l" = ( +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) +"o" = ( +/obj/machinery/computer{ + dir = 4; + name = "Shuttle computer" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"p" = ( +/obj/structure/chair/comfy/shuttle, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"r" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) +"y" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"z" = ( +/obj/structure/shuttle/engine/propulsion/left{ + dir = 4 + }, +/turf/open/space/basic, +/area/shuttle/feeder_shuttle) +"C" = ( +/obj/structure/table/reinforced, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"D" = ( +/obj/structure/shuttle/engine/heater{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/plating, +/area/shuttle/feeder_shuttle) +"F" = ( +/obj/machinery/door/window/survival_pod, +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) +"G" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"I" = ( +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/shuttle/feeder_shuttle) +"J" = ( +/obj/machinery/door/airlock/hatch{ + name = "airlock"; + req_access_txt = "150" + }, +/obj/structure/fans/tiny, +/obj/docking_port/mobile{ + dir = 8; + shuttle_id = "feeder_ship"; + port_direction = 4; + shuttle_areas = /area/shuttle/feeder_shuttle; + dwidth = 3; + height = 7; + width = 7 + }, +/turf/open/floor/plating, +/area/shuttle/feeder_shuttle) +"M" = ( +/obj/machinery/porta_turret/fattening, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/feeder_shuttle) +"P" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) +"Q" = ( +/turf/template_noop, +/area/template_noop) +"S" = ( +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/machinery/suit_storage_unit/syndicatemod, +/turf/open/floor/mineral/plastitanium/red, +/area/shuttle/feeder_shuttle) +"X" = ( +/obj/machinery/computer/shuttle/syndicate{ + name = "shuttle terminal"; + dir = 4; + shuttleId = "feeder_ship"; + possible_destinations = "feeder_home;whiteship_home;feeder_custom" + }, +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) +"Y" = ( +/obj/effect/spawner/structure/window/plastitanium, +/obj/structure/grille, +/turf/open/floor/plating, +/area/shuttle/feeder_shuttle) +"Z" = ( +/obj/machinery/door/window/survival_pod{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/shuttle/feeder_shuttle) + +(1,1,1) = {" +Q +M +Y +Y +Y +M +Q +"} +(2,1,1) = {" +Q +Y +o +X +g +Y +Q +"} +(3,1,1) = {" +Q +j +G +P +C +j +Q +"} +(4,1,1) = {" +j +I +a +l +S +I +j +"} +(5,1,1) = {" +j +p +Z +l +F +y +j +"} +(6,1,1) = {" +j +D +r +l +r +k +j +"} +(7,1,1) = {" +Q +z +j +J +j +z +Q +"} diff --git a/tgstation.dme b/tgstation.dme index 3f46eac511..62676067f6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3941,6 +3941,7 @@ #include "GainStation13\code\datums\bark.dm" #include "GainStation13\code\datums\lavaland_ruins.dm" #include "GainStation13\code\datums\ruins.dm" +#include "GainStation13\code\datums\shuttles.dm" #include "GainStation13\code\datums\traits.dm" #include "GainStation13\code\datums\achievements\fat.dm" #include "GainStation13\code\datums\components\fattening_door.dm" From 439c27de8e63a1b1e6515604cc938d3d3f9a4adc Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Tue, 18 Feb 2025 12:56:05 -0500 Subject: [PATCH 23/25] updates the den and fixes grenades --- .../den abductors/purchaseble_goodies.dm | 16 ++++++++-------- GainStation13/code/modules/weapons/grenades.dm | 2 ++ .../code/obj/weapons/fattening_batons.dm | 11 +++++++++++ _maps/RandomRuins/SpaceRuins/feeders_den.dmm | 2 +- tgstation.dme | 1 + 5 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 GainStation13/code/obj/weapons/fattening_batons.dm diff --git a/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm b/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm index e7147be734..cabb3e48e8 100644 --- a/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm +++ b/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm @@ -1,10 +1,10 @@ /datum/feeders_den_goodie /// What is the name of the goodie we want to buy? - var/name + var/name /// How much credits does this cost to buy? var/credit_cost = 0 /// How much stock of this can be bought? If this is null, infinite can be bought - var/initial_stock + var/initial_stock /// What is the path of the item to dispense? var/item_to_dispense @@ -13,11 +13,6 @@ credit_cost = 100 item_to_dispense = /obj/item/vending_refill/mealdor -/datum/feeders_den_goodie/gizmo - name = "Science Tool" - credit_cost = 120 - item_to_dispense = /obj/item/abductor/gizmo/feeder - /datum/feeders_den_goodie/nutripump_turbo name = "Nutri-Pump TURBO Autosurgeon" credit_cost = 150 @@ -85,4 +80,9 @@ name = "Livestock Implant" credit_cost = 250 item_to_dispense = /obj/item/implantcase/docile/livestock - initial_stock = 5 + +/datum/feeders_den_goodie/space_suit + name = "Boxed Space Suit and Helmet" + credit_cost = 300 + item_to_dispense = /obj/item/storage/box/syndie_kit/space + initial_stock = 2 diff --git a/GainStation13/code/modules/weapons/grenades.dm b/GainStation13/code/modules/weapons/grenades.dm index 78615c30a5..8295839c41 100644 --- a/GainStation13/code/modules/weapons/grenades.dm +++ b/GainStation13/code/modules/weapons/grenades.dm @@ -3,6 +3,7 @@ /obj/item/grenade/chem_grenade/lipoifier_strong name = "lipoifier grenade" desc = "For when you want everyone in the room to gain a couple hundred pounds." + stage = 3 /obj/item/grenade/chem_grenade/lipoifier_strong/Initialize(mapload) . = ..() @@ -21,6 +22,7 @@ /obj/item/grenade/chem_grenade/lipoifier_weak name = "lipoifier grenade" desc = "For when you want everyone in the room to gain a couple dozen pounds." + stage = 3 /obj/item/grenade/chem_grenade/lipoifier_weak/Initialize(mapload) . = ..() diff --git a/GainStation13/code/obj/weapons/fattening_batons.dm b/GainStation13/code/obj/weapons/fattening_batons.dm new file mode 100644 index 0000000000..85caf00455 --- /dev/null +++ b/GainStation13/code/obj/weapons/fattening_batons.dm @@ -0,0 +1,11 @@ +/obj/item/melee/baton/stunsword/fattening + name = "fattening stunsword" + desc = "functions the same as it's standard counterpart, but fattens targets when used aggressively." + force = 20 + damtype = FAT + +/obj/item/melee/baton/fattening + name = "fattening stunbaton" + desc = "functions the same as it's standard counterpart, but fattens targets when used aggressively." + force = 20 + damtype = FAT diff --git a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm index 0554ca3084..ef3b3b9262 100644 --- a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm +++ b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm @@ -73,7 +73,7 @@ "jh" = (/obj/structure/table,/obj/machinery/disposal/bin{pixel_y = -10},/obj/structure/disposalpipe/trunk{dir = 1},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "jI" = (/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "jO" = (/obj/effect/turf_decal/tile/red{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) -"jS" = (/obj/structure/rack/shelf,/obj/item/electropack/shockcollar,/obj/item/clothing/neck/petcollar,/obj/item/melee/baton/stunsword,/obj/item/restraints/handcuffs,/obj/item/restraints/handcuffs/cable/zipties,/obj/effect/turf_decal/tile/brown,/obj/effect/turf_decal/tile/brown{dir = 8},/obj/item/melee/baton/stunsword,/obj/item/clothing/neck/petcollar/calorite,/obj/item/clothing/mask/cowmask/gag,/obj/item/clothing/mask/cowmask/gag,/obj/item/clothing/mask/pig/gag,/obj/item/clothing/mask/pig/gag,/obj/item/stock_parts/cell/high,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"jS" = (/obj/structure/rack/shelf,/obj/item/electropack/shockcollar,/obj/item/clothing/neck/petcollar,/obj/item/melee/baton/stunsword/fattening,/obj/item/restraints/handcuffs,/obj/item/restraints/handcuffs/cable/zipties,/obj/effect/turf_decal/tile/brown,/obj/effect/turf_decal/tile/brown{dir = 8},/obj/item/melee/baton/stunsword/fattening,/obj/item/clothing/neck/petcollar/calorite,/obj/item/clothing/mask/cowmask/gag,/obj/item/clothing/mask/cowmask/gag,/obj/item/clothing/mask/pig/gag,/obj/item/clothing/mask/pig/gag,/obj/item/stock_parts/cell/high,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "kd" = (/obj/structure/table,/obj/item/kitchen/rollingpin,/obj/item/kitchen/knife/butcher,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "kg" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/shutters/old/preopen{id = "feederden_south"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "ko" = (/obj/machinery/space_heater,/obj/machinery/airalarm/syndicate{pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) diff --git a/tgstation.dme b/tgstation.dme index 62676067f6..365f21daff 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4105,6 +4105,7 @@ #include "GainStation13\code\obj\weapons\alter_rays.dm" #include "GainStation13\code\obj\weapons\fatbeam.dm" #include "GainStation13\code\obj\weapons\fatoray.dm" +#include "GainStation13\code\obj\weapons\fattening_batons.dm" #include "GainStation13\code\obj\weapons\feeder_ebow.dm" #include "GainStation13\code\structures\chair.dm" #include "GainStation13\code\structures\trapped_items.dm" From 3db9558134ca417b236b3d084740ee68fd8f79e1 Mon Sep 17 00:00:00 2001 From: scooooop6576576 Date: Tue, 18 Feb 2025 13:26:45 -0500 Subject: [PATCH 24/25] a fix to the butt of the latex --- hyperstation/icons/mobs/suits.dmi | Bin 15785 -> 14583 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hyperstation/icons/mobs/suits.dmi b/hyperstation/icons/mobs/suits.dmi index e7fd46fc51a0fc3963b6cfc1d253e0872428ce8c..da0f890982f7726b8d296e163e4034e1f6198a47 100644 GIT binary patch literal 14583 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 O0OX~Wq)H@>zWgtr`=6o! From 33613d344472a87124c2d38e2c896a7214936ac5 Mon Sep 17 00:00:00 2001 From: evilew Date: Wed, 19 Feb 2025 15:05:16 +0100 Subject: [PATCH 25/25] detailing feeder den and feeder ship maps --- _maps/RandomRuins/SpaceRuins/feeders_den.dmm | 93 +++++++++++--------- _maps/shuttles/feeder_ship_default.dmm | 45 ++++++++-- 2 files changed, 88 insertions(+), 50 deletions(-) diff --git a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm index ef3b3b9262..6ef2cc89c2 100644 --- a/_maps/RandomRuins/SpaceRuins/feeders_den.dmm +++ b/_maps/RandomRuins/SpaceRuins/feeders_den.dmm @@ -21,6 +21,7 @@ "cW" = (/obj/structure/cable{icon_state = "0-4"},/obj/machinery/power/apc{name = "Base Power Controller"; pixel_x = -28},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dd" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/disposalpipe/segment,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "de" = (/obj/structure/sign/poster/contraband/donut_corp{pixel_y = 32},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) +"dj" = (/obj/structure/sink{dir = 4; pixel_x = 12},/obj/structure/mirror{pixel_x = 24},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "dl" = (/obj/structure/rack/shelf,/obj/item/stack/sheet/glass/fifty,/obj/item/stack/sheet/metal/fifty,/obj/item/stack/sheet/mineral/titanium/fifty{pixel_x = -4; pixel_y = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dr" = (/obj/machinery/door/airlock/external,/obj/effect/turf_decal{dir = 8},/obj/effect/turf_decal{dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "dv" = (/obj/machinery/chem_dispenser/mutagensaltpeter,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -63,8 +64,8 @@ "hl" = (/obj/item/storage/toolbox/syndicate,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "hT" = (/obj/machinery/atmospherics/components/unary/vent_pump/on,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "ie" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/seed_extractor,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"ik" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/machinery/computer/shuttle/syndicate{name = "shuttle terminal"; dir = 4; shuttleId = "feeder_ship"; possible_destinations = "feeder_home;whiteship_home;feeder_custom"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"iu" = (/obj/structure/curtain,/obj/effect/turf_decal/tile{dir = 1},/obj/effect/turf_decal/tile{dir = 4},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) +"ik" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/machinery/quantumpad/supply_only{map_pad_id = "denbase"; map_pad_link_id = "lavalandbase"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"iu" = (/obj/structure/curtain,/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "iv" = (/obj/structure/chair/sofa/corner,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "iN" = (/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/processor,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "iO" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) @@ -86,7 +87,7 @@ "lQ" = (/obj/structure/chair/sofa/right,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "lR" = (/obj/machinery/iv_drip/feeding_tube,/obj/machinery/light/small{dir = 1},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) "ma" = (/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"mf" = (/obj/structure/ore_box,/obj/effect/turf_decal/tile/brown{dir = 8},/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/effect/turf_decal/tile/brown{dir = 1},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"mf" = (/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown{dir = 1},/obj/machinery/computer/shuttle/syndicate{name = "shuttle terminal"; dir = 4; shuttleId = "feeder_ship"; possible_destinations = "feeder_home;whiteship_home;feeder_custom"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "mm" = (/obj/machinery/vending/mealdor{free = 1},/obj/machinery/light{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "mD" = (/obj/structure/closet/emcloset/anchored,/obj/effect/turf_decal/stripes/white/line{dir = 2},/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "mJ" = (/obj/structure/chair/sofa/corner{dir = 4},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) @@ -94,11 +95,11 @@ "nd" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "nr" = (/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) "nu" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/door/airlock/public/glass{name = "Cell 1"; id_tag = "feederden_cell1"},/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) -"nw" = (/obj/machinery/light/small{dir = 1},/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"nw" = (/obj/machinery/light/small{dir = 1},/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "nA" = (/obj/machinery/atmospherics/pipe/manifold/supply,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "nE" = (/obj/structure/flora/junglebush,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "nQ" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate{pixel_x = -10},/obj/item/clothing/head/helmet/space/syndicate{pixel_x = -10},/obj/item/clothing/mask/gas{pixel_x = -10; pixel_y = 3},/obj/item/clothing/suit/space/syndicate/orange{pixel_x = 8; name = "extra stretchy space suit"},/obj/item/clothing/head/helmet/space/syndicate/orange{pixel_x = 10},/obj/item/clothing/mask/gas{pixel_x = 10; pixel_y = 3},/obj/item/tank/jetpack/carbondioxide/eva,/obj/effect/turf_decal/stripes/white/line{dir = 9},/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"nW" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"nW" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/obj/structure/cable{icon_state = "1-2"},/obj/effect/turf_decal{dir = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "oF" = (/obj/structure/chair/office/dark{dir = 8},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "oH" = (/obj/structure/lattice/catwalk,/turf/template_noop,/area/ruin/space/has_grav/feedersden) "oK" = (/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) @@ -110,14 +111,14 @@ "ph" = (/obj/machinery/vending/gato{free = 1},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) "pl" = (/obj/machinery/porta_turret/fattening,/obj/structure/lattice/catwalk,/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "pO" = (/obj/structure/table/wood,/obj/item/reagent_containers/food/snacks/meat/bacon,/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) -"qh" = (/obj/machinery/food_cart,/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"qh" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/structure/ore_box,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/obj/item/stack/sheet/mineral/calorite,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "qi" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "qq" = (/obj/machinery/atmospherics/pipe/manifold/supply,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 6},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "qt" = (/obj/effect/mob_spawn/human/feeders_den/fanatic{dir = 8},/obj/item/flashlight/seclite,/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red,/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "qC" = (/obj/structure/falsewall/plastitanium,/obj/structure/fans/tiny/invisible,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "qD" = (/obj/machinery/computer/security/telescreen/entertainment,/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) "qF" = (/obj/structure/lattice,/turf/closed/mineral/random,/area/ruin/unpowered/no_grav) -"qM" = (/obj/effect/turf_decal,/obj/effect/turf_decal{dir = 4},/obj/machinery/light{dir = 1; light_color = "#706891"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"qM" = (/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/effect/turf_decal/stripes/line{dir = 6},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "rf" = (/obj/effect/turf_decal/stripes/white/line{dir = 8; icon_state = "steel_decals4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "ri" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/components/unary/tank/air,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "rj" = (/obj/machinery/iv_drip/feeding_tube,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) @@ -126,10 +127,13 @@ "rt" = (/obj/structure/chair/sofa,/obj/item/reagent_containers/food/snacks/pizzaslice/margherita,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "rB" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "rE" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/vending/hydroseeds{slogan_delay = 700; free = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"rH" = (/obj/effect/turf_decal{dir = 1},/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "rJ" = (/obj/machinery/atmospherics/pipe/manifold/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/disposalpipe/segment{dir = 10},/obj/structure/cable{icon_state = "2-4"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) +"rO" = (/obj/machinery/light/small{brightness = 2; dir = 8},/obj/structure/rack/shelf,/obj/item/reagent_containers/rag/towel/syndicate,/obj/item/reagent_containers/rag/towel/syndicate,/obj/item/soap/syndie,/obj/item/reagent_containers/rag/towel/syndicate,/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/turf/open/floor/plasteel/yellowsiding,/area/ruin/space/has_grav/feedersden) "rS" = (/obj/structure/table,/obj/item/reagent_containers/glass/beaker/fizulphite{pixel_x = -8},/obj/item/reagent_containers/glass/beaker/lipoifier{name = "lipoifier beaker"; pixel_y = -5},/obj/item/clothing/glasses/science{pixel_y = 8},/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "rW" = (/turf/open/floor/wood{icon_state = "wood-broken7"},/area/ruin/space/has_grav/feedersden) "sa" = (/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"sn" = (/obj/structure/lattice/catwalk,/obj/machinery/porta_turret/fattening,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "sq" = (/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "su" = (/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/obj/structure/rack/shelf,/obj/item/storage/box/ingredients/wildcard,/obj/item/storage/box/ingredients/wildcard,/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) "sC" = (/obj/machinery/vending/hydronutrients{free = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -140,7 +144,7 @@ "tb" = (/obj/structure/table/wood,/obj/machinery/chem_dispenser/drinks/fullupgrade{dir = 1},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "tf" = (/obj/item/trash/plate{pixel_x = -5; pixel_y = 4},/turf/open/floor/wood{icon_state = "wood-broken7"},/area/ruin/space/has_grav/feedersden) "tj" = (/obj/item/book/manual/blubbery_bartender{pixel_y = -4; pixel_x = -4},/obj/item/book/manual/fatty_chems{pixel_y = -8; pixel_x = -8},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) -"ty" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{brightness = 2; dir = 8},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) +"ty" = (/obj/effect/turf_decal/stripes/white/line{dir = 8; icon_state = "steel_decals_central4"},/turf/open/floor/plasteel/yellowsiding{dir = 8},/area/ruin/space/has_grav/feedersden) "tB" = (/obj/effect/turf_decal/loading_area{icon_state = "steel_decals_central7"},/obj/effect/turf_decal/loading_area{dir = 9; icon_state = "steel_decals4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "tE" = (/obj/structure/table/wood,/obj/item/reagent_containers/food/drinks/soda_cans/cola,/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb{pixel_y = -7; pixel_x = -5},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) "tH" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes/white/line{dir = 2; icon_state = "steel_decals_central4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -156,7 +160,7 @@ "uF" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/stock_parts/cell/high/plus,/obj/structure/cable{icon_state = "1-2"},/obj/item/gps,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "uO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "uX" = (/obj/machinery/computer/security/telescreen/entertainment,/obj/structure/disposalpipe/segment,/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) -"vf" = (/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"vf" = (/obj/machinery/button/door{desc = "A remote control-switch for secure storage."; id = "feederden_hangar"; name = "Syndicate Hangar Blast Doors"; req_access_txt = "11"; pixel_y = -24},/obj/effect/turf_decal/caution{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "vk" = (/obj/item/trash/candy{pixel_x = 10; pixel_y = -3},/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) "vp" = (/obj/machinery/abductor/feeder_console,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "vt" = (/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "steel_decals9"},/obj/effect/turf_decal{dir = 4},/obj/effect/turf_decal{dir = 8},/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -165,7 +169,7 @@ "vH" = (/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "vL" = (/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals1"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "vY" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) -"wk" = (/obj/effect/turf_decal,/obj/effect/turf_decal{dir = 8},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"wk" = (/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/effect/turf_decal/stripes/line{dir = 10},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "wn" = (/obj/machinery/atmospherics/components/unary/vent_pump/on,/obj/structure/rack/shelf,/obj/item/storage/box/beakers/bluespace,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "ww" = (/obj/structure/flora/rock,/turf/open/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav) "wy" = (/obj/machinery/button/door{id = "feederden_cell1"; name = "Cell 1 Control"; normaldoorcontrol = 1; specialfunctions = 4; pixel_y = 32; pixel_x = -8},/obj/machinery/button/door{id = "feederden_cell2"; name = "Cell 2 Control"; normaldoorcontrol = 1; specialfunctions = 4; pixel_y = 32; pixel_x = 8},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -181,7 +185,7 @@ "yb" = (/obj/structure/sign/poster/contraband/eat{pixel_y = 32},/obj/structure/chair/sofachair,/obj/machinery/light/small{dir = 1},/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "yg" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "yk" = (/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central7"},/obj/effect/turf_decal/stripes/white/line{dir = 2; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals3"},/obj/effect/turf_decal/stripes/white/line{dir = 4; icon_state = "steel_decals3"},/obj/machinery/light{light_color = "#cee5d2"},/obj/item/storage/bag/plants,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"yq" = (/obj/effect/turf_decal{dir = 1},/obj/effect/turf_decal{dir = 4},/obj/machinery/light{light_color = "#c9d3e8"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"yq" = (/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/effect/turf_decal/stripes/line{dir = 5},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "zc" = (/obj/effect/turf_decal/loading_area{icon_state = "steel_decals6"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "zg" = (/obj/machinery/airalarm/syndicate{pixel_y = 32},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "zl" = (/obj/machinery/autolathe/hacked,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -197,6 +201,7 @@ "zS" = (/obj/structure/chair/sofa/right{dir = 4},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "zY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/spawner/structure/window/plastitanium,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Aa" = (/obj/structure/fans/tiny,/obj/effect/turf_decal{dir = 4},/obj/effect/turf_decal{dir = 8},/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Ae" = (/obj/machinery/shower{dir = 4},/turf/open/pool,/area/ruin/space/has_grav/feedersden) "Ag" = (/obj/machinery/vending/boozeomat/all_access,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) "Aj" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "AD" = (/obj/structure/table/wood,/obj/item/storage/box/drinkingglasses{pixel_y = 10; pixel_x = 4},/obj/item/reagent_containers/glass/beaker/bluespace{pixel_y = 10; pixel_x = -10},/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) @@ -207,26 +212,29 @@ "Bz" = (/obj/structure/flora/rock/pile,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "BD" = (/obj/machinery/atmospherics/pipe/manifold/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "BP" = (/obj/structure/rack/shelf,/obj/item/vending_refill/kink,/obj/item/vending_refill/mealdor,/obj/item/vending_refill/mealdor,/obj/item/vending_refill/mealdor,/obj/item/vending_refill/mealdor,/obj/item/vending_refill/cola,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"BV" = (/obj/effect/turf_decal/stripes{icon_state = "trim"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"BV" = (/obj/effect/turf_decal/stripes{icon_state = "trim"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "Cc" = (/obj/structure/chair/sofa/left,/turf/open/floor/carpet/orange,/area/ruin/space/has_grav/feedersden) +"Cd" = (/obj/structure/lattice/catwalk,/turf/open/floor/plating,/area/ruin/unpowered/no_grav) "Cn" = (/obj/structure/lattice,/turf/closed/wall/r_wall/syndicate/nodiagonal,/area/ruin/space/has_grav/feedersden) "Cu" = (/obj/machinery/door/airlock/hatch{name = "airlock"; req_access_txt = "150"},/obj/effect/turf_decal/stripes/red/line{dir = 4},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "CH" = (/obj/item/reagent_containers/food/snacks/pizzaslice/margherita,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) +"CT" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/turf/open/floor/plasteel/yellowsiding,/area/ruin/space/has_grav/feedersden) "Dc" = (/turf/closed/wall/r_wall/syndicate/nodiagonal,/area/ruin/space/has_grav/feedersden) "Dq" = (/obj/structure/closet/crate/secure/weapon,/obj/item/clothing/glasses/hud/health/night,/obj/item/kitchen/knife/combat,/obj/effect/turf_decal/tile/brown,/obj/item/gun/energy/fatoray,/obj/item/book/granter/spell/fattening,/obj/item/gun/energy/laser/alter_ray/gainrate,/obj/item/cookiesynth,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/structure/window/reinforced/tinted{dir = 4},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Ds" = (/turf/closed/mineral/random,/area/template_noop) "Dx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "DB" = (/obj/structure/cable,/obj/machinery/power/smes{charge = 5e+006},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "DK" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = null},/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/milk,/obj/item/reagent_containers/food/condiment/milk,/obj/item/reagent_containers/food/condiment/milk,/obj/item/reagent_containers/food/condiment/rice,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"DM" = (/obj/machinery/power/rtg/advanced/fullupgrade,/obj/structure/cable,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"DO" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"DU" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"Eh" = (/obj/structure/cable{icon_state = "1-4"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"Ek" = (/obj/structure/cable,/obj/machinery/power/rtg/advanced/fullupgrade,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"DM" = (/obj/machinery/power/rtg/advanced/fullupgrade,/obj/structure/cable,/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"DO" = (/obj/effect/turf_decal/tile/brown{dir = 1},/obj/effect/turf_decal/tile/brown{dir = 8},/obj/machinery/food_cart,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"DU" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/structure/cable{icon_state = "2-8"},/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Eh" = (/obj/structure/cable{icon_state = "1-4"},/obj/structure/cable{icon_state = "1-2"},/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Ek" = (/obj/structure/cable,/obj/machinery/power/rtg/advanced/fullupgrade,/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "En" = (/obj/item/reagent_containers/food/snacks/chocolatebar,/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) -"Eq" = (/obj/machinery/shower{dir = 8},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) +"Eq" = (/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Es" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/closed/wall/r_wall/syndicate,/area/ruin/space/has_grav/feedersden) "Ex" = (/obj/item/trash/boritos,/turf/open/floor/wood,/area/ruin/space/has_grav/feedersden) +"EB" = (/obj/structure/pool/ladder{dir = 8},/turf/open/pool,/area/ruin/space/has_grav/feedersden) "EH" = (/obj/structure/reagent_dispensers/keg/milk,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "EU" = (/obj/structure/table/wood,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/obj/item/paper/fluff/ruins/feeder_den/report4,/obj/item/pen/red,/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "EW" = (/obj/machinery/porta_turret/fattening,/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/structure/lattice/catwalk,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) @@ -266,7 +274,7 @@ "LN" = (/obj/structure/table,/obj/item/reagent_containers/food/condiment/enzyme{layer = 5; pixel_x = -5; pixel_y = 6},/obj/item/reagent_containers/food/condiment/enzyme{layer = 5; pixel_x = 1; pixel_y = 6},/obj/item/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/item/reagent_containers/food/condiment/saltshaker{pixel_x = 9},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "LT" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes{icon_state = "steel_grid"; dir = 5},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "LV" = (/obj/machinery/adipoelectric_transformer,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"Ma" = (/obj/structure/sink{dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -24},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) +"Ma" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/turf/open/floor/plasteel/yellowsiding/corner{dir = 8},/area/ruin/space/has_grav/feedersden) "Md" = (/obj/structure/table,/obj/machinery/microwave,/obj/machinery/button/door{name = "Window Shutters South"; id = "feederden_south"; pixel_y = -25},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Mi" = (/obj/structure/disposalpipe/segment{dir = 10},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Mq" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"},/obj/effect/turf_decal/stripes/white/line{dir = 5; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 10; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -280,13 +288,13 @@ "Nz" = (/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "NA" = (/obj/structure/sign/poster/contraband/donut_corp{pixel_x = -32},/obj/structure/scale,/turf/open/floor/mineral/basaltstone_floor,/area/ruin/space/has_grav/feedersden) "NB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/stripes{icon_state = "steel_grid"; dir = 10},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"NJ" = (/obj/structure/curtain,/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "borderfloor"},/turf/open/floor/plasteel/freezer,/area/ruin/space/has_grav/feedersden) +"NJ" = (/obj/structure/curtain,/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "NR" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "NX" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/railing,/turf/open/floor/plasteel/stairs/left{dir = 4},/area/ruin/space/has_grav/feedersden) "Oc" = (/turf/open/floor/wood{icon_state = "wood-broken"},/area/ruin/space/has_grav/feedersden) "Ow" = (/obj/effect/turf_decal/sand/plating,/turf/open/floor/plating/asteroid,/area/ruin/space/has_grav/feedersden) "OE" = (/obj/item/trash/can,/obj/effect/mob_spawn/human/feeders_den/victim{dir = 8},/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) -"OH" = (/obj/effect/turf_decal{dir = 1},/obj/effect/turf_decal{dir = 8},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) +"OH" = (/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/effect/turf_decal/stripes/line{dir = 9},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "Pg" = (/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/medkit_cabinet{pixel_y = 27},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Pk" = (/obj/effect/turf_decal{dir = 1},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "Pv" = (/obj/effect/turf_decal/tile/brown{dir = 8},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -304,9 +312,10 @@ "Rw" = (/obj/machinery/atmospherics/components/unary/outlet_injector/on{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plating/airless,/area/ruin/space/has_grav/feedersden) "Rz" = (/obj/structure/railing{dir = 1},/turf/open/floor/plasteel/stairs/left{dir = 8},/area/ruin/space/has_grav/feedersden) "RC" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{dir = 8; piping_layer = 3; pixel_x = 5; pixel_y = 5},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"RV" = (/obj/structure/toilet{dir = 8},/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Sh" = (/obj/machinery/telecomms/relay/preset/ruskie{use_power = 0},/obj/item/multitool{pixel_x = 8},/turf/open/floor/circuit/red,/area/ruin/space/has_grav/feedersden) "Sm" = (/obj/structure/cable{icon_state = "1-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) -"Sp" = (/obj/structure/sign/warning/radiation{pixel_y = -31},/obj/structure/cable,/obj/machinery/power/rtg/advanced/fullupgrade,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Sp" = (/obj/structure/sign/warning/radiation{pixel_y = -31},/obj/structure/cable,/obj/machinery/power/rtg/advanced/fullupgrade,/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "Ss" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "Sy" = (/obj/structure/table,/obj/item/reagent_containers/food/condiment/sugar{pixel_x = -7},/obj/item/reagent_containers/glass/beaker{pixel_x = 9},/obj/item/reagent_containers/glass/beaker/bluespace{pixel_y = 3},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "SX" = (/obj/structure/filingcabinet,/obj/item/paper/fluff/ruins/feeder_den/report1,/obj/item/paper/fluff/ruins/feeder_den/report2,/obj/item/paper/fluff/ruins/feeder_den/report3,/obj/structure/fluff/paper,/obj/item/paper,/obj/item/paper,/obj/item/paper,/obj/item/paper,/obj/item/paper,/obj/item/paper,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/obj/effect/turf_decal/tile/red,/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) @@ -323,11 +332,11 @@ "Ue" = (/obj/machinery/atmospherics/pipe/manifold/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment,/obj/structure/cable{icon_state = "1-4"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "UB" = (/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/obj/structure/disposalpipe/segment,/obj/effect/turf_decal/stripes{icon_state = "steel_grid"; dir = 5},/turf/open/floor/plasteel/dark,/area/ruin/space/has_grav/feedersden) "UE" = (/turf/open/floor/carpet/black,/area/ruin/space/has_grav/feedersden) -"UJ" = (/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"UJ" = (/obj/structure/cable{icon_state = "2-8"},/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "UZ" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/open/floor/plating/airless,/area/ruin/space/has_grav/feedersden) "Ve" = (/obj/structure/flora/junglebush,/turf/open/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav) -"Vv" = (/obj/effect/turf_decal/stripes/white/line{dir = 8; icon_state = "steel_decals4"},/obj/machinery/quantumpad/supply_only{map_pad_id = "denbase"; map_pad_link_id = "lavalandbase"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) -"Vx" = (/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Vv" = (/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/obj/effect/turf_decal/stripes/box,/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) +"Vx" = (/obj/effect/turf_decal/stripes{icon_state = "trim"; dir = 1},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "VF" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/effect/spawner/lootdrop/bedsheet,/obj/item/toy/plush/random,/obj/item/toy/plush/random,/obj/item/toy/plush/random,/obj/machinery/light{dir = 4},/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "VW" = (/obj/effect/turf_decal/stripes/white/line{dir = 1; icon_state = "steel_decals_central4"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "Wr" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4; piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/effect/turf_decal/stripes{icon_state = "steel_decals5"; dir = 1},/obj/effect/turf_decal/stripes/white/line{dir = 6; icon_state = "steel_decals7"},/obj/effect/turf_decal/stripes/white/line{dir = 9; icon_state = "steel_decals7"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) @@ -349,7 +358,9 @@ "Yk" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{piping_layer = 3; pixel_x = 5; pixel_y = 5},/obj/machinery/door/airlock/public/glass{name = "Cell 3"; id_tag = "feederden_cell3"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "Yp" = (/obj/machinery/atmospherics/components/unary/vent_pump/on{dir = 8},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "YA" = (/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "steel_decals9"},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "steel_decals9"},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"YB" = (/obj/structure/fans/tiny,/obj/machinery/door/poddoor{id = "feederden_hangar"; name = "den hangar door"; dir = 4},/turf/open/floor/plating,/area/ruin/space/has_grav/feedersden) "YE" = (/obj/structure/rack,/obj/item/storage/toolbox/syndicate,/obj/item/multitool,/obj/item/clothing/head/welding,/obj/effect/turf_decal/tile/brown{dir = 4},/obj/effect/turf_decal/tile/brown{dir = 1},/obj/structure/sign/poster/contraband/syndicate_pistol{pixel_y = 32},/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) +"YI" = (/obj/effect/turf_decal,/obj/item/stack/marker_beacon{anchored = 1; icon_state = "markerburgundy-on"; light_color = "#FA644B"; light_power = 3; light_range = 2; name = "landing marker"; picked_color = "Burgundy"},/turf/open/floor/mineral/plastitanium/red,/area/ruin/space/has_grav/feedersden) "YN" = (/obj/item/trash/fatoray_scrap1,/obj/structure/sign/warning/securearea{pixel_y = 32},/turf/open/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav) "YU" = (/obj/structure/table,/obj/item/reagent_containers/food/snacks/burger/cheese,/turf/open/floor/plasteel,/area/ruin/space/has_grav/feedersden) "YX" = (/turf/open/floor/circuit/red,/area/ruin/space/has_grav/feedersden) @@ -382,21 +393,21 @@ FEebebebqFBrBrnrfMsqelzCnrLMelwnnrSXXFXFwODcwYrWOclQeSiXGFCcoKoKoKNzItgUeZICnrhl FEFEFEFEFEBrBrDcnrnrnurkDcgUKHzYDcDcgUdHDcDccwoKoKOcoKoKoKvkrWoKoKNzItDcDcDcDcgUYkzYDcftbxnrnrDcBrBrFEFEFEFEFE FEFEFEFEFEBrBrBrnrtZlltPwyLoJWMqLoKofbcdcdzgcdRpRpqiRpRpRpXhRpRpRpjOkKkKRzKoLusabcQKzwgnLTmmnrBrBrFEFEFEFEFEFE FEFEFEFEfmBrBrBrnrZnNBLvAjNRgZKWNRAjNXTGTGTGTGBDTGXWZhZhZhqquOuOuOuOuOrJZOWrndWrsNnArBxJLfZnnrqFebebebFEFEFEFE -FEFEFEfmfmBrBrBrDcDcNJNJDcnrnrnrnrnrnrnrnrnrDcWJiONxgUgUgUuXZpTKDcnrnrQFnrnrnrnrnrnrDciuiuDcDcBrFEFEFEFEFEFEFE -FEFEBrZCfmISBrBrBrnrMaEqnrNggqvpnrWNYEfncnbanrDxvYFDLNdCsRiNvYSsnrZeIoxCkoPgnrridlkCnrfNginrBrBrBrFEFEFEFEFEFE -FEFEBrBrfmfmBrBrBrnrtyEqnrIGJhJhWsDOlsuklslsvtDxvYSyBeaaaaUBvYmUnrcWmaUerscxtVbXJhkMnrfNdAnrBrBrBrFEFEFEFEFEFE -FEFEFEBrwwfmeEBrBrDcnrnrDcxGHpEHNkDOtHguboygaQoYvYvYvYvYvYvwvYkdnrgFXsFHYpDBnrzlJhXPDcnrnrDcBrBrBrFEFEFEFEFEFE -FEFEFEBrxZfmfmBrDcDcDcDcDcDcnrnrDcDOlsucaEBPnrvYaDMYMdRhDKjhANYUnrnrnrTPJhfKDcnrRanrDcBrEWYNxZBrBrBrFEFEFEFEFE -FEFEFEFEfmfmBrBrDcgkgkqMJhJhJhwknrqhlslszcVFDczAnrnrnrkgnrnrnrnrDcmDnQddRCuFnrNtVWdvnrISVefmfmfxBrBrFEFEFEFEFE -FEFEFEFEFEfmBrBrDcJhJhJhJhJhJhJhnrmfrfVvYhdzPItjfhnroHoHoHdrVxnwAaYAtBTYzGzEHivLMisCkgeEfmFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhnrikrfrfYhDqbWTxsunroHoHoHdrBVBVAaYApeWZlhFmEsieuqrEuyRwfmFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhRccRvfPvzJjSTUnrnrnrpfgDoHWtpfnrnrnrnrnrnWnrnrDcaMsIaMtIUZFEFEFEebFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhDcnrnrnrnrnrnrXLdLebebebebebqFXLBrBrDcEhDUUJDcaMsIaMDcqFebebqFqFFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcJhJhJhJhJhJhJhDcXLXLXLXLXLXLBrplVeFEFEFEFEVeEWVefmDcEkSpDMDcaMykaMDcDsFEFEBrBrFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcPkPkyqJhJhJhOHDcBrBrBrBrBrBrBrISfmFEFEFEFEfmISZCISDcDcDcDcDcDcDcDcDcDsFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEBrBrDcDcDcDcDcDcDcDcDcBrBrFEFEBrBrFEFEFEFEFEFEFEBrfmfmwwxZfmfmfmBrBrqFqFDsDsFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEBrBrBrBrBrBrBrBrBrBrBrBrFEFEFEFEFEFEFEFEFEFEFEBrBrVefmfmfmfmeEfmKuqFqFKuFEFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrZCZCfmFEFEFEebebFEFEFEFEFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrBrFEFEFEFEFEebFEFEFEFEFEFEFEFEFEFEFEFEFE +FEFEFEfmfmBrBrDcDcDcNJNJDcnrnrnrnrnrnrnrnrnrDcWJiONxgUgUgUuXZpTKDcnrnrQFnrnrnrnrnrnrDciuiuDcDcBrFEFEFEFEFEFEFE +FEFEBrZCfmISBrDcrOCTMadjnrNggqvpnrWNYEfncnbanrDxvYFDLNdCsRiNvYSsnrZeIoxCkoPgnrridlkCnrfNginrBrBrBrFEFEFEFEFEFE +FEFEBrBrfmfmBrDcAeEBtyEqnrIGJhJhWslslsuklslsvtDxvYSyBeaaaaUBvYmUnrcWmaUerscxtVbXJhkMnrfNdAnrBrBrBrFEFEFEFEFEFE +FEFEFEBrfmfmeEDcAeEBtyRVDcxGHpEHNklstHguboygaQoYvYvYvYvYvYvwvYkdnrgFXsFHYpDBnrzlJhXPDcnrnrDcBrBrBrFEFEFEFEFEFE +FEFEFEBrfmsnVvpfDcDcDcDcDcDcnrnrDcDOlsucaEBPnrvYaDMYMdRhDKjhANYUnrnrnrTPJhfKDcnrRanrDcBrEWYNxZBrBrBrFEFEFEFEFE +FEFEFEFEfmfmCdYBYIgkgkqMJhJhJhwknrqhlslszcVFDczAnrnrnrkgnrnrnrnrDcmDnQddRCuFnrNtVWdvnrISVefmfmfxBrBrFEFEFEFEFE +FEFEFEFEFEfmCdYBJhJhJhJhJhJhJhJhnrmfrflsYhdzPItjfhnroHoHoHdrVxnwAaYAtBTYzGzEHivLMisCkgeEfmFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFECdYBJhJhJhJhJhJhJhJhnrikrflsYhDqbWTxsunroHoHoHdrBVBVAaYApeWZlhFmEsieuqrEuyRwfmFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFECdYBJhJhJhJhJhJhJhRccRvfPvzJjSTUnrnrnrpfgDoHWtpfnrnrnrnrnrnWnrnrDcaMsIaMtIUZFEFEFEebFEFEFEFEFEFEFE +FEFEFEFEFEFECdYBJhJhJhJhJhJhJhJhDcnrnrnrnrnrnrXLdLebebebebebqFXLBrBrDcEhDUUJDcaMsIaMDcqFebebqFqFFEFEFEFEFEFEFE +FEFEFEFEFEFECdYBJhJhJhJhJhJhJhJhDcBrBrBrBrBrBrBrplVeFEFEFEFEVeEWVefmDcEkSpDMDcaMykaMDcDsFEFEBrBrFEFEFEFEFEFEFE +FEFEFEFEFEFECdYBrHPkPkyqJhJhJhOHDcBrBrBrBrBrBrBrISfmFEFEFEFEfmISZCISDcDcDcDcDcDcDcDcDcDsFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEsnVvpfDcDcDcDcDcDcDcDcDcBrBrBrFEBrBrFEFEFEFEFEFEFEBrfmfmwwxZfmfmfmBrBrqFqFDsDsFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEBrBrBrBrBrBrBrBrBrBrBrBrBrBrFEFEFEFEFEFEFEFEFEFEFEBrBrVefmfmfmfmeEfmKuqFqFKuFEFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEFEBrBrBrBrBrBrBrBrBrBrBrBrFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrZCZCfmFEFEFEebebFEFEFEFEFEFEFEFEFEFEFEFEFE +FEFEFEFEFEFEFEFEBrBrBrBrBrFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrBrFEFEFEFEFEebFEFEFEFEFEFEFEFEFEFEFEFEFE FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEBrBrBrBrFEFEFEFEFEebFEFEFEFEFEFEFEFEFEFEFEFEFE "} diff --git a/_maps/shuttles/feeder_ship_default.dmm b/_maps/shuttles/feeder_ship_default.dmm index 4ffbc3137a..ff2ef608c3 100644 --- a/_maps/shuttles/feeder_ship_default.dmm +++ b/_maps/shuttles/feeder_ship_default.dmm @@ -4,6 +4,10 @@ dir = 8 }, /obj/structure/closet/emcloset/anchored, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/tank/internals/emergency_oxygen/double, +/obj/item/tank/internals/emergency_oxygen/double, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/feeder_shuttle) "g" = ( @@ -44,6 +48,7 @@ /area/shuttle/feeder_shuttle) "p" = ( /obj/structure/chair/comfy/shuttle, +/obj/machinery/door/window/survival_pod, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/feeder_shuttle) "r" = ( @@ -51,12 +56,21 @@ dir = 4; light_color = "#c1caff" }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/structure/medkit_cabinet{ + pixel_x = 24 + }, /turf/open/floor/mineral/plastitanium, /area/shuttle/feeder_shuttle) "y" = ( /obj/structure/chair/comfy/shuttle{ dir = 1 }, +/obj/machinery/door/window/survival_pod{ + dir = 1 + }, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/feeder_shuttle) "z" = ( @@ -67,6 +81,7 @@ /area/shuttle/feeder_shuttle) "C" = ( /obj/structure/table/reinforced, +/obj/machinery/cell_charger, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/feeder_shuttle) "D" = ( @@ -80,7 +95,16 @@ /turf/open/floor/plating, /area/shuttle/feeder_shuttle) "F" = ( -/obj/machinery/door/window/survival_pod, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = 24 + }, /turf/open/floor/mineral/plastitanium, /area/shuttle/feeder_shuttle) "G" = ( @@ -135,6 +159,9 @@ shuttleId = "feeder_ship"; possible_destinations = "feeder_home;whiteship_home;feeder_custom" }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, /turf/open/floor/mineral/plastitanium, /area/shuttle/feeder_shuttle) "Y" = ( @@ -143,8 +170,8 @@ /turf/open/floor/plating, /area/shuttle/feeder_shuttle) "Z" = ( -/obj/machinery/door/window/survival_pod{ - dir = 1 +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 }, /turf/open/floor/mineral/plastitanium, /area/shuttle/feeder_shuttle) @@ -188,17 +215,17 @@ j (5,1,1) = {" j p -Z l -F +l +l y j "} (6,1,1) = {" j D -r -l +F +Z r k j @@ -206,9 +233,9 @@ j (7,1,1) = {" Q z -j +I J -j +I z Q "}