From c47049212fd510ab904bc02e980e70751fb863b4 Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:31:31 +0200 Subject: [PATCH] Fixes the watcher trophy not working on basic mobs (#88991) ## About The Pull Request currently, the watcher trophy has no effect on 95% of the lavaland mobs since theyve all been refactored to basic mobs, this rectifies that ## Why It's Good For The Game Fixes the watcher trophy not working on basic mobs ## Changelog :cl: fix: Fixes the watcher trophy not working on basic mobs /:cl: --------- Co-authored-by: Jacquerel --- code/__DEFINES/cooldowns.dm | 8 +++++ code/__DEFINES/crusher_defines.dm | 16 ++++++++++ .../signals/signals_mob/signals_mob_main.dm | 3 ++ code/datums/components/ranged_attacks.dm | 5 +++ .../kinetic_crusher_trophies.dm | 6 +++- .../kinetic_crusher/trophies_fauna.dm | 31 ++++++++++++++----- .../kinetic_crusher/trophies_megafauna.dm | 16 ++++++++++ tgstation.dme | 1 + 8 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 code/__DEFINES/crusher_defines.dm diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index 0ff525dac5a..bd6310575c3 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -116,3 +116,11 @@ #define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0) #define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time)) + +///adds to existing cooldown timer if its started, otherwise starts anew +#define COOLDOWN_INCREMENT(cd_source, cd_index, cd_increment) \ + if(COOLDOWN_FINISHED(cd_source, cd_index)) { \ + COOLDOWN_START(cd_source, cd_index, cd_increment); \ + return; \ + } \ + cd_source.cd_index += (cd_increment); \ diff --git a/code/__DEFINES/crusher_defines.dm b/code/__DEFINES/crusher_defines.dm new file mode 100644 index 00000000000..9f403acd65c --- /dev/null +++ b/code/__DEFINES/crusher_defines.dm @@ -0,0 +1,16 @@ +//the IDs of crusher trophies +#define TROPHY_WATCHER "trophy watcher" +#define TROPHY_BEAR_PAW "trophy bear paw" +#define TROPHY_LOBSTER_CLAW "trophy lobster claw" +#define TROPHY_ICE_DEMON "trophy ice cube" +#define TROPHY_GOLIATH_TENTACLE "trophy goliath tentacle" +#define TROPHY_BRIMDEMON_FANG "trophy brimdemon fang" +#define TROPHY_BLASTER_TUBES "trophy blaster tubes" +#define TROPHY_WOLF_EAR "trophy wolf ear" +#define TROPHY_MINER_EYE "trophy miner eye" +#define TROPHY_TAIL_SPIKE "trophy tail spike" +#define TROPHY_VORTEX "trophy vortex" +#define TROPHY_ICE_BLOCK "trophy ice block" +#define TROPHY_BROOD_TONGUE "trophy brood tongue" +#define TROPHY_DEMON_CLAWS "trophy demon claws" +#define TROPHY_LEGIONNAIRE_SPINE "trophy legionnaire spine" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 2ee1f7ce038..f4557f4b5c1 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -268,3 +268,6 @@ /// from /obj/item/reagent_containers/dropper/interact_with_atom(atom/target, mob/living/user, list/modifiers): (mob/living/user, atom/dropper, datum/reagents/reagents, fraction) #define COMSIG_MOB_REAGENTS_DROPPED_INTO_EYES "mob_reagents_drop_into_eyes" + +///from /obj/item/crusher_trophy/on_mark_activate(): (trophy, user) +#define COMSIG_MOB_TROPHY_ACTIVATED(identifier) "COMSIG_MOB_TROPHY_ACTIVATED[identifier]" diff --git a/code/datums/components/ranged_attacks.dm b/code/datums/components/ranged_attacks.dm index 58883ce5811..e60c3645206 100644 --- a/code/datums/components/ranged_attacks.dm +++ b/code/datums/components/ranged_attacks.dm @@ -47,6 +47,7 @@ . = ..() RegisterSignal(parent, COMSIG_MOB_ATTACK_RANGED, PROC_REF(fire_ranged_attack)) ADD_TRAIT(parent, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, type) + RegisterSignal(parent, COMSIG_MOB_TROPHY_ACTIVATED(TROPHY_WATCHER), PROC_REF(disable_attack)) /datum/component/ranged_attacks/UnregisterFromParent() . = ..() @@ -88,3 +89,7 @@ SEND_SIGNAL(parent, COMSIG_BASICMOB_POST_ATTACK_RANGED, target, modifiers) return +/datum/component/ranged_attacks/proc/disable_attack(obj/item/crusher_trophy/used_trophy, mob/living/user) + SIGNAL_HANDLER + var/stun_duration = (used_trophy.bonus_value * 0.1) SECONDS + COOLDOWN_INCREMENT(src, fire_cooldown, stun_duration) diff --git a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm index 6a00423206e..be8530a678d 100644 --- a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm +++ b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm @@ -9,6 +9,8 @@ icon_state = "tail_spike" /// if it has a bonus effect, this is how much that effect is var/bonus_value = 10 + /// id of the trophy to be sent by the signal + var/trophy_id /// what type of trophies will block this trophy from being added, must be overriden var/denied_type = /obj/item/crusher_trophy @@ -60,4 +62,6 @@ /// Does an effect when you hit a mob that is marked via the projectile /obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user - return + SHOULD_CALL_PARENT(TRUE) + //if we dont have a set id, use the typepath as identifier + SEND_SIGNAL(target, COMSIG_MOB_TROPHY_ACTIVATED(trophy_id || type), src, user) diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm index 2327980a983..24b5dbc94f0 100644 --- a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm @@ -8,19 +8,23 @@ desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." icon_state = "watcher_wing" denied_type = /obj/item/crusher_trophy/watcher_wing + trophy_id = TROPHY_WATCHER bonus_value = 5 /obj/item/crusher_trophy/watcher_wing/effect_desc() return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" /obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) - if(ishostile(target)) - var/mob/living/simple_animal/hostile/H = target - if(H.ranged) //briefly delay ranged attacks - if(H.ranged_cooldown >= world.time) - H.ranged_cooldown += bonus_value - else - H.ranged_cooldown = bonus_value + world.time + . = ..() + if(!ishostile(target)) + return + var/mob/living/simple_animal/hostile/hostile_animal = target + if(!hostile_animal.ranged) + return + if(hostile_animal.ranged_cooldown >= world.time) //briefly delay ranged attacks + hostile_animal.ranged_cooldown += bonus_value + else + hostile_animal.ranged_cooldown = bonus_value + world.time //magmawing watcher /obj/item/crusher_trophy/blaster_tubes/magma_wing @@ -75,6 +79,7 @@ icon_state = "goliath_tentacle" denied_type = /obj/item/crusher_trophy/goliath_tentacle bonus_value = 2 + trophy_id = TROPHY_GOLIATH_TENTACLE /// Your missing health is multiplied by this value to find the bonus damage var/missing_health_ratio = 0.1 /// Amount of health you must lose to gain damage, according to the examine text. Cached so we don't recalculate it every examine. @@ -88,6 +93,7 @@ return "mark detonation to do [bonus_value] more damage for every [missing_health_desc] health you are missing" /obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() var/missing_health = user.maxHealth - user.health missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health missing_health *= bonus_value //multiply the remaining amount by bonus_value @@ -100,12 +106,14 @@ icon_state = "lobster_claw" desc = "A lobster claw." denied_type = /obj/item/crusher_trophy/lobster_claw + trophy_id = TROPHY_LOBSTER_CLAW bonus_value = 1 /obj/item/crusher_trophy/lobster_claw/effect_desc() return "mark detonation to briefly rebuke the target for [bonus_value] seconds" /obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.apply_status_effect(/datum/status_effect/rebuked, bonus_value SECONDS) // Brimdemon - makes a funny sound, the most essential trophy out of all @@ -114,6 +122,7 @@ icon_state = "brimdemon_fang" desc = "A fang from a brimdemon's corpse." denied_type = /obj/item/crusher_trophy/brimdemon_fang + trophy_id = TROPHY_BRIMDEMON_FANG /// Cartoon punching vfx var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM") @@ -121,6 +130,7 @@ return "mark detonation to create visual and audiosensory effects at the target" /obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.balloon_alert_to_viewers("[pick(comic_phrases)]!") playsound(target, 'sound/mobs/non-humanoids/brimdemon/brimdemon_crush.ogg', 100) @@ -155,6 +165,7 @@ return "mark detonation launches projectiles in cardinal directions on a 10 second cooldown. Also gives you an AOE when mining minerals" /obj/item/crusher_trophy/bileworm_spewlet/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() //ability itself handles cooldowns. ability.InterceptClickOn(user, null, target) @@ -180,6 +191,7 @@ desc = "A stone cold cube dropped from an ice demon." icon_state = "ice_demon_cube" denied_type = /obj/item/crusher_trophy/ice_demon_cube + trophy_id = TROPHY_ICE_DEMON ///how many will we summon? var/summon_amount = 2 ///cooldown to summon demons upon the target @@ -189,6 +201,7 @@ return "mark detonation to unleash demonic ice clones upon the target" /obj/item/crusher_trophy/ice_demon_cube/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(isnull(target) || !COOLDOWN_FINISHED(src, summon_cooldown)) return for(var/i in 1 to summon_amount) @@ -214,12 +227,14 @@ name = "wolf ear" desc = "It's a wolf ear." icon_state = "wolf_ear" + trophy_id = TROPHY_WOLF_EAR denied_type = /obj/item/crusher_trophy/wolf_ear /obj/item/crusher_trophy/wolf_ear/effect_desc() return "mark detonation to gain a slight speed boost temporarily" /obj/item/crusher_trophy/wolf_ear/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.apply_status_effect(/datum/status_effect/speed_boost, 1 SECONDS) // Polar bear @@ -227,12 +242,14 @@ name = "polar bear paw" desc = "It's a polar bear paw." icon_state = "bear_paw" + trophy_id = TROPHY_BEAR_PAW denied_type = /obj/item/crusher_trophy/bear_paw /obj/item/crusher_trophy/bear_paw/effect_desc() return "mark detonation to attack twice if you are below half your life" /obj/item/crusher_trophy/bear_paw/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(user.health / user.maxHealth > 0.5) return var/obj/item/I = user.get_active_held_item() diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm index ba302999010..119099f587b 100644 --- a/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm @@ -7,24 +7,28 @@ name = "eye of a blood-drunk hunter" desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher." icon_state = "hunter_eye" + trophy_id = TROPHY_MINER_EYE denied_type = /obj/item/crusher_trophy/miner_eye /obj/item/crusher_trophy/miner_eye/effect_desc() return "mark detonation to grant stun immunity and 90% damage reduction for 1 second" /obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.apply_status_effect(/datum/status_effect/blooddrunk) //ash drake /obj/item/crusher_trophy/tail_spike desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher." denied_type = /obj/item/crusher_trophy/tail_spike + trophy_id = TROPHY_TAIL_SPIKE bonus_value = 5 /obj/item/crusher_trophy/tail_spike/effect_desc() return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" /obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() for(var/mob/living/living_target in oview(2, user)) if(user.faction_check_atom(living_target) || living_target.stat == DEAD) continue @@ -45,6 +49,7 @@ gender = PLURAL denied_type = /obj/item/crusher_trophy/demon_claws bonus_value = 10 + trophy_id = TROPHY_DEMON_CLAWS var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) /obj/item/crusher_trophy/demon_claws/effect_desc() @@ -68,6 +73,7 @@ user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order) /obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order) //colossus @@ -78,6 +84,7 @@ gender = PLURAL denied_type = /obj/item/crusher_trophy/blaster_tubes bonus_value = 15 + trophy_id = TROPHY_BLASTER_TUBES var/deadly_shot = FALSE /obj/item/crusher_trophy/blaster_tubes/effect_desc() @@ -92,6 +99,7 @@ deadly_shot = FALSE /obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() deadly_shot = TRUE addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE) @@ -103,12 +111,14 @@ name = "vortex talisman" desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher." icon_state = "vortex_talisman" + trophy_id = TROPHY_VORTEX denied_type = /obj/item/crusher_trophy/vortex_talisman /obj/item/crusher_trophy/vortex_talisman/effect_desc() return "mark detonation to create a homing hierophant chaser" /obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(isliving(target)) var/obj/effect/temp_visual/hierophant/chaser/chaser = new(get_turf(user), user, target, 3, TRUE) chaser.monster_damage_boost = FALSE // Weaker cuz no cooldown @@ -120,12 +130,14 @@ name = "ice block talisman" desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason." icon_state = "ice_trap_talisman" + trophy_id = TROPHY_ICE_BLOCK denied_type = /obj/item/crusher_trophy/ice_block_talisman /obj/item/crusher_trophy/ice_block_talisman/effect_desc() return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving" /obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.apply_status_effect(/datum/status_effect/ice_block_talisman) // Wendigo @@ -156,6 +168,7 @@ icon_state = "broodmother_tongue" denied_type = /obj/item/crusher_trophy/broodmother_tongue bonus_value = 10 + trophy_id = TROPHY_BROOD_TONGUE /// Time at which the item becomes usable again var/use_time @@ -163,6 +176,7 @@ return "mark detonation to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location" /obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(prob(bonus_value) && target.stat != DEAD) new /obj/effect/goliath_tentacle/broodmother/patch(get_turf(target), user) @@ -189,6 +203,7 @@ icon_state = "legionnaire_spine" denied_type = /obj/item/crusher_trophy/legionnaire_spine bonus_value = 20 + trophy_id = TROPHY_LEGIONNAIRE_SPINE /// Time at which the item becomes usable again var/next_use_time @@ -196,6 +211,7 @@ return "mark detonation to have a [bonus_value]% chance to summon a loyal legion skull" /obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(!prob(bonus_value) || target.stat == DEAD) return var/mob/living/basic/legion_brood/minion = new (user.loc) diff --git a/tgstation.dme b/tgstation.dme index 979ceb8a1a7..4ccdc79f8d5 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -72,6 +72,7 @@ #include "code\__DEFINES\configuration.dm" #include "code\__DEFINES\cooldowns.dm" #include "code\__DEFINES\crafting.dm" +#include "code\__DEFINES\crusher_defines.dm" #include "code\__DEFINES\crushing.dm" #include "code\__DEFINES\ctf.dm" #include "code\__DEFINES\cult.dm"