Skip to content
This repository has been archived by the owner on May 30, 2022. It is now read-only.

Flock AI Tweaks 2: Electric Boogaloo #126

Merged
merged 23 commits into from
Apr 14, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9f4e550
not working lol
amylizzle Mar 18, 2022
1ac717a
Merge branch 'stonepillars:master' into flock_ai_tweaks_part_2
amylizzle Mar 18, 2022
09d15aa
Merge branch 'stonepillars:master' into flock_ai_tweaks_part_2
amylizzle Mar 31, 2022
bb761a7
Merge branch 'stonepillars:master' into flock_ai_tweaks_part_2
amylizzle Apr 5, 2022
0f8d457
holy shit that's better
amylizzle Apr 5, 2022
125b0be
Merge branch 'flock_ai_tweaks_part_2' of https://github.com/amylizzle…
amylizzle Apr 5, 2022
30ec1e2
almost done
amylizzle Apr 5, 2022
a51061b
mobai is an adventure
amylizzle Apr 5, 2022
92ed983
Merge branch 'stonepillars:master' into flock_ai_tweaks_part_2
amylizzle Apr 6, 2022
5dc6329
much better, range weighting is now normalized
amylizzle Apr 6, 2022
40eea23
Update code/mob/living/critter/ai/flock/flocktasks.dm
amylizzle Apr 6, 2022
d26d937
Update code/mob/living/critter/ai/flock/flocktasks.dm
amylizzle Apr 6, 2022
91f1e83
add nesting icon to control panel
amylizzle Apr 7, 2022
7ea8e39
Merge branch 'flock_ai_tweaks_part_2' of https://github.com/amylizzle…
amylizzle Apr 7, 2022
56f5117
codereview
amylizzle Apr 9, 2022
b50c83a
Apply suggestions from code review
amylizzle Apr 11, 2022
f66b19a
couple code review tweaks + new pathfinding behaviour for caging
amylizzle Apr 11, 2022
2ccda90
bunch of 0 -> FALSE, 1->TRUE
amylizzle Apr 11, 2022
22b24a1
move behaviour is now faster.
amylizzle Apr 11, 2022
0bcb781
fix for taking control of drones, plus minor tweak to shooting
amylizzle Apr 11, 2022
11c7d7f
Merge branch 'master' into flock_ai_tweaks_part_2
amylizzle Apr 11, 2022
c8b3341
Fix for drones smashing their face against a wall - pathing was going…
amylizzle Apr 13, 2022
e78423d
Merge branch 'flock_ai_tweaks_part_2' of https://github.com/amylizzle…
amylizzle Apr 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/datums/controllers/process/mob_ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ datum/controller/process/mob_ai
else
H.ai_process()
scheck()
else if(istype(X,/mob/living/critter))
var/mob/living/critter/C = X
if(C.is_npc && C.ai)
C.ai.tick()
else if(M.ai)
M.ai.tick()
scheck()
Expand Down
2 changes: 2 additions & 0 deletions code/datums/flock/flock.dm
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@
/datum/flock/proc/reserveTurf(var/turf/simulated/T, var/name)
if(T in all_owned_tiles)
return
if(T in src.busy_tiles)
return //can't reserve tiles that are already reserved
src.busy_tiles[name] = T
src.updateAnnotations()

Expand Down
1 change: 1 addition & 0 deletions code/mob/living/critter/ai/flock/flockdrone.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
..()
// populate the list of tasks
transition_tasks += holder.get_instance(/datum/aiTask/sequence/goalbased/replicate, list(holder, src))
transition_tasks += holder.get_instance(/datum/aiTask/sequence/goalbased/nest, list(holder, src))
transition_tasks += holder.get_instance(/datum/aiTask/sequence/goalbased/build/drone, list(holder, src))
transition_tasks += holder.get_instance(/datum/aiTask/sequence/goalbased/repair, list(holder, src))
transition_tasks += holder.get_instance(/datum/aiTask/sequence/goalbased/deposit, list(holder, src))
Expand Down
140 changes: 100 additions & 40 deletions code/mob/living/critter/ai/flock/flocktasks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
//task priorities and preconditions at a glance:
/*
replicate
-weight 7
-precondition: can_afford(100)

nest
-weight 6
-precondition: can_afford(100)

building
-weight 5
-precondition: can_afford(20)

building-drone
building/drone
-weight 1
-precondition: can_afford(20)

Expand All @@ -20,7 +24,7 @@ repair
-precondition: can_afford(10)

deposit
-weight 7
-weight 8
-procondition: can_afford(10)

open_container
Expand Down Expand Up @@ -73,14 +77,13 @@ butcher
max_dist = 0
// most of the functionality here is already in the base goalbased task, we only want movement


///////////////////////////////////////////////////////////////////////////////////////////////////////////
// REPLICATION GOAL
// targets: valid nesting sites
// precondition: 100 resources
/datum/aiTask/sequence/goalbased/replicate
name = "replicating"
weight = 6
weight = 7
can_be_adjacent_to_target = 0

/datum/aiTask/sequence/goalbased/replicate/New(parentHolder, transTask)
Expand All @@ -100,7 +103,7 @@ butcher
if(isnull(locate(/obj/flock_structure/egg) in F))
// if we can get a valid path to the target, include it for consideration
. += F
. = get_path_to(holder.owner, ., 40, 0)
. = get_path_to(holder.owner, ., max_dist*2, can_be_adjacent_to_target)

////////

Expand Down Expand Up @@ -131,15 +134,54 @@ butcher
/datum/aiTask/succeedable/replicate/on_reset()
has_started = 0


///////////////////////////////////////////////////////////////////////////////////////////////////////////
// NEST + REPLICATION GOAL
// targets: valid nesting sites
// precondition: 120 resources, no flocktiles in view
/datum/aiTask/sequence/goalbased/nest
name = "nesting"
weight = 6
can_be_adjacent_to_target = 1
amylizzle marked this conversation as resolved.
Show resolved Hide resolved
max_dist = 2

/datum/aiTask/sequence/goalbased/nest/New(parentHolder, transTask)
..(parentHolder, transTask)
add_task(holder.get_instance(/datum/aiTask/succeedable/build, list(holder)))
//add_task(holder.get_instance(/datum/aiTask/succeedable/replicate, list(holder)))
amylizzle marked this conversation as resolved.
Show resolved Hide resolved

/datum/aiTask/sequence/goalbased/nest/precondition()
. = 0
amylizzle marked this conversation as resolved.
Show resolved Hide resolved
var/mob/living/critter/flock/drone/F = holder.owner
if(F?.can_afford(120))
. = 1 //we can afford
amylizzle marked this conversation as resolved.
Show resolved Hide resolved
for(var/turf/simulated/floor/feather/T in view(max_dist, holder.owner))
. = 0 //but there's a flocktile in view
amylizzle marked this conversation as resolved.
Show resolved Hide resolved


/datum/aiTask/sequence/goalbased/nest/get_targets()
. = list()
var/mob/living/critter/flock/F = holder.owner
// grab a nearby unconverted tile
for(var/turf/simulated/floor/T in view(max_dist, holder.owner))
if(!isfeathertile(T))
if(F?.flock && !F.flock.isTurfFree(T, F.real_name))
continue // this tile's been claimed by someone else
// if we can get a valid path to the target, include it for consideration
. += T
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// BUILDING GOAL
// targets: priority tiles, fetched from holder.owner.flock (with casting)
// or, if they're not available, whatever's available nearby
// precondition: 20 resources
/datum/aiTask/sequence/goalbased/build
name = "building"
weight = 5
max_dist = 2
weight = 10
max_dist = 5

/datum/aiTask/sequence/goalbased/build/New(parentHolder, transTask)
..(parentHolder, transTask)
Expand All @@ -159,28 +201,35 @@ butcher
F.flock.reserveTurf(T, F.real_name)

/datum/aiTask/sequence/goalbased/build/get_targets()
. = list()
var/mob/living/critter/flock/F = holder.owner

if(F?.flock)
// if we can go for a tile we already have reserved, go for it
var/turf/simulated/reserved = F.flock.busy_tiles[F.real_name]
if(istype(reserved) && !isfeathertile(reserved) && get_path_to(holder.owner, reserved, 20, 1))
. += reserved
return
if(istype(reserved) && !isfeathertile(reserved))
. = get_path_to(holder.owner, reserved, max_dist, 1)
if(length(.) > 0)
return
else
//unreserve the turf if we can't get at it
F.flock.busy_tiles[F.real_name] = null
amylizzle marked this conversation as resolved.
Show resolved Hide resolved

// if there's a priority tile we can go for, do it
var/list/priority_turfs = F.flock.getPriorityTurfs(F)
if(length(priority_turfs))
. += priority_turfs
. = get_path_to(holder.owner, priority_turfs, max_dist, 1)
if(length(.) > 0)
amylizzle marked this conversation as resolved.
Show resolved Hide resolved
return

. = list()
// else just go for one nearby
for(var/turf/simulated/T in view(max_dist, holder.owner))
if(!isfeathertile(T))
if(F?.flock && !F.flock.isTurfFree(T, F.real_name))
continue // this tile's been claimed by someone else
// if we can get a valid path to the target, include it for consideration
. += T
. = get_path_to(holder.owner, ., 60, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)
amylizzle marked this conversation as resolved.
Show resolved Hide resolved

////////

Expand Down Expand Up @@ -226,28 +275,35 @@ butcher
/datum/aiTask/sequence/goalbased/build/drone
name = "building"
weight = 1
max_dist = 4 //max dist is higher so we can find walls in bigger rooms
max_dist = 4

/datum/aiTask/sequence/goalbased/build/drone/precondition()
var/mob/living/critter/flock/F = holder.owner
return F?.can_afford(20)


/datum/aiTask/sequence/goalbased/build/drone/get_targets()
. = list()
var/mob/living/critter/flock/F = holder.owner

if(F?.flock)
// if we can go for a tile we already have reserved, go for it
var/turf/simulated/reserved = F.flock.busy_tiles[F.real_name]
if(istype(reserved) && !isfeathertile(reserved) && get_path_to(holder.owner, reserved, 20, 1))
. += reserved
return
if(istype(reserved) && !isfeathertile(reserved))
. = get_path_to(holder.owner, reserved, max_dist, 1)
if(length(.))
return
else
//unreserve the turf if we can't get at it
F.flock.busy_tiles[F.real_name] = null

// if there's a priority tile we can go for, do it
var/list/priority_turfs = F.flock.getPriorityTurfs(F)
if(length(priority_turfs))
. += priority_turfs
. = get_path_to(holder.owner, priority_turfs, max_dist, 1)
if(length(.))
return

. = list()
//as drone, we want to prioritise converting doors and walls and containers
for(var/turf/simulated/T in view(max_dist, holder.owner))
if(!isfeathertile(T) && (
Expand All @@ -267,7 +323,7 @@ butcher
continue // this tile's been claimed by someone else
// if we can get a valid path to the target, include it for consideration
. += T
. = get_path_to(holder.owner, ., 60, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -305,7 +361,7 @@ butcher
if(F.get_health_percentage() < 0.66 && !isdead(F))//yeesh dont try to repair something which is dead
// if we can get a valid path to the target, include it for consideration
. += F
. = get_path_to(holder.owner, ., 40, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -343,7 +399,7 @@ butcher
// precondition: 10 resources
/datum/aiTask/sequence/goalbased/deposit
name = "depositing"
weight = 7
weight = 8

/datum/aiTask/sequence/goalbased/deposit/New(parentHolder, transTask)
..(parentHolder, transTask)
Expand All @@ -370,7 +426,7 @@ butcher
if(S.flock == F.flock && S.goal > S.currentmats)
// if we can get a valid path to the target, include it for consideration
. += S
. = get_path_to(holder.owner, ., 40, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -426,7 +482,7 @@ butcher
if(!S.open && !S.welded && !S.locked)
// if we can get a valid path to the target, include it for consideration
. += S
. = get_path_to(holder.owner, ., 10, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -482,7 +538,7 @@ butcher
if(length(I.contents) && I.loc != holder.owner && I.does_not_open_in_pocket)
// if we can get a valid path to the target, include it for consideration
. += I
. = get_path_to(holder.owner, ., 10, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -555,7 +611,7 @@ butcher
/datum/aiTask/sequence/goalbased/harvest
name = "harvesting"
weight = 2
max_dist = 4
max_dist = 6

/datum/aiTask/sequence/goalbased/harvest/New(parentHolder, transTask)
..(parentHolder, transTask)
Expand All @@ -574,18 +630,9 @@ butcher
if(!I.anchored && I.loc != holder.owner)
if(istype(I, /obj/item/game_kit))
continue // fuck the game kit
if(istype(I, /obj/item/paper_bin))
// special consideration because these things can empty out
var/obj/item/paper_bin/P = I
if(P.amount <= 0)
continue // do not try to fetch paper out of an empty paper bin forever
if(istype(I,/obj/item/card_group))
if(I.loc == holder.owner) //checks hand for card to allow taking from pockets/storage
holder.owner.u_equip(I)
holder.owner.put_in_hand_or_drop(I)
// if we can get a valid path to the target, include it for consideration
. += I
. = get_path_to(holder.owner, ., 40, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down Expand Up @@ -613,8 +660,21 @@ butcher
else
F.empty_hand(1) // drop whatever we might be holding just in case
// grab the item
F.set_dir(get_dir(F, harvest_target))
F.hand_attack(harvest_target)
F.set_dir(get_dir(F, harvest_target)) //look at it
//special item type handling
if(istype(harvest_target,/obj/item/card_group))
if(harvest_target.loc == holder.owner) //checks hand for card to allow taking from pockets/storage
holder.owner.u_equip(harvest_target)
holder.owner.put_in_hand_or_drop(harvest_target)
else if(istype(harvest_target, /obj/item/paper_bin))
// special consideration because these things can empty out
var/obj/item/paper_bin/P = harvest_target
if(P.amount <= 0) //if it's empty, pick up the bin
holder.owner.put_in_hand_or_drop(harvest_target)
else
F.hand_attack(harvest_target) //else grab some paper
else
F.hand_attack(harvest_target)
// if we have the item, equip it into our horrifying death chamber
if(F.is_in_hands(harvest_target))
F.absorber.equip(harvest_target) // hooray!
Expand Down Expand Up @@ -742,7 +802,7 @@ butcher
if(!istype(M.loc.type, /obj/icecube/flockdrone))
// if we can get a valid path to the target, include it for consideration
. += M
. = get_path_to(holder.owner, ., 40, 1)
. = get_path_to(holder.owner, ., target_range*2, 1)


////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -773,7 +833,7 @@ butcher
continue
if(isdead(F))
. += F
. = get_path_to(holder.owner, ., 40, 1)
. = get_path_to(holder.owner, ., max_dist*2, 1)

////////

Expand Down
Loading