mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-12 00:27:31 +01:00
Experiment with replacing weakrefs in AI blackboard with deleting signals, ideally making it easier to work with and harder to cause hard deletes (#74791)
## About The Pull Request Replaces weakref usage in AI blackboards with deleting signals All blackboard var setting must go through setters rather than directly ## Why It's Good For The Game This both makes it a ton easier to develop AI for, and also makes it harder for hard deletes to sneak in, as has been seen with recent 515 prs showing hard deletes in AI blackboards (To quantify "making it easier to develop AI", I found multiple bugs in existing AI code due to the usage of weakrefs.) I'm looking for `@Jacquerel` `@tralezab` 's opinions on the matter, also maybe `@LemonInTheDark` if they're interested ## Changelog 🆑 Melbert refactor: Mob ai refactored once again /🆑
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
udder_component()
|
||||
setup_eating()
|
||||
. = ..()
|
||||
ai_controller.blackboard[BB_BASIC_FOODS] = food_types
|
||||
ai_controller.set_blackboard_key(BB_BASIC_FOODS, food_types)
|
||||
|
||||
///wrapper for the udder component addition so you can have uniquely uddered cow subtypes
|
||||
/mob/living/basic/cow/proc/udder_component()
|
||||
@@ -86,5 +86,5 @@
|
||||
/mob/living/basic/cow/proc/set_tip_react_blackboard(mob/living/carbon/tipper)
|
||||
if(!HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, TIPPED_OVER) || !ai_controller)
|
||||
return
|
||||
ai_controller.blackboard[BB_BASIC_MOB_TIP_REACTING] = TRUE
|
||||
ai_controller.blackboard[BB_BASIC_MOB_TIPPER] = tipper
|
||||
ai_controller.set_blackboard_key(BB_BASIC_MOB_TIP_REACTING, TRUE)
|
||||
ai_controller.set_blackboard_key(BB_BASIC_MOB_TIPPER, tipper)
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_SHOE)
|
||||
var/time_to_freeze_for = (rand(5, 10) SECONDS)
|
||||
ai_controller.blackboard[BB_STATIONARY_SECONDS] = time_to_freeze_for
|
||||
ai_controller.blackboard[BB_STATIONARY_COOLDOWN] = (time_to_freeze_for * (rand(3, 5)))
|
||||
ai_controller.blackboard[BB_STATIONARY_TARGETS] = stationary_scary_things
|
||||
ai_controller.set_blackboard_key(BB_STATIONARY_SECONDS, time_to_freeze_for)
|
||||
ai_controller.set_blackboard_key(BB_STATIONARY_COOLDOWN, (time_to_freeze_for * (rand(3, 5))))
|
||||
ai_controller.set_blackboard_key(BB_STATIONARY_TARGETS, stationary_scary_things)
|
||||
|
||||
/datum/ai_controller/basic_controller/deer
|
||||
blackboard = list(
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
AddElement(/datum/element/death_drops, list(/obj/item/stack/rods))
|
||||
var/datum/action/cooldown/mob_cooldown/charge_apc/charge_ability = new(src)
|
||||
charge_ability.Grant(src)
|
||||
ai_controller.blackboard[BB_FESTIVE_APC] = WEAKREF(charge_ability)
|
||||
ai_controller.set_blackboard_key(BB_FESTIVE_APC, charge_ability)
|
||||
|
||||
/datum/ai_controller/basic_controller/festivus_pole
|
||||
blackboard = list(
|
||||
@@ -98,8 +98,7 @@
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/apcs/target_caught(mob/living/basic/hunter, obj/machinery/power/apc/hunted)
|
||||
var/datum/weakref/ability_weakref = hunter.ai_controller.blackboard[BB_FESTIVE_APC]
|
||||
var/datum/action/cooldown/mob_cooldown/charge_ability = ability_weakref?.resolve()
|
||||
var/datum/action/cooldown/mob_cooldown/charge_ability = hunter.ai_controller.blackboard[BB_FESTIVE_APC]
|
||||
if(isnull(charge_ability))
|
||||
return
|
||||
charge_ability.Activate(hunted)
|
||||
|
||||
@@ -86,8 +86,7 @@
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/star_gazer/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/target = weak_target?.resolve()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
if(!isliving(target))
|
||||
|
||||
@@ -56,6 +56,6 @@
|
||||
devour.Grant(src)
|
||||
var/datum/action/adjust_vision/bileworm/adjust_vision = new(src)
|
||||
adjust_vision.Grant(src)
|
||||
ai_controller.blackboard[BB_BILEWORM_SPEW_BILE] = WEAKREF(spew_bile)
|
||||
ai_controller.blackboard[BB_BILEWORM_RESURFACE] = WEAKREF(resurface)
|
||||
ai_controller.blackboard[BB_BILEWORM_DEVOUR] = WEAKREF(devour)
|
||||
ai_controller.set_blackboard_key(BB_BILEWORM_SPEW_BILE, spew_bile)
|
||||
ai_controller.set_blackboard_key(BB_BILEWORM_RESURFACE, resurface)
|
||||
ai_controller.set_blackboard_key(BB_BILEWORM_DEVOUR, devour)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
to_chat(burrower, span_warning("Couldn't burrow anywhere near the target!"))
|
||||
if(burrower.ai_controller?.ai_status == AI_STATUS_ON)
|
||||
//this is a valid reason to give up on a target
|
||||
burrower.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = null
|
||||
burrower.ai_controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET)
|
||||
return
|
||||
playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(burrower))
|
||||
|
||||
@@ -13,17 +13,15 @@
|
||||
|
||||
/datum/ai_planning_subtree/bileworm_attack/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
|
||||
var/datum/weakref/weak_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
var/mob/living/target = weak_target?.resolve()
|
||||
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
if(QDELETED(target))
|
||||
return
|
||||
|
||||
var/datum/weakref/weak_action = controller.blackboard[BB_BILEWORM_RESURFACE]
|
||||
var/datum/action/cooldown/mob_cooldown/resurface = weak_action?.resolve()
|
||||
var/datum/action/cooldown/mob_cooldown/resurface = controller.blackboard[BB_BILEWORM_RESURFACE]
|
||||
|
||||
//because one ability is always INFINITY cooldown, this actually works to check which ability should be used
|
||||
//sometimes it will try to spew bile on infinity cooldown, but that's okay because as soon as resurface is ready it will attempt that
|
||||
if(resurface && resurface.next_use_time <= world.time)
|
||||
if(!QDELETED(resurface) && resurface.next_use_time <= world.time)
|
||||
controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_RESURFACE, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
else
|
||||
controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_SPEW_BILE, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
@@ -33,8 +31,7 @@
|
||||
|
||||
/datum/ai_planning_subtree/bileworm_execute/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
|
||||
var/datum/weakref/weak_target = controller.blackboard[BB_BASIC_MOB_EXECUTION_TARGET]
|
||||
var/mob/living/target = weak_target?.resolve()
|
||||
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_EXECUTION_TARGET]
|
||||
if(QDELETED(target) || target.stat < UNCONSCIOUS)
|
||||
return
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/datum/pet_command/point_targetting/attack/dog/set_command_active(mob/living/parent, mob/living/commander)
|
||||
. = ..()
|
||||
parent.ai_controller.blackboard[BB_DOG_HARASS_HARM] = TRUE
|
||||
parent.ai_controller.set_blackboard_key(BB_DOG_HARASS_HARM, TRUE)
|
||||
|
||||
/mob/living/basic/pet/dog
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
@@ -159,7 +159,7 @@
|
||||
/mob/living/basic/pet/dog/corgi/proc/stop_deadchat_plays()
|
||||
var/controller_type = initial(ai_controller)
|
||||
ai_controller = new controller_type(src)
|
||||
ai_controller?.blackboard[BB_DOG_IS_SLOW] = is_slow
|
||||
ai_controller?.set_blackboard_key(BB_DOG_IS_SLOW, is_slow)
|
||||
|
||||
/mob/living/basic/pet/dog/corgi/handle_atom_del(atom/A)
|
||||
if(A == inventory_head)
|
||||
@@ -556,7 +556,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
held_state = "old_corgi"
|
||||
icon_dead = "old_corgi_dead"
|
||||
desc = "At a ripe old age of [record_age], Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
|
||||
ai_controller?.blackboard[BB_DOG_IS_SLOW] = TRUE
|
||||
ai_controller?.set_blackboard_key(BB_DOG_IS_SLOW, TRUE)
|
||||
is_slow = TRUE
|
||||
speed = 2
|
||||
|
||||
|
||||
@@ -118,8 +118,9 @@
|
||||
|
||||
teleport = new(src)
|
||||
teleport.Grant(src)
|
||||
ai_controller.blackboard[BB_CARP_RIFT] = WEAKREF(teleport)
|
||||
ai_controller.blackboard[BB_OBSTACLE_TARGETTING_WHITELIST] = allowed_obstacle_targets
|
||||
ai_controller.set_blackboard_key(BB_CARP_RIFT, teleport)
|
||||
ai_controller.set_blackboard_key(BB_OBSTACLE_TARGETTING_WHITELIST, allowed_obstacle_targets)
|
||||
|
||||
|
||||
/mob/living/basic/carp/Destroy()
|
||||
QDEL_NULL(teleport)
|
||||
@@ -129,7 +130,7 @@
|
||||
/mob/living/basic/carp/proc/setup_eating()
|
||||
AddElement(/datum/element/basic_eating, 10, 0, null, desired_food)
|
||||
AddElement(/datum/element/basic_eating, 0, 10, BRUTE, desired_trash) // We are killing our planet
|
||||
ai_controller.blackboard[BB_BASIC_FOODS] = desired_food + desired_trash
|
||||
ai_controller.set_blackboard_key(BB_BASIC_FOODS, desired_food + desired_trash)
|
||||
|
||||
/// Set a random colour on the carp, override to do something else
|
||||
/mob/living/basic/carp/proc/apply_colour()
|
||||
@@ -151,9 +152,16 @@
|
||||
/mob/living/basic/carp/ranged_secondary_attack(atom/atom_target, modifiers)
|
||||
teleport.Trigger(target = atom_target)
|
||||
|
||||
/// Gives the carp a list of destinations to try and travel between when it has nothing better to do
|
||||
/mob/living/basic/carp/proc/migrate_to(list/migration_points)
|
||||
ai_controller.blackboard[BB_CARP_MIGRATION_PATH] = migration_points
|
||||
/// Gives the carp a list of weakrefs of destinations to try and travel between when it has nothing better to do
|
||||
/mob/living/basic/carp/proc/migrate_to(list/datum/weakref/migration_points)
|
||||
var/list/actual_points = list()
|
||||
for(var/datum/weakref/point_ref as anything in migration_points)
|
||||
var/turf/point_resolved = point_ref.resolve()
|
||||
if(QDELETED(point_resolved))
|
||||
return // invalid list, we can't migrate to this
|
||||
actual_points += point_resolved
|
||||
|
||||
ai_controller.set_blackboard_key(BB_CARP_MIGRATION_PATH, actual_points)
|
||||
|
||||
/**
|
||||
* Holographic carp from the holodeck
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target
|
||||
|
||||
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/datum/weakref/weak_action = controller.blackboard[BB_MAGICARP_SPELL]
|
||||
var/datum/action/cooldown/using_action = weak_action?.resolve()
|
||||
var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL]
|
||||
if (QDELETED(using_action))
|
||||
return
|
||||
if (!using_action.IsAvailable())
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
if (!length(migration_points))
|
||||
return
|
||||
|
||||
var/datum/weakref/weak_target = controller.blackboard[BB_CARP_MIGRATION_TARGET]
|
||||
var/turf/moving_to = weak_target?.resolve()
|
||||
var/turf/moving_to = controller.blackboard[BB_CARP_MIGRATION_TARGET]
|
||||
|
||||
// If we don't have a target or are close enough to it, pick a new one
|
||||
if (isnull(moving_to) || get_dist(controller.pawn, moving_to) <= CARP_DESTINATION_SEARCH_RANGE)
|
||||
@@ -48,13 +47,12 @@
|
||||
var/list/blackboard_points = controller.blackboard[path_key]
|
||||
var/list/potential_migration_points = blackboard_points.Copy()
|
||||
while (length(potential_migration_points))
|
||||
var/datum/weakref/weak_destination = popleft(potential_migration_points)
|
||||
var/turf/potential_destination = weak_destination.resolve()
|
||||
var/turf/potential_destination = popleft(potential_migration_points)
|
||||
if (!isnull(potential_destination) && get_dist(controller.pawn, potential_destination) > CARP_DESTINATION_SEARCH_RANGE)
|
||||
controller.blackboard[target_key] = weak_destination
|
||||
controller.set_blackboard_key(target_key, potential_destination)
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return
|
||||
controller.blackboard[path_key] = potential_migration_points.Copy()
|
||||
controller.set_blackboard_key(path_key, potential_migration_points.Copy())
|
||||
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
|
||||
|
||||
@@ -12,14 +12,9 @@
|
||||
if (!rift_behaviour)
|
||||
CRASH("Forgot to specify rift behaviour for [src]")
|
||||
|
||||
var/datum/weakref/weak_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
var/mob/living/target = weak_target?.resolve()
|
||||
if (!target)
|
||||
return
|
||||
|
||||
var/datum/weakref/weak_action = controller.blackboard[BB_CARP_RIFT]
|
||||
var/datum/action/cooldown/using_action = weak_action?.resolve()
|
||||
if (isnull(using_action) || !using_action.IsAvailable())
|
||||
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
var/datum/action/cooldown/using_action = controller.blackboard[BB_CARP_RIFT]
|
||||
if (QDELETED(target) || QDELETED(using_action) || !using_action.IsAvailable())
|
||||
return
|
||||
|
||||
controller.queue_behavior(rift_behaviour, BB_CARP_RIFT, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
@@ -53,20 +48,12 @@
|
||||
/datum/ai_behavior/make_carp_rift
|
||||
|
||||
/datum/ai_behavior/make_carp_rift/setup(datum/ai_controller/controller, ability_key, target_key)
|
||||
var/datum/weakref/weak_action = controller.blackboard[ability_key]
|
||||
var/datum/action/cooldown/mob_cooldown/lesser_carp_rift/ability = weak_action?.resolve()
|
||||
if (!ability)
|
||||
return FALSE
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/target = weak_target?.resolve()
|
||||
return target
|
||||
return controller.blackboard[ability_key] && controller.blackboard[target_key]
|
||||
|
||||
/datum/ai_behavior/make_carp_rift/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_action = controller.blackboard[ability_key]
|
||||
var/datum/action/cooldown/mob_cooldown/lesser_carp_rift/ability = weak_action?.resolve()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/target = weak_target?.resolve()
|
||||
var/datum/action/cooldown/mob_cooldown/lesser_carp_rift/ability = controller.blackboard[ability_key]
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
|
||||
if (!validate_target(controller, target, ability))
|
||||
finish_action(controller, FALSE, ability_key, target_key)
|
||||
@@ -187,9 +174,8 @@
|
||||
var/minimum_distance = 2
|
||||
|
||||
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/datum/weakref/weak_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
var/mob/living/target = weak_target?.resolve()
|
||||
if (isnull(target))
|
||||
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
if (QDELETED(target))
|
||||
return
|
||||
|
||||
var/distance_to_target = get_dist(controller.pawn, target)
|
||||
|
||||
@@ -88,7 +88,7 @@ GLOBAL_LIST_INIT(magicarp_spell_colours, list(
|
||||
spell.projectile_type = spell_type
|
||||
spell.button_icon_state = initial(spell_type.icon_state)
|
||||
spell.Grant(src)
|
||||
ai_controller.blackboard[BB_MAGICARP_SPELL] = WEAKREF(spell)
|
||||
ai_controller.set_blackboard_key(BB_MAGICARP_SPELL, spell)
|
||||
assign_spell_ai(spell_type)
|
||||
|
||||
/// If you have certain spells, use a different targetting datum
|
||||
@@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(magicarp_spell_colours, list(
|
||||
/obj/projectile/magic/resurrection = MAGICARP_SPELL_CORPSES,
|
||||
)
|
||||
|
||||
ai_controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETTING] = spell_special_targetting[spell_type]
|
||||
ai_controller.set_blackboard_key(BB_MAGICARP_SPELL_SPECIAL_TARGETTING, spell_special_targetting[spell_type])
|
||||
|
||||
/// Shoot when you click away from you
|
||||
/mob/living/basic/carp/magic/RangedAttack(atom/atom_target, modifiers)
|
||||
@@ -123,7 +123,7 @@ GLOBAL_LIST_INIT(magicarp_spell_colours, list(
|
||||
chaos_bolt.permitted_projectiles = allowed_projectile_types
|
||||
chaos_bolt.Grant(src)
|
||||
spell = chaos_bolt
|
||||
ai_controller.blackboard[BB_MAGICARP_SPELL] = spell
|
||||
ai_controller.set_blackboard_key(BB_MAGICARP_SPELL, spell)
|
||||
RegisterSignal(spell, COMSIG_ACTION_TRIGGER, PROC_REF(apply_colour))
|
||||
|
||||
/// Has a more limited spell pool but can appear from gold slime cores
|
||||
|
||||
@@ -67,8 +67,7 @@
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/faithless/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/target = weak_target?.resolve()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
if(!isliving(target))
|
||||
|
||||
@@ -119,13 +119,8 @@
|
||||
/mob/living/basic/garden_gnome/proc/ai_retaliate_behaviour(mob/living/attacker)
|
||||
if (!istype(attacker))
|
||||
return
|
||||
var/list/enemy_refs
|
||||
for (var/mob/living/basic/garden_gnome/potential_gnome in oview(src, 7))
|
||||
enemy_refs = potential_gnome.ai_controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST]
|
||||
if (!enemy_refs)
|
||||
enemy_refs = list()
|
||||
enemy_refs |= WEAKREF(attacker)
|
||||
potential_gnome.ai_controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST] = enemy_refs
|
||||
potential_gnome.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker)
|
||||
|
||||
/datum/ai_controller/basic_controller/garden_gnome
|
||||
blackboard = list(
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
var/datum/action/cooldown/lay_web/webbing = new web_type(src)
|
||||
webbing.webbing_time *= web_speed
|
||||
webbing.Grant(src)
|
||||
ai_controller.blackboard[BB_SPIDER_WEB_ACTION] = WEAKREF(webbing)
|
||||
ai_controller.set_blackboard_key(BB_SPIDER_WEB_ACTION, webbing)
|
||||
|
||||
/mob/living/basic/giant_spider/Login()
|
||||
. = ..()
|
||||
|
||||
@@ -15,16 +15,15 @@
|
||||
/datum/ai_behavior/find_unwebbed_turf/perform(seconds_per_tick, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
var/mob/living/spider = controller.pawn
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/current_target = weak_target?.resolve()
|
||||
var/atom/current_target = controller.blackboard[target_key]
|
||||
if (current_target && !(locate(/obj/structure/spider/stickyweb) in current_target))
|
||||
finish_action(controller, succeeded = FALSE) // Already got a target
|
||||
return
|
||||
|
||||
controller.blackboard[target_key] = null
|
||||
controller.clear_blackboard_key(target_key)
|
||||
var/turf/our_turf = get_turf(spider)
|
||||
if (is_valid_web_turf(our_turf))
|
||||
controller.blackboard[target_key] = WEAKREF(our_turf)
|
||||
controller.set_blackboard_key(target_key, our_turf)
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return
|
||||
|
||||
@@ -38,7 +37,7 @@
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
|
||||
controller.blackboard[target_key] = WEAKREF(get_closest_atom(/turf/, potential_turfs, our_turf))
|
||||
controller.set_blackboard_key(target_key, get_closest_atom(/turf/, potential_turfs, our_turf))
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
|
||||
/datum/ai_behavior/find_unwebbed_turf/proc/is_valid_web_turf(turf/target_turf, mob/living/spider)
|
||||
@@ -54,11 +53,9 @@
|
||||
var/target_key = BB_SPIDER_WEB_TARGET
|
||||
|
||||
/datum/ai_planning_subtree/spin_web/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/using_action = weak_action?.resolve()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/turf/target_turf = weak_target?.resolve()
|
||||
if (!using_action || !target_turf)
|
||||
var/datum/action/cooldown/using_action = controller.blackboard[action_key]
|
||||
var/turf/target_turf = controller.blackboard[target_key]
|
||||
if (QDELETED(using_action) || QDELETED(target_turf))
|
||||
return
|
||||
controller.queue_behavior(/datum/ai_behavior/spin_web, action_key, target_key)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
@@ -70,10 +67,8 @@
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/spin_web/setup(datum/ai_controller/controller, action_key, target_key)
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/web_action = weak_action?.resolve()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/turf/target_turf = weak_target?.resolve()
|
||||
var/datum/action/cooldown/web_action = controller.blackboard[action_key]
|
||||
var/turf/target_turf = controller.blackboard[target_key]
|
||||
if (!web_action || !target_turf)
|
||||
return FALSE
|
||||
|
||||
@@ -82,10 +77,9 @@
|
||||
|
||||
/datum/ai_behavior/spin_web/perform(seconds_per_tick, datum/ai_controller/controller, action_key, target_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/web_action = weak_action?.resolve()
|
||||
var/datum/action/cooldown/web_action = controller.blackboard[action_key]
|
||||
finish_action(controller, succeeded = web_action?.Trigger(), action_key = action_key, target_key = target_key)
|
||||
|
||||
/datum/ai_behavior/spin_web/finish_action(datum/ai_controller/controller, succeeded, action_key, target_key)
|
||||
controller.blackboard[target_key] = null
|
||||
controller.clear_blackboard_key(target_key)
|
||||
return ..()
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
|
||||
spikes = new(src)
|
||||
spikes.Grant(src)
|
||||
ai_controller.blackboard[BB_METEOR_HEART_GROUND_SPIKES] = WEAKREF(spikes)
|
||||
ai_controller.set_blackboard_key(BB_METEOR_HEART_GROUND_SPIKES, spikes)
|
||||
|
||||
traps = new(src)
|
||||
traps.Grant(src)
|
||||
ai_controller.blackboard[BB_METEOR_HEART_SPINE_TRAPS] = WEAKREF(traps)
|
||||
ai_controller.set_blackboard_key(BB_METEOR_HEART_SPINE_TRAPS, traps)
|
||||
|
||||
ai_controller.set_ai_status(AI_STATUS_OFF)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
fugu.melee_damage_upper = 20
|
||||
fugu.status_flags |= GODMODE
|
||||
fugu.obj_damage = 60
|
||||
fugu.ai_controller.blackboard[BB_BASIC_MOB_FLEEING] = FALSE
|
||||
fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE)
|
||||
fugu.ai_controller.CancelActions()
|
||||
|
||||
/datum/status_effect/inflated/on_remove()
|
||||
@@ -84,7 +84,7 @@
|
||||
if (fugu.stat != DEAD)
|
||||
fugu.icon_state = "Fugu0"
|
||||
fugu.obj_damage = 0
|
||||
fugu.ai_controller.blackboard[BB_BASIC_MOB_FLEEING] = TRUE
|
||||
fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, TRUE)
|
||||
fugu.ai_controller.CancelActions()
|
||||
|
||||
/// Remove status effect if we die
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), ROUNDSTART_TRAIT)
|
||||
expand = new(src)
|
||||
expand.Grant(src)
|
||||
ai_controller.blackboard[BB_FUGU_INFLATE] = WEAKREF(expand)
|
||||
ai_controller.set_blackboard_key(BB_FUGU_INFLATE, expand)
|
||||
|
||||
/mob/living/basic/wumborian_fugu/Destroy()
|
||||
QDEL_NULL(expand)
|
||||
|
||||
@@ -379,8 +379,7 @@
|
||||
/datum/ai_planning_subtree/flee_target/mouse
|
||||
|
||||
/datum/ai_planning_subtree/flee_target/mouse/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/datum/weakref/hunting_weakref = controller.blackboard[BB_CURRENT_HUNTING_TARGET]
|
||||
var/atom/hunted_cheese = hunting_weakref?.resolve()
|
||||
var/atom/hunted_cheese = controller.blackboard[BB_CURRENT_HUNTING_TARGET]
|
||||
if (!isnull(hunted_cheese))
|
||||
return // We see some cheese, which is more important than our life
|
||||
return ..()
|
||||
|
||||
Reference in New Issue
Block a user