mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 21:18:37 +01:00
Turtles (#87493)
## About The Pull Request adds turtles to the game! but these aren't your typical turtles.  these are flora-turtles, with giant trees growing on their shells. These trees can emit fields which affects nearby hydroponic plants. Initially, the trees start out as young buds, from there the tree can evolve into different types depending on what you feed the turtle. Feeding them pesticides causes the tree to blossom to be purple. this tree's fields will help kill some pests and weeds in nearby plants. Feeding them nutrients gives you the green tree, the fields will heal nearby plants Feeding them mutators like uranium or left 4 zed gives you the yellow tree. the fields increase instability of plants The turtle will emit these fields every once in a while, ONLY when its feeling happy. therefore you'll have to pet it, clean it and feed it every once in a while to keep it satisfied. You can view the turtle's happiness by shift clicking it. https://github.com/user-attachments/assets/a47136a1-06a1-419e-acc2-2f6f4468e296 The turtle only eats seeds. after eating a seed, itll process it and spit out its corresponding fruit! (for example, feeding it an apple seed gives you an apple). itll also sometimes playfully headbutt your legs and it loves going around smelling the scent from nearby plants you can get these turtles by fishing the hydroponics tray or by ordering them through cargo. ## Why It's Good For The Game adds a new fun way for botanists to take care of their plants. While these turtles alone arent enough to fully replace plant dedicated nutrients, they add small extra support. ## Changelog 🆑 add: adds flora-turtles. obtainable through cargo or by fishing from the hydroponics tray /🆑
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
#define PATH_PEST_KILLER "path_pest_killer"
|
||||
#define PATH_PLANT_HEALER "path_plant_healer"
|
||||
#define PATH_PLANT_MUTATOR "path_plant_mutator"
|
||||
#define REQUIRED_TREE_GROWTH 250
|
||||
#define UPPER_BOUND_VOLUME 50
|
||||
#define LOWER_BOUND_VOLUME 10
|
||||
|
||||
/mob/living/basic/turtle
|
||||
name = "turtle"
|
||||
desc = "Dog."
|
||||
icon_state = "turtle"
|
||||
icon_living = "turtle"
|
||||
icon_dead = "turtle_dead"
|
||||
base_icon_state = "turtle"
|
||||
icon = 'icons/mob/simple/pets.dmi'
|
||||
butcher_results = list(/obj/item/food/meat/slab = 3, /obj/item/food/pickle = 1, /obj/item/stack/sheet/mineral/wood = 10)
|
||||
mob_biotypes = MOB_ORGANIC | MOB_PLANT
|
||||
mobility_flags = MOBILITY_FLAGS_REST_CAPABLE_DEFAULT
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
speed = 5
|
||||
verb_say = "snaps"
|
||||
verb_ask = "snaps curiously"
|
||||
verb_exclaim = "snaps loudly"
|
||||
verb_yell = "snaps loudly"
|
||||
faction = list(FACTION_NEUTRAL)
|
||||
ai_controller = /datum/ai_controller/basic_controller/turtle
|
||||
///our displayed tree
|
||||
var/mutable_appearance/grown_tree
|
||||
///growth progress of our tree
|
||||
var/list/path_growth_progress = list(
|
||||
PATH_PLANT_HEALER = 0,
|
||||
PATH_PLANT_MUTATOR = 0,
|
||||
PATH_PEST_KILLER = 0,
|
||||
)
|
||||
///what nutrients leads to each evolution path
|
||||
var/static/list/path_requirements = list(
|
||||
//plant healers
|
||||
/datum/reagent/plantnutriment/eznutriment = PATH_PLANT_HEALER,
|
||||
/datum/reagent/plantnutriment/robustharvestnutriment = PATH_PLANT_HEALER,
|
||||
/datum/reagent/plantnutriment/endurogrow = PATH_PLANT_HEALER,
|
||||
//plant mutators
|
||||
/datum/reagent/plantnutriment/left4zednutriment = PATH_PLANT_MUTATOR,
|
||||
/datum/reagent/uranium = PATH_PLANT_MUTATOR,
|
||||
//pest killers
|
||||
/datum/reagent/toxin/pestkiller = PATH_PEST_KILLER,
|
||||
)
|
||||
///if we are fully grown, what is our path
|
||||
var/developed_path
|
||||
///our last east/west direction
|
||||
var/last_direction = WEST
|
||||
|
||||
/mob/living/basic/turtle/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
desc = pick(
|
||||
"Likely Dog...",
|
||||
"Praise the Dog!",
|
||||
"Dog ahead.",
|
||||
"Could this be a Dog?",
|
||||
)
|
||||
var/static/list/eatable_food = list(/obj/item/seeds)
|
||||
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(eatable_food))
|
||||
AddElement(/datum/element/basic_eating, food_types = eatable_food)
|
||||
AddComponent(/datum/component/happiness)
|
||||
RegisterSignal(src, COMSIG_MOB_PRE_EAT, PROC_REF(pre_eat_food))
|
||||
update_appearance()
|
||||
create_reagents(150, REAGENT_HOLDER_ALIVE)
|
||||
add_verb(src, /mob/living/proc/toggle_resting)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/mob/living/basic/turtle/setDir(newdir)
|
||||
if(REVERSE_DIR(last_direction) & newdir)
|
||||
transform = transform.Scale(-1, 1)
|
||||
last_direction = REVERSE_DIR(last_direction)
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/turtle/proc/retrieve_destined_path()
|
||||
var/current_max_growth = 0
|
||||
var/destined_path
|
||||
for(var/evolution_path in path_growth_progress)
|
||||
if(path_growth_progress[evolution_path] > current_max_growth)
|
||||
destined_path = evolution_path
|
||||
current_max_growth = path_growth_progress[evolution_path]
|
||||
if(isnull(destined_path))
|
||||
destined_path = PATH_PLANT_HEALER
|
||||
return destined_path
|
||||
|
||||
/mob/living/basic/turtle/process(seconds_per_tick)
|
||||
if(isnull(reagents) || !length(reagents.reagent_list)) //if we have no reagents, default to our highest destined path
|
||||
set_plant_growth(retrieve_destined_path(), 0.5)
|
||||
return
|
||||
|
||||
for(var/datum/reagent/existing_reagent as anything in reagents.reagent_list)
|
||||
var/evolution_path = path_requirements[existing_reagent.type]
|
||||
|
||||
switch(existing_reagent.volume)
|
||||
if(UPPER_BOUND_VOLUME to INFINITY)
|
||||
set_plant_growth(evolution_path, 3)
|
||||
if(LOWER_BOUND_VOLUME to UPPER_BOUND_VOLUME)
|
||||
set_plant_growth(evolution_path, 2)
|
||||
if(1 to LOWER_BOUND_VOLUME)
|
||||
set_plant_growth(evolution_path, 1)
|
||||
|
||||
reagents.remove_reagent(existing_reagent.type, 0.5)
|
||||
|
||||
/mob/living/basic/turtle/proc/set_plant_growth(evolution_path, amount)
|
||||
path_growth_progress[evolution_path] += amount
|
||||
if(path_growth_progress[evolution_path] >= REQUIRED_TREE_GROWTH)
|
||||
evolve_turtle(evolution_path)
|
||||
|
||||
/mob/living/basic/turtle/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
if(stat == DEAD)
|
||||
. += span_notice("Its tree seems to be all withered...")
|
||||
return
|
||||
|
||||
var/destined_path = retrieve_destined_path()
|
||||
var/current_max_growth = path_growth_progress[destined_path]
|
||||
|
||||
var/text_to_display = "Its tree seems to be exuding "
|
||||
switch(destined_path)
|
||||
if(PATH_PEST_KILLER)
|
||||
text_to_display += "pest killing"
|
||||
if(PATH_PLANT_HEALER)
|
||||
text_to_display += "plant healing"
|
||||
if(PATH_PLANT_MUTATOR)
|
||||
text_to_display += "plant mutating"
|
||||
|
||||
text_to_display += " properties... which [current_max_growth >= REQUIRED_TREE_GROWTH ? "seems to be fully grown" : "is yet to develop"]."
|
||||
. += span_notice(text_to_display)
|
||||
|
||||
|
||||
/mob/living/basic/turtle/proc/evolve_turtle(evolution_path)
|
||||
var/static/list/evolution_gains = list(
|
||||
PATH_PLANT_HEALER = list(
|
||||
"tree_appearance" = "healer_tree",
|
||||
"tree_ability" = /datum/action/cooldown/mob_cooldown/turtle_tree/healer,
|
||||
),
|
||||
PATH_PEST_KILLER = list(
|
||||
"tree_appearance" = "killer_tree",
|
||||
"tree_ability" = /datum/action/cooldown/mob_cooldown/turtle_tree/killer,
|
||||
),
|
||||
PATH_PLANT_MUTATOR = list(
|
||||
"tree_appearance" = "mutator_tree",
|
||||
"tree_ability" = /datum/action/cooldown/mob_cooldown/turtle_tree/mutator,
|
||||
),
|
||||
)
|
||||
|
||||
var/tree_icon_state = evolution_gains[evolution_path]["tree_appearance"]
|
||||
grown_tree = mutable_appearance(icon = 'icons/mob/simple/turtle_trees.dmi', icon_state = tree_icon_state)
|
||||
|
||||
var/new_ability_path = evolution_gains[evolution_path]["tree_ability"]
|
||||
developed_path = evolution_path
|
||||
var/datum/action/cooldown/tree_ability = new new_ability_path(src)
|
||||
tree_ability?.Grant(src)
|
||||
ai_controller?.set_blackboard_key(BB_TURTLE_TREE_ABILITY, tree_ability)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/turtle/update_icon_state()
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
icon_state = resting ? "[base_icon_state]_resting" : base_icon_state
|
||||
|
||||
/mob/living/basic/turtle/update_overlays()
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
var/mutable_appearance/dead_overlay = mutable_appearance(icon = 'icons/mob/simple/pets.dmi', icon_state = developed_path ? "dead_tree" : "growing_tree")
|
||||
dead_overlay.pixel_y = -2
|
||||
. += dead_overlay
|
||||
return
|
||||
var/pixel_offset = resting ? -2 : 2
|
||||
var/mutable_appearance/living_tree = grown_tree ? grown_tree : mutable_appearance(icon = icon, icon_state = "growing_tree")
|
||||
living_tree.pixel_y = pixel_offset
|
||||
. += living_tree
|
||||
|
||||
/mob/living/basic/turtle/update_resting()
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/turtle/item_interaction(mob/living/user, obj/item/used_item, list/modifiers)
|
||||
if(!istype(used_item, /obj/item/reagent_containers))
|
||||
return NONE
|
||||
|
||||
if(isnull(used_item.reagents))
|
||||
balloon_alert(user, "empty!")
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if(stat == DEAD)
|
||||
balloon_alert(user, "its dead!")
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
var/should_transfer = FALSE
|
||||
for(var/reagent in path_requirements)
|
||||
if(used_item.reagents.has_reagent(reagent))
|
||||
should_transfer = TRUE
|
||||
break
|
||||
|
||||
if(!should_transfer)
|
||||
balloon_alert(user, "refuses to drink!")
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if(!do_after(user, 1.5 SECONDS, target = src))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
used_item.reagents.trans_to(reagents, 5)
|
||||
balloon_alert(user, "drinks happily")
|
||||
playsound(src, 'sound/items/drink.ogg', vol = 25, vary = TRUE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/mob/living/basic/turtle/proc/pre_eat_food(datum/source, obj/item/seeds/potential_food)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(potential_food))
|
||||
return NONE
|
||||
if(ispath(potential_food.product, /obj/item/food/grown))
|
||||
addtimer(CALLBACK(src, PROC_REF(process_food), potential_food.product), 30 SECONDS)
|
||||
return NONE
|
||||
|
||||
/mob/living/basic/turtle/proc/process_food(food_path)
|
||||
if(QDELETED(src) || stat != CONSCIOUS)
|
||||
return
|
||||
new food_path(drop_location())
|
||||
balloon_alert_to_viewers("spits out some food")
|
||||
|
||||
/mob/living/basic/turtle/death(gibbed)
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
|
||||
#undef PATH_PEST_KILLER
|
||||
#undef PATH_PLANT_HEALER
|
||||
#undef PATH_PLANT_MUTATOR
|
||||
#undef REQUIRED_TREE_GROWTH
|
||||
#undef UPPER_BOUND_VOLUME
|
||||
#undef LOWER_BOUND_VOLUME
|
||||
@@ -0,0 +1,140 @@
|
||||
#define TREE_FIELD_DURATION_EFFECT 10 SECONDS
|
||||
#define WARP_ANIMATE_TIME 0.35 SECONDS
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree
|
||||
name = "Tree Ability"
|
||||
desc = "Invoke your tree's special ability."
|
||||
cooldown_time = 2 MINUTES
|
||||
click_to_activate = FALSE
|
||||
button_icon = 'icons/mob/simple/pets.dmi'
|
||||
button_icon_state = "turtle"
|
||||
///type of effect our tree releases
|
||||
var/effect_path
|
||||
///how many times our ability affects surroundings
|
||||
var/maximum_intervals = 5
|
||||
///time between each interval
|
||||
var/time_between_intervals = 3 SECONDS
|
||||
///range our tree affects
|
||||
var/tree_range = 5
|
||||
///warp effect to apply some distortion to our field
|
||||
var/atom/movable/warp_effect/turtle_field/warp
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/Activate(atom/target)
|
||||
. = ..()
|
||||
warp = new(owner)
|
||||
RegisterSignal(warp, COMSIG_QDELETING, PROC_REF(remove_warp))
|
||||
warp.alpha = 0
|
||||
owner.vis_contents += warp
|
||||
|
||||
for(var/index in 0 to maximum_intervals)
|
||||
addtimer(CALLBACK(src, PROC_REF(tree_effect)), time_between_intervals * index)
|
||||
|
||||
animate(warp, transform = matrix(), alpha = warp::alpha, time = WARP_ANIMATE_TIME)
|
||||
addtimer(CALLBACK(src, PROC_REF(warp_extinguish)), (time_between_intervals * maximum_intervals) + 3 SECONDS)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/proc/warp_extinguish()
|
||||
if(QDELETED(warp))
|
||||
return
|
||||
animate(warp, alpha = 0, time = WARP_ANIMATE_TIME)
|
||||
addtimer(CALLBACK(src, PROC_REF(remove_warp)), WARP_ANIMATE_TIME)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/proc/remove_warp()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
UnregisterSignal(warp, COMSIG_QDELETING)
|
||||
warp = null
|
||||
|
||||
///effect we apply on our trees
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/proc/tree_effect()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
return (pre_effect_apply())
|
||||
|
||||
///things we should check for before applying our effects
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/proc/pre_effect_apply()
|
||||
if(QDELETED(owner) || owner.stat == DEAD)
|
||||
return FALSE
|
||||
var/obj/effect/tree_effect = new effect_path
|
||||
owner.vis_contents += tree_effect
|
||||
return TRUE
|
||||
|
||||
///healer tree, heals nearby plants by small amounts
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/healer
|
||||
effect_path = /obj/effect/temp_visual/circle_wave/tree/healer
|
||||
///amount we heal plants by
|
||||
var/heal_amount = 5
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/healer/tree_effect()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
for(var/obj/machinery/hydroponics/hydro in oview(tree_range, owner))
|
||||
if(isnull(hydro.myseed))
|
||||
continue
|
||||
hydro.adjust_plant_health(heal_amount)
|
||||
|
||||
///killer tree, kills plant's pests and weeds, aswell as nearby vermin
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/killer
|
||||
effect_path = /obj/effect/temp_visual/circle_wave/tree/killer
|
||||
///amount we heal plants by
|
||||
var/vermin_damage_amount = 20
|
||||
///type of vermin our field affects
|
||||
var/static/list/vermin_mob_targets = typecacheof(list(
|
||||
/mob/living/basic/cockroach,
|
||||
/mob/living/basic/mouse/rat,
|
||||
))
|
||||
///how much we reduce weed levels
|
||||
var/weed_level_reduce = 2
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/killer/tree_effect()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
for(var/atom/possible_target as anything in oview(tree_range, owner))
|
||||
|
||||
if(is_type_in_typecache(possible_target, vermin_mob_targets))
|
||||
var/mob/living/living_target = possible_target
|
||||
living_target.apply_damage(vermin_damage_amount)
|
||||
continue
|
||||
|
||||
if(!istype(possible_target, /obj/machinery/hydroponics))
|
||||
continue
|
||||
|
||||
var/obj/machinery/hydroponics/hydro = possible_target
|
||||
if(isnull(hydro.myseed))
|
||||
continue
|
||||
hydro.set_weedlevel(hydro.weedlevel - weed_level_reduce)
|
||||
|
||||
///mutator tree, mutates nearby plants!
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/mutator
|
||||
effect_path = /obj/effect/temp_visual/circle_wave/tree/mutator
|
||||
///how much we mutate plants
|
||||
var/mutator_boost = 1
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/turtle_tree/mutator/tree_effect()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
for(var/obj/machinery/hydroponics/hydro in oview(tree_range, owner))
|
||||
hydro.myseed?.adjust_instability(mutator_boost)
|
||||
|
||||
/atom/movable/warp_effect/turtle_field
|
||||
alpha = 75
|
||||
|
||||
///effects we give our tree abilities depending on their type
|
||||
/obj/effect/temp_visual/circle_wave/tree
|
||||
vis_flags = VIS_INHERIT_DIR | VIS_INHERIT_PLANE
|
||||
duration = 10 SECONDS
|
||||
amount_to_scale = 3
|
||||
|
||||
/obj/effect/temp_visual/circle_wave/tree/healer
|
||||
color = "#28a3bc"
|
||||
|
||||
/obj/effect/temp_visual/circle_wave/tree/killer
|
||||
color = "#ce3ebf"
|
||||
|
||||
/obj/effect/temp_visual/circle_wave/tree/mutator
|
||||
color = "#c49f26"
|
||||
|
||||
#undef TREE_FIELD_DURATION_EFFECT
|
||||
#undef WARP_ANIMATE_TIME
|
||||
@@ -0,0 +1,92 @@
|
||||
/datum/ai_controller/basic_controller/turtle
|
||||
blackboard = list(
|
||||
BB_HAPPY_EMOTIONS = list(
|
||||
"wiggles its tree in excitement!",
|
||||
"raises its head up high!",
|
||||
"wags its tail enthusiastically!",
|
||||
),
|
||||
BB_MODERATE_EMOTIONS = list(
|
||||
"keeps its head level, eyes half-closed.",
|
||||
"basks in the light peacefully.",
|
||||
),
|
||||
BB_SAD_EMOTIONS = list(
|
||||
"looks towards the floor in dissapointment...",
|
||||
"the leaves on its tree droop...",
|
||||
),
|
||||
)
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_food,
|
||||
/datum/ai_planning_subtree/express_happiness,
|
||||
/datum/ai_planning_subtree/use_mob_ability/turtle_tree,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/headbutt_people, //playfully headbutt people's legs
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/sniff_flora, //mmm the aroma
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/use_mob_ability/turtle_tree
|
||||
ability_key = BB_TURTLE_TREE_ABILITY
|
||||
|
||||
/datum/ai_planning_subtree/use_mob_ability/turtle_tree/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/happiness_count = controller.blackboard[BB_BASIC_HAPPINESS] * 100
|
||||
if(happiness_count > 75)
|
||||
return ..()
|
||||
if(!SPT_PROB(happiness_count / 50, seconds_per_tick))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/sniff_flora
|
||||
target_key = BB_TURTLE_FLORA_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/sniff_flora
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/sniff_flora
|
||||
hunt_targets = list(
|
||||
/obj/machinery/hydroponics,
|
||||
/obj/item/kirbyplants,
|
||||
)
|
||||
hunt_range = 5
|
||||
hunt_chance = 45
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/sniff_flora
|
||||
action_cooldown = 1 MINUTES
|
||||
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/sniff_flora/valid_dinner(mob/living/source, obj/machinery/hydroponics/dinner, radius, datum/ai_controller/controller, seconds_per_tick)
|
||||
if(!istype(dinner))
|
||||
return TRUE
|
||||
if(isnull(dinner.myseed))
|
||||
return FALSE
|
||||
if(dinner.weedlevel > 5 || dinner.pestlevel > 5) //too smelly
|
||||
return FALSE
|
||||
return can_see(source, dinner, radius)
|
||||
|
||||
/datum/ai_behavior/hunt_target/sniff_flora
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/sniff_flora/target_caught(mob/living/hunter, atom/hunted)
|
||||
hunter.manual_emote("Enjoys the sweet scent eminating from [hunted::name]!")
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/headbutt_people
|
||||
target_key = BB_TURTLE_HEADBUTT_VICTIM
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/human_to_headbutt
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/headbutt_leg
|
||||
hunt_targets = list(/mob/living/carbon/human)
|
||||
hunt_range = 4
|
||||
hunt_chance = 45
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/human_to_headbutt
|
||||
action_cooldown = 2 MINUTES
|
||||
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/human_to_headbutt/valid_dinner(mob/living/source, mob/living/carbon/human/dinner, radius, datum/ai_controller/controller, seconds_per_tick)
|
||||
if(dinner.stat != CONSCIOUS)
|
||||
return FALSE
|
||||
if(isnull(dinner.get_bodypart(BODY_ZONE_R_LEG)) && isnull(dinner.get_bodypart(BODY_ZONE_L_LEG))) //no legs to headbutt!
|
||||
return FALSE
|
||||
return can_see(source, dinner, radius)
|
||||
|
||||
/datum/ai_behavior/hunt_target/headbutt_leg
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/headbutt_leg/target_caught(mob/living/hunter, atom/hunted)
|
||||
hunter.manual_emote("playfully headbutts [hunted]'s legs!")
|
||||
|
||||
Reference in New Issue
Block a user