diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm index ec641c0fa891..d05c11502787 100644 --- a/code/__DEFINES/interaction_flags.dm +++ b/code/__DEFINES/interaction_flags.dm @@ -24,6 +24,8 @@ #define INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT (1<<11) /// Bypass all can_perform_action checks for mouse drop #define INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY (1<<12) +/// Bypass adjacency but for real this time +#define INTERACT_ATOM_BYPASS_ADJACENCY (1<<13) /// Bypass all adjacency and other checks for mouse drop #define INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS (INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT | INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index aefd99f4d72b..7405654762e7 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -153,6 +153,7 @@ DEFINE_BITFIELD(interaction_flags_atom, list( "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, "INTERACT_ATOM_ALLOW_USER_LOCATION" = INTERACT_ATOM_ALLOW_USER_LOCATION, "INTERACT_ATOM_IGNORE_MOBILITY" = INTERACT_ATOM_IGNORE_MOBILITY, + "INTERACT_ATOM_BYPASS_ADJACENCY" = INTERACT_ATOM_BYPASS_ADJACENCY, )) DEFINE_BITFIELD(interaction_flags_machine, list( diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 44b303da3426..734b4b728efe 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -101,7 +101,7 @@ return FALSE /atom/proc/can_interact(mob/user, require_adjacent_turf = TRUE) - if(!user.in_range_to_interact_with(src, interaction_flags_atom & INTERACT_ATOM_ALLOW_USER_LOCATION)) + if(!user.in_range_to_interact_with(src, interaction_flags_atom & INTERACT_ATOM_ALLOW_USER_LOCATION, interaction_flags_atom & INTERACT_ATOM_BYPASS_ADJACENCY)) return FALSE if((interaction_flags_atom & INTERACT_ATOM_REQUIRES_DEXTERITY) && !ISADVANCEDTOOLUSER(user)) to_chat(user, span_warning("You don't have the dexterity to do this!")) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2bc75483b6c3..9f28e063c6a8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1066,7 +1066,7 @@ return ..(M, force, check_loc, buckle_mob_flags) ///Can the mob interact() with an atom? -/mob/proc/in_range_to_interact_with(atom/A, treat_mob_as_adjacent) +/mob/proc/in_range_to_interact_with(atom/A, treat_mob_as_adjacent, bypass_adjacency) if(isAdminGhostAI(src)) return TRUE //Return early. we do not need to check that we are on adjacent turfs (i.e we are inside a closet) @@ -1077,7 +1077,8 @@ var/datum/dna/mob_dna = has_dna() if(mob_dna?.check_mutation(/datum/mutation/human/telekinesis) && tkMaxRangeCheck(src, A)) return TRUE - + if(bypass_adjacency) // I hate badly named things + return TRUE //range check if(!interaction_range) // If you don't have extra length, GO AWAY return FALSE diff --git a/maplestation.dme b/maplestation.dme index 8175a56b1147..d0f3314f32fa 100644 --- a/maplestation.dme +++ b/maplestation.dme @@ -6396,6 +6396,7 @@ #include "maplestation_modules\code\game\objects\items\umbrellas.dm" #include "maplestation_modules\code\game\objects\items\weaponry.dm" #include "maplestation_modules\code\game\objects\items\devices\flashlight.dm" +#include "maplestation_modules\code\game\objects\items\devices\handheld_xenobio.dm" #include "maplestation_modules\code\game\objects\items\devices\triage_projector.dm" #include "maplestation_modules\code\game\objects\items\devices\PDA\PDA_types.dm" #include "maplestation_modules\code\game\objects\items\devices\radio\encryptionkey.dm" @@ -6581,6 +6582,7 @@ #include "maplestation_modules\code\modules\food_and_drinks\food\pizza.dm" #include "maplestation_modules\code\modules\food_and_drinks\food\resprites.dm" #include "maplestation_modules\code\modules\food_and_drinks\food\starfruit.dm" +#include "maplestation_modules\code\modules\food_and_drinks\machinery\smartfridge.dm" #include "maplestation_modules\code\modules\food_and_drinks\recipes\drinks_recipes.dm" #include "maplestation_modules\code\modules\food_and_drinks\recipes\food\egg_recipes.dm" #include "maplestation_modules\code\modules\food_and_drinks\recipes\food\pizza_recipes.dm" diff --git a/maplestation_modules/code/game/objects/items/devices/handheld_xenobio.dm b/maplestation_modules/code/game/objects/items/devices/handheld_xenobio.dm new file mode 100644 index 000000000000..866f65fd2162 --- /dev/null +++ b/maplestation_modules/code/game/objects/items/devices/handheld_xenobio.dm @@ -0,0 +1,140 @@ +#define GREY_CORE_FLAG (1<<0) +#define METAL_CORE_FLAG (1<<1) +#define ORANGE_CORE_FLAG (1<<2) +#define PURPLE_CORE_FLAG (1<<3) +#define BLUE_CORE_FLAG (1<<4) +#define ALL_REQUIRED_CORES (GREY_CORE_FLAG | METAL_CORE_FLAG | ORANGE_CORE_FLAG | PURPLE_CORE_FLAG | BLUE_CORE_FLAG) + +/// Makes sure we don't accidentally keep it on when we use this +/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) + . = ..() + interaction_flags_atom &= ~INTERACT_ATOM_BYPASS_ADJACENCY + +/// Link to an existing xenobio console to use it outside of the lab. Stop being a hermit! +/obj/item/handheld_xenobio + name = "Game-Slime portable console" + desc = "A handheld device capable of linking to a slime management console for keeping your slimes alive at a distance." + icon = 'maplestation_modules/icons/obj/devices.dmi' + icon_state = "gameslime" + item_flags = NOBLUDGEON + throwforce = 3 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 7 + drop_sound = 'maplestation_modules/sound/items/drop/device2.ogg' + pickup_sound = 'maplestation_modules/sound/items/pickup/device.ogg' + /// Buffer to save the slime management console in + var/datum/weakref/console_buffer + /// Slime cores required to activate the machine. If all are in, then we're good! + var/core_flags = NONE + /// The overlay we use to show if we're linked to a console, stored so we can remove it if needed + var/mutable_appearance/linked_overlay + +/obj/item/handheld_xenobio/Initialize(mapload) + . = ..() + linked_overlay = mutable_appearance(icon, "gs_linked") + +/obj/item/handheld_xenobio/examine(mob/user) + . = ..() + if((core_flags & ALL_REQUIRED_CORES) == ALL_REQUIRED_CORES) + return + var/list/missing_core_colors = list() + if(!(core_flags & GREY_CORE_FLAG)) + missing_core_colors += "grey" + if(!(core_flags & ORANGE_CORE_FLAG)) + missing_core_colors += "orange" + if(!(core_flags & PURPLE_CORE_FLAG)) + missing_core_colors += "purple" + if(!(core_flags & BLUE_CORE_FLAG)) + missing_core_colors += "blue" + if(!(core_flags & METAL_CORE_FLAG)) + missing_core_colors += "metal" + /// Build a string from our list because for some reason we don't have a helper to put "and" at the end of a joined list + var/length_of_colors = LAZYLEN(missing_core_colors) + var/color_core_index = 1 + var/built_string_list = "" + for(var/color_name in missing_core_colors) + // Last core in a list over 1 + if(length_of_colors > 1 && color_core_index == length_of_colors) + built_string_list += "and [color_name]" + break + // List is just 1 + if(length_of_colors == 1) + built_string_list += "[color_name]" + break + // First core in a list of 2 + if(length_of_colors == 2 && color_core_index == 1) + built_string_list += "[color_name] " + color_core_index++ + continue + // All others + built_string_list += "[color_name], " + color_core_index++ + . += span_notice("The console requires a [built_string_list] slime extract to function.") + +/obj/item/handheld_xenobio/attack_self(mob/user, modifiers) + . = ..() + if((core_flags & ALL_REQUIRED_CORES) != ALL_REQUIRED_CORES) + to_chat(user, span_notice("The console is missing required extracts!")) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return + if(isnull(console_buffer)) + to_chat(user, span_notice("No linked console!")) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return + var/obj/machinery/computer/camera_advanced/xenobio/buffered_camera = console_buffer?.resolve() + if(isnull(buffered_camera)) + to_chat(user, span_notice("Linked console connection severed!")) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + cut_overlay(linked_overlay) + console_buffer = null // just to be 100% sure + return + buffered_camera.interaction_flags_atom |= INTERACT_ATOM_BYPASS_ADJACENCY + buffered_camera.attack_hand(user) + +/obj/item/handheld_xenobio/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() + if((core_flags & ALL_REQUIRED_CORES) == ALL_REQUIRED_CORES) + return NONE + if(!(core_flags & GREY_CORE_FLAG) && istype(tool, /obj/item/slime_extract/grey)) + insert_extract(tool, GREY_CORE_FLAG) + return ITEM_INTERACT_SUCCESS + if(!(core_flags & METAL_CORE_FLAG) && istype(tool, /obj/item/slime_extract/metal)) + insert_extract(tool, METAL_CORE_FLAG) + return ITEM_INTERACT_SUCCESS + if(!(core_flags & ORANGE_CORE_FLAG) && istype(tool, /obj/item/slime_extract/orange)) + insert_extract(tool, ORANGE_CORE_FLAG) + return ITEM_INTERACT_SUCCESS + if(!(core_flags & PURPLE_CORE_FLAG) && istype(tool, /obj/item/slime_extract/purple)) + insert_extract(tool, PURPLE_CORE_FLAG) + return ITEM_INTERACT_SUCCESS + if(!(core_flags & BLUE_CORE_FLAG) && istype(tool, /obj/item/slime_extract/blue)) + insert_extract(tool, BLUE_CORE_FLAG) + return ITEM_INTERACT_SUCCESS + +/obj/item/handheld_xenobio/proc/insert_extract(obj/item/extract, flag_to_flip) + var/mutable_appearance/inserted_overlay = mutable_appearance(icon, "gs_[extract.icon_state]") + add_overlay(inserted_overlay) + qdel(extract) + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + core_flags |= flag_to_flip + +/obj/item/handheld_xenobio/attack_atom(atom/attacked_atom, mob/living/user, params) + if(!istype(attacked_atom, /obj/machinery/computer/camera_advanced/xenobio)) + return ..() + if(!isnull(console_buffer)) + to_chat(user, span_notice("Already linked!")) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return ..() + var/obj/machinery/computer/camera_advanced/xenobio/new_buffered_console = attacked_atom + console_buffer = WEAKREF(new_buffered_console) + playsound(src, 'sound/machines/ping.ogg', 50, FALSE) + add_overlay(linked_overlay) + to_chat(user, span_nicegreen("Linked to console!")) + +#undef GREY_CORE_FLAG +#undef METAL_CORE_FLAG +#undef ORANGE_CORE_FLAG +#undef PURPLE_CORE_FLAG +#undef BLUE_CORE_FLAG +#undef ALL_REQUIRED_CORES diff --git a/maplestation_modules/code/modules/food_and_drinks/machinery/smartfridge.dm b/maplestation_modules/code/modules/food_and_drinks/machinery/smartfridge.dm new file mode 100644 index 000000000000..45147b685dfe --- /dev/null +++ b/maplestation_modules/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -0,0 +1,6 @@ +// File for overriding smart fridges +/obj/machinery/smartfridge/extract/accept_check(obj/item/weapon) + return (istype(weapon, /obj/item/slime_extract) || istype(weapon, /obj/item/slime_scanner) || istype(weapon, /obj/item/handheld_xenobio)) + +/obj/machinery/smartfridge/extract/preloaded + initial_contents = list(/obj/item/slime_scanner = 2, /obj/item/handheld_xenobio = 1) diff --git a/maplestation_modules/icons/obj/devices.dmi b/maplestation_modules/icons/obj/devices.dmi index 5e6c1ac234fc..0d4f41272012 100644 Binary files a/maplestation_modules/icons/obj/devices.dmi and b/maplestation_modules/icons/obj/devices.dmi differ