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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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("<span class='danger'>[H] steps on [A].</span>", \
|
||||
"<span class='userdanger'>You step on [A]!</span>")
|
||||
else
|
||||
H.visible_message("<span class='danger'>[H] slides on [A]!</span>", \
|
||||
"<span class='userdanger'>You slide on [A]!</span>")
|
||||
|
||||
cooldown = world.time
|
||||
H.Knockdown(60)
|
||||
@@ -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("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
|
||||
|
||||
/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, "<span class='userdanger'>You step on the D4!</span>")
|
||||
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]")
|
||||
|
||||
@@ -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("<span class='danger'>[H] steps in the broken glass!</span>", \
|
||||
"<span class='userdanger'>You step in the broken glass!</span>")
|
||||
else
|
||||
H.visible_message("<span class='danger'>[H] slides on the broken glass!</span>", \
|
||||
"<span class='userdanger'>You slide on the broken glass!</span>")
|
||||
|
||||
cooldown = world.time
|
||||
H.Knockdown(60)
|
||||
. = ..()
|
||||
|
||||
@@ -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("<span class='danger'>[H] steps on a cactus!</span>", \
|
||||
"<span class='userdanger'>You step on a cactus!</span>")
|
||||
/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"
|
||||
|
||||
Reference in New Issue
Block a user