mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
seedling basic mobs (#78224)
## About The Pull Request this is a mob that was removed from the game since years ago. this pr refactors them and readds them to the game. seedlings now can have different colored petals!  to obtain this monster, botany can now grow them out of 'seedling' seeds that they can find in the exotic seeds crate. this mob loves to help all plants and when its grown out of the seed, it will help the botanists look after their plants. it can water plants (if it finds a bucket), remove weeds and remove dead plants. they will also use their solarbeam ability to provide small healing to damaged plants. it will try to refill its bucket with water if there is a water source near by. it will also follow the orders of whoever harvested it.  traitors can buy a seed from the uplink that grows an evil version of the seedlings, they can command them to attack people and use abilities and to cause chaos on the station. ## Why It's Good For The Game refacotrs the seedlings into basic mobs ## Changelog 🆑 refactor: seedlings have been refactored into basic mobs please report any bugs add: seedlings now can have different colored petals and can look after botanys plants add: seedlings are re-added to the game! they grow out of seedling seeds obtainable from exotic seed crates or traitor uplink /🆑
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
#define SEEDLING_STATE_NEUTRAL 0
|
||||
#define SEEDLING_STATE_WARMUP 1
|
||||
#define SEEDLING_STATE_ACTIVE 2
|
||||
|
||||
/**
|
||||
* A mobile plant with a rapid ranged attack.
|
||||
* It can pick up watering cans and look after plants.
|
||||
*/
|
||||
/mob/living/basic/seedling
|
||||
name = "seedling"
|
||||
desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon."
|
||||
icon = 'icons/mob/simple/jungle/seedling.dmi'
|
||||
icon_state = "seedling"
|
||||
icon_living = "seedling"
|
||||
icon_dead = "seedling_dead"
|
||||
habitable_atmos = list("min_oxy" = 2, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minimum_survivable_temperature = 0
|
||||
maximum_survivable_temperature = 450
|
||||
mob_biotypes = MOB_ORGANIC | MOB_PLANT
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
pixel_y = -14
|
||||
base_pixel_y = -14
|
||||
pixel_x = -14
|
||||
base_pixel_x = -14
|
||||
response_harm_continuous = "strikes"
|
||||
response_harm_simple = "strike"
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
lighting_cutoff_green = 20
|
||||
lighting_cutoff_blue = 25
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_vis_effect = ATTACK_EFFECT_SLASH
|
||||
ai_controller = /datum/ai_controller/basic_controller/seedling
|
||||
///the state of combat we are in
|
||||
var/combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
///the colors our petals can have
|
||||
var/static/list/possible_colors = list(COLOR_RED, COLOR_YELLOW, COLOR_OLIVE, COLOR_CYAN)
|
||||
///appearance when we are in our normal state
|
||||
var/mutable_appearance/petal_neutral
|
||||
///appearance when we are in our warmup state
|
||||
var/mutable_appearance/petal_warmup
|
||||
///appearance when we are in the firing state
|
||||
var/mutable_appearance/petal_active
|
||||
///appearance when we are dead
|
||||
var/mutable_appearance/petal_dead
|
||||
///the bucket we carry
|
||||
var/obj/item/reagent_containers/cup/held_can
|
||||
///commands we follow
|
||||
var/list/seedling_commands = list(
|
||||
/datum/pet_command/idle,
|
||||
/datum/pet_command/free,
|
||||
/datum/pet_command/follow,
|
||||
)
|
||||
|
||||
/mob/living/basic/seedling/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/seed_attack = new(src)
|
||||
seed_attack.Grant(src)
|
||||
ai_controller.set_blackboard_key(BB_RAPIDSEEDS_ABILITY, seed_attack)
|
||||
var/datum/action/cooldown/mob_cooldown/solarbeam/beam_attack = new(src)
|
||||
beam_attack.Grant(src)
|
||||
ai_controller.set_blackboard_key(BB_SOLARBEAM_ABILITY, beam_attack)
|
||||
|
||||
var/petal_color = pick(possible_colors)
|
||||
|
||||
petal_neutral = mutable_appearance(icon, "[icon_state]_overlay")
|
||||
petal_neutral.color = petal_color
|
||||
|
||||
petal_warmup = mutable_appearance(icon, "[icon_state]_charging_overlay")
|
||||
petal_warmup.color = petal_color
|
||||
|
||||
petal_active = mutable_appearance(icon, "[icon_state]_fire_overlay")
|
||||
petal_active.color = petal_color
|
||||
|
||||
petal_dead = mutable_appearance(icon, "[icon_state]_dead_overlay")
|
||||
petal_dead.color = petal_color
|
||||
|
||||
AddElement(/datum/element/wall_smasher)
|
||||
AddComponent(/datum/component/obeys_commands, seedling_commands)
|
||||
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
|
||||
RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_can))
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/seedling/proc/pre_attack(mob/living/puncher, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(istype(target, /obj/machinery/hydroponics))
|
||||
treat_hydro_tray(target)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
if(isnull(held_can))
|
||||
return
|
||||
|
||||
if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/reagent_dispensers))
|
||||
INVOKE_ASYNC(held_can, TYPE_PROC_REF(/obj/item, melee_attack_chain), src, target)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
|
||||
///seedlings can water trays, remove weeds, or remove dead plants
|
||||
/mob/living/basic/seedling/proc/treat_hydro_tray(obj/machinery/hydroponics/hydro)
|
||||
|
||||
if(hydro.plant_status == HYDROTRAY_PLANT_DEAD)
|
||||
balloon_alert(src, "dead plant removed")
|
||||
hydro.set_seed(null)
|
||||
return
|
||||
|
||||
if(hydro.weedlevel > 0)
|
||||
balloon_alert(src, "weeds uprooted")
|
||||
hydro.set_weedlevel(0)
|
||||
return
|
||||
|
||||
var/list/can_reagents = held_can?.reagents.reagent_list
|
||||
|
||||
if(!length(can_reagents))
|
||||
return
|
||||
|
||||
if((locate(/datum/reagent/water) in can_reagents) && (hydro.waterlevel < hydro.maxwater))
|
||||
INVOKE_ASYNC(held_can, TYPE_PROC_REF(/obj/item, melee_attack_chain), src, hydro)
|
||||
return
|
||||
|
||||
/mob/living/basic/seedling/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
|
||||
. = ..()
|
||||
|
||||
if(!. || !proximity_flag || held_can)
|
||||
return
|
||||
|
||||
if(!istype(attack_target, /obj/item/reagent_containers/cup/watering_can))
|
||||
return
|
||||
|
||||
var/obj/item/can_target = attack_target
|
||||
can_target.forceMove(src)
|
||||
|
||||
/mob/living/basic/seedling/proc/change_combatant_state(state)
|
||||
combatant_state = state
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/seedling/attackby(obj/item/can, mob/living/carbon/human/user, list/modifiers)
|
||||
if(istype(can, /obj/item/reagent_containers/cup/watering_can) && isnull(held_can))
|
||||
can.forceMove(src)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/seedling/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
||||
if(istype(arrived, /obj/item/reagent_containers/cup/watering_can))
|
||||
held_can = arrived
|
||||
update_appearance()
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/seedling/update_overlays()
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
. += petal_dead
|
||||
return
|
||||
|
||||
switch(combatant_state)
|
||||
if(SEEDLING_STATE_NEUTRAL)
|
||||
. += petal_neutral
|
||||
if(held_can)
|
||||
. += mutable_appearance(icon, "seedling_can_overlay")
|
||||
if(SEEDLING_STATE_WARMUP)
|
||||
. += petal_warmup
|
||||
if(SEEDLING_STATE_ACTIVE)
|
||||
. += petal_active
|
||||
|
||||
/mob/living/basic/seedling/update_icon_state()
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
switch(combatant_state)
|
||||
if(SEEDLING_STATE_NEUTRAL)
|
||||
icon_state = "seedling"
|
||||
if(SEEDLING_STATE_WARMUP)
|
||||
icon_state = "seedling_charging"
|
||||
if(SEEDLING_STATE_ACTIVE)
|
||||
icon_state = "seedling_fire"
|
||||
|
||||
/mob/living/basic/seedling/proc/drop_can(mob/living/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(isnull(held_can))
|
||||
return
|
||||
dropItemToGround(held_can)
|
||||
return COMSIG_KB_ACTIVATED
|
||||
|
||||
/mob/living/basic/seedling/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone != held_can)
|
||||
return
|
||||
held_can = null
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/seedling/death(gibbed)
|
||||
. = ..()
|
||||
if(isnull(held_can))
|
||||
return
|
||||
held_can.forceMove(drop_location())
|
||||
|
||||
/mob/living/basic/seedling/Destroy()
|
||||
QDEL_NULL(held_can)
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/seedling/meanie
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
faction = list(FACTION_JUNGLE)
|
||||
ai_controller = /datum/ai_controller/basic_controller/seedling/meanie
|
||||
seedling_commands = list(
|
||||
/datum/pet_command/idle,
|
||||
/datum/pet_command/free,
|
||||
/datum/pet_command/follow,
|
||||
/datum/pet_command/point_targetting/attack,
|
||||
/datum/pet_command/point_targetting/use_ability/solarbeam,
|
||||
/datum/pet_command/point_targetting/use_ability/rapidseeds,
|
||||
)
|
||||
|
||||
//abilities
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling
|
||||
name = "Solar Energy"
|
||||
button_icon = 'icons/obj/weapons/guns/projectiles.dmi'
|
||||
button_icon_state = "seedling"
|
||||
desc = "Fire small beams of solar energy."
|
||||
cooldown_time = 10 SECONDS
|
||||
projectile_type = /obj/projectile/seedling
|
||||
default_projectile_spread = 10
|
||||
shot_count = 10
|
||||
shot_delay = 0.2 SECONDS
|
||||
melee_cooldown_time = 0 SECONDS
|
||||
shared_cooldown = NONE
|
||||
///how long we must charge up before firing off
|
||||
var/charge_up_timer = 3 SECONDS
|
||||
///is the owner of this ability a seedling?
|
||||
var/is_seedling = FALSE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/Grant(mob/grant_to)
|
||||
. = ..()
|
||||
if(isnull(owner))
|
||||
return
|
||||
is_seedling = istype(owner, /mob/living/basic/seedling)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/IsAvailable(feedback)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(!is_seedling)
|
||||
return TRUE
|
||||
var/mob/living/basic/seedling/seed_owner = owner
|
||||
if(seed_owner.combatant_state != SEEDLING_STATE_NEUTRAL)
|
||||
if(feedback)
|
||||
seed_owner.balloon_alert(seed_owner, "charging!")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/Activate(atom/target)
|
||||
if(is_seedling)
|
||||
var/mob/living/basic/seedling/seed_owner = owner
|
||||
seed_owner.change_combatant_state(state = SEEDLING_STATE_WARMUP)
|
||||
addtimer(CALLBACK(src, PROC_REF(attack_sequence), owner, target), charge_up_timer)
|
||||
StartCooldown()
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/attack_sequence(mob/living/firer, atom/target)
|
||||
if(is_seedling)
|
||||
var/mob/living/basic/seedling/seed_owner = owner
|
||||
seed_owner.change_combatant_state(state = SEEDLING_STATE_ACTIVE)
|
||||
addtimer(CALLBACK(seed_owner, TYPE_PROC_REF(/mob/living/basic/seedling, change_combatant_state), SEEDLING_STATE_NEUTRAL), 4 SECONDS)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/solarbeam
|
||||
name = "Solar Beam"
|
||||
button_icon = 'icons/effects/beam.dmi'
|
||||
button_icon_state = "solar_beam"
|
||||
desc = "Concentrate the power of the sun onto your target!"
|
||||
cooldown_time = 30 SECONDS
|
||||
shared_cooldown = NONE
|
||||
///how long will it take for us to charge up the beam
|
||||
var/beam_charge_up = 3 SECONDS
|
||||
///is the owner of this ability a seedling?
|
||||
var/is_seedling = FALSE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/solarbeam/Grant(mob/grant_to)
|
||||
. = ..()
|
||||
if(isnull(owner))
|
||||
return
|
||||
is_seedling = istype(owner, /mob/living/basic/seedling)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/solarbeam/IsAvailable(feedback)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(!is_seedling)
|
||||
return TRUE
|
||||
var/mob/living/basic/seedling/seed_owner = owner
|
||||
if(seed_owner.combatant_state != SEEDLING_STATE_NEUTRAL)
|
||||
if(feedback)
|
||||
seed_owner.balloon_alert(seed_owner, "charging!")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/solarbeam/Activate(atom/target)
|
||||
if(is_seedling)
|
||||
var/mob/living/basic/seedling/seed_owner = owner
|
||||
seed_owner.change_combatant_state(state = SEEDLING_STATE_WARMUP)
|
||||
|
||||
var/turf/target_turf = get_turf(target)
|
||||
playsound(owner, 'sound/effects/seedling_chargeup.ogg', 100, FALSE)
|
||||
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/owner_beam = new(get_turf(owner))
|
||||
animate(owner_beam, transform = matrix().Scale(1, 32), alpha = 255, time = beam_charge_up)
|
||||
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/target_beam = new(target_turf)
|
||||
animate(target_beam, transform = matrix().Scale(2, 1), alpha = 255, time = beam_charge_up)
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(launch_beam), owner, target_turf), beam_charge_up)
|
||||
StartCooldown()
|
||||
return TRUE
|
||||
|
||||
///the solarbeam will damage people, otherwise it will heal plants
|
||||
/datum/action/cooldown/mob_cooldown/solarbeam/proc/launch_beam(mob/living/firer, turf/target_turf)
|
||||
for(var/atom/target_atom as anything in target_turf)
|
||||
|
||||
if(istype(target_atom, /obj/machinery/hydroponics))
|
||||
var/obj/machinery/hydroponics/hydro = target_atom
|
||||
hydro.adjust_plant_health(10)
|
||||
new /obj/effect/temp_visual/heal(target_turf, COLOR_HEALING_CYAN)
|
||||
|
||||
if(!isliving(target_atom))
|
||||
continue
|
||||
|
||||
var/mob/living/living_target = target_atom
|
||||
living_target.adjust_fire_stacks(0.2)
|
||||
living_target.ignite_mob()
|
||||
living_target.adjustFireLoss(30)
|
||||
|
||||
playsound(target_turf, 'sound/magic/lightningbolt.ogg', 50, TRUE)
|
||||
if(!is_seedling)
|
||||
return
|
||||
var/mob/living/basic/seedling/seed_firer = firer
|
||||
seed_firer.change_combatant_state(state = SEEDLING_STATE_NEUTRAL)
|
||||
|
||||
#undef SEEDLING_STATE_NEUTRAL
|
||||
#undef SEEDLING_STATE_WARMUP
|
||||
#undef SEEDLING_STATE_ACTIVE
|
||||
@@ -0,0 +1,178 @@
|
||||
/datum/ai_controller/basic_controller/seedling
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
|
||||
BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends,
|
||||
BB_WEEDLEVEL_THRESHOLD = 3,
|
||||
BB_WATERLEVEL_THRESHOLD = 90,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/watering_can,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/fill_watercan,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/treat_hydroplants,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/watering_can
|
||||
target_key = BB_WATERCAN_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target
|
||||
hunt_targets = list(/obj/item/reagent_containers/cup/watering_can)
|
||||
hunt_range = 7
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/watering_can/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
if(locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn) //we already have what we came for!
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/treat_hydroplants
|
||||
target_key = BB_HYDROPLANT_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_and_set/treatable_hydro
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant
|
||||
hunt_targets = list(/obj/machinery/hydroponics)
|
||||
hunt_range = 7
|
||||
|
||||
/datum/ai_behavior/find_and_set/treatable_hydro
|
||||
|
||||
/datum/ai_behavior/find_and_set/treatable_hydro/search_tactic(datum/ai_controller/controller, locate_path, search_range)
|
||||
var/list/possible_trays = list()
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
var/waterlevel_threshold = controller.blackboard[BB_WATERLEVEL_THRESHOLD]
|
||||
var/weedlevel_threshold = controller.blackboard[BB_WEEDLEVEL_THRESHOLD]
|
||||
var/watering_can = locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn
|
||||
|
||||
for(var/obj/machinery/hydroponics/hydro in oview(search_range, controller.pawn))
|
||||
if(isnull(hydro.myseed))
|
||||
continue
|
||||
if(hydro.waterlevel < waterlevel_threshold && watering_can)
|
||||
possible_trays += hydro
|
||||
continue
|
||||
if(hydro.weedlevel > weedlevel_threshold || hydro.plant_status == HYDROTRAY_PLANT_DEAD)
|
||||
possible_trays += hydro
|
||||
continue
|
||||
|
||||
if(possible_trays.len)
|
||||
return pick(possible_trays)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant
|
||||
hunt_cooldown = 2 SECONDS
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant/target_caught(mob/living/living_pawn, obj/machinery/hydroponics/hydro_target)
|
||||
if(QDELETED(hydro_target) || QDELETED(hydro_target.myseed))
|
||||
return
|
||||
|
||||
if(hydro_target.plant_status == HYDROTRAY_PLANT_DEAD)
|
||||
living_pawn.manual_emote("weeps...") //weep over the dead plants
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants
|
||||
target_key = BB_BEAMABLE_HYDROPLANT_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_and_set/beamable_hydroplants
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam
|
||||
hunt_targets = list(/obj/machinery/hydroponics)
|
||||
hunt_range = 7
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/datum/action/cooldown/solar_ability = controller.blackboard[BB_SOLARBEAM_ABILITY]
|
||||
if(QDELETED(solar_ability) || !solar_ability.IsAvailable())
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
required_distance = 2
|
||||
action_cooldown = 1 MINUTES
|
||||
ability_key = BB_SOLARBEAM_ABILITY
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam/setup(datum/ai_controller/controller, target_key, ability_key)
|
||||
. = ..()
|
||||
var/obj/target = controller.blackboard[target_key]
|
||||
if(QDELETED(target))
|
||||
return FALSE
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/find_and_set/beamable_hydroplants/search_tactic(datum/ai_controller/controller, locate_path, search_range)
|
||||
var/list/possible_trays = list()
|
||||
|
||||
for(var/obj/machinery/hydroponics/hydro in oview(search_range, controller.pawn))
|
||||
if(isnull(hydro.myseed))
|
||||
continue
|
||||
if(hydro.plant_health < hydro.myseed.endurance)
|
||||
possible_trays += hydro
|
||||
|
||||
if(possible_trays.len)
|
||||
return pick(possible_trays)
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/fill_watercan
|
||||
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/suitable_dispenser
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/water_source
|
||||
hunt_targets = list(/obj/structure/sink, /obj/structure/reagent_dispensers)
|
||||
hunt_range = 7
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/fill_watercan/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
var/obj/item/reagent_containers/can = locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn
|
||||
|
||||
if(isnull(can))
|
||||
return
|
||||
if(locate(/datum/reagent/water) in can.reagents.reagent_list)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/suitable_dispenser
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/suitable_dispenser/valid_dinner(mob/living/source, obj/structure/water_source, radius)
|
||||
if(!(locate(/datum/reagent/water) in water_source.reagents.reagent_list))
|
||||
return FALSE
|
||||
|
||||
return can_see(source, water_source, radius)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/water_source
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
hunt_cooldown = 5 SECONDS
|
||||
|
||||
/datum/ai_controller/basic_controller/seedling/meanie
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
|
||||
BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends,
|
||||
)
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/seedling_rapid,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/solarbeam,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/seedling_rapid
|
||||
ability_key = BB_RAPIDSEEDS_ABILITY
|
||||
finish_planning = FALSE
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/solarbeam
|
||||
ability_key = BB_SOLARBEAM_ABILITY
|
||||
finish_planning = FALSE
|
||||
|
||||
///pet commands
|
||||
/datum/pet_command/point_targetting/use_ability/solarbeam
|
||||
command_name = "Launch solarbeam"
|
||||
command_desc = "Command your pet to launch a solarbeam at your target!"
|
||||
radial_icon = 'icons/effects/beam.dmi'
|
||||
radial_icon_state = "solar_beam"
|
||||
speech_commands = list("beam", "solar")
|
||||
pet_ability_key = BB_SOLARBEAM_ABILITY
|
||||
|
||||
/datum/pet_command/point_targetting/use_ability/rapidseeds
|
||||
command_name = "Rapid seeds"
|
||||
command_desc = "Command your pet to launch a volley of seeds at your target!"
|
||||
radial_icon = 'icons/obj/weapons/guns/projectiles.dmi'
|
||||
radial_icon_state = "seedling"
|
||||
speech_commands = list("rapid", "seeds", "volley")
|
||||
pet_ability_key = BB_RAPIDSEEDS_ABILITY
|
||||
@@ -0,0 +1,32 @@
|
||||
/obj/projectile/seedling
|
||||
name = "solar energy"
|
||||
icon_state = "seedling"
|
||||
damage = 10
|
||||
damage_type = BURN
|
||||
light_range = 2
|
||||
armor_flag = ENERGY
|
||||
light_color = LIGHT_COLOR_DIM_YELLOW
|
||||
speed = 1.6
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
|
||||
/obj/projectile/seedling/on_hit(atom/target)
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
|
||||
var/mob/living/living_target = target
|
||||
if(FACTION_JUNGLE in living_target.faction)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/effect/temp_visual/solarbeam_killsat
|
||||
name = "beam of solar energy"
|
||||
icon_state = "solar_beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_PRIMARY_LAYER
|
||||
duration = 3 SECONDS
|
||||
alpha = 200
|
||||
randomdir = FALSE
|
||||
Reference in New Issue
Block a user