Wall smashing > Wall tearing (#79432)

## About The Pull Request

This PR replaces a bunch of instances of mobs being able to smash walls
by clicking them once to being able to tear walls by standing next to
them for a few seconds while an animation occurs. Wall tearing is a
three-part animation and can be cancelled and resumed at any point from
the most recently completed step so it isn't _exactly_ a single two
second interaction, and is resultingly harder to interrupt.


![dreamseeker_pmnBB9YzNi](https://github.com/tgstation/tgstation/assets/7483112/edca2d02-58f1-499a-a01c-6155ad49a7b2)

Some mobs still destroy walls in a single click, such as Flesh Worms and
Star Gazers. Really whether I replaced this or not was largely down to
vibes.

It also deletes the `tear_walls` element because it was the same as
`wall_tearer` but without the fun visuals.

## Why It's Good For The Game

Deleting walls instantly with a single click is pretty obnoxious. This
method slows it down a _little_ bit but also looks visually cooler and
gives people on the _other_ side of the wall a warning that something is
about to bust through kool-aid man style.

## Changelog

🆑
balance: Gorillas, Seedlings, Gold Grubs, Mooks, Constructs, Ascended
Knock Heretics, Fugu and mobs subject to a Fugu Gland now rip up walls
in a slightly slower but more cinematic way.
/🆑
This commit is contained in:
Jacquerel
2023-11-03 01:52:27 +00:00
committed by GitHub
parent 7e97909899
commit 72c8a02f6c
13 changed files with 14 additions and 62 deletions
-48
View File
@@ -1,48 +0,0 @@
/**
* Attached to a basic mob that will then be able to tear down a wall after some time.
*/
/datum/element/tear_wall
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 3
/// The rate at which we can break regular walls
var/regular_tear_time
/// The rate at which we can break reinforced walls
var/reinforced_tear_time
/datum/element/tear_wall/Attach(datum/target, regular_tear_time = 2 SECONDS, reinforced_tear_time = 4 SECONDS)
. = ..()
if(!isbasicmob(target))
return ELEMENT_INCOMPATIBLE
src.regular_tear_time = regular_tear_time
src.reinforced_tear_time = reinforced_tear_time
RegisterSignal(target, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(attack_wall))
/datum/element/bonus_damage/Detach(datum/source)
UnregisterSignal(source, COMSIG_HOSTILE_POST_ATTACKINGTARGET)
return ..()
/// Checks if we are attacking a wall
/datum/element/tear_wall/proc/attack_wall(mob/living/basic/attacker, atom/target, success)
SIGNAL_HANDLER
if(!iswallturf(target))
return
var/turf/closed/wall/thewall = target
var/prying_time = regular_tear_time
if(istype(thewall, /turf/closed/wall/r_wall))
prying_time = reinforced_tear_time
INVOKE_ASYNC(src, PROC_REF(async_attack_wall), attacker, thewall, prying_time)
/// Performs taking down the wall
/datum/element/tear_wall/proc/async_attack_wall(mob/living/basic/attacker, turf/closed/wall/thewall, prying_time)
if(DOING_INTERACTION_WITH_TARGET(attacker, thewall))
attacker.balloon_alert(attacker, "busy!")
return
to_chat(attacker, span_warning("You begin tearing through the wall..."))
playsound(attacker, 'sound/machines/airlock_alien_prying.ogg', 100, TRUE)
if(do_after(attacker, prying_time, target = thewall))
if(isopenturf(thewall))
return
thewall.dismantle_wall(1)
playsound(attacker, 'sound/effects/meteorimpact.ogg', 100, TRUE)
+2 -1
View File
@@ -20,7 +20,7 @@
/// What interaction key do we use for our interaction
var/do_after_key
/datum/element/wall_tearer/Attach(datum/target, allow_reinforced = TRUE, tear_time = 4 SECONDS, reinforced_multiplier = 3, do_after_key = null)
/datum/element/wall_tearer/Attach(datum/target, allow_reinforced = TRUE, tear_time = 2 SECONDS, reinforced_multiplier = 2, do_after_key = null)
. = ..()
if (!isliving(target))
return ELEMENT_INCOMPATIBLE
@@ -62,6 +62,7 @@
var/is_valid = validate_target(target, tearer)
if (is_valid != WALL_TEAR_ALLOWED)
return
tearer.do_attack_animation(target)
target.AddComponent(/datum/component/torn_wall)
is_valid = validate_target(target, tearer) // And now we might have just destroyed it
if (is_valid == WALL_TEAR_ALLOWED)
@@ -26,7 +26,7 @@
monster.melee_damage_lower = max((monster.melee_damage_lower * 2), 40)
monster.melee_damage_upper = monster.melee_damage_upper / 2
monster.transform *= 1.5
monster.AddElement(/datum/element/wall_smasher, strength_flag = ENVIRONMENT_SMASH_RWALLS)
monster.AddElement(/datum/element/wall_tearer)
/datum/action/cooldown/spell/shapeshift/eldritch/ascension/do_unshapeshift(mob/living/caster)
. = ..()
@@ -43,7 +43,7 @@
var/can_repair_self = FALSE
/// Theme controls color. THEME_CULT is red THEME_WIZARD is purple and THEME_HOLY is blue
var/theme = THEME_CULT
/// Can this construct smash walls? Gets the wall_smasher element if so.
/// Can this construct destroy walls?
var/smashes_walls = FALSE
/// The different flavors of goop constructs can drop, depending on theme.
var/static/list/remains_by_theme = list(
@@ -59,7 +59,7 @@
if(length(remains))
AddElement(/datum/element/death_drops, remains)
if(smashes_walls)
AddElement(/datum/element/wall_smasher, strength_flag = ENVIRONMENT_SMASH_WALLS)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
if(can_repair)
AddComponent(\
/datum/component/healing_touch,\
@@ -54,7 +54,7 @@
/mob/living/basic/gorilla/Initialize(mapload)
. = ..()
add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT)
AddElement(/datum/element/wall_smasher)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
AddElement(/datum/element/dextrous)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_BAREFOOT)
AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = gorilla_food)
@@ -77,7 +77,7 @@
petal_dead = mutable_appearance(icon, "[icon_state]_dead_overlay")
petal_dead.color = petal_color
AddElement(/datum/element/wall_smasher)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
AddComponent(/datum/component/obeys_commands, seedling_commands)
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_can))
@@ -53,7 +53,7 @@
burrow.Grant(src)
ai_controller.set_blackboard_key(BB_SPIT_ABILITY, spit)
ai_controller.set_blackboard_key(BB_BURROW_ABILITY, burrow)
AddElement(/datum/element/wall_smasher)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
AddComponent(/datum/component/ai_listen_to_weather)
AddComponent(\
/datum/component/appearance_on_aggro,\
@@ -59,7 +59,7 @@
ore_overlay = mutable_appearance(icon, "mook_ore_overlay")
AddComponent(/datum/component/ai_listen_to_weather)
AddElement(/datum/element/wall_smasher)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_ore))
@@ -63,7 +63,7 @@
add_traits(list(TRAIT_SPACEWALK, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_NO_FLOATING_ANIM, TRAIT_HEALS_FROM_CARP_RIFTS), INNATE_TRAIT)
AddElement(/datum/element/simple_flying)
AddElement(/datum/element/content_barfer)
AddElement(/datum/element/wall_tearer, do_after_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION)
AddElement(/datum/element/wall_tearer, tear_time = 4 SECONDS, reinforced_multiplier = 3, do_after_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION)
AddElement(/datum/element/door_pryer, pry_time = 4 SECONDS, interaction_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION)
AddComponent(/datum/component/seethrough_mob)
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
@@ -335,7 +335,7 @@
var/datum/action/cooldown/mob_cooldown/command_spiders/warning_spiders/spiders_warning = new(src)
spiders_warning.Grant(src)
AddElement(/datum/element/tear_wall)
AddElement(/datum/element/wall_tearer)
AddElement(/datum/element/web_walker, /datum/movespeed_modifier/below_average_web)
/**
@@ -38,6 +38,6 @@
animal.melee_damage_lower = max((animal.melee_damage_lower * 2), 10)
animal.melee_damage_upper = max((animal.melee_damage_upper * 2), 10)
animal.transform *= 2
animal.AddElement(/datum/element/wall_smasher, strength_flag = ENVIRONMENT_SMASH_RWALLS)
AddElement(/datum/element/wall_tearer)
to_chat(user, span_info("You increase the size of [animal], giving [animal.p_them()] a surge of strength!"))
qdel(src)
@@ -58,7 +58,7 @@
RegisterSignal(fugu, COMSIG_MOB_STATCHANGE, PROC_REF(check_death))
fugu.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/inflated)
ADD_TRAIT(fugu, TRAIT_FUGU_GLANDED, TRAIT_STATUS_EFFECT(id))
fugu.AddElement(/datum/element/wall_smasher)
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
fugu.mob_size = MOB_SIZE_LARGE
fugu.icon_state = "Fugu1"
fugu.melee_damage_lower = 15
@@ -76,7 +76,7 @@
UnregisterSignal(fugu, COMSIG_MOB_STATCHANGE)
fugu.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/inflated)
REMOVE_TRAIT(fugu, TRAIT_FUGU_GLANDED, TRAIT_STATUS_EFFECT(id))
fugu.RemoveElement(/datum/element/wall_smasher)
fugu.RemoveElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
fugu.mob_size = MOB_SIZE_SMALL
fugu.melee_damage_lower = 0
fugu.melee_damage_upper = 0
-1
View File
@@ -1400,7 +1400,6 @@
#include "code\datums\elements\strippable.dm"
#include "code\datums\elements\structure_repair.dm"
#include "code\datums\elements\swabbable.dm"
#include "code\datums\elements\tear_wall.dm"
#include "code\datums\elements\temporary_atom.dm"
#include "code\datums\elements\tenacious.dm"
#include "code\datums\elements\tiny_mob_hunter.dm"