From c1d4fbc2bad694567b62109f41e5a792ea5ed04b Mon Sep 17 00:00:00 2001 From: san7890 Date: Wed, 17 Apr 2024 11:57:35 -0600 Subject: [PATCH] Regal Rats can now tear down posters (#82673) ## About The Pull Request i was fixing something on bagil and someone who was playing a regal rat (after the round ended) said they wanted to be able to tear down posters as a regal rat so i decided to code it because it made sense. it's an element so literally any mob can tear down posters but i can't think of any other mobs that would make sense to let it tear down posters so we'll leave it just for _The Champion of All Mislaid Creatures_ for now ## Why It's Good For The Game Regal Rats should be all about sludgemaxxing and fucking up maintenance to make it look even more grody than it should be. Being able to tear up those disgusting and well-drawn posters to leave behind nothing but scraps fits that motif. The element has a `do_after()` just to make sure His Holiness doesn't accidentally tear down his posters while clicking (i think all mobs should have this but that's a different issue man) also includes some code improvement and user feedback in some failure cases that already existed in the code. ## Changelog :cl: add: Regal Rats are now able to tear down those colorful posters those weird grey creatures keep spackling up on the walls of their rightful domain. /:cl: --- code/datums/elements/poster_tearer.dm | 45 +++++++++++++++++++ code/game/objects/effects/posters/poster.dm | 19 +++++--- .../basic/space_fauna/regal_rat/regal_rat.dm | 1 + tgstation.dme | 1 + 4 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 code/datums/elements/poster_tearer.dm diff --git a/code/datums/elements/poster_tearer.dm b/code/datums/elements/poster_tearer.dm new file mode 100644 index 00000000000..7a784a48615 --- /dev/null +++ b/code/datums/elements/poster_tearer.dm @@ -0,0 +1,45 @@ +/// Allows mobs with this element attached to just simply tear down any poster they desire to. +/datum/element/poster_tearer + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// The amount of time it takes to tear down a poster. + var/tear_time + /// Interaction key to use whilst tearing down a poster. + var/interaction_key + +/datum/element/poster_tearer/Attach(datum/target, tear_time = 2 SECONDS, interaction_key = null) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.tear_time = tear_time + src.interaction_key = interaction_key + + RegisterSignals(target, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK), PROC_REF(on_attacked_poster)) + +/datum/element/poster_tearer/Detach(datum/source) + . = ..() + UnregisterSignal(source, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK)) + +/// Try to tear up a poster on the wall +/datum/element/poster_tearer/proc/on_attacked_poster(mob/living/user, atom/target, proximity_flag) + SIGNAL_HANDLER + if(!istype(target, /obj/structure/sign/poster)) + return NONE // don't care we move on + + if(DOING_INTERACTION_WITH_TARGET(user, target) || (!isnull(interaction_key) && DOING_INTERACTION(user, interaction_key))) + user.balloon_alert(target, "busy!") + return COMPONENT_CANCEL_ATTACK_CHAIN + + INVOKE_ASYNC(src, PROC_REF(tear_it_down), user, target) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/// Actually work on tearing down that poster +/datum/element/poster_tearer/proc/tear_it_down(mob/living/user, obj/structure/sign/poster/target) + if(!target.check_tearability(user)) // this proc will handle user feedback + return + + target.balloon_alert(user, "tearing down the poster...") + if(!do_after(user, tear_time, target, interaction_key = interaction_key)) // just in case the user actually enjoys art + return + target.tear_poster(user) diff --git a/code/game/objects/effects/posters/poster.dm b/code/game/objects/effects/posters/poster.dm index c4703d700c4..4ced5babbbf 100644 --- a/code/game/objects/effects/posters/poster.dm +++ b/code/game/objects/effects/posters/poster.dm @@ -184,12 +184,17 @@ /obj/structure/sign/poster/attack_hand(mob/user, list/modifiers) . = ..() - if(.) - return - if(ruined) + if(. || !check_tearability()) return tear_poster(user) +/// Check to see if this poster is tearable and gives the user feedback if it is not. +/obj/structure/sign/poster/proc/check_tearability(mob/user) + if(ruined) + balloon_alert(user, "already ruined!") + return FALSE + return TRUE + /obj/structure/sign/poster/proc/spring_trap(mob/user) var/obj/item/shard/payload = trap?.resolve() if (!payload) @@ -264,10 +269,10 @@ playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, TRUE) spring_trap(user) - var/obj/structure/sign/poster/ripped/R = new(loc) - R.pixel_y = pixel_y - R.pixel_x = pixel_x - R.add_fingerprint(user) + var/obj/structure/sign/poster/ripped/torn_poster = new(loc) + torn_poster.pixel_y = pixel_y + torn_poster.pixel_x = pixel_x + torn_poster.add_fingerprint(user) qdel(src) // Various possible posters follow diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm index 51379ce88a0..c0fb9b67e7f 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm @@ -55,6 +55,7 @@ AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling) AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/door_pryer, pry_time = 5 SECONDS, interaction_key = REGALRAT_INTERACTION) + AddElement(/datum/element/poster_tearer, interaction_key = REGALRAT_INTERACTION) AddComponent(\ /datum/component/ghost_direct_control,\ poll_candidates = poll_ghosts,\ diff --git a/tgstation.dme b/tgstation.dme index aa9d394e36e..5d3fa366c54 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1469,6 +1469,7 @@ #include "code\datums\elements\pet_bonus.dm" #include "code\datums\elements\plant_backfire.dm" #include "code\datums\elements\point_of_interest.dm" +#include "code\datums\elements\poster_tearer.dm" #include "code\datums\elements\prevent_attacking_of_types.dm" #include "code\datums\elements\projectile_drop.dm" #include "code\datums\elements\projectile_shield.dm"