diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index f5e8a30b70c..6aff54abbb5 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -390,6 +390,3 @@ /// Possible value of [/atom/movable/buckle_lying]. If set to a different (positive-or-zero) value than this, the buckling thing will force a lying angle on the buckled. #define NO_BUCKLE_LYING -1 -// Return values for [/mob/living/proc/handle_ventcrawl()] -#define VENTCRAWL_IN_SUCCESS 1 -#define VENTCRAWL_OUT_SUCCESS 2 diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 73f0605413a..9f1484930f8 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -147,9 +147,9 @@ stat("Resources:",resources) -/mob/living/simple_animal/hostile/swarmer/handle_ventcrawl(obj/machinery/atmospherics/ventcrawl_target) +/mob/living/simple_animal/hostile/swarmer/move_into_vent(obj/machinery/atmospherics/ventcrawl_target, message = TRUE) . = ..() - if(. == VENTCRAWL_IN_SUCCESS && light_on) + if(. && light_on) ToggleLight() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 6a615a761be..836eeb0e78f 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1275,8 +1275,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g return -/// Conditional proc that allows ventcrawling with this item, if it has TRAIT_VENTCRAWLER_ITEM_BASED trait. -/// Always allows by default. +/// Conditional proc that allows ventcrawling with an item, if it has trait TRAIT_VENTCRAWLER_ITEM_BASED. /obj/item/proc/used_for_ventcrawling(mob/living/user, provide_feedback = TRUE) - return TRUE + return FALSE diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 42318e8bed9..f7fcab7fa10 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -867,18 +867,18 @@ clothing_traits = list(TRAIT_VENTCRAWLER_ITEM_BASED) -/obj/item/clothing/under/contortionist/used_for_ventcrawling(mob/living/user, provide_feedback = TRUE) - // Allowed to wear: glasses, shoes, gloves, pockets, mask, and jumpsuit (obviously) - var/slots_must_be_empty = ITEM_SLOT_BACK|ITEM_SLOT_BELT|ITEM_SLOT_HEAD|ITEM_SLOT_CLOTH_OUTER|ITEM_SLOT_HANDS|ITEM_SLOT_HANDCUFFED|ITEM_SLOT_LEGCUFFED - - for(var/obj/item/item as anything in user.get_equipped_items(include_hands = TRUE)) - if(item.slot_flags & slots_must_be_empty) - if(provide_feedback) - to_chat(user, span_warning("Вы не можете ползать по вентиляции с [item.name].")) - return FALSE +/// Allowed to wear: glasses, shoes, gloves, mask, ears, pockets, id, pda and jumpsuit (obviously) +#define CONTORTIONIST_ALLOWED_SLOTS (ITEM_SLOT_CLOTH_INNER|ITEM_SLOT_ID|ITEM_SLOT_PDA|ITEM_SLOT_GLOVES|ITEM_SLOT_FEET|ITEM_SLOT_MASK|ITEM_SLOT_EYES|ITEM_SLOT_EARS|ITEM_SLOT_POCKETS) +/obj/item/clothing/under/contortionist/used_for_ventcrawling(mob/living/user, provide_feedback = TRUE) + if(user.get_equipped_slots(include_hands = TRUE) & ~CONTORTIONIST_ALLOWED_SLOTS) + if(provide_feedback) + to_chat(user, span_warning("Вы можете ползать по вентиляции только с перчатками, обувью, маской, очками, наушниками, а также комбинезоном с ID-картой и PDA.")) + return FALSE return TRUE +#undef CONTORTIONIST_ALLOWED_SLOTS + /obj/item/clothing/under/cursedclown name = "cursed clown suit" diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 799cf7cd771..750c6ae8417 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -616,11 +616,10 @@ * and not actually wearing it in any REAL equipment slot. */ /mob/proc/is_general_slot(slot) - return (slot & (ITEM_SLOT_HANDS|ITEM_SLOT_POCKETS|ITEM_SLOT_BACKPACK|ITEM_SLOT_HANDCUFFED|ITEM_SLOT_LEGCUFFED)) + return (slot & (ITEM_SLOT_HANDS|ITEM_SLOT_POCKETS|ITEM_SLOT_BACKPACK|ITEM_SLOT_HANDCUFFED|ITEM_SLOT_LEGCUFFED|ITEM_SLOT_ACCESSORY)) -//Outdated but still in use apparently. This should at least be a human proc. -//Daily reminder to murder this - Remie. +/// Collects all items in possibly equipped slots. /mob/proc/get_equipped_items(include_pockets = FALSE, include_hands = FALSE) var/list/items = list() if(back) @@ -635,6 +634,20 @@ return items +/// Same as above but we get slots, not items. +/mob/proc/get_equipped_slots(include_pockets = FALSE, include_hands = FALSE) + . = NONE + if(back) + . |= ITEM_SLOT_BACK + if(wear_mask) + . |= ITEM_SLOT_MASK + if(include_hands) + if(l_hand) + . |= ITEM_SLOT_HAND_LEFT + if(r_hand) + . |= ITEM_SLOT_HAND_RIGHT + + /mob/proc/get_all_slots() return list(wear_mask, back, l_hand, r_hand) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 0e312050531..fc08585f6a6 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -154,3 +154,13 @@ items += l_store return items + +/mob/living/carbon/alien/humanoid/get_equipped_slots(include_pockets = FALSE, include_hands = FALSE) + . = ..() + if(!include_pockets) + return . + if(r_store) + . |= ITEM_SLOT_POCKET_RIGHT + if(l_store) + . |= ITEM_SLOT_POCKET_LEFT + diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index ee5d86ac819..a9bd98bbde5 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -609,6 +609,37 @@ return items +/mob/living/carbon/human/get_equipped_slots(include_pockets = FALSE, include_hands = FALSE) + . = ..() + if(belt) + . |= ITEM_SLOT_BELT + if(l_ear) + . |= ITEM_SLOT_EAR_LEFT + if(r_ear) + . |= ITEM_SLOT_EAR_RIGHT + if(glasses) + . |= ITEM_SLOT_EYES + if(gloves) + . |= ITEM_SLOT_GLOVES + if(neck) + . |= ITEM_SLOT_NECK + if(shoes) + . |= ITEM_SLOT_FEET + if(wear_id) + . |= ITEM_SLOT_ID + if(wear_pda) + . |= ITEM_SLOT_PDA + if(w_uniform) + . |= ITEM_SLOT_CLOTH_INNER + if(include_pockets) + if(r_store) + . |= ITEM_SLOT_POCKET_RIGHT + if(l_store) + . |= ITEM_SLOT_POCKET_LEFT + if(s_store) + . |= ITEM_SLOT_SUITSTORE + + /mob/living/carbon/human/equipped_speed_mods() . = ..() for(var/obj/item/thing as anything in get_equipped_items()) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 9bdd0fb7d23..8685bd8db8c 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -496,6 +496,14 @@ return items +/mob/living/carbon/get_equipped_slots(include_pockets = FALSE, include_hands = FALSE) + . = ..() + if(wear_suit) + . |= ITEM_SLOT_CLOTH_OUTER + if(head) + . |= ITEM_SLOT_HEAD + + /mob/living/carbon/update_equipment_speed_mods() . = ..() update_limbless_slowdown() // in case we get crutches diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 7e74f02cba6..2b3aeae4257 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -193,11 +193,12 @@ return TRUE -/mob/living/silicon/handle_ventcrawl(obj/machinery/atmospherics/ventcrawl_target) +/mob/living/silicon/move_into_vent(obj/machinery/atmospherics/ventcrawl_target, message = TRUE) . = ..() - if(. == VENTCRAWL_IN_SUCCESS && inventory_head) - drop_hat() - visible_message("[name] опрокинул шляпу при залезании в вентиляцию!", "Помеха корпуса была утеряна.") + if(. && inventory_head) + drop_hat(drop_on_turf = TRUE) + if(message) + ventcrawl_target.visible_message("[name] опрокинул шляпу при залезании в вентиляцию!") /mob/living/silicon/robot/welder_act(mob/user, obj/item/I) diff --git a/code/modules/mob/living/silicon/silicon_hat.dm b/code/modules/mob/living/silicon/silicon_hat.dm index 94abb2e102f..9a137255af8 100644 --- a/code/modules/mob/living/silicon/silicon_hat.dm +++ b/code/modules/mob/living/silicon/silicon_hat.dm @@ -235,9 +235,13 @@ return TRUE -/mob/living/silicon/proc/drop_hat() + +/mob/living/silicon/proc/drop_hat(drop_on_turf = FALSE) if(inventory_head) - drop_item_ground(inventory_head) + if(drop_on_turf) + transfer_item_to_loc(inventory_head, get_turf(src)) + else + drop_item_ground(inventory_head) null_hat() regenerate_icons() diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 4b9476d89cb..4e7980f1115 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -46,7 +46,7 @@ if(HAS_TRAIT(src, TRAIT_VENTCRAWLER_ITEM_BASED)) var/item_allowed = FALSE - for(var/obj/item/item as anything in get_equipped_items(include_pockets = TRUE, include_hands = TRUE)) + for(var/obj/item/item as anything in get_equipped_items(include_pockets = TRUE)) if(item.used_for_ventcrawling(src, provide_feedback)) item_allowed = TRUE break @@ -64,20 +64,19 @@ //Handle the exit here if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) && is_ventcrawling(src) && (movement_type & VENTCRAWLING)) if(!can_ventcrawl(ventcrawl_target)) - return + return FALSE to_chat(src, span_notice("Вы начинаете вылезать из вентиляции...")) if(!do_after(src, 1 SECONDS, target = ventcrawl_target)) - return + return FALSE if(has_client && isnull(client)) - return + return FALSE if(!can_ventcrawl(ventcrawl_target)) - return - stop_ventcrawling() - return VENTCRAWL_OUT_SUCCESS + return FALSE + return stop_ventcrawling(ventcrawl_target) //Entrance here if(!can_ventcrawl(ventcrawl_target, entering = TRUE)) - return + return FALSE var/crawl_overlay = image('icons/effects/vent_indicator.dmi', "arrow", ABOVE_MOB_LAYER, dir = get_dir(src.loc, ventcrawl_target.loc)) //ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "arrow", ABOVE_MOB_LAYER, dir = get_dir(src.loc, ventcrawl_target.loc)), 2 SECONDS) @@ -88,15 +87,14 @@ ) if(!do_after(src, 4.5 SECONDS, target = ventcrawl_target)) ventcrawl_target?.cut_overlay(crawl_overlay) - return + return FALSE ventcrawl_target?.cut_overlay(crawl_overlay) if(has_client && isnull(client)) - return + return FALSE if(!can_ventcrawl(ventcrawl_target, entering = TRUE)) - return + return FALSE ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "insert", ABOVE_MOB_LAYER), 1 SECONDS) - move_into_vent(ventcrawl_target) - return VENTCRAWL_IN_SUCCESS + return move_into_vent(ventcrawl_target) /** @@ -104,8 +102,13 @@ * * Arguments: * * ventcrawl_target - The vent into which we are moving the mob + * * message - if TRUE shows visible message to everyone + * + * Returns `TRUE` on success. */ /mob/living/proc/move_into_vent(obj/machinery/atmospherics/ventcrawl_target, message = TRUE) + SHOULD_CALL_PARENT(TRUE) + if(message) visible_message( span_notice("[name] залез[genderize_ru(gender, "", "ла", "ло", "ли")] в вентиляцию!"), @@ -114,15 +117,21 @@ abstract_move(ventcrawl_target) ADD_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT) update_pipe_vision() + return TRUE /** * Moves living mob to the turf contents and cleanse ventcrawling stuff * * Arguments: + * * ventcrawl_target - The vent from which we are moved from * * message - if TRUE shows visible message to everyone + * + * Returns `TRUE` on success. */ -/mob/living/proc/stop_ventcrawling(message = TRUE) +/mob/living/proc/stop_ventcrawling(obj/machinery/atmospherics/ventcrawl_target, message = TRUE) + SHOULD_CALL_PARENT(TRUE) + if(!is_ventcrawling(src)) return FALSE var/turf/new_turf = get_turf(src)