mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
Replace basic mob attack telegraph with slower reaction times (#90585)
## About The Pull Request This PR removes the `basic_mob_attack_telegraph` component from all mobs which were using it and instead implements an attack delay directly into the basic melee AI behaviour. This delay simulates "moving your mouse into position", human reaction times, and the fact that the previous implentation of simple mobs would only try to melee attack on a predictable timer you could "juke" around. The way that this delay works is that it starts as soon as the mob enters melee range and resets if you are ever out of the mob's reach, so there will be no delay if you are foolish enough (or unfortunately preventing from doing otherwise) to continue standing next to a mob but there is enough of a one to duck in and out of melee range with a goliath while using a crusher without getting hit, although trying to run past one usually won't work. This delay defaults to 0.3 seconds which in my testing experience was roughly enough to dip in and out of range without getting hit but not enough to run all the way past a mob without getting hit. It can be overriden via the blackboard, although currently no mob does this. I _was_ testing this locally with no latency though so I guess we'll listen out to see if miners start yelling. ## Why It's Good For The Game The visible attack broadcast is very cool but its visibility made melee combat with any mob that had it significantly easier to such a degree that any mob with it on could not really be expected to do melee damage to any character that wasn't suffering some kind of immobilisation effect which was never really the intention. Removing it also removes any additional handicap that was applied to sapient versions of these mobs, which was never really necessary or intended in the first place. I did not remove the component entirely from the game for two reasons: - Out of the hope that there is some use for it somewhere, because I think it's cool, but more importantly: - Because it's still being used by simple mob megafauna as a workaround for a bug we couldn't figure out. ## Changelog 🆑 balance: Most mobs will now hesitate for a moment before attacking rather than instantly hitting anything that enters melee range, to better simulate human behaviour. Please report if this delay seems too short, or too long. balance: Most mobs which telegraphed their basic attacks on you now will not do that /🆑
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
/// Amount of time to wait before executing attack if not specified
|
||||
#define DEFAULT_ATTACK_DELAY (0.4 SECONDS)
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack
|
||||
action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
///do we finish this action after hitting once?
|
||||
var/terminate_after_action = FALSE
|
||||
|
||||
@@ -16,20 +19,32 @@
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (isnull(target))
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
if (!controller.pawn.CanReach(target))
|
||||
controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER)
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
|
||||
var/can_attack_time = controller.blackboard[BB_BASIC_MOB_MELEE_COOLDOWN_TIMER]
|
||||
if (isnull(can_attack_time))
|
||||
var/blackboard_delay = controller.blackboard[BB_BASIC_MOB_MELEE_DELAY]
|
||||
var/attack_delay = isnull(blackboard_delay) ? DEFAULT_ATTACK_DELAY : blackboard_delay
|
||||
controller.set_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER, world.time + attack_delay)
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
if (can_attack_time > world.time)
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
|
||||
if (isliving(controller.pawn))
|
||||
var/mob/living/pawn = controller.pawn
|
||||
if (world.time < pawn.next_move)
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
|
||||
var/mob/living/basic/basic_mob = controller.pawn
|
||||
//targeting strategy will kill the action if not real anymore
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
if(!targeting_strategy.can_attack(basic_mob, target))
|
||||
if(!targeting_strategy.can_attack(controller.pawn, target))
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
|
||||
var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target) //If this is valid, theyre hidden in something!
|
||||
|
||||
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
||||
|
||||
@@ -41,6 +56,7 @@
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER)
|
||||
if(!succeeded)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
@@ -145,3 +161,5 @@
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
#undef DEFAULT_ATTACK_DELAY
|
||||
|
||||
Reference in New Issue
Block a user