From 2e256a4b142a1abcbec025e8cd01cfe876aa7115 Mon Sep 17 00:00:00 2001 From: xDanilcusx Date: Mon, 6 Nov 2023 02:09:47 +0300 Subject: [PATCH] finally WORKING CROOSHIE --- .../abilities/crusher/crusher_abilities.dm | 11 ++ .../carbon/xenomorph/ai/movement/crusher.dm | 163 ++++++++++++------ .../living/carbon/xenomorph/castes/Crusher.dm | 4 +- .../mutators/strains/crusher/charger.dm | 2 +- 4 files changed, 125 insertions(+), 55 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm index 022640d50d..61d6c62525 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm @@ -214,6 +214,17 @@ shake_camera(Mob, 7, 3) animation_flash_color(Mob) + for(var/mob/living/carbon/human/Mob in orange(1, Xeno)) + if(Mob.knocked_down) + continue + + if(momentum < max_momentum / 2) + continue + + Mob.apply_effect(0.5, WEAKEN) + animation_flash_color(Mob) + shake_camera(Mob, 4, 2) + Xeno.recalculate_speed() /datum/action/xeno_action/onclick/charger_charge/proc/handle_dir_change(datum/source, old_dir, new_dir) diff --git a/code/modules/mob/living/carbon/xenomorph/ai/movement/crusher.dm b/code/modules/mob/living/carbon/xenomorph/ai/movement/crusher.dm index 4831e3f98f..7193491733 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/movement/crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/movement/crusher.dm @@ -1,83 +1,142 @@ -#define CRUSHER_MOMENTUM_MOBILITY 3 -#define CRUSHER_CHARGE_DISTANCE 10 -#define CROOSH_MODE_TIME 16 SECONDS -#define CROOSH_MODE_CD 4 SECONDS - /datum/xeno_ai_movement/crusher - var/datum/action/xeno_action/onclick/charger_charge/charge_action - var/croosh_mode = FALSE - COOLDOWN_DECLARE(croosh_mode_cooldown) - COOLDOWN_DECLARE(croosh_mode_timer) + /// The turf we force our crusher to walk to when he charges + var/turf/charge_turf + + +#define AI_NEW_TARGET_COOLDOWN 5 SECONDS /datum/xeno_ai_movement/crusher/New(mob/living/carbon/xenomorph/parent) . = ..() - charge_action = get_xeno_action_by_type(parent, /datum/action/xeno_action/onclick/charger_charge) + addtimer(CALLBACK(src, PROC_REF(get_new_target), parent), AI_NEW_TARGET_COOLDOWN, TIMER_UNIQUE|TIMER_LOOP|TIMER_DELETE_ME) + +/datum/xeno_ai_movement/crusher/proc/get_new_target(mob/living/carbon/xenomorph/parent) + parent.current_target = parent.get_target(parent.ai_range) + +#undef AI_NEW_TARGET_COOLDOWN + + +#define MIN_TARGETS_TO_CHARGE 3 +#define MIN_CHARGE_DISTANCE 5 +#define CHARGE_DEVIATION 1 /datum/xeno_ai_movement/crusher/ai_move_target(delta_time) var/mob/living/carbon/xenomorph/moving_xeno = parent if(moving_xeno.throwing) return - check_ai_mode() + var/target = moving_xeno.current_target - if(HAS_TRAIT(moving_xeno, TRAIT_CHARGING)) - var/turf/current_loc = moving_xeno.loc - var/mob/target = moving_xeno.current_target - var/moving_dir = moving_xeno.dir + if(charge_turf) + if(get_dist(target, moving_xeno) >= moving_xeno.ai_range) + toggle_charging(FALSE) + return TRUE - if(!(get_dir(target, moving_xeno) in reverse_nearby_direction(moving_dir) + NONE)) - if(charge_action.momentum <= CRUSHER_MOMENTUM_MOBILITY) - charge_action.stop_momentum() - return ..() + var/list/to_ram = list() + for(var/turf/turfs in getline2(moving_xeno, charge_turf)) + to_ram += turfs.contents - charge_action.lose_momentum(1.5) + var/charging_dir = get_dir(moving_xeno, charge_turf) + if(moving_xeno.move_to_next_turf(charge_turf, world.maxx, to_ram)) + if(charging_dir in cardinal) + return TRUE - var/turf/charge_turf = current_loc - var/list/to_ram = list() + var/turf/next_turf = get_step(moving_xeno, charging_dir) + if(LinkBlocked(moving_xeno, get_turf(moving_xeno), next_turf)) + if(moving_xeno.Move(next_turf, 0)) + return TRUE - for(var/i=0, i<=CRUSHER_CHARGE_DISTANCE, i++) - var/turf/T = get_step(charge_turf, moving_dir) - for(var/atom/A in T) - to_ram += A + toggle_charging(FALSE) + return TRUE - if(LinkBlocked(moving_xeno, moving_xeno.loc, T, list(target, moving_xeno) + to_ram)) - break + if(get_dist(moving_xeno, target) <= MIN_CHARGE_DISTANCE) + return ..() - charge_turf = T + var/humans_x = 0 + var/humans_y = 0 + var/humans_count = 0 - if(!moving_xeno.move_to_next_turf(charge_turf, ignore = to_ram)) - return ..() + for(var/mob/living/carbon/human/humie in view(MIN_CHARGE_DISTANCE, target)) + if(humie.stat) + continue - var/turf/next_turf = get_step(moving_xeno.loc, moving_dir) + humans_x += humie.x + humans_y += humie.y + humans_count++ - if(next_turf.density) - if(!moving_xeno.Move(next_turf, moving_dir)) - charge_action.stop_momentum() + if(humans_count < MIN_TARGETS_TO_CHARGE) + return ..() - return + humans_x = Floor(humans_x / humans_count) + rand(-CHARGE_DEVIATION, CHARGE_DEVIATION) + humans_y = Floor(humans_y / humans_count) + rand(-CHARGE_DEVIATION, CHARGE_DEVIATION) + + var/turf/middle = locate(humans_x, humans_y, moving_xeno.z) + + var/turf/WE_move_variant = locate(moving_xeno.x, middle.y, moving_xeno.z) + var/turf/NS_move_variant = locate(middle.x, moving_xeno.y, moving_xeno.z) + + var/list/possible_blocked_turfs = list(WE_move_variant, NS_move_variant) + var/list/non_blocked_turfs = list() + + for(var/i=1 to LAZYLEN(possible_blocked_turfs)) + var/turf/next_turf = possible_blocked_turfs[i] + var/blocked = FALSE + + for(var/I=0 to MIN_CHARGE_DISTANCE) + var/turf/last_turf = next_turf + next_turf = get_step(next_turf, get_dir(next_turf, middle)) + + if(LinkBlocked(moving_xeno, last_turf, next_turf)) + blocked = TRUE + + if(blocked) + continue + + non_blocked_turfs += possible_blocked_turfs[i] + + var/lenght = LAZYLEN(non_blocked_turfs) + if(!lenght) + return ..() + + var/turf/to_move + if(lenght == 1) + to_move = pick(non_blocked_turfs) + + if(!to_move) + var/dist_check = get_dist(WE_move_variant, parent) > get_dist(NS_move_variant, parent) + to_move = dist_check ? NS_move_variant : WE_move_variant + + if(!moving_xeno.move_to_next_turf(to_move)) + return ..() + + if(get_turf(moving_xeno) != to_move) + return TRUE + + var/step_dir = get_dir(to_move, middle) + var/turf/edge_turf = get_step(moving_xeno, step_dir) + + while(!edge_turf.density) + edge_turf = get_step(edge_turf, step_dir) + + toggle_charging(TRUE) + charge_turf = edge_turf + + return TRUE + +#undef CHARGE_DEVIATION +#undef MIN_CHARGE_DISTANCE +#undef MIN_TARGETS_TO_CHARGE - return ..() -/datum/xeno_ai_movement/crusher/proc/check_ai_mode() - var/mob/living/carbon/xenomorph/croosher = parent +/datum/xeno_ai_movement/crusher/proc/toggle_charging(toggle) + var/datum/action/xeno_action/onclick/charger_charge/charge_action = get_xeno_action_by_type(parent, /datum/action/xeno_action/onclick/charger_charge) - if(COOLDOWN_FINISHED(src, croosh_mode_cooldown) && !croosh_mode) + if(toggle && !charge_action.activated) INVOKE_ASYNC(charge_action, TYPE_PROC_REF(/datum/action/xeno_action/onclick/charger_charge, use_ability_wrapper)) - COOLDOWN_START(src, croosh_mode_timer, CROOSH_MODE_TIME) - croosher.emote("roar") - croosh_mode = TRUE - if(COOLDOWN_FINISHED(src, croosh_mode_timer) && croosh_mode && !HAS_TRAIT(croosher, TRAIT_CHARGING)) + if(!toggle && charge_action.activated) INVOKE_ASYNC(charge_action, TYPE_PROC_REF(/datum/action/xeno_action/onclick/charger_charge, use_ability_wrapper)) - COOLDOWN_START(src, croosh_mode_cooldown, CROOSH_MODE_CD) - croosher.emote("growl") - croosh_mode = FALSE - -#undef CROOSH_MODE_CD -#undef CROOSH_MODE_TIME -#undef CRUSHER_CHARGE_DISTANCE -#undef CRUSHER_MOMENTUM_MOBILITY + charge_turf = null /mob/living/carbon/xenomorph/crusher/Move(NewLoc, direct) if(direct == 0) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm index a2e23fd602..b8648b7a54 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm @@ -70,7 +70,7 @@ icon_xeno = 'icons/mob/xenos/crusher.dmi' icon_xenonid = 'icons/mob/xenonids/crusher.dmi' - ai_range = 24 + ai_range = 28 /mob/living/carbon/xenomorph/crusher/init_movement_handler() return new /datum/xeno_ai_movement/crusher(src) @@ -296,6 +296,6 @@ . += "Shield: [shield_total]" /datum/behavior_delegate/crusher_base/on_update_icons() - if(bound_xeno.throwing || is_charging) //Let it build up a bit so we're not changing icons every single turf + if(HAS_TRAIT(bound_xeno, TRAIT_CHARGING) && !bound_xeno.lying) bound_xeno.icon_state = "[bound_xeno.mutation_icon_state || bound_xeno.mutation_type] Crusher Charging" return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm index 9b402d4d92..704782344c 100644 --- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm +++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm @@ -136,7 +136,7 @@ charger_ability.stop_momentum() return - health -= CHARGER_DESTROY //Usually knocks it down. + health -= CHARGER_DESTROY * 2 //Usually knocks it down. healthcheck() if(QDELETED(src))