diff --git a/code/datums/ai/_ai_behavior.dm b/code/datums/ai/_ai_behavior.dm index d0501fe58bb..e1bcef0fe1d 100644 --- a/code/datums/ai/_ai_behavior.dm +++ b/code/datums/ai/_ai_behavior.dm @@ -23,6 +23,16 @@ controller.behavior_args -= type if(behavior_flags & AI_BEHAVIOR_REQUIRE_MOVEMENT) //If this was a movement task, reset our movement target if necessary if(!(behavior_flags & AI_BEHAVIOR_KEEP_MOVE_TARGET_ON_FINISH)) - controller.set_movement_target(null) + clear_movement_target(controller) if(!(behavior_flags & AI_BEHAVIOR_KEEP_MOVING_TOWARDS_TARGET_ON_FINISH)) controller.ai_movement.stop_moving_towards(controller) + +/// Helper proc to ensure consistency in setting the source of the movement target +/datum/ai_behavior/proc/set_movement_target(datum/ai_controller/controller, atom/target, datum/ai_movement/new_movement) + controller.set_movement_target(type, target, new_movement) + +/// Clear the controller's movement target only if it was us who last set it +/datum/ai_behavior/proc/clear_movement_target(datum/ai_controller/controller) + if (controller.movement_target_source != type) + return + controller.set_movement_target(type, null) diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index f00edf3e92c..6fcb5baf892 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -19,6 +19,8 @@ multiple modular subtrees with behaviors var/ai_status ///Current movement target of the AI, generally set by decision making. var/atom/current_movement_target + ///Identifier for what last touched our movement target, so it can be cleared conditionally + var/movement_target_source ///This is a list of variables the AI uses and can be mutated by actions. When an action is performed you pass this list and any relevant keys for the variables it can mutate. var/list/blackboard = list() ///Stored arguments for behaviors given during their initial creation @@ -64,7 +66,8 @@ multiple modular subtrees with behaviors return ..() ///Sets the current movement target, with an optional param to override the movement behavior -/datum/ai_controller/proc/set_movement_target(atom/target, datum/ai_movement/new_movement) +/datum/ai_controller/proc/set_movement_target(source, atom/target, datum/ai_movement/new_movement) + movement_target_source = source current_movement_target = target if(new_movement) change_ai_movement_type(new_movement) diff --git a/code/datums/ai/_item_behaviors.dm b/code/datums/ai/_item_behaviors.dm index 434cd63b64f..ef9407fe1bb 100644 --- a/code/datums/ai/_item_behaviors.dm +++ b/code/datums/ai/_item_behaviors.dm @@ -25,7 +25,10 @@ /datum/ai_behavior/item_move_close_and_attack/setup(datum/ai_controller/controller, target_key, throw_count_key) . = ..() var/datum/weakref/target_ref = controller.blackboard[target_key] - controller.set_movement_target(target_ref?.resolve()) + var/atom/target = target_ref?.resolve() + if (isnull(target)) + return FALSE + set_movement_target(controller, target) /datum/ai_behavior/item_move_close_and_attack/perform(delta_time, datum/ai_controller/controller, target_key, throw_count_key) . = ..() diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm index 767b8447c66..6548f28da35 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm @@ -12,7 +12,7 @@ var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key] if (!targetting_datum) return - controller.set_movement_target(target) + set_movement_target(controller, target) /datum/ai_behavior/basic_melee_attack/perform(delta_time, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) . = ..() @@ -52,7 +52,7 @@ var/atom/target = weak_target?.resolve() if(!target) return FALSE - controller.set_movement_target(target) + set_movement_target(controller, target) /datum/ai_behavior/basic_ranged_attack/perform(delta_time, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) . = ..() diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm index c40c6ef432a..2a3232e8186 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm @@ -21,7 +21,7 @@ var/atom/target = weak_target?.resolve() var/escaped = !target || !can_see(controller.pawn, target, run_distance) // If we can't see it we got away if (escaped) - finish_action(controller, succeeded = TRUE) + finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key) return if (!in_range(controller.pawn, controller.current_movement_target)) return @@ -30,4 +30,8 @@ /datum/ai_behavior/run_away_from_target/proc/plot_path_away_from(datum/ai_controller/controller, atom/target) var/run_direction = get_dir(controller.pawn, get_step_away(controller.pawn, target)) var/turf/target_destination = get_ranged_target_turf(controller.pawn, run_direction, run_distance) - controller.set_movement_target(target_destination) + set_movement_target(controller, target_destination) + +/datum/ai_behavior/run_away_from_target/finish_action(datum/ai_controller/controller, succeeded, target_key, hiding_location_key) + . = ..() + controller.blackboard[target_key] = null diff --git a/code/datums/ai/cursed/cursed_subtrees.dm b/code/datums/ai/cursed/cursed_subtrees.dm index 21a8fe99375..bb20cb6585f 100644 --- a/code/datums/ai/cursed/cursed_subtrees.dm +++ b/code/datums/ai/cursed/cursed_subtrees.dm @@ -11,5 +11,4 @@ if(get_dist(curse_target, item_pawn) > CURSED_VIEW_RANGE) controller.blackboard[BB_CURSE_TARGET] = null return - controller.set_movement_target(curse_target) - controller.queue_behavior(/datum/ai_behavior/item_move_close_and_attack/ghostly/cursed) + controller.queue_behavior(/datum/ai_behavior/item_move_close_and_attack/ghostly/cursed, BB_CURSE_TARGET) diff --git a/code/datums/ai/dog/dog_subtrees.dm b/code/datums/ai/dog/dog_subtrees.dm index a7e24a996ed..e31106f0a8c 100644 --- a/code/datums/ai/dog/dog_subtrees.dm +++ b/code/datums/ai/dog/dog_subtrees.dm @@ -18,7 +18,7 @@ if(!controller.blackboard[BB_SIMPLE_CARRY_ITEM] && controller.blackboard[BB_FETCH_TARGET]) var/atom/movable/interact_target = controller.blackboard[BB_FETCH_TARGET] if(in_range(living_pawn, interact_target) && (isturf(interact_target.loc))) - controller.set_movement_target(interact_target) + controller.set_movement_target(type, interact_target) if(IS_EDIBLE(interact_target)) controller.queue_behavior(/datum/ai_behavior/eat_snack) else if(isitem(interact_target)) @@ -35,6 +35,6 @@ // if the return target isn't in sight, we'll just forget about it and carry the thing around controller.blackboard[BB_FETCH_DELIVER_TO] = null return - controller.set_movement_target(return_target) + controller.set_movement_target(type, return_target) controller.queue_behavior(/datum/ai_behavior/deliver_item) return diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm index bd454e3c27d..c70eeb41874 100644 --- a/code/datums/ai/generic/generic_behaviors.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -31,7 +31,7 @@ /datum/ai_behavior/break_spine/setup(datum/ai_controller/controller, target_key) . = ..() - controller.set_movement_target(controller.blackboard[target_key]) + set_movement_target(controller, controller.blackboard[target_key]) /datum/ai_behavior/break_spine/perform(delta_time, datum/ai_controller/controller, target_key) var/mob/living/batman = controller.blackboard[target_key] @@ -90,7 +90,7 @@ var/target = target_ref?.resolve() if(!target) return FALSE - controller.set_movement_target(target) + set_movement_target(controller, target) /datum/ai_behavior/use_on_object/perform(delta_time, datum/ai_controller/controller, target_key) . = ..() @@ -119,7 +119,7 @@ /datum/ai_behavior/give/setup(datum/ai_controller/controller, target_key) . = ..() var/datum/weakref/target_ref = controller.blackboard[target_key] - controller.set_movement_target(target_ref?.resolve()) + set_movement_target(controller, target_ref?.resolve()) /datum/ai_behavior/give/perform(delta_time, datum/ai_controller/controller, target_key) . = ..() @@ -186,7 +186,7 @@ /datum/ai_behavior/consume/setup(datum/ai_controller/controller, target_key) . = ..() var/datum/weakref/target_ref = controller.blackboard[target_key] - controller.set_movement_target(target_ref?.resolve()) + set_movement_target(controller, target_ref?.resolve()) /datum/ai_behavior/consume/perform(delta_time, datum/ai_controller/controller, target_key, hunger_timer_key) . = ..() @@ -245,7 +245,7 @@ finish_action(controller, TRUE) return - controller.set_movement_target(living_target) + set_movement_target(controller, living_target) attack(controller, living_target) /datum/ai_behavior/attack/finish_action(datum/ai_controller/controller, succeeded) @@ -281,7 +281,7 @@ finish_action(controller, TRUE) return - controller.set_movement_target(living_target) + set_movement_target(controller, living_target) /datum/ai_behavior/follow/finish_action(datum/ai_controller/controller, succeeded) . = ..() diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm index 43267ff4f43..31975d7ea53 100644 --- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm +++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm @@ -31,16 +31,10 @@ if(HAS_TRAIT(controller.pawn, TRAIT_HANDS_BLOCKED) || living_pawn.stat != CONSCIOUS) return - // We're targeting something else for another reason - var/datum/weakref/target_weakref = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] - var/atom/target = target_weakref?.resolve() - if(!QDELETED(target)) - return - var/datum/weakref/hunting_weakref = controller.blackboard[target_key] var/atom/hunted = hunting_weakref?.resolve() // We're not hunting anything, look around for something - if(QDELETED(hunted)) + if(isnull(hunted)) controller.queue_behavior(finding_behavior, target_key, hunt_targets, hunt_range) // We ARE hunting something, execute the hunt. @@ -85,7 +79,10 @@ /datum/ai_behavior/hunt_target/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) . = ..() var/datum/weakref/hunting_weakref = controller.blackboard[hunting_target_key] - controller.set_movement_target(hunting_weakref?.resolve()) + var/atom/hunt_target = hunting_weakref?.resolve() + if (isnull(hunt_target)) + return FALSE + set_movement_target(controller, hunt_target) /datum/ai_behavior/hunt_target/perform(delta_time, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) . = ..() @@ -93,7 +90,7 @@ var/datum/weakref/hunting_weakref = controller.blackboard[hunting_target_key] var/atom/hunted = hunting_weakref?.resolve() - if(QDELETED(hunted)) + if(isnull(hunted)) //Target is gone for some reason. forget about this task! controller[hunting_target_key] = null finish_action(controller, FALSE, hunting_target_key) diff --git a/code/datums/ai/monkey/monkey_behaviors.dm b/code/datums/ai/monkey/monkey_behaviors.dm index 45322bc3e4d..37e59fd10ba 100644 --- a/code/datums/ai/monkey/monkey_behaviors.dm +++ b/code/datums/ai/monkey/monkey_behaviors.dm @@ -143,7 +143,7 @@ /datum/ai_behavior/monkey_attack_mob/setup(datum/ai_controller/controller, target_key) . = ..() var/datum/weakref/target_ref = controller.blackboard[target_key] - controller.set_movement_target(target_ref?.resolve()) + set_movement_target(controller, target_ref?.resolve()) /datum/ai_behavior/monkey_attack_mob/perform(delta_time, datum/ai_controller/controller, target_key) . = ..() @@ -241,7 +241,7 @@ /datum/ai_behavior/disposal_mob/setup(datum/ai_controller/controller, attack_target_key, disposal_target_key) . = ..() var/datum/weakref/target_ref = controller.blackboard[attack_target_key] - controller.set_movement_target(target_ref?.resolve()) + set_movement_target(controller, target_ref?.resolve()) /datum/ai_behavior/disposal_mob/finish_action(datum/ai_controller/controller, succeeded, attack_target_key, disposal_target_key) . = ..() @@ -259,7 +259,7 @@ var/mob/living/target = target_ref?.resolve() var/mob/living/living_pawn = controller.pawn - controller.set_movement_target(target) + set_movement_target(controller, target) if(!target) finish_action(controller, FALSE) @@ -272,7 +272,7 @@ var/datum/weakref/disposal_ref = controller.blackboard[disposal_target_key] var/obj/machinery/disposal/disposal = disposal_ref.resolve() - controller.set_movement_target(disposal) + set_movement_target(controller, disposal) if(!disposal) finish_action(controller, FALSE) diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index b2bcb7bdd93..e37d22b8443 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -134,7 +134,7 @@ have ways of interacting with a specific mob and control it. return FALSE blackboard[BB_MONKEY_PICKUPTARGET] = weapon - set_movement_target(weapon) + set_movement_target(type, weapon) if(pickpocket) queue_behavior(/datum/ai_behavior/monkey_equip/pickpocket) else diff --git a/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm b/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm index c0f1c3e622d..db5950c71e8 100644 --- a/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm +++ b/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm @@ -7,7 +7,7 @@ /datum/ai_behavior/vendor_crush/setup(datum/ai_controller/controller, target_key) . = ..() - controller.set_movement_target(controller.blackboard[target_key]) + set_movement_target(controller, controller.blackboard[target_key]) /datum/ai_behavior/vendor_crush/perform(delta_time, datum/ai_controller/controller) diff --git a/code/datums/ai/oldhostile/hostile_tameable.dm b/code/datums/ai/oldhostile/hostile_tameable.dm index 4fa6a2255de..31db515cb4d 100644 --- a/code/datums/ai/oldhostile/hostile_tameable.dm +++ b/code/datums/ai/oldhostile/hostile_tameable.dm @@ -180,7 +180,7 @@ CancelActions() blackboard[BB_HOSTILE_ORDER_MODE] = HOSTILE_COMMAND_FOLLOW blackboard[BB_FOLLOW_TARGET] = WEAKREF(commander) - set_movement_target(commander) + set_movement_target(type, commander) var/mob/living/living_pawn = pawn if(living_pawn.buckled) queue_behavior(/datum/ai_behavior/resist)//in case they are in bed or something @@ -211,7 +211,7 @@ if(blackboard[BB_HOSTILE_ORDER_MODE] == HOSTILE_COMMAND_ATTACK) pawn.visible_message(span_notice("[pawn] follows [pointing_friend]'s gesture towards [pointed_movable] and [blackboard[BB_HOSTILE_ATTACK_WORD]] intensely!")) - set_movement_target(pointed_movable) + set_movement_target(type, pointed_movable) blackboard[BB_ATTACK_TARGET] = WEAKREF(pointed_movable) if(living_pawn.buckled) queue_behavior(/datum/ai_behavior/resist)//in case they are in bed or something diff --git a/code/datums/ai/robot_customer/robot_customer_behaviors.dm b/code/datums/ai/robot_customer/robot_customer_behaviors.dm index 08b9018e2c4..0cdf489886e 100644 --- a/code/datums/ai/robot_customer/robot_customer_behaviors.dm +++ b/code/datums/ai/robot_customer/robot_customer_behaviors.dm @@ -122,7 +122,7 @@ /datum/ai_behavior/leave_venue/setup(datum/ai_controller/controller, venue_key) . = ..() var/datum/venue/attending_venue = controller.blackboard[venue_key] - controller.set_movement_target(attending_venue.restaurant_portal) + set_movement_target(controller, attending_venue.restaurant_portal) /datum/ai_behavior/leave_venue/perform(delta_time, datum/ai_controller/controller, venue_key) . = ..() diff --git a/code/datums/ai/robot_customer/robot_customer_subtrees.dm b/code/datums/ai/robot_customer/robot_customer_subtrees.dm index e315f50ebf7..74417b1d2e2 100644 --- a/code/datums/ai/robot_customer/robot_customer_subtrees.dm +++ b/code/datums/ai/robot_customer/robot_customer_subtrees.dm @@ -15,7 +15,7 @@ controller.queue_behavior(/datum/ai_behavior/find_seat) return SUBTREE_RETURN_FINISH_PLANNING - controller.set_movement_target(seat_marker) + controller.set_movement_target(type, seat_marker) if(!controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]) //We haven't ordered yet even ordered yet. go on! go over there and go do it! controller.queue_behavior(/datum/ai_behavior/order_food) diff --git a/code/datums/components/tameable.dm b/code/datums/components/tameable.dm index b7eb5890af7..bff0af494a4 100644 --- a/code/datums/components/tameable.dm +++ b/code/datums/components/tameable.dm @@ -40,21 +40,21 @@ return COMPONENT_CANCEL_ATTACK_CHAIN attacker.visible_message(span_notice("[attacker] hand-feeds [food] to [parent]."), span_notice("You hand-feed [food] to [parent].")) - qdel(food) if(tame) return COMPONENT_CANCEL_ATTACK_CHAIN if (prob(tame_chance)) //note: lack of feedback message is deliberate, keep them guessing! - on_tame(attacker) + on_tame(attacker, food) else tame_chance += bonus_tame_chance + qdel(food) return COMPONENT_CANCEL_ATTACK_CHAIN ///Ran once taming succeeds -/datum/component/tameable/proc/on_tame(mob/living/tamer) +/datum/component/tameable/proc/on_tame(mob/living/tamer, atom/food) SIGNAL_HANDLER tame = TRUE - after_tame?.Invoke(tamer)//Run custom behavior if needed + after_tame?.Invoke(tamer, food)//Run custom behavior if needed if (isliving(parent) && isliving(tamer)) var/mob/living/tamed = parent diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index 1ec6f390c5e..6e871f8f113 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -29,6 +29,8 @@ ai_controller = /datum/ai_controller/basic_controller/mouse + /// Whether this rat is friendly to players + var/tame = FALSE /// What color our mouse is. Brown, gray and white - leave blank for random. var/body_color /// Does this mouse contribute to the ratcap? @@ -36,23 +38,30 @@ /// Probability that, if we successfully bite a shocked cable, that we will die to it. var/cable_zap_prob = 85 -/mob/living/basic/mouse/Initialize(mapload) +/mob/living/basic/mouse/Initialize(mapload, tame = FALSE) . = ..() if(contributes_to_ratcap) SSmobs.cheeserats |= src ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) + src.tame = tame if(isnull(body_color)) body_color = pick("brown", "gray", "white") held_state = "mouse_[body_color]" // not handled by variety element AddElement(/datum/element/animal_variety, "mouse", body_color, FALSE) AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10) AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever - var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) AddElement(/datum/element/connect_loc, loc_connections) + make_tameable() + +/mob/living/basic/mouse/proc/make_tameable() + if (tame) + faction |= FACTION_NEUTRAL + else + AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/cheese), tame_chance = 100, after_tame = CALLBACK(src, PROC_REF(tamed))) /mob/living/basic/mouse/Destroy() SSmobs.cheeserats -= src @@ -137,6 +146,14 @@ if(ishuman(entered) && stat == CONSCIOUS) to_chat(entered, span_notice("[icon2html(src, entered)] Squeak!")) +/// Called when a mouse is hand-fed some cheese, it will stop being afraid of humans +/mob/living/basic/mouse/proc/tamed(mob/living/tamer, obj/item/food/cheese/cheese) + new /obj/effect/temp_visual/heart(loc) + faction |= FACTION_NEUTRAL + tame = TRUE + try_consume_cheese(cheese) + ai_controller.CancelActions() // Interrupt any current fleeing + /// Attempts to consume a piece of cheese, causing a few effects. /mob/living/basic/mouse/proc/try_consume_cheese(obj/item/food/cheese/cheese) // Royal cheese will evolve us into a regal rat @@ -183,7 +200,7 @@ /// Creates a new mouse based on this mouse's subtype. /mob/living/basic/mouse/proc/create_a_new_rat() - new /mob/living/basic/mouse(loc) + new /mob/living/basic/mouse(loc, /* tame = */ tame) /// Biting into a cable will cause a mouse to get shocked and die if applicable. Or do nothing if they're lucky. /mob/living/basic/mouse/proc/try_bite_cable(obj/structure/cable/cable) @@ -234,7 +251,10 @@ response_harm_continuous = "splats" response_harm_simple = "splat" gold_core_spawnable = NO_SPAWN - faction = list(FACTION_RAT, FACTION_MAINT_CREATURES, FACTION_NEUTRAL) + +/mob/living/basic/mouse/brown/tom/make_tameable() + tame = TRUE + return ..() /mob/living/basic/mouse/brown/tom/Initialize(mapload) . = ..() @@ -243,7 +263,7 @@ AddElement(/datum/element/pet_bonus, "squeaks happily!") /mob/living/basic/mouse/brown/tom/create_a_new_rat() - new /mob/living/basic/mouse/brown(loc) // dominant gene + new /mob/living/basic/mouse/brown(loc, /* tame = */ tame) // dominant gene /mob/living/basic/mouse/rat name = "rat" @@ -257,6 +277,9 @@ ai_controller = /datum/ai_controller/basic_controller/mouse/rat +/mob/living/basic/mouse/rat/make_tameable() + return // Unlike in real life, space rats are horrible creatures who don't like you + /mob/living/basic/mouse/rat/create_a_new_rat() new /mob/living/basic/mouse/rat(loc) @@ -349,9 +372,21 @@ /datum/ai_planning_subtree/find_and_hunt_target/look_for_cables, ) +/// Don't look for anything to run away from if you are distracted by being adjacent to cheese /datum/ai_planning_subtree/flee_target/mouse flee_behaviour = /datum/ai_behavior/run_away_from_target/mouse +/datum/ai_planning_subtree/flee_target/mouse + +/datum/ai_planning_subtree/flee_target/mouse/SelectBehaviors(datum/ai_controller/controller, delta_time) + var/datum/weakref/hunting_weakref = controller.blackboard[BB_CURRENT_HUNTING_TARGET] + var/atom/hunted_cheese = hunting_weakref?.resolve() + if (!isnull(hunted_cheese)) + return // We see some cheese, which is more important than our life + return ..() + +/datum/ai_planning_subtree/flee_target/mouse/select + /datum/ai_behavior/run_away_from_target/mouse run_distance = 3 // Mostly exists in small tunnels, don't get ahead of yourself diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm index 785fbe41272..24f0e2537cb 100644 --- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm +++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm @@ -305,6 +305,7 @@ /datum/action/cooldown/riot/proc/make_minion(mob/living/new_minion, minion_desc, list/command_list = mouse_commands) if (isbasicmob(new_minion)) // One day this will work for frogs too new_minion.AddComponent(/datum/component/obeys_commands, command_list) + qdel(new_minion.GetComponent(/datum/component/tameable)) // Rats don't share new_minion.befriend(owner) new_minion.faction = owner.faction.Copy() // Give a hint in description too diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index e194dac7664..a86c3ae0421 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -109,7 +109,7 @@ return FALSE var/datum/ai_controller/mod_ai = new /datum/ai_controller/mod(module.mod) module.mod.ai_controller = mod_ai - mod_ai.set_movement_target(imp_in) + mod_ai.set_movement_target(type, imp_in) mod_ai.blackboard[BB_MOD_TARGET] = imp_in mod_ai.blackboard[BB_MOD_IMPLANT] = src module.mod.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP