mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-21 21:17:44 +01:00
[MIRROR] Mining mob tweaks [MDB IGNORE] (#23242)
* Mining mob tweaks (#77763) ## About The Pull Request ~~I wanted to do this after #77700 (wow cool numbers) but nobody has merged it yet despite how simple it is so i'll just hope they don't conflict.~~ Thanks san I'm fucking about with mining mobs with the intention of making them more interesting but not necessarily towards making mining _harder_, but some of these changes unquestionably have done so. These changes are mostly in response to feedback about Watchers who are definitely significantly more threatening than previously, although some of this is user error. - Watchers are annoying when traversing lavaland because they use their ability on you instantly upon acquiring a target, if you are trying to escape other fauna this quickly becomes deadly. - A lot of players don't really realise what the overwatch ability is actually doing and so just complain about getting machine gunned. - If you _do_ react properly to the ability it still makes fighting them take a lot longer than it used to. - The "look away" icon is hard to see in the dark sometimes To ammeliorate these factors I have: - Reduced watcher health by ~20% - Display an alerted graphic over the head of the watcher every time you trigger the overwatch. - Multiple watchers now won't overwatch you at the same time (this made the "penalty" volley essentially become instant death) - The "look away" icon is rendered above the lighting plane so you can always see it - Added a new component which tracks how long a mob has had a specific target. - - Watchers will now only Overwatch you if they've seen you for at least 5 seconds (usually they'll try and shoot at you twice before this). - - Goliaths will only tentacle you if they've seen you for at least 3 seconds. If overwatch is still problematic after this I guess I can just nerf it to not track movement at all and only respond to attacks. ## Why It's Good For The Game I don't want to discourage miners from "actually mining" by having them get sniped just for walking around and the added time-to-kill on these guys could make clearing tendrils more tedious too. ## Changelog 🆑 balance: Watchers have less health balance: You can't be overwatched by several watchers at a time balance: Watchers won't overwatch you instantly upon seeing you balance: Goliaths won't launch tentacles at you instantly upon seeing you /🆑 * Mining mob tweaks --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddElement(/datum/element/footstep, FOOTSTEP_MOB_HEAVY)
|
||||
AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = goliath_foods)
|
||||
AddComponent(/datum/component/ai_target_timer)
|
||||
AddComponent(/datum/component/basic_mob_attack_telegraph)
|
||||
AddComponentFrom(INNATE_TRAIT, /datum/component/shovel_hands)
|
||||
if (tameable)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/// We won't use tentacles unless we have had the same target for this long
|
||||
#define MIN_TIME_TO_TENTACLE 3 SECONDS
|
||||
|
||||
/datum/ai_controller/basic_controller/goliath
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items/goliath,
|
||||
@@ -20,12 +23,16 @@
|
||||
stat_attack = HARD_CRIT
|
||||
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree/goliath
|
||||
operational_datums = list(/datum/component/ai_target_timer)
|
||||
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/goliath
|
||||
|
||||
/// Go for the tentacles if they're available
|
||||
/datum/ai_behavior/basic_melee_attack/goliath
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/goliath/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key)
|
||||
var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0
|
||||
if (time_on_target < MIN_TIME_TO_TENTACLE)
|
||||
return ..()
|
||||
var/mob/living/target = controller.blackboard[target_key]
|
||||
// Interrupt attack chain to use tentacles, unless the target is already tentacled
|
||||
if (ismecha(target) || (isliving(target) && !target.has_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled)))
|
||||
@@ -37,11 +44,15 @@
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/goliath_tentacles
|
||||
ability_key = BB_GOLIATH_TENTACLES
|
||||
operational_datums = list(/datum/component/ai_target_timer)
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/goliath_tentacles/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/target = controller.blackboard[target_key]
|
||||
if (!(isliving(target) || ismecha(target)) || (isliving(target) && target.has_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled)))
|
||||
return // Target can be an item or already grabbed, we don't want to tentacle those
|
||||
var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0
|
||||
if (time_on_target < MIN_TIME_TO_TENTACLE)
|
||||
return // We need to spend some time acquiring our target first
|
||||
return ..()
|
||||
|
||||
/// If we got nothing better to do, find a turf we can search for tasty roots and such
|
||||
@@ -115,3 +126,5 @@
|
||||
/datum/ai_behavior/goliath_dig/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
||||
. = ..()
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
#undef MIN_TIME_TO_TENTACLE
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
base_pixel_x = -12
|
||||
speak_emote = list("chimes")
|
||||
speed = 3
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
maxHealth = 160
|
||||
health = 160
|
||||
attack_verb_continuous = "buffets"
|
||||
attack_verb_simple = "buffet"
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing
|
||||
@@ -44,6 +44,7 @@
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddElement(/datum/element/simple_flying)
|
||||
AddElement(/datum/element/content_barfer)
|
||||
AddComponent(/datum/component/ai_target_timer)
|
||||
AddComponent(/datum/component/basic_ranged_ready_overlay, overlay_state = eye_glow)
|
||||
AddComponent(\
|
||||
/datum/component/ranged_attacks,\
|
||||
@@ -84,8 +85,8 @@
|
||||
icon_living = "watcher_magmawing"
|
||||
icon_dead = "watcher_magmawing_dead"
|
||||
eye_glow = "fire_glow"
|
||||
maxHealth = 215 //Compensate for the lack of slowdown on projectiles with a bit of extra health
|
||||
health = 215
|
||||
maxHealth = 175 //Compensate for the lack of slowdown on projectiles with a bit of extra health
|
||||
health = 175
|
||||
projectile_type = /obj/projectile/temp/watcher/magma_wing
|
||||
gaze_attack = /datum/action/cooldown/mob_cooldown/watcher_gaze/fire
|
||||
crusher_loot = /obj/item/crusher_trophy/blaster_tubes/magma_wing
|
||||
@@ -98,8 +99,8 @@
|
||||
icon_state = "watcher_icewing"
|
||||
icon_living = "watcher_icewing"
|
||||
icon_dead = "watcher_icewing_dead"
|
||||
maxHealth = 170
|
||||
health = 170
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
projectile_type = /obj/projectile/temp/watcher/ice_wing
|
||||
gaze_attack = /datum/action/cooldown/mob_cooldown/watcher_gaze/ice
|
||||
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/bone = 1)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/overwatch
|
||||
ability_key = BB_WATCHER_OVERWATCH
|
||||
operational_datums = list(/datum/component/ai_target_timer)
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/overwatch/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
@@ -24,6 +25,9 @@
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (QDELETED(target) || HAS_TRAIT(target, TRAIT_OVERWATCH_IMMUNE))
|
||||
return // We should probably let miners move sometimes
|
||||
var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0
|
||||
if (time_on_target < 5 SECONDS)
|
||||
return // We need to spend some time acquiring our target first
|
||||
return ..()
|
||||
|
||||
/datum/ai_planning_subtree/use_mob_ability/gaze
|
||||
|
||||
@@ -84,7 +84,8 @@
|
||||
/// Display an animated overlay over our head to indicate what's going on
|
||||
/datum/action/cooldown/mob_cooldown/watcher_gaze/proc/show_indicator_overlay(overlay_state)
|
||||
clear_current_overlay()
|
||||
current_overlay = image(icon = 'icons/effects/eldritch.dmi', loc = owner, icon_state = overlay_state, pixel_x = -owner.pixel_x, pixel_y = 28)
|
||||
current_overlay = image(icon = 'icons/effects/eldritch.dmi', loc = owner, icon_state = overlay_state, pixel_x = -owner.pixel_x, pixel_y = 28, layer = ABOVE_ALL_MOB_LAYER)
|
||||
SET_PLANE_EXPLICIT(current_overlay, ABOVE_LIGHTING_PLANE, owner)
|
||||
for(var/client/add_to in GLOB.clients)
|
||||
add_to.images += current_overlay
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
ADD_TRAIT(owner, TRAIT_OVERWATCHED, TRAIT_STATUS_EFFECT(id))
|
||||
owner.add_traits(list(TRAIT_OVERWATCHED, TRAIT_OVERWATCH_IMMUNE), TRAIT_STATUS_EFFECT(id))
|
||||
owner.do_alert_animation()
|
||||
owner.Immobilize(0.25 SECONDS) // Just long enough that they don't trigger it by mistake
|
||||
owner.playsound_local(owner, 'sound/machines/chime.ogg', 50, TRUE)
|
||||
@@ -109,7 +109,7 @@
|
||||
/datum/status_effect/overwatch/on_remove()
|
||||
UnregisterSignal(owner, forbidden_actions + list(COMSIG_QDELETING, COMSIG_LIVING_DEATH))
|
||||
QDEL_NULL(link)
|
||||
REMOVE_TRAIT(owner, TRAIT_OVERWATCHED, TRAIT_STATUS_EFFECT(id))
|
||||
owner.remove_traits(list(TRAIT_OVERWATCHED, TRAIT_OVERWATCH_IMMUNE), TRAIT_STATUS_EFFECT(id))
|
||||
if (!QDELETED(owner))
|
||||
owner.apply_status_effect(/datum/status_effect/overwatch_immune)
|
||||
return ..()
|
||||
@@ -135,6 +135,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
overwatch_triggered = TRUE
|
||||
watcher.do_alert_animation()
|
||||
INVOKE_ASYNC(watcher, TYPE_PROC_REF(/atom/, fire_projectile), projectile_type, owner, projectile_sound)
|
||||
|
||||
/// Can't overwatch you if I don't exist
|
||||
|
||||
Reference in New Issue
Block a user