From 52cce9fbcef75ac3d3615954c888322f175028e5 Mon Sep 17 00:00:00 2001 From: Haha26315 Date: Wed, 7 Sep 2022 23:36:07 -0400 Subject: [PATCH] Constructing Railings Allow players to construct railings of their very own, unfasten them from the flooring, deconstruct them including with RCDs, and all the good stuff from grilles, like electrification. Also solves the bug whereby you could climb over railings into solid tiles. --- code/game/objects/items/RCD.dm | 2 +- code/game/objects/items/stacks/rods.dm | 7 +- code/game/objects/structures/grille.dm | 14 +- .../game/objects/{ => structures}/railings.dm | 171 +++++++++++++++++- tgstation.dme | 2 +- 5 files changed, 180 insertions(+), 16 deletions(-) rename hyperstation/code/game/objects/{ => structures}/railings.dm (59%) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 6abf34c72..839232a32 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -489,7 +489,7 @@ RLD to_chat(user, "You change RCD's mode to '[choice]'.") /obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with - if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder)) + if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder) || (istype(A, /obj/structure/railing) && mode==RCD_DECONSTRUCT)) return TRUE else return FALSE diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 537873624..215facd38 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -1,5 +1,10 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe_list("railings", \ + list( \ + new/datum/stack_recipe("railing", /obj/structure/railing/unachored, 1, time = 10, one_per_turf = 0, on_floor = 1, window_checks = 1), \ + new/datum/stack_recipe("handrail", /obj/structure/railing/handrail/unachored, 1, time = 10, one_per_turf = 0, on_floor = 1, window_checks = 1), \ + )), \ new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("scooter frame", /obj/item/scooter_frame, 10, time = 25, one_per_turf = 0), \ )) @@ -25,7 +30,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ /obj/item/stack/rods/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to stuff \the [src] down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide!")//it looks like theyre ur mum return BRUTELOSS - + /obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE) . = ..() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 0d4444303..c8ac770ee 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -11,8 +11,8 @@ armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) max_integrity = 50 integrity_failure = 20 - var/rods_type = /obj/item/stack/rods - var/rods_amount = 2 + var/buildstacktype = /obj/item/stack/rods + var/buildstackamount = 2 var/rods_broken = TRUE var/grille_type = null var/broken_type = /obj/structure/grille/broken @@ -84,7 +84,7 @@ /obj/structure/grille/attack_animal(mob/user) . = ..() - if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the grille) + if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the grille. take_damage(rand(5,10), BRUTE, "melee", 1) /obj/structure/grille/attack_paw(mob/user) @@ -217,7 +217,7 @@ if(!loc) //if already qdel'd somehow, we do nothing return if(!(flags_1&NODECONSTRUCT_1)) - var/obj/R = new rods_type(drop_location(), rods_amount) + var/obj/R = new buildstacktype(drop_location(), buildstackamount) transfer_fingerprints_to(R) qdel(src) ..() @@ -225,7 +225,7 @@ /obj/structure/grille/obj_break() if(!broken && !(flags_1 & NODECONSTRUCT_1)) new broken_type(src.loc) - var/obj/R = new rods_type(drop_location(), rods_broken) + var/obj/R = new buildstacktype(drop_location(), rods_broken) transfer_fingerprints_to(R) qdel(src) @@ -279,7 +279,7 @@ density = FALSE obj_integrity = 20 broken = TRUE - rods_amount = 1 + buildstackamount = 1 rods_broken = FALSE grille_type = /obj/structure/grille broken_type = null @@ -315,7 +315,7 @@ density = FALSE obj_integrity = 20 broken = TRUE - rods_amount = 1 + buildstackamount = 1 rods_broken = FALSE grille_type = /obj/structure/grille/ratvar broken_type = null diff --git a/hyperstation/code/game/objects/railings.dm b/hyperstation/code/game/objects/structures/railings.dm similarity index 59% rename from hyperstation/code/game/objects/railings.dm rename to hyperstation/code/game/objects/structures/railings.dm index 154829b5c..0fde72934 100644 --- a/hyperstation/code/game/objects/railings.dm +++ b/hyperstation/code/game/objects/structures/railings.dm @@ -7,6 +7,7 @@ icon = 'hyperstation/icons/obj/railings.dmi' var/icon_modifier = "grey_" icon_state = "grey_railing0" + flags_1 = CONDUCT_1 density = FALSE layer = 4 @@ -16,15 +17,19 @@ var/heat_resistance = 800 var/health = 70 var/maxhealth = 70 + var/decon_speed = 5 layer = BELOW_MOB_LAYER - resistance_flags = ACID_PROOF armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) CanAtmosPass = ATMOS_PASS_PROC var/real_explosion_block //ignore this, just use explosion_block var/breaksound = "shatter" var/hitsound = 'sound/effects/Glasshit.ogg' + + var/buildstacktype = /obj/item/stack/rods + var/buildstackamount = 1 + rad_insulation = RAD_VERY_LIGHT_INSULATION rad_flags = RAD_PROTECT_CONTENTS var/check = 0 @@ -44,6 +49,18 @@ /obj/effect/crystalline_reentry )) //Gotta make sure certain things can phase through it otherwise the railings also block them. +/obj/structure/railing/unachored + anchored = FALSE + +/obj/structure/railing/ComponentInitialize() + . = ..() + AddComponent( + /datum/component/simple_rotation, + ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, + null, + CALLBACK(src, .proc/can_be_rotated), + ) + /obj/structure/railing/CanPass(atom/movable/mover, turf/target) if(istype(mover) && (mover.pass_flags & PASSGLASS) || is_type_in_typecache(mover, freepass)) return 1 @@ -87,7 +104,7 @@ /obj/structure/railing/Initialize() . = ..() if(src.anchored) - update_icon(0) + update_icon(1) /obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1) check = 0 @@ -129,6 +146,7 @@ /obj/structure/railing/update_icon(var/UpdateNeighgors = 1) NeighborsCheck(UpdateNeighgors) + overlays.Cut() if (!check || !anchored)//|| !anchored icon_state = "[icon_modifier]railing0" @@ -161,21 +179,145 @@ . += "It looks damaged!" if(0.5 to 1.0) . += "It has a few scrapes and dents." + if(anchored) + . += "It's secured in place with screws. The [src]'s rods look like they could be cut through." + else + . += "The anchoring screws are unscrewed. The [src]'s rods look like they could be cut through." /obj/structure/railing/take_damage(amount) health -= amount + playsound(src, 'sound/effects/grillehit.ogg', 50, 1) if(health <= 0) visible_message("\The [src] breaks down!") - playsound(src, 'sound/effects/grillehit.ogg', 50, 1) new /obj/item/stack/rods(get_turf(src)) qdel(src) +/obj/structure/railing/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + switch(the_rcd.mode) + if(RCD_DECONSTRUCT) + return list("mode" = RCD_DECONSTRUCT, "delay" = 10, "cost" = 5) + return FALSE + +/obj/structure/railing/rcd_act(mob/user, var/obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, "You deconstruct the [src].") + qdel(src) + NeighborsCheck() + return TRUE + return FALSE + +/obj/structure/railing/attackby(obj/item/W, mob/user, params) + user.changeNext_move(CLICK_CD_MELEE) + add_fingerprint(user) + if(istype(W, /obj/item/wirecutters)) + if(!shock(user, 100)) + W.play_tool_sound(src, 100) + deconstruct() + NeighborsCheck() + else if((istype(W, /obj/item/screwdriver)) && (isturf(loc) || anchored)) + if(!shock(user, 90)) + W.play_tool_sound(src, 100) + if(W.use_tool(src, user, decon_speed)) + setAnchored(!anchored) + user.visible_message("[user] [anchored ? "fastens" : "unfastens"] [src].", \ + "You [anchored ? "fasten [src] to" : "unfasten [src] from"] the floor.") + update_icon(1) + return + + else if(istype(W, /obj/item/shard) || !shock(user, 70)) + return ..() + +/obj/structure/grille/attack_paw(mob/user) + return attack_hand(user) + +/obj/structure/grille/hulk_damage() + return 60 + +/obj/structure/grille/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) + if(user.a_intent == INTENT_HARM) + if(!shock(user, 70)) + ..(user, 1) + return TRUE + +/obj/structure/grille/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(!shock(user, 70)) + user.visible_message("[user] gets shocked by [src]!", null, null, COMBAT_MESSAGE_RANGE) + take_damage(rand(5,10), BRUTE, "melee", 1) + +/obj/structure/grille/attack_alien(mob/living/user) + user.do_attack_animation(src) + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE) + if(!shock(user, 70)) + take_damage(20, BRUTE, "melee", 1) + +/obj/structure/railing/deconstruct(disassembled = TRUE) + if(!loc) //if already qdel'd somehow, we do nothing + return + if(!(flags_1&NODECONSTRUCT_1)) + var/obj/R = new buildstacktype(drop_location(), buildstackamount) + transfer_fingerprints_to(R) + qdel(src) + ..() + +/obj/structure/railing/Bumped(atom/movable/AM) + if(!ismob(AM)) + return + var/mob/M = AM + shock(M, 70) + +/obj/structure/railing/attack_animal(mob/user) + . = ..() + if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the rail. + take_damage(rand(5,10), BRUTE, "melee", 1) + +/obj/structure/railing/hulk_damage() + return 60 + +/obj/structure/railing/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) + if(user.a_intent == INTENT_HARM) + if(!shock(user, 70)) + ..(user, 1) + return TRUE + +// shock user with probability prb (if all connections & power are working) +// returns 1 if shocked, 0 otherwise + +/obj/structure/railing/proc/shock(mob/user, prb) + if(!anchored) // unanchored railings are never connected + return FALSE + if(!prob(prb)) + return FALSE + if(!in_range(src, user))//To prevent TK and mech users from getting shocked + return FALSE + + var/turf/T = get_turf(src) + var/obj/structure/cable/C = T.get_cable_node() + if(C) + if(electrocute_mob(user, C, src, 1, TRUE)) + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, src) + s.start() + return TRUE + else + return FALSE + return FALSE + /obj/structure/railing/MouseDrop_T(mob/living/M, mob/living/user) if(!istype(user)) return if(!isliving(user)) return + //Sanity check so players can't climb over railings into occupied spaces. + var/turf/T = get_step(src, src.dir) + if(CanPass(user, T) == 0) + return FALSE + usr.visible_message("[user] starts climbing onto \the [src]!") if(!do_after(user, 15, src)) @@ -183,7 +325,7 @@ if(get_turf(user) == get_turf(src)) usr.dir = get_dir(usr.loc, get_step(src, src.dir))//turn and face railing - usr.forceMove(get_step(src, src.dir)) + usr.forceMove(T) else usr.dir = get_dir(usr.loc, loc)//turn and face railing usr.forceMove(get_turf(src)) @@ -191,6 +333,20 @@ usr.visible_message("[user] climbed over \the [src]!") usr.do_twist(targetangle = 45, timer = 8) +/obj/structure/railing/proc/can_be_rotated(mob/user,rotation_type) + if(anchored) + to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE + + var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90) + + if(!valid_window_location(loc, target_dir)) + to_chat(user, "[src] cannot be rotated in that direction!") + return FALSE + return TRUE + + add_fingerprint(user) + /obj/structure/railing/Initialize(mapload) //mobs will show under the south railing sprite, thanks Cyanosis for helping with the fix . = ..() if(!mapload) @@ -208,8 +364,10 @@ icon_state = "hand_railing0" max_integrity = 100 -/obj/structure/railing/handrail/update_icon(var/UpdateNeighgors = 1) - NeighborsCheck(UpdateNeighgors) +/obj/structure/railing/handrail/unachored + anchored = FALSE + +/obj/structure/railing/handrail/update_icon(var/UpdateNeighbors = 1) overlays.Cut() if (!check || !anchored)//|| !anchored icon_state = "[icon_modifier]railing0" @@ -227,6 +385,7 @@ overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = 32) if (SOUTH) overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = -32) + layer = ABOVE_MOB_LAYER if (EAST) overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = -32) if (WEST) diff --git a/tgstation.dme b/tgstation.dme index 0998356ec..7ccd8076d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3117,7 +3117,6 @@ #include "hyperstation\code\game\machinery\announcement_system.dm" #include "hyperstation\code\game\machinery\lore_terminal.dm" #include "hyperstation\code\game\machinery\computer\timeclock.dm" -#include "hyperstation\code\game\objects\railings.dm" #include "hyperstation\code\game\objects\effects\landmarks.dm" #include "hyperstation\code\game\objects\effects\temporary_visuals\miscellaneous.dm" #include "hyperstation\code\game\objects\items\cards.dm" @@ -3131,6 +3130,7 @@ #include "hyperstation\code\game\objects\items\storage\big_bag.dm" #include "hyperstation\code\game\objects\structures\bench.dm" #include "hyperstation\code\game\objects\structures\ghost_role_spawners.dm" +#include "hyperstation\code\game\objects\structures\railings.dm" #include "hyperstation\code\game\objects\structures\sauna_oven.dm" #include "hyperstation\code\game\objects\structures\tables_racks.dm" #include "hyperstation\code\game\turfs\open.dm"