From fdc05066a6fcf399a5c153899ded4f4afc60bfa9 Mon Sep 17 00:00:00 2001 From: Paxilmaniac <82386923+Paxilmaniac@users.noreply.github.com> Date: Thu, 17 Nov 2022 13:51:27 -0500 Subject: [PATCH] Adds falling hazard element, beware of falling tools, wear your hardhat, comically timed piano falling on the clown (#70970) ## About The Pull Request https://user-images.githubusercontent.com/82386923/199180691-6605c8cc-e8aa-490e-ab65-909d45d12ca0.mp4 Do note that the damage in this video is extremely exaggerated compared to what the normal value is. ## Why It's Good For The Game All these signs about engineers needing to wear their hardhat, and for what? For the assistant dropping toolboxes onto them from above, that's what! Also allows people to do as god intended by allowing them to drop pianos on people. ## Changelog :cl: add: A variety of items, mainly tools, around the station might hurt if they fall on your head, remember to wear your hardhat and to avoid standing under large red X marks on the ground with a piano hanging above them. /:cl: Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- .../signals_atom/signals_atom_movement.dm | 2 + code/datums/elements/falling_hazard.dm | 80 +++++++++++++++++++ code/game/atoms_movable.dm | 2 + code/game/objects/items/paint.dm | 4 + code/game/objects/items/storage/toolbox.dm | 2 + code/game/objects/items/tools/crowbar.dm | 4 + code/game/objects/items/tools/screwdriver.dm | 1 + code/game/objects/items/tools/weldingtool.dm | 2 + code/game/objects/items/tools/wirecutters.dm | 3 + code/game/objects/items/tools/wrench.dm | 4 + code/modules/instruments/stationary.dm | 4 + code/modules/library/book.dm | 2 + code/modules/vehicles/mecha/_mecha.dm | 2 + tgstation.dme | 1 + 14 files changed, 113 insertions(+) create mode 100644 code/datums/elements/falling_hazard.dm diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm index e0b8def1581..3784a079ce0 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -11,6 +11,8 @@ #define COMSIG_ATOM_NO_LONGER_PULLING "movable_no_longer_pulling" ///called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels) #define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" +///signal sent out by an atom upon onZImpact : (turf/impacted_turf, levels) +#define COMSIG_ATOM_ON_Z_IMPACT "movable_on_z_impact" ///called on a movable (NOT living) when it starts pulling (atom/movable/pulled, state, force) #define COMSIG_ATOM_START_PULL "movable_start_pull" ///called on /living when someone starts pulling (atom/movable/pulled, state, force) diff --git a/code/datums/elements/falling_hazard.dm b/code/datums/elements/falling_hazard.dm new file mode 100644 index 00000000000..cfa9285e7f8 --- /dev/null +++ b/code/datums/elements/falling_hazard.dm @@ -0,0 +1,80 @@ +/// An element that will make a target thing do damage to any mob that it falls on from a z-level above +/datum/element/falling_hazard + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + + /// The amount of damage to do when the target falls onto a mob + var/fall_damage = 5 + /// The wound bonus to give damage dealt against mobs we fall on + var/fall_wound_bonus = 0 + /// Does we take into consideration if the target has head protection (hardhat, or a strong enough helmet) + var/obeys_hardhats = TRUE + /// Does the target crush and flatten whoever it falls on + var/crushes_people = FALSE + /// What sound is played when the target falls onto a mob + var/impact_sound = 'sound/magic/clockwork/fellowship_armory.ogg' //CLANG + +/datum/element/falling_hazard/Attach(datum/target, damage, wound_bonus, hardhat_safety, crushes, impact_sound) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.fall_damage = damage + src.fall_wound_bonus = wound_bonus + src.obeys_hardhats = hardhat_safety + src.crushes_people = crushes + src.impact_sound = impact_sound + + RegisterSignal(target, COMSIG_ATOM_ON_Z_IMPACT, PROC_REF(fall_onto_stuff)) + +/datum/element/falling_hazard/Detach(datum/target) + . = ..() + UnregisterSignal(target, COMSIG_ATOM_ON_Z_IMPACT) + +/// Gathers every mob in the turf the target falls on, and does damage/crushes them/makes a message about the target falling on them +/datum/element/falling_hazard/proc/fall_onto_stuff(datum/source, turf/impacted_turf, levels) + SIGNAL_HANDLER + + var/mob/living/poor_target = locate(/mob/living) in impacted_turf + + if(!poor_target) + return + + var/target_head_armor = poor_target.run_armor_check(BODY_ZONE_HEAD, MELEE, silent = TRUE) + + if(obeys_hardhats && target_head_armor >= 15) // 15 melee armor is enough that most head items dont have this, but anything above a hardhat should protect you + poor_target.visible_message( + span_warning("[source] falls on [poor_target], thankfully [poor_target.p_they()] had a helmet on!"), + span_userdanger("You are hit on the head by [source], good thing you had a helmet on!"), + span_hear("You hear a [crushes_people ? "crash" : "bonk"]!"), + ) + + if(crushes_people) + poor_target.Knockdown(0.25 SECONDS * fall_damage) // For a piano, that would be 15 seconds + + playsound(poor_target, 'sound/weapons/parry.ogg', 50, TRUE) // You PARRIED the falling object with your EPIC hardhat + return + + var/obj/item/bodypart/target_head = poor_target.get_bodypart(BODY_ZONE_HEAD) + + // This does more damage the more levels the falling object has fallen + if(!crushes_people && target_head) + poor_target.apply_damage(fall_damage * levels, def_zone = BODY_ZONE_HEAD, forced = TRUE, wound_bonus = fall_wound_bonus) + else + poor_target.apply_damage(fall_damage * levels, forced = TRUE, spread_damage = TRUE, wound_bonus = fall_wound_bonus) + + poor_target.visible_message( + span_userdanger("[source] falls on [poor_target], [crushes_people ? "crushing [poor_target.p_them()]" : "hitting [poor_target.p_them()]"] [target_head ? "on the head!" : "!"]"), + span_userdanger("You are [crushes_people ? "crushed" : "hit"] by [source]!"), + span_hear("You hear a [crushes_people ? "crash" : "bonk"]!"), + ) + + playsound(poor_target, impact_sound, 50, TRUE) + + if(!crushes_people) + return + + poor_target.AddElement(/datum/element/squish, 30 SECONDS) + poor_target.Paralyze(0.5 SECONDS * fall_damage) // For a piano, that would be 30 seconds + + add_memory_in_range(poor_target, 7, MEMORY_VENDING_CRUSHED, list(DETAIL_PROTAGONIST = poor_target, DETAIL_WHAT_BY = src), story_value = STORY_VALUE_AMAZING, memory_flags = MEMORY_CHECK_BLINDNESS, protagonist_memory_flags = MEMORY_SKIP_UNCONSCIOUS) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0049b0bb4fc..d01a08a8958 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -220,6 +220,7 @@ . += emissive_block /atom/movable/proc/onZImpact(turf/impacted_turf, levels, message = TRUE) + SHOULD_CALL_PARENT(TRUE) if(message) visible_message(span_danger("[src] crashes into [impacted_turf]!")) var/atom/highest = impacted_turf @@ -230,6 +231,7 @@ if(hurt_atom.layer > highest.layer) highest = hurt_atom INVOKE_ASYNC(src, PROC_REF(SpinAnimation), 5, 2) + SEND_SIGNAL(src, COMSIG_ATOM_ON_Z_IMPACT, impacted_turf, levels) return TRUE /* diff --git a/code/game/objects/items/paint.dm b/code/game/objects/items/paint.dm index f83dae18c8b..c8fe4db5bfe 100644 --- a/code/game/objects/items/paint.dm +++ b/code/game/objects/items/paint.dm @@ -16,6 +16,10 @@ /// How many uses are left var/paintleft = 10 +/obj/item/paint/Initialize(mapload) + . = ..() + AddElement(/datum/element/falling_hazard, damage = 20, wound_bonus = 5, hardhat_safety = TRUE, crushes = FALSE) // You ever watched home alone? + /obj/item/paint/red name = "red paint" paint_color = COLOR_RED diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 8dbcbc9a608..eaf3ac030f2 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -33,6 +33,8 @@ latches = "triple_latch" update_appearance() + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + /obj/item/storage/toolbox/update_overlays() . = ..() if(has_latches) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index e6cc1c23793..5c8672efd0c 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -24,6 +24,10 @@ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 50, ACID = 30) var/force_opens = FALSE +/obj/item/crowbar/Initialize(mapload) + . = ..() + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + /obj/item/crowbar/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 01300df0512..bb769f1a0ba 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -54,6 +54,7 @@ set_greyscale(colors=list(screwdriver_colors[our_color])) . = ..() AddElement(/datum/element/eyestab) + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) /obj/item/screwdriver/abductor name = "alien screwdriver" diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 347c6d424f4..ab4ad9a9430 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -53,6 +53,8 @@ . = ..() AddElement(/datum/element/update_icon_updates_onmob, ITEM_SLOT_HANDS) AddElement(/datum/element/tool_flash, light_range) + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + create_reagents(max_fuel) reagents.add_reagent(/datum/reagent/fuel, max_fuel) update_appearance() diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index b352139b074..6eae41a2cc7 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -46,6 +46,9 @@ if(random_color) var/our_color = pick(wirecutter_colors) set_greyscale(colors=list(wirecutter_colors[our_color])) + + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + return ..() /obj/item/wirecutters/attack(mob/living/carbon/attacked_carbon, mob/user) diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 9f4ec159044..f4f41b6783b 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -24,6 +24,10 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 50, ACID = 30) +/obj/item/wrench/Initialize(mapload) + . = ..() + AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) + /obj/item/wrench/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) diff --git a/code/modules/instruments/stationary.dm b/code/modules/instruments/stationary.dm index 1b726e823ff..a1cc70dace2 100644 --- a/code/modules/instruments/stationary.dm +++ b/code/modules/instruments/stationary.dm @@ -41,6 +41,10 @@ density = TRUE var/broken_icon_state = "pianobroken" +/obj/structure/musician/piano/Initialize(mapload) + . = ..() + AddElement(/datum/element/falling_hazard, damage = 60, wound_bonus = 10, hardhat_safety = FALSE, crushes = TRUE, impact_sound = 'sound/effects/piano_hit.ogg') + /obj/structure/musician/piano/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) diff --git a/code/modules/library/book.dm b/code/modules/library/book.dm index e1d58a155d2..22358fe20e4 100644 --- a/code/modules/library/book.dm +++ b/code/modules/library/book.dm @@ -110,6 +110,8 @@ . = ..() book_data = new(starting_title, starting_author, starting_content) + AddElement(/datum/element/falling_hazard, damage = 5, wound_bonus = 0, hardhat_safety = TRUE, crushes = FALSE, impact_sound = drop_sound) + /obj/item/book/proc/on_read(mob/living/user) if(book_data?.content) user << browse("Penned by [book_data.author].
" + "[book_data.content]", "window=book[window_size != null ? ";size=[window_size]" : ""]") diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 1438503b54f..b835eb2f55e 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -258,6 +258,8 @@ thing.attach(src, FALSE) equip_by_category[key] -= path + AddElement(/datum/element/falling_hazard, damage = 80, wound_bonus = 10, hardhat_safety = FALSE, crushes = TRUE) + /obj/vehicle/sealed/mecha/Destroy() for(var/ejectee in occupants) mob_exit(ejectee, silent = TRUE) diff --git a/tgstation.dme b/tgstation.dme index 2020ab8acdb..2a7e1dc192e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1041,6 +1041,7 @@ #include "code\datums\elements\embed.dm" #include "code\datums\elements\empprotection.dm" #include "code\datums\elements\eyestab.dm" +#include "code\datums\elements\falling_hazard.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\footstep.dm" #include "code\datums\elements\forced_gravity.dm"