diff --git a/code/datums/components/traits/waddle.dm b/code/datums/components/traits/waddle.dm index 4f1e82b7b0..8548e19599 100644 --- a/code/datums/components/traits/waddle.dm +++ b/code/datums/components/traits/waddle.dm @@ -22,9 +22,9 @@ SIGNAL_HANDLER if (QDELETED(our_atom)) return - //Living owner only. No waddling while downed. + //Living owner only. No waddling while downed or being thrown. if(living_owner) - if(living_owner.stat != CONSCIOUS || living_owner.resting) + if(living_owner.stat != CONSCIOUS || living_owner.resting || living_owner.throwing) return if(waddling) waddle_waddle(our_atom) diff --git a/code/game/objects/structures/spring_trap.dm b/code/game/objects/structures/spring_trap.dm new file mode 100644 index 0000000000..8e8e79c3ec --- /dev/null +++ b/code/game/objects/structures/spring_trap.dm @@ -0,0 +1,131 @@ +/obj/structure/spring_trap + name = "spring trap" + gender = PLURAL + layer = 2.6 + anchored = TRUE + + var/sprung = TRUE + var/distance = 3 + var/max_distance = 10 + var/reset_time = 15 SECONDS + + icon = 'icons/obj/items.dmi' + icon_state = "spring_trap" + +/obj/structure/spring_trap/start_active + sprung = FALSE + +/obj/structure/spring_trap/attackby(obj/item/W, mob/user, attack_modifier, click_parameters) + if(W.has_tool_quality(TOOL_WRENCH)) + playsound(src, W.usesound, 50, TRUE) + if(do_after(user, 10 SECONDS, target = src)) + user.visible_message(span_danger("[user] has disassembled \the [src]."), span_notice("You disassemble \the [src].")) + sprung = TRUE + new /obj/item/spring_trap_kit(get_turf(src)) + qdel(src) + else if(!sprung) + trigger(user, TRUE) + return + if(W.has_tool_quality(TOOL_SCREWDRIVER)) + playsound(src, W.usesound, 50, TRUE) + if(do_after(user, 10 SECONDS, target = src)) + user.visible_message(span_danger("[user] starts adjusting the spring in \the [src]"), span_notice("You adjust the spring in \the [src]")) + distance = tgui_input_number(user, "Pick distance", "distance", min_value = 1, max_value = max_distance) + return + if(W.has_tool_quality(TOOL_CROWBAR)) + playsound(src, W.usesound, 50, TRUE) + if(do_after(user, 10 SECONDS, target = src)) + user.visible_message(span_danger("[user] starts adjusting the spring in \the [src]"), span_notice("You adjust the spring in \the [src]")) + var/temp_dir = tgui_input_list(user, "Pick direction", "direction", list("north", "south", "east", "west"), SOUTH) + dir = text2dir(temp_dir) + return + . = ..() + +/obj/structure/spring_trap/attack_hand(mob/user) + if(!sprung) + user.visible_message( + span_danger("[user] starts to disarm \the [src]."),span_notice("You begin disarming \the [src]."), "You hear the slow creaking of a spring.") + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + + if(do_after(user, 10 SECONDS, target = src)) + user.visible_message(span_danger("[user] has disarmed \the [src]."), span_notice("You have disarmed \the [src].")) + sprung = TRUE + update_icon() + else + trigger(user, TRUE) + else + user.visible_message(span_danger("[user] starts to reset \the [src]."), span_notice("You begin resetting \the [src]."), "You hear the slow creaking of a spring.") + if(do_after(user, 5 SECONDS, target = src)) + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + sprung = FALSE + update_icon() + +/obj/structure/spring_trap/proc/trigger(mob/living/target) + SSmotiontracker.ping(src, 100) + log_and_message_admins("has been yote by a [name] at \the [get_area(loc)], last touched by [forensic_data?.get_lastprint()]", target) + playsound(src, 'sound/machines/click.ogg', 50, 1) + + visible_message(span_danger("[target] triggers \the [src]."), span_danger("You trigger \the [src]."), span_infoplain(span_bold("You hear a spring creaking!"))) + + var/turf/T = get_turf(src) + if(!T) + return + + var/turf/land_turf = T + + for(var/i, i < max_distance, i++) + if(iswall(land_turf)) + continue + land_turf = get_step(land_turf, dir) + + for(var/atom/movable/thing in (T.contents | target)) + if(thing == src || thing.anchored) + continue + if(isliving(target)) + var/mob/living/L = target + if(L.mob_size <= MOB_TINY) + var/turf/new_turf = land_turf + for(var/i, i < max_distance, i++) + if(iswall(new_turf)) + continue + new_turf = get_step(new_turf, dir) + L.throw_at(new_turf, distance, 1) + continue + thing.throw_at(land_turf, distance, 1) + + sprung = TRUE + addtimer(CALLBACK(src, PROC_REF(reset)), reset_time, TIMER_DELETE_ME) + +/obj/structure/spring_trap/Crossed(atom/movable/AM) + if(AM.is_incorporeal()) + return + if(!sprung) + if(isliving(AM)) + var/mob/living/L = AM + if(!(L.m_intent == I_RUN)) + return + trigger(AM) + ..() + +/obj/structure/spring_trap/proc/reset() + if(!sprung) + return FALSE + SSmotiontracker.ping(src, 100) + visible_message(span_notice("[src] clicks as it resets itself."), "You hear the slow creaking of a spring.") + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + sprung = FALSE + +/obj/item/spring_trap_kit + name = "spring trap assembly kit" + gender = PLURAL + icon = 'icons/obj/items.dmi' + icon_state = "spring_trap-kit" + +/obj/item/spring_trap_kit/attack_self(mob/user, modifiers) + . = ..() + user.visible_message(span_danger("[user] starts to construct \the [src]."), span_notice("You start constructing \the [src]")) + if(do_after(user, 10 SECONDS, target = src)) + playsound(src, 'sound/machines/click.ogg', 50, 1) + var/obj/structure/spring_trap/spring_trap = new(get_turf(src)) + spring_trap.add_fingerprint(user) + qdel(src) diff --git a/code/modules/research/tg/designs/tool_designs.dm b/code/modules/research/tg/designs/tool_designs.dm index a92c09bbbb..0bbc58515b 100644 --- a/code/modules/research/tg/designs/tool_designs.dm +++ b/code/modules/research/tg/designs/tool_designs.dm @@ -317,6 +317,17 @@ RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_JANITORIAL ) +/datum/design_techweb/springtrap + name = "spring trap kit" + desc = "A mechanically activated spring trap. Low-tech, but reliable." + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_STEEL = 18750) + id = "springtrap" + build_path = /obj/item/spring_trap_kit + category = list( + RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_JANITORIAL + ) + /datum/design_techweb/experimental_welder name = "Experimental welding tool" desc = "A welding tool that generate fuel for itself." diff --git a/code/modules/research/tg/techwebs/nodes/service_nodes.dm b/code/modules/research/tg/techwebs/nodes/service_nodes.dm index a6b4611df5..0f2bafc105 100644 --- a/code/modules/research/tg/techwebs/nodes/service_nodes.dm +++ b/code/modules/research/tg/techwebs/nodes/service_nodes.dm @@ -65,6 +65,7 @@ "beartrap", "barbedwire", "snarewire", + "springtrap", // "buffer", "washing" ) diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 2ebe64650d..b139826d50 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 71578587f5..e69ac7339e 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2050,6 +2050,7 @@ #include "code\game\objects\structures\simple_doors.dm" #include "code\game\objects\structures\simple_doors_vr.dm" #include "code\game\objects\structures\snowman.dm" +#include "code\game\objects\structures\spring_trap.dm" #include "code\game\objects\structures\stasis_cage.dm" #include "code\game\objects\structures\tank_dispenser.dm" #include "code\game\objects\structures\target_stake.dm"