Skip to content

Commit

Permalink
Facehugger AI 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xDanilcusx committed Jan 16, 2024
1 parent a342db6 commit 9ffea68
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 34 deletions.
2 changes: 1 addition & 1 deletion code/modules/admin/game_master/game_master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

// Spawn stuff
#define DEFAULT_SPAWN_XENO_STRING XENO_CASTE_DRONE
#define GAME_MASTER_AI_XENOS list(XENO_CASTE_DRONE, XENO_CASTE_RUNNER, XENO_CASTE_LURKER, XENO_CASTE_FACEHUGGER, XENO_CASTE_CRUSHER)
#define GAME_MASTER_AI_XENOS list(XENO_CASTE_DRONE, XENO_CASTE_RUNNER, XENO_CASTE_LURKER, XENO_CASTE_CRUSHER, XENO_CASTE_FACEHUGGER)

#define DEFAULT_XENO_AMOUNT_TO_SPAWN 1

Expand Down
41 changes: 10 additions & 31 deletions code/modules/cm_aliens/structures/egg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
icon_state = "Egg Growing"
density = FALSE
anchored = TRUE
layer = LYING_BETWEEN_MOB_LAYER //to stop hiding eggs under corpses
layer = BELOW_TABLE_LAYER //so facehuggers will be above the eggs
health = 80
plane = GAME_PLANE
var/list/egg_triggers = list()
var/status = EGG_GROWING //can be EGG_GROWING, EGG_GROWN, EGG_BURST, EGG_BURSTING, or EGG_DESTROYED; all mutually exclusive
var/on_fire = FALSE
var/hivenumber = XENO_HIVE_NORMAL
var/flags_embryo = NO_FLAGS
var/trigger_radius = 2

/obj/effect/alien/egg/Initialize(mapload, hive)
. = ..()
create_egg_triggers()
if (hive)
hivenumber = hive

Expand Down Expand Up @@ -93,21 +93,10 @@
update_icon()
deploy_egg_triggers()

/obj/effect/alien/egg/proc/create_egg_triggers()
for(var/i in 1 to 8)
egg_triggers += new /obj/effect/egg_trigger(src, src)

/obj/effect/alien/egg/proc/deploy_egg_triggers()
var/i = 1
var/x_coords = list(-1,-1,-1,0,0,1,1,1)
var/y_coords = list(1,0,-1,1,-1,1,0,-1)
var/turf/target_turf
for(var/trigger in egg_triggers)
var/obj/effect/egg_trigger/ET = trigger
target_turf = locate(x+x_coords[i],y+y_coords[i], z)
if(target_turf)
ET.forceMove(target_turf)
i++
var/list/observed_turfs = orange(trigger_radius, src)
for(var/target_turf in observed_turfs)
egg_triggers += new /obj/effect/egg_trigger(target_turf, src)

/obj/effect/alien/egg/proc/hide_egg_triggers()
for(var/trigger in egg_triggers)
Expand Down Expand Up @@ -136,20 +125,10 @@
status = EGG_BURST
if(is_hugger_player_controlled)
return //Don't need to spawn a hugger, a player controls it already!
var/obj/item/clothing/mask/facehugger/child = new(loc, hivenumber)

child.flags_embryo = flags_embryo
flags_embryo = NO_FLAGS // Lose the embryo flags when passed on

if(X && X.caste.can_hold_facehuggers && (!X.l_hand || !X.r_hand)) //sanity checks
X.put_in_hands(child)
return

if(instant_trigger)
if(!child.leap_at_nearest_target())
child.return_to_egg(src)
else
child.go_idle()
var/mob/living/carbon/xenomorph/facehugger/child = new(loc)
if(hivenumber != XENO_HIVE_NORMAL)
child.set_hive_and_update(hivenumber)

/obj/effect/alien/egg/bullet_act(obj/projectile/P)
..()
Expand Down Expand Up @@ -286,9 +265,9 @@
/obj/effect/egg_trigger/Crossed(atom/movable/AM)
if(!linked_egg && !linked_eggmorph) //something went very wrong.
qdel(src)
else if(linked_egg && (get_dist(src, linked_egg) != 1 || !isturf(linked_egg.loc))) //something went wrong
else if(linked_egg && (get_dist(src, linked_egg) > linked_egg.trigger_radius || !isturf(linked_egg.loc))) //something went wrong
forceMove(linked_egg)
else if(linked_eggmorph && (get_dist(src, linked_eggmorph) != 1 || !isturf(linked_eggmorph.loc))) //something went wrong
else if(linked_eggmorph && (get_dist(src, linked_eggmorph) > linked_egg.trigger_radius || !isturf(linked_eggmorph.loc))) //something went wrong
forceMove(linked_eggmorph)
else if(iscarbon(AM))
var/mob/living/carbon/C = AM
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
/datum/xeno_ai_movement/linger/facehugger/New(mob/living/carbon/xenomorph/parent)
. = ..()
var/turf/current_turf = get_turf(parent)
if(. != INITIALIZE_HINT_QDEL && (locate(/obj/effect/alien/egg) in current_turf))
home_turf = current_turf

/datum/xeno_ai_movement/linger/facehugger/ai_move_idle(delta_time)
var/mob/living/carbon/xenomorph/facehugger/idle_xeno = parent
if(idle_xeno.throwing)
return

if(next_home_search < world.time && (!home_turf || !(locate(/obj/effect/alien/egg) in home_turf) || get_dist(home_turf, idle_xeno) > max_distance_from_home))
var/turf/T = get_turf(idle_xeno.loc)
next_home_search = world.time + home_search_delay
var/obj/effect/alien/egg/possible_egg = locate(/obj/effect/alien/egg) in T
if(possible_egg && possible_egg.status == EGG_BURST)
home_turf = T
else
var/shortest_distance = INFINITY
for(var/i in RANGE_TURFS(home_locate_range, T))
var/turf/potential_home = i
possible_egg = locate(/obj/effect/alien/egg) in potential_home
if(possible_egg && possible_egg.status == EGG_BURST && get_dist(idle_xeno, potential_home) < shortest_distance)
home_turf = potential_home
shortest_distance = get_dist(idle_xeno, potential_home)

if(!home_turf)
return

var/obj/effect/alien/egg/eggy = locate(/obj/effect/alien/egg) in home_turf
if(idle_xeno.move_to_next_turf(home_turf, home_locate_range) && eggy && eggy.status == EGG_BURST)
if(get_dist(home_turf, idle_xeno) <= 0)
idle_xeno.climb_in_egg(eggy)
else
home_turf = null

/datum/xeno_ai_movement/linger/facehugger/ai_move_target(delta_time)
var/mob/living/carbon/xenomorph/moving_xeno = parent

Expand Down Expand Up @@ -42,7 +78,27 @@
#undef FIND_NEW_TRAVEL_RADIUS_MAX

/mob/living/carbon/xenomorph/facehugger/check_mob_target(mob/living/carbon/human/checked_human)
if(istype(checked_human.wear_mask, /obj/item/clothing/mask/facehugger))
return FALSE

if(checked_human.status_flags & XENO_HOST)
return FALSE

return ..()
if(can_not_harm(checked_human))
return FALSE

if(checked_human.stat == DEAD)
return FALSE

return TRUE

/mob/living/carbon/xenomorph/facehugger/proc/climb_in_egg(obj/effect/alien/egg/eggy)
set waitfor = FALSE

if(do_after(src, 10, INTERRUPT_ALL, BUSY_ICON_GENERIC, eggy))
visible_message(SPAN_XENOWARNING("[src] crawls back into [eggy]!"))
eggy.status = EGG_GROWN
eggy.icon_state = "Egg"
eggy.deploy_egg_triggers()
qdel(src)

13 changes: 12 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/xeno_ai_interaction.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ At bare minimum, make sure the relevant checks from parent types gets copied in
if(!density)
return 0

if(unslashable && !climbable)
if((unslashable || isfacehugger(X)) && !climbable)
return

return OBJECT_PENALTY
Expand Down Expand Up @@ -91,8 +91,19 @@ At bare minimum, make sure the relevant checks from parent types gets copied in
if(locked || welded || isElectrified())
return INFINITY

if(isfacehugger(X))
return -1 // We LOVE going under doors!

return DOOR_PENALTY

// TABLES
/obj/structure/surface/table/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target)
. = ..()
if(isfacehugger(X))
return -1 // We also love to skiddle under the tables!

return

// HUMANS
/mob/living/carbon/human/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target)
if(status_flags & GODMODE)
Expand Down

0 comments on commit 9ffea68

Please sign in to comment.