mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 04:26:03 +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:
@@ -130,3 +130,19 @@
|
||||
#define BB_AUTOMATED_MINING "automated_mining"
|
||||
/// key that stores the nearest dead human
|
||||
#define BB_NEARBY_DEAD_MINER "nearby_dead_miner"
|
||||
|
||||
//seedling keys
|
||||
/// the water can we will pick up
|
||||
#define BB_WATERCAN_TARGET "watercan_target"
|
||||
/// the hydrotray we will heal
|
||||
#define BB_HYDROPLANT_TARGET "hydroplant_target"
|
||||
/// minimum weed levels for us to cure
|
||||
#define BB_WEEDLEVEL_THRESHOLD "weedlevel_threshold"
|
||||
/// minimum water levels for us to refill
|
||||
#define BB_WATERLEVEL_THRESHOLD "waterlevel_threshold"
|
||||
/// key holds our solarbeam ability
|
||||
#define BB_SOLARBEAM_ABILITY "solarbeam_ability"
|
||||
/// key holds our rapid seeds ability
|
||||
#define BB_RAPIDSEEDS_ABILITY "rapidseeds_ability"
|
||||
/// key holds the tray we will beam
|
||||
#define BB_BEAMABLE_HYDROPLANT_TARGET "beamable_hydroplant_target"
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
var/hunt_range = 2
|
||||
/// What are the chances we hunt something at any given moment
|
||||
var/hunt_chance = 100
|
||||
///do we finish planning subtree
|
||||
var/finish_planning = TRUE
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/New()
|
||||
. = ..()
|
||||
@@ -35,13 +37,15 @@
|
||||
// We're not hunting anything, look around for something
|
||||
if(isnull(hunted))
|
||||
controller.queue_behavior(finding_behavior, target_key, hunt_targets, hunt_range)
|
||||
return
|
||||
|
||||
// We ARE hunting something, execute the hunt.
|
||||
// Note that if our AI controller has multiple hunting subtrees set,
|
||||
// we may accidentally be executing another tree's hunt - not ideal,
|
||||
// try to set a unique target key if you have multiple
|
||||
else
|
||||
controller.queue_behavior(hunting_behavior, target_key, BB_HUNTING_COOLDOWN)
|
||||
|
||||
controller.queue_behavior(hunting_behavior, target_key, BB_HUNTING_COOLDOWN)
|
||||
if(finish_planning)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING //If we're hunting we're too busy for anything else
|
||||
|
||||
/// Finds a specific atom type to hunt.
|
||||
@@ -124,3 +128,19 @@
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/target_caught(mob/living/hunter, obj/structure/cable/hunted)
|
||||
hunter.UnarmedAttack(hunted, TRUE)
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target
|
||||
always_reset_target = TRUE
|
||||
///the ability we will use
|
||||
var/ability_key
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
|
||||
var/datum/action/cooldown/ability = controller.blackboard[ability_key]
|
||||
if(QDELETED(ability) || !ability.IsAvailable())
|
||||
finish_action(controller, FALSE, hunting_target_key)
|
||||
return ..()
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target/target_caught(mob/living/hunter, atom/hunted)
|
||||
var/datum/action/cooldown/ability = hunter.ai_controller.blackboard[ability_key]
|
||||
ability.InterceptClickOn(hunter, null, hunted)
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
/obj/item/seeds/liberty = 5,
|
||||
/obj/item/seeds/replicapod = 5,
|
||||
/obj/item/seeds/reishi = 5,
|
||||
/obj/item/seeds/seedling = 5,
|
||||
/obj/item/seeds/nettle/death = 1,
|
||||
/obj/item/seeds/plump/walkingmushroom = 1,
|
||||
/obj/item/seeds/cannabis/rainbow = 1,
|
||||
|
||||
@@ -62,18 +62,20 @@
|
||||
including one replica-pod seed and two mystery seeds!"
|
||||
cost = CARGO_CRATE_VALUE * 3
|
||||
access_view = ACCESS_HYDROPONICS
|
||||
contains = list(/obj/item/seeds/nettle,
|
||||
/obj/item/seeds/replicapod,
|
||||
/obj/item/seeds/plump,
|
||||
/obj/item/seeds/liberty,
|
||||
/obj/item/seeds/amanita,
|
||||
/obj/item/seeds/reishi,
|
||||
/obj/item/seeds/bamboo,
|
||||
/obj/item/seeds/eggplant/eggy,
|
||||
/obj/item/seeds/rainbow_bunch,
|
||||
/obj/item/seeds/shrub,
|
||||
/obj/item/seeds/random = 2,
|
||||
)
|
||||
contains = list(
|
||||
/obj/item/seeds/amanita,
|
||||
/obj/item/seeds/bamboo,
|
||||
/obj/item/seeds/eggplant/eggy,
|
||||
/obj/item/seeds/liberty,
|
||||
/obj/item/seeds/nettle,
|
||||
/obj/item/seeds/plump,
|
||||
/obj/item/seeds/replicapod,
|
||||
/obj/item/seeds/reishi,
|
||||
/obj/item/seeds/rainbow_bunch,
|
||||
/obj/item/seeds/seedling,
|
||||
/obj/item/seeds/shrub,
|
||||
/obj/item/seeds/random = 2,
|
||||
)
|
||||
crate_name = "exotic seeds crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/obj/item/seeds/seedling
|
||||
name = "pack of seedling seeds"
|
||||
desc = "These seeds grow into a floral assistant which can help look after other plants!"
|
||||
icon_state = "seed-seedling"
|
||||
growing_icon = 'icons/obj/service/hydroponics/growing_fruits.dmi'
|
||||
species = "seedling"
|
||||
plantname = "Seedling Plant"
|
||||
product = /mob/living/basic/seedling
|
||||
lifespan = 40
|
||||
endurance = 7
|
||||
maturation = 10
|
||||
production = 1
|
||||
growthstages = 2
|
||||
yield = 1
|
||||
instability = 15
|
||||
potency = 30
|
||||
|
||||
/obj/item/seeds/seedling/harvest(mob/harvester)
|
||||
var/obj/machinery/hydroponics/parent = loc
|
||||
var/list/grow_locations = get_adjacent_open_turfs(parent)
|
||||
var/turf/final_location = length(grow_locations) ? pick(grow_locations) : get_turf(parent)
|
||||
var/mob/living/basic/seedling/seed_pet = new product(final_location)
|
||||
seed_pet.befriend(harvester)
|
||||
parent.update_tray(user = harvester, product_count = 1)
|
||||
|
||||
/obj/item/seeds/seedling/evil
|
||||
product = /mob/living/basic/seedling/meanie
|
||||
icon_state = "seed-seedling-evil"
|
||||
@@ -93,6 +93,10 @@
|
||||
return FALSE
|
||||
|
||||
var/mob/living/mob_target = target
|
||||
|
||||
if(mob_target.mob_biotypes & MOB_PLANT)
|
||||
return FALSE
|
||||
|
||||
var/datum/ai_controller/basic_controller/bee_ai = owner.ai_controller
|
||||
if(isnull(bee_ai))
|
||||
return FALSE
|
||||
|
||||
@@ -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
|
||||
@@ -1,240 +0,0 @@
|
||||
#define SEEDLING_STATE_NEUTRAL 0
|
||||
#define SEEDLING_STATE_WARMUP 1
|
||||
#define SEEDLING_STATE_ACTIVE 2
|
||||
#define SEEDLING_STATE_RECOVERY 3
|
||||
|
||||
//A plant rooted in the ground that forfeits its melee attack in favor of ranged barrages.
|
||||
//It will fire flurries of solar energy, and occasionally charge up a powerful blast that makes it vulnerable to attack.
|
||||
/mob/living/simple_animal/hostile/jungle/seedling
|
||||
name = "seedling"
|
||||
desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon, and it will not die until its hidden vital organs are sliced out. \
|
||||
The concentrated streams of energy it sometimes produces require its full attention, attacking it during this time will prevent it from finishing its attack."
|
||||
icon = 'icons/mob/simple/jungle/seedling.dmi'
|
||||
icon_state = "seedling"
|
||||
icon_living = "seedling"
|
||||
icon_dead = "seedling_dead"
|
||||
mob_biotypes = MOB_ORGANIC | MOB_PLANT
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
SET_BASE_PIXEL(-16, -14)
|
||||
|
||||
minimum_distance = 3
|
||||
move_to_delay = 20
|
||||
vision_range = 9
|
||||
aggro_vision_range = 15
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 10
|
||||
projectiletype = /obj/projectile/seedling
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
robust_searching = TRUE
|
||||
stat_attack = HARD_CRIT
|
||||
move_resist = MOVE_FORCE_EXTREMELY_STRONG
|
||||
var/combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
var/mob/living/beam_debuff_target
|
||||
var/solar_beam_identifier = 0
|
||||
|
||||
/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
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
|
||||
/obj/projectile/seedling/Bump(atom/A)//Stops seedlings from destroying other jungle mobs through FF
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(FACTION_JUNGLE in L.faction)
|
||||
return FALSE
|
||||
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 = 5
|
||||
randomdir = FALSE
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator
|
||||
id = "seedling beam indicator"
|
||||
duration = 3 SECONDS
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
tick_interval = 0.2 SECONDS
|
||||
var/atom/movable/screen/seedling/seedling_screen_object
|
||||
var/atom/target
|
||||
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_creation(mob/living/new_owner, target_plant)
|
||||
. = ..()
|
||||
if(.)
|
||||
target = target_plant
|
||||
tick()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_apply()
|
||||
if(owner.client)
|
||||
seedling_screen_object = new /atom/movable/screen/seedling()
|
||||
owner.client.screen += seedling_screen_object
|
||||
tick()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/Destroy()
|
||||
if(owner)
|
||||
if(owner.client)
|
||||
owner.client.screen -= seedling_screen_object
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/tick(seconds_between_ticks)
|
||||
var/target_angle = get_angle(owner, target)
|
||||
var/matrix/final = matrix()
|
||||
final.Turn(target_angle)
|
||||
seedling_screen_object.transform = final
|
||||
|
||||
/atom/movable/screen/seedling
|
||||
icon = 'icons/mob/simple/jungle/arachnid.dmi'
|
||||
icon_state = "seedling_beam_indicator"
|
||||
screen_loc = "CENTER:-16,CENTER:-16"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/Goto()
|
||||
if(combatant_state != SEEDLING_STATE_NEUTRAL)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/AttackingTarget()
|
||||
if(isliving(target))
|
||||
if(ranged_cooldown <= world.time && combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
OpenFire(target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/OpenFire()
|
||||
WarmupAttack()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/WarmupAttack()
|
||||
if(combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
combatant_state = SEEDLING_STATE_WARMUP
|
||||
SSmove_manager.stop_looping(src)
|
||||
update_icons()
|
||||
var/target_dist = get_dist(src,target)
|
||||
var/living_target_check = isliving(target)
|
||||
if(living_target_check)
|
||||
if(target_dist > 7)//Offscreen check
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
if(get_dist(src,target) >= 4 && prob(40))
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
addtimer(CALLBACK(src, PROC_REF(Volley)), 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/SolarBeamStartup(mob/living/living_target)//It's more like requiem than final spark
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
living_target.apply_status_effect(/datum/status_effect/seedling_beam_indicator, src)
|
||||
beam_debuff_target = living_target
|
||||
playsound(src,'sound/effects/seedling_chargeup.ogg', 100, FALSE)
|
||||
if(get_dist(src,living_target) > 7)
|
||||
playsound(living_target,'sound/effects/seedling_chargeup.ogg', 100, FALSE)
|
||||
solar_beam_identifier = world.time
|
||||
addtimer(CALLBACK(src, PROC_REF(Beamu), living_target, solar_beam_identifier), 35)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Beamu(mob/living/living_target, beam_id = 0)
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && living_target && beam_id == solar_beam_identifier)
|
||||
if(living_target.z == z)
|
||||
update_icons()
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/S = new (get_turf(src))
|
||||
var/matrix/starting = matrix()
|
||||
starting.Scale(1,32)
|
||||
starting.Translate(0,520)
|
||||
S.transform = starting
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/K = new (get_turf(living_target))
|
||||
var/matrix/final = matrix()
|
||||
final.Scale(1,32)
|
||||
final.Translate(0,512)
|
||||
K.transform = final
|
||||
living_target.adjustFireLoss(30)
|
||||
living_target.adjust_fire_stacks(0.2)//Just here for the showmanship
|
||||
living_target.ignite_mob()
|
||||
playsound(living_target,'sound/weapons/sear.ogg', 50, TRUE)
|
||||
addtimer(CALLBACK(src, PROC_REF(AttackRecovery)), 5)
|
||||
return
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Volley()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
update_icons()
|
||||
var/datum/callback/cb = CALLBACK(src, PROC_REF(InaccurateShot))
|
||||
for(var/i in 1 to 13)
|
||||
addtimer(cb, i)
|
||||
addtimer(CALLBACK(src, PROC_REF(AttackRecovery)), 14)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/InaccurateShot()
|
||||
if(!QDELETED(target) && combatant_state == SEEDLING_STATE_ACTIVE && !stat)
|
||||
if(get_dist(src,target) <= 3)//If they're close enough just aim straight at them so we don't miss at point blank ranges
|
||||
Shoot(target)
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
var/obj/projectile/seedling/readied_shot = new /obj/projectile/seedling(our_turf)
|
||||
readied_shot.preparePixelProjectile(target, src, null, rand(-10, 10))
|
||||
readied_shot.fire()
|
||||
playsound(src, projectilesound, 100, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/AttackRecovery()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
combatant_state = SEEDLING_STATE_RECOVERY
|
||||
update_icons()
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
if(target)
|
||||
face_atom(target)
|
||||
addtimer(CALLBACK(src, PROC_REF(ResetNeutral)), 10)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/ResetNeutral()
|
||||
combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
if(target && !stat)
|
||||
update_icons()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && beam_debuff_target)
|
||||
beam_debuff_target.remove_status_effect(/datum/status_effect/seedling_beam_indicator)
|
||||
beam_debuff_target = null
|
||||
solar_beam_identifier = 0
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/update_icons()
|
||||
. = ..()
|
||||
if(!stat)
|
||||
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"
|
||||
if(SEEDLING_STATE_RECOVERY)
|
||||
icon_state = "seedling"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/GiveTarget()
|
||||
if(target)
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)//So it doesn't 180 and blast you in the face while it's firing at someone else
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/LoseTarget()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
#undef SEEDLING_STATE_NEUTRAL
|
||||
#undef SEEDLING_STATE_WARMUP
|
||||
#undef SEEDLING_STATE_ACTIVE
|
||||
#undef SEEDLING_STATE_RECOVERY
|
||||
@@ -136,7 +136,6 @@
|
||||
/mob/living/simple_animal/hostile/jungle,
|
||||
/mob/living/simple_animal/hostile/jungle/leaper,
|
||||
/mob/living/simple_animal/hostile/jungle/mook,
|
||||
/mob/living/simple_animal/hostile/jungle/seedling,
|
||||
/mob/living/simple_animal/hostile/megafauna,
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner,
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom,
|
||||
|
||||
@@ -325,3 +325,10 @@
|
||||
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist.
|
||||
restricted_roles = list(JOB_RESEARCH_DIRECTOR, JOB_SCIENTIST)
|
||||
surplus = 5
|
||||
|
||||
/datum/uplink_item/role_restricted/evil_seedling
|
||||
name = "Evil Seedling"
|
||||
desc = "A rare seed we have recovered that grows into a dangerous species that will aid you with your tasks!"
|
||||
item = /obj/item/seeds/seedling/evil
|
||||
cost = 8
|
||||
restricted_roles = list(JOB_BOTANIST)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
+4
-1
@@ -3863,6 +3863,7 @@
|
||||
#include "code\modules\hydroponics\grown\random.dm"
|
||||
#include "code\modules\hydroponics\grown\replicapod.dm"
|
||||
#include "code\modules\hydroponics\grown\root.dm"
|
||||
#include "code\modules\hydroponics\grown\seedling.dm"
|
||||
#include "code\modules\hydroponics\grown\sugarcane.dm"
|
||||
#include "code\modules\hydroponics\grown\tea_coffee.dm"
|
||||
#include "code\modules\hydroponics\grown\tobacco.dm"
|
||||
@@ -4283,6 +4284,9 @@
|
||||
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid.dm"
|
||||
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_abilities.dm"
|
||||
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_ai.dm"
|
||||
#include "code\modules\mob\living\basic\jungle\seedling\seedling.dm"
|
||||
#include "code\modules\mob\living\basic\jungle\seedling\seedling_ai.dm"
|
||||
#include "code\modules\mob\living\basic\jungle\seedling\seedling_projectiles.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\mining.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\basilisk\basilisk.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\basilisk\basilisk_overheat.dm"
|
||||
@@ -4616,7 +4620,6 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\jungle\seedling.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\_megafauna.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
|
||||
|
||||
Reference in New Issue
Block a user