From 9d59e362896a2c84ec4bdc6d593fd9b96bca4fe6 Mon Sep 17 00:00:00 2001 From: coiax Date: Sun, 10 Dec 2017 16:31:56 +0000 Subject: [PATCH] Add caltrop component for spikey floor objects (#33280) * Add caltrop component for spikey floor objects The caltrop component now can be added to any crossable atom, and it'll act like a shard of glass, or a d4. Additional flags are possible for it to bypass shoes or ignore people who are walking. This means d4 don't reimplement shard logic, and also open the window for caltrop grenades later. Also, it taught me how components work. * Code review I * Caltrop damage is 4 * Cactus hurts * Whoops * Ignore restraints = true --- code/__DEFINES/components.dm | 4 ++ code/datums/components/caltrop.dm | 60 +++++++++++++++++++ code/game/objects/items/dice.dm | 12 ++-- .../game/objects/items/stacks/sheets/glass.dm | 26 +------- code/modules/mining/lavaland/ash_flora.dm | 16 ++--- tgstation.dme | 1 + 6 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 code/datums/components/caltrop.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 7da895a593..87c226b839 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -77,6 +77,10 @@ #define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): () #define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () + // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) + +#define CALTROP_BYPASS_SHOES 1 +#define CALTROP_IGNORE_WALKERS 2 diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm new file mode 100644 index 0000000000..5b8adf0175 --- /dev/null +++ b/code/datums/components/caltrop.dm @@ -0,0 +1,60 @@ +/datum/component/caltrop + var/min_damage + var/max_damage + var/probability + var/flags + + var/cooldown = 0 + +/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _flags = NONE) + min_damage = _min_damage + max_damage = max(_min_damage, _max_damage) + probability = _probability + flags = _flags + + RegisterSignal(list(COMSIG_MOVABLE_CROSSED), .proc/Crossed) + +/datum/component/caltrop/proc/Crossed(atom/movable/AM) + var/atom/A = parent + if(!A.has_gravity()) + return + + if(!prob(probability)) + return + + if(ishuman(AM)) + var/mob/living/carbon/human/H = AM + if(PIERCEIMMUNE in H.dna.species.species_traits) + return + + if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK) + return + + var/picked_def_zone = pick("l_leg", "r_leg") + var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) + if(!istype(O)) + return + if(O.status == BODYPART_ROBOTIC) + return + + var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET)) + + if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover)) + return + + if((H.movement_type & FLYING) || H.buckled) + return + + var/damage = rand(min_damage, max_damage) + H.apply_damage(damage, BRUTE, picked_def_zone) + + if(cooldown < world.time - 10) //cooldown to avoid message spam. + if(!H.incapacitated(ignore_restraints = TRUE)) + H.visible_message("[H] steps on [A].", \ + "You step on [A]!") + else + H.visible_message("[H] slides on [A]!", \ + "You slide on [A]!") + + cooldown = world.time + H.Knockdown(60) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 4fe27d1320..334be4a645 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -73,6 +73,10 @@ icon_state = "d4" sides = 4 +/obj/item/dice/d4/Initialize(mapload) + . = ..() + AddComponent(/datum/component/caltrop, 4) + /obj/item/dice/d6 name = "d6" @@ -182,14 +186,6 @@ else if(!src.throwing) //Dice was thrown and is coming to rest visible_message("[src] rolls to a stop, landing on [result]. [comment]") -/obj/item/dice/d4/Crossed(mob/living/carbon/human/H) - if(istype(H) && !H.shoes) - if(PIERCEIMMUNE in H.dna.species.species_traits) - return 0 - to_chat(H, "You step on the D4!") - H.apply_damage(4,BRUTE,(pick("l_leg", "r_leg"))) - H.Knockdown(60) - /obj/item/dice/update_icon() cut_overlays() add_overlay("[src.icon_state][src.result]") diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index c6a5d074e7..a70692a07d 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -205,6 +205,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ /obj/item/shard/Initialize() . = ..() + AddComponent(/datum/component/caltrop, force) icon_state = pick("large", "medium", "small") switch(icon_state) if("small") @@ -257,27 +258,4 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ /obj/item/shard/Crossed(mob/AM) if(istype(AM) && has_gravity(loc)) playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if(PIERCEIMMUNE in H.dna.species.species_traits) - return - var/picked_def_zone = pick("l_leg", "r_leg") - var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) - if(!istype(O)) - return - if(O.status == BODYPART_ROBOTIC) - return - var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET) - if(H.shoes || feetCover || H.movement_type & FLYING || H.buckled) - return - H.apply_damage(5, BRUTE, picked_def_zone) - if(cooldown < world.time - 10) //cooldown to avoid message spam. - if(!H.incapacitated()) - H.visible_message("[H] steps in the broken glass!", \ - "You step in the broken glass!") - else - H.visible_message("[H] slides on the broken glass!", \ - "You slide on the broken glass!") - - cooldown = world.time - H.Knockdown(60) + . = ..() diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 6d6587a73a..6ecdc91635 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -137,18 +137,10 @@ regrowth_time_low = 4800 regrowth_time_high = 7200 -/obj/structure/flora/ash/cacti/Crossed(mob/AM) - if(ishuman(AM) && has_gravity(loc) && prob(70)) - var/mob/living/carbon/human/H = AM - if(!H.shoes && !H.lying) //ouch, my feet. - var/picked_def_zone = pick("l_leg", "r_leg") - var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) - if(!istype(O) || (PIERCEIMMUNE in H.dna.species.species_traits)) - return - H.apply_damage(rand(3, 6), BRUTE, picked_def_zone) - H.Knockdown(40) - H.visible_message("[H] steps on a cactus!", \ - "You step on a cactus!") +/obj/structure/flora/ash/cacti/Initialize(mapload) + . = ..() + // min dmg 3, max dmg 6, prob(70) + AddComponent(/datum/component/caltrop, 3, 6, 70) /obj/item/reagent_containers/food/snacks/grown/ash_flora name = "mushroom shavings" diff --git a/tgstation.dme b/tgstation.dme index 0e23640d22..b95733097c 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -334,6 +334,7 @@ #include "code\datums\antagonists\wizard.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" +#include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" #include "code\datums\components\infective.dm"