From 36dfee27eb609be9bf91e858b7b0d383c42d6236 Mon Sep 17 00:00:00 2001 From: skull132 Date: Mon, 29 May 2017 01:29:35 +0300 Subject: [PATCH] Leg actuators for RIGs (#2421) Preview: https://kama.skullnet.me/index.php/s/GsEdb7q733nO1LK Okay. These modules allow you to fall from any height without taking damage. As long as your suit is powered and they're enabled, anyways. Secondly, they allow you to leap! Civilian grade allow you to leap 4 tiles, military grade ones (syndicate + ERT commander) allow you to leap 7 tiles and to also grapple people (Vox leap feature). On top of that, if you middle click on the tile you're on with them selected, you will try to leap upwards. If the tile you're facing above you is a solid (non-open turf, but not dense either), then you will start to climb onto that tile. Civilian grade model isn't powerful enough to jump you there fully, so you gotta spend 4 seconds grappling for your life. Get interrupted in that time, you fall. Military grade models hop you instantly. --- code/game/turfs/turf.dm | 2 +- .../spacesuits/rig/modules/utility.dm | 142 ++++++++++++++++++ .../clothing/spacesuits/rig/suits/light.dm | 3 +- .../clothing/spacesuits/rig/suits/merc.dm | 6 +- .../clothing/spacesuits/rig/suits/station.dm | 6 +- .../mob/living/carbon/human/human_powers.dm | 22 +-- code/modules/multiz/movement.dm | 10 +- code/modules/multiz/turf.dm | 7 + html/changelogs/skull132-actuators.yml | 6 + 9 files changed, 188 insertions(+), 16 deletions(-) create mode 100644 html/changelogs/skull132-actuators.yml diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f67a00faf56..f5b7f5bd10f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -38,7 +38,7 @@ for(var/atom/movable/AM as mob|obj in src) Entered(AM) - + turfs += src if(dynamic_lighting) diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 16c89569fc0..a3c2471011e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -14,6 +14,8 @@ * /obj/item/rig_module/device/paperdispenser * /obj/item/rig_module/device/pen * /obj/item/rig_module/device/stamp + * /obj/item/rig_module/actuators + * /obj/item/rig_module/actuators/combat */ /obj/item/rig_module/device @@ -472,3 +474,143 @@ interface_desc = "Eats trash like no one's business." device_type = /obj/item/weapon/matter_decompiler + +/obj/item/rig_module/actuators + name = "leg actuators" + desc = "A set of electromechanical actuators, for safe travesal of multilevelled areas." + icon_state = "generic" + interface_name = "leg actuators" + interface_desc = "Allows you to fall from heights and to jump up onto ledges." + + disruptive = 1 + + use_power_cost = 5 + module_cooldown = 25 + + /* + * TOGGLE - dampens fall, on or off. + * SELECTABLE - Jump forward or up! + */ + toggleable = 1 + selectable = 1 + usable = 0 + + engage_string = "Toggle Leg Actuators" + activate_string = "Enable Leg Actuators" + deactivate_string = "Disable Leg Actuators" + + var/combatType = 0 // Determines whether or not the actuators can do special combat oriented tasks. + // Such as leaping faster, or grappling targets. + var/leapDistance = 4 // Determines how far the actuators allow you to leap (radius, inclusive). + +/obj/item/rig_module/actuators/combat + name = "military grade leg actuators" + desc = "A set of high-powered hydraulic actuators, for improved traversal of multilevelled areas." + interface_name = "combat leg actuators" + + combatType = 1 + leapDistance = 7 + + use_power_cost = 10 + +/obj/item/rig_module/actuators/engage(var/atom/target) + if (!..()) + return 0 + + // This is for when you toggle it on or off. Why do they both run the same + // proc chain ...? :l + if (!target) + return 1 + + var/mob/living/carbon/human/H = holder.wearer + + if (!isturf(H.loc)) + to_chat(H, "You cannot leap out of your current location!") + return 0 + + var/turf/T = get_turf(target) + + if (!T || T.density) + to_chat(H, "You cannot leap at solid walls!") + return 0 + + // Saved, we need it more than 1 place. + var/dist = max(get_dist(T, get_turf(H)), 0) + + if (dist) + for (var/A in T) + var/atom/aa = A + if (combatType && ismob(aa)) + continue + + if (aa.density) + to_chat(H, "You cannot leap at a location with solid objects on it!") + return 0 + + if (T.z != H.z || dist > leapDistance) + to_chat(H, "You cannot leap at such a distant object!") + return 0 + + // Handle leaping at targets with a combat capable version here. + if (combatType && dist && (ismob(target) || (locate(/mob/living) in T))) + H.leap(target, leapDistance) + return 1 + + // If dist -> horizontal leap. Otherwise, the user clicked the turf that they're + // currently on. Which means they want to do a vertical leap upwards! + if (dist) + H.visible_message("\The [H] leaps horizontally at \the [T]!", + "You leap horizontally at \the [T]!", + "You hear an electric whirr followed by a weighty thump!") + H.face_atom(T) + H.throw_at(T, leapDistance, 1, src) + return 1 + else + var/turf/simulated/open/TA = GetAbove(src) + if (!istype(TA)) + to_chat(H, "There is a ceiling above you that stop you from leaping upwards!") + return 0 + + for (var/atom/A in TA) + if (!A.CanPass(src, TA, 1.5, 0)) + to_chat(H, "\The [A] blocks you!") + return 0 + + var/turf/leapEnd = get_step(TA, H.dir) + if (!leapEnd || istype(leapEnd, /turf/simulated/open) || istype(leapEnd, /turf/space)\ + || leapEnd.density || leapEnd.contains_dense_objects()) + to_chat(H, "There is no valid ledge to scale ahead of you!") + return 0 + + H.visible_message("\The [H] leaps up, out of view!", + "You leap up!") + + // This setting is necessary even for combat type, to stop you from moving onto + // the turf, falling back down, and then getting forcemoved to the final destination. + LAZYADD(TA.climbers, H) + + H.forceMove(TA) + + // Combat type actuators are better, they allow you to jump instantly onto + // a ledge. Regular actuators make you have to climb the rest of the way. + if (!combatType) + H.visible_message("\The [H] starts pulling \himself up onto \the [leapEnd].", + "You start pulling yourself up onto \the [leapEnd].") + if (!do_after(H, 4 SECONDS, use_user_turf = TRUE)) + H.visible_message("\The [H] is interrupted and falls!", + "You are interrupted and fall back down!") + LAZYREMOVE(TA.climbers, H) + + ADD_FALLING_ATOM(H) + return 1 + + H.visible_message("\The [H] finishes climbing onto \the [leapEnd].", + "You finish climbing onto \the [leapEnd].") + else + H.visible_message("\The [H] lands on \the [leapEnd] with a heavy slam!", + "You land on \the [leapEnd] with a heavy thud!") + + LAZYREMOVE(TA.climbers, H) + H.forceMove(leapEnd) + + return 1 diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index 0795d09ec04..68b8a785e9c 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -97,7 +97,8 @@ /obj/item/rig_module/ai_container, /obj/item/rig_module/power_sink, /obj/item/rig_module/datajack, - /obj/item/rig_module/self_destruct + /obj/item/rig_module/self_destruct, + /obj/item/rig_module/actuators/combat ) ..() diff --git a/code/modules/clothing/spacesuits/rig/suits/merc.dm b/code/modules/clothing/spacesuits/rig/suits/merc.dm index d56db0c3f6d..211b783fc0d 100644 --- a/code/modules/clothing/spacesuits/rig/suits/merc.dm +++ b/code/modules/clothing/spacesuits/rig/suits/merc.dm @@ -25,12 +25,14 @@ /obj/item/rig_module/power_sink, /obj/item/rig_module/electrowarfare_suite, /obj/item/rig_module/chem_dispenser/combat, - /obj/item/rig_module/fabricator/energy_net + /obj/item/rig_module/fabricator/energy_net, + /obj/item/rig_module/actuators/combat ) //Has most of the modules removed /obj/item/weapon/rig/merc/empty initial_modules = list( /obj/item/rig_module/ai_container, - /obj/item/rig_module/electrowarfare_suite //might as well + /obj/item/rig_module/electrowarfare_suite, //might as well + /obj/item/rig_module/actuators/combat // What the dude above me said. ) diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 3b56e45540b..6f0222d30be 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -81,7 +81,8 @@ /obj/item/rig_module/device/drill, /obj/item/rig_module/device/orescanner, /obj/item/rig_module/device/rcd, - /obj/item/rig_module/vision/meson + /obj/item/rig_module/vision/meson, + /obj/item/rig_module/actuators ) /obj/item/weapon/rig/industrial/syndicate @@ -147,7 +148,8 @@ /obj/item/rig_module/maneuvering_jets, /obj/item/rig_module/mounted/plasmacutter, /obj/item/rig_module/device/rcd, - /obj/item/rig_module/vision/meson + /obj/item/rig_module/vision/meson, + /obj/item/rig_module/actuators ) /obj/item/clothing/gloves/rig/ce diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 10bcfd127a2..3bdc97c1498 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -49,7 +49,7 @@ if ((O.client && !( O.blinded ))) O.show_message(text("[] [failed ? "tried to tackle" : "has tackled"] down []!", src, T), 1) -/mob/living/carbon/human/proc/leap() +/mob/living/carbon/human/proc/leap(var/mob/living/T = null, var/max_range = 4) set category = "Abilities" set name = "Leap" set desc = "Leap at a target and grab them aggressively." @@ -61,17 +61,18 @@ src << "You cannot leap in your current state." return - var/list/choices = list() - for(var/mob/living/M in view(6,src)) - if(!istype(M,/mob/living/silicon)) - choices += M - choices -= src + if (!T) + var/list/choices = list() + for(var/mob/living/M in view(6,src)) + if(!istype(M,/mob/living/silicon)) + choices += M + choices -= src - var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices + T = input(src,"Who do you wish to leap at?") as null|anything in choices if(!T || !src || src.stat) return - if(get_dist(get_turf(T), get_turf(src)) > 4) return + if(get_dist(get_turf(T), get_turf(src)) > max_range) return if(last_special > world.time) return @@ -85,7 +86,10 @@ src.visible_message("\The [src] leaps at [T]!") src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src) - playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) + + // Only Vox get to shriek. Seriously. + if (isvox(src)) + playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) sleep(5) diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 95a4613bdbb..35ebccfbf86 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -189,8 +189,12 @@ if(locate(/obj/structure/lattice, dest) || locate(/obj/structure/stairs, dest)) return FALSE + // The var/climbers API is implemented here. + if (LAZYLEN(dest.climbers) && (src in dest.climbers)) + return FALSE + // See if something prevents us from falling. - for(var/atom/A in below) + for (var/atom/A in below) if(!A.CanPass(src, dest)) return FALSE @@ -212,6 +216,10 @@ // Only things that stop mechas are atoms that, well, stop them. // Lattices and stairs get crushed in fall_through. /obj/mecha/can_fall(turf/below, turf/simulated/open/dest = src.loc) + // The var/climbers API is implemented here. + if (LAZYLEN(dest.climbers) && (src in dest.climbers)) + return FALSE + // See if something prevents us from falling. for(var/atom/A in below) if(!A.CanPass(src, dest)) diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index a47b00b51b7..d74bd86aaf9 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -42,6 +42,9 @@ var/tmp/depth + var/tmp/list/climbers // A lazy list to contain a list of mobs who are currently scaling + // up this turf. Used in human/can_fall. + // An override of turf/Enter() to make it so that magboots allow you to stop // falling off the damned rock. /turf/simulated/open/Enter(mob/living/carbon/human/mover, atom/oldloc) @@ -66,6 +69,10 @@ above = null below = null + + LAZYCLEARLIST(climbers) + UNSETEMPTY(climbers) + return ..() /turf/simulated/open/get_smooth_underlay_icon(image/underlay_appearance, turf/asking_turf, adjacency_dir) diff --git a/html/changelogs/skull132-actuators.yml b/html/changelogs/skull132-actuators.yml new file mode 100644 index 00000000000..d761b3da3ef --- /dev/null +++ b/html/changelogs/skull132-actuators.yml @@ -0,0 +1,6 @@ +author: Skull132 + +delete-after: True + +changes: + - rscadd: "Added the leg actuator RIG module. These allow you to fall from heights if enabled, without taking damage; to leap horizontally (Vox style); and to climb up open turfs if you're facing a solid turf above you. Combat versions also allow you to grapel people."