Skip to content

Commit

Permalink
Initial
Browse files Browse the repository at this point in the history
  • Loading branch information
morrowwolf committed Oct 14, 2023
1 parent 944bbf7 commit 32ffc0a
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 22 deletions.
6 changes: 2 additions & 4 deletions code/controllers/subsystem/xeno_ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ SUBSYSTEM_DEF(xeno_ai)
/// A list of AI mobs
var/list/ai_mobs = list()

var/game_evaluation = 0

var/ai_kill = FALSE

/datum/controller/subsystem/xeno_ai/stat_entry(msg)
msg = "P:[length(ai_mobs)]|Eval:[game_evaluation]"
msg = "P:[length(ai_mobs)]"
return ..()

/datum/admins/proc/toggle_ai()
Expand All @@ -39,7 +37,7 @@ SUBSYSTEM_DEF(xeno_ai)
var/mob/living/carbon/xenomorph/M = current_run[current_run.len]
current_run.len--
if(!QDELETED(M) && !M.client && M.stat != DEAD)
M.process_ai(wait * 0.1, game_evaluation)
M.process_ai(wait * 0.1)
else
remove_ai(M)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,31 @@
var/list/pounce_callbacks = null // Specific callbacks to invoke when a pounce lands on an atom of a specific type
// (note that if a collided atom does not match any of the key types, defaults to the appropriate X_launch_collision proc)

default_ai_action = TRUE
var/prob_chance = 80

/datum/action/xeno_action/activable/pounce/process_ai(mob/living/carbon/xenomorph/pouncing_xeno, delta_time)
if(get_dist(pouncing_xeno, pouncing_xeno.current_target) > distance || !DT_PROB(prob_chance, delta_time))
return

var/turf/last_turf = pouncing_xeno.loc
var/clear = TRUE

pouncing_xeno.add_temp_pass_flags(PASS_OVER_THROW_MOB)

for(var/i in getline2(pouncing_xeno, pouncing_xeno.current_target, FALSE))
var/turf/new_turf = i
if(LinkBlocked(pouncing_xeno, last_turf, new_turf, list(pouncing_xeno.current_target, pouncing_xeno)))
clear = FALSE
break

pouncing_xeno.remove_temp_pass_flags(PASS_OVER_THROW_MOB)

if(!clear)
return

use_ability_async(pouncing_xeno.current_target)

/datum/action/xeno_action/activable/pounce/New()
. = ..()
initialize_pounce_pass_flags()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
macro_path = /datum/action/xeno_action/verb/verb_pounce
action_type = XENO_ACTION_CLICK
ability_primacy = XENO_PRIMARY_ACTION_1
xeno_cooldown = 30
xeno_cooldown = 50
plasma_cost = 0

// Config options
Expand Down
23 changes: 20 additions & 3 deletions code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
var/action_type = XENO_ACTION_CLICK // Determines how macros interact with this action. Defines are in xeno.dm in the defines folder.
var/ability_primacy = XENO_NOT_PRIMARY_ACTION // Determines how the default ability macros handle this.

/// Whether this action gets added to AI xenos
var/default_ai_action = FALSE

// Cooldown
/// Cooldown of the ability (do not use the cooldown var)
/// Probably should only have the cooldown var, but that is for another rework
Expand Down Expand Up @@ -58,6 +61,11 @@
action.update_button_icon()
return TRUE

/// Used for AI xenos to prevent them from sleeping
/datum/action/xeno_action/proc/use_ability_async(atom/A)
set waitfor = FALSE
use_ability(A)

// Track statistics for this ability
/datum/action/xeno_action/proc/track_xeno_ability_stats()
if(!owner)
Expand All @@ -74,10 +82,19 @@
if(X && !X.is_mob_incapacitated() && !X.dazed && !X.lying && !X.buckled && X.plasma_stored >= plasma_cost)
return TRUE

/datum/action/xeno_action/give_to(mob/living/L)
/datum/action/xeno_action/give_to(mob/living/living_mob)
..()

if(macro_path)
add_verb(L, macro_path)
add_verb(living_mob, macro_path)

if(!istype(living_mob, /mob/living/carbon/xenomorph))
return

var/mob/living/carbon/xenomorph/xeno_mob = living_mob

if(default_ai_action)
xeno_mob.register_ai_action(src)

/datum/action/xeno_action/update_button_icon()
if(!button)
Expand All @@ -92,7 +109,7 @@
else
button.color = rgb(255,255,255,255)

/datum/action/xeno_action/proc/process_ai(mob/living/carbon/xenomorph/X, delta_time, game_evaluation)
/datum/action/xeno_action/proc/process_ai(mob/living/carbon/xenomorph/X, delta_time)
SHOULD_NOT_SLEEP(TRUE)
return PROCESS_KILL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
parent = null
return ..()

/datum/xeno_ai_movement/proc/ai_move_idle(delta_time, game_evaluation)
/datum/xeno_ai_movement/proc/ai_move_idle(delta_time)
SHOULD_NOT_SLEEP(TRUE)
var/mob/living/carbon/xenomorph/idle_xeno = parent
if(idle_xeno.throwing)
Expand Down Expand Up @@ -47,7 +47,7 @@
else
home_turf = null

/datum/xeno_ai_movement/proc/ai_move_target(delta_time, game_evaluation)
/datum/xeno_ai_movement/proc/ai_move_target(delta_time)
SHOULD_NOT_SLEEP(TRUE)
var/mob/living/carbon/xenomorph/X = parent
if(X.throwing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
blacklisted_turfs = null

//drones expand the hive
/datum/xeno_ai_movement/drone/ai_move_idle(delta_time, game_evaluation)
/datum/xeno_ai_movement/drone/ai_move_idle(delta_time)
var/mob/living/carbon/xenomorph/idle_xeno = parent

if(idle_xeno.throwing)
Expand Down
56 changes: 56 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/ai/movement/linger.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/datum/xeno_ai_movement/linger

/// The turf the xeno is currently attempting to travel to
var/turf/travelling_turf

/// Distance in turfs that the xeno will try to run to when the marine is not incapacitated or out of view
var/linger_range = 5

/// The deviation in turfs of linger_range, gives the bounds a + and - of upper and inner range
var/linger_deviation = 1

/// The cooldown for how long the xeno will wait out of view before attempting to re-engage
COOLDOWN_DECLARE(reengage_cooldown)

/datum/xeno_ai_movement/linger/ai_move_target(delta_time)
var/mob/living/carbon/xenomorph/moving_xeno = parent
if(moving_xeno.throwing)
return

if(moving_xeno.current_target.is_mob_incapacitated())
return ..()

check_for_travelling_turf_change(moving_xeno)

if(!moving_xeno.move_to_next_turf(travelling_turf))
travelling_turf = get_turf(moving_xeno.current_target)
return TRUE

#define REENGAGE_COOLDOWN (2 SECONDS)
#define FIND_NEW_TRAVEL_TURF_LIMIT 5

/datum/xeno_ai_movement/linger/proc/check_for_travelling_turf_change(mob/living/carbon/xenomorph/moving_xeno)
if(!(moving_xeno in view(world.view, moving_xeno.current_target)) && COOLDOWN_FINISHED(src, reengage_cooldown))
travelling_turf = get_turf(moving_xeno.current_target)
COOLDOWN_START(src, reengage_cooldown, REENGAGE_COOLDOWN)
return

if(!travelling_turf || get_dist(travelling_turf, moving_xeno) <= 0)
for(var/i = 0 to FIND_NEW_TRAVEL_TURF_LIMIT)
travelling_turf = get_random_turf_in_range_unblocked(moving_xeno.current_target, linger_range + linger_deviation, linger_range - linger_deviation)

if(!travelling_turf)
continue

var/travelling_turf_dir = get_dir(moving_xeno, travelling_turf)
var/current_target_dir = get_dir(moving_xeno, moving_xeno.current_target)

if(current_target_dir != travelling_turf_dir && current_target_dir != turn(travelling_turf_dir, 45) && current_target_dir != turn(travelling_turf_dir, -45))
break

if(!travelling_turf)
travelling_turf = get_turf(moving_xeno.current_target)
return

#undef REENGAGE_COOLDOWN
#undef FIND_NEW_TRAVEL_TURF_LIMIT
19 changes: 9 additions & 10 deletions code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ GLOBAL_LIST_INIT(ai_target_limbs, list(
registered_ai_abilities -= XA
XA.ai_unregistered(src)

/mob/living/carbon/xenomorph/proc/process_ai(delta_time, game_evaluation)
/mob/living/carbon/xenomorph/proc/process_ai(delta_time)
SHOULD_NOT_SLEEP(TRUE)
SHOULD_CALL_PARENT(TRUE)
if(!hive || !get_turf(src))
Expand All @@ -72,10 +72,10 @@ GLOBAL_LIST_INIT(ai_target_limbs, list(
a_intent = INTENT_HARM

if(!current_target)
ai_move_idle(delta_time, game_evaluation)
ai_move_idle(delta_time)
return TRUE

if(ai_move_target(delta_time, game_evaluation))
if(ai_move_target(delta_time))
return TRUE

for(var/x in registered_ai_abilities)
Expand All @@ -87,23 +87,23 @@ GLOBAL_LIST_INIT(ai_target_limbs, list(
if(XA.hidden)
continue

if(XA.process_ai(src, delta_time, game_evaluation) == PROCESS_KILL)
if(XA.process_ai(src, delta_time) == PROCESS_KILL)
unregister_ai_action(XA)

if(get_dist(src, current_target) <= 1 && DT_PROB(XENO_SLASH, delta_time))
INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, do_click), current_target, "", list())
INVOKE_ASYNC(src, PROC_REF(do_click), current_target, "", list())

/** Controls movement when idle. Called by process_ai */
/mob/living/carbon/xenomorph/proc/ai_move_idle(delta_time, game_evaluation)
/mob/living/carbon/xenomorph/proc/ai_move_idle(delta_time)
if(!ai_movement_handler)
CRASH("No valid movement handler for [src]!")
ai_movement_handler.ai_move_idle(delta_time, game_evaluation)
ai_movement_handler.ai_move_idle(delta_time)

/** Controls movement towards target. Called by process_ai */
/mob/living/carbon/xenomorph/proc/ai_move_target(delta_time, game_evaluation)
/mob/living/carbon/xenomorph/proc/ai_move_target(delta_time)
if(!ai_movement_handler)
CRASH("No valid movement handler for [src]!")
return ai_movement_handler.ai_move_target(delta_time, game_evaluation)
return ai_movement_handler.ai_move_target(delta_time)

/atom/proc/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction)
return INFINITY
Expand All @@ -126,7 +126,6 @@ GLOBAL_LIST_INIT(ai_target_limbs, list(
next_move_slowdown = 0
return TRUE


/mob/living/carbon/xenomorph/proc/set_path(list/path)
current_path = path
if(!path)
Expand Down
56 changes: 56 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Runner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,68 @@
icon_xeno = 'icons/mob/xenos/runner.dmi'
icon_xenonid = 'icons/mob/xenonids/runner.dmi'

var/linger_range = 5
var/linger_deviation = 1
var/pull_direction

/mob/living/carbon/xenomorph/runner/initialize_pass_flags(datum/pass_flags_container/PF)
..()
if (PF)
PF.flags_pass |= PASS_FLAGS_CRAWLER

/mob/living/carbon/xenomorph/runner/launch_towards(datum/launch_metadata/LM)
if(!current_target)
return ..()

pull_direction = turn(get_dir(src, current_target), 180)

if(!(pull_direction in GLOB.cardinals))
if(abs(x - current_target.x) < abs(y - current_target.y))
pull_direction &= (NORTH|SOUTH)
else
pull_direction &= (EAST|WEST)
return ..()

/mob/living/carbon/xenomorph/runner/init_movement_handler()
var/datum/xeno_ai_movement/linger/linger_movement = new(src)
linger_movement.linger_range = linger_range
linger_movement.linger_deviation = linger_deviation
return linger_movement

/mob/living/carbon/xenomorph/runner/ai_move_target(delta_time)
if(throwing)
return

if(pulling)
if(can_move_and_apply_move_delay())
if(!Move(get_step(loc, pull_direction), pull_direction))
pull_direction = turn(pull_direction, pick(45, -45))
current_path = null
return

..()

if(get_dist(current_target, src) > 1)
return

if(!current_target.is_mob_incapacitated())
return

if(isxeno(current_target.pulledby))
return

if(!DT_PROB(RUNNER_GRAB, delta_time))
return

INVOKE_ASYNC(src, PROC_REF(start_pulling), current_target)
swap_hand()

/mob/living/carbon/xenomorph/runner/process_ai(delta_time)
if(get_active_hand())
swap_hand()
zone_selected = pick(GLOB.ai_target_limbs)
return ..()

/datum/behavior_delegate/runner_base
name = "Base Runner Behavior Delegate"

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@
if(istype(AM, /atom/movable/clone))
AM = AM.mstr //If AM is a clone, refer to the real target

if ( QDELETED(AM) || !usr || src==AM || !isturf(loc) || !isturf(AM.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
if (QDELETED(AM) || src == AM || !isturf(loc) || !isturf(AM.loc)) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
return

if (AM.anchored || AM.throwing)
Expand Down
1 change: 1 addition & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,7 @@ s// DM Environment file for colonialmarines.dme.
#include "code\modules\mob\living\carbon\xenomorph\ai\xeno_ai.dm"
#include "code\modules\mob\living\carbon\xenomorph\ai\movement\base_define.dm"
#include "code\modules\mob\living\carbon\xenomorph\ai\movement\drone.dm"
#include "code\modules\mob\living\carbon\xenomorph\ai\movement\linger.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\Boiler.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\Burrower.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\Carrier.dm"
Expand Down

0 comments on commit 32ffc0a

Please sign in to comment.