mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
more code clean up (#10330)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/human/ai_controlled/greytide/Initialize()
|
||||
/mob/living/carbon/human/ai_controlled/greytide/Initialize(mapload)
|
||||
to_wear_r_hand = pick(
|
||||
prob(20); /obj/item/storage/toolbox/electrical,
|
||||
prob(20); /obj/item/storage/toolbox/mechanical,
|
||||
@@ -20,7 +20,7 @@
|
||||
)
|
||||
else
|
||||
to_wear_gloves = null
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/human/ai_controlled/greytide
|
||||
name = "John Greytide" //theyll get a normal name on spawn
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma
|
||||
projectiletype = /obj/item/projectile/energy/mob/electric_spider
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega
|
||||
projectiletype = /obj/item/projectile/energy/mob/smalllaser
|
||||
@@ -1,39 +0,0 @@
|
||||
//File unticked due to combat refactor walkback
|
||||
|
||||
/mob/living/simple_mob/metroid/jellybrig
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/baby
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/super
|
||||
health = 125
|
||||
maxHealth = 125
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/alpha
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/zeta
|
||||
health = 250
|
||||
maxHealth = 250
|
||||
melee_damage_lower = 7
|
||||
melee_damage_upper = 12
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega
|
||||
health = 300
|
||||
maxHealth = 300
|
||||
melee_damage_lower = 12
|
||||
melee_damage_upper = 20
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/queen
|
||||
health = 500
|
||||
maxHealth = 500
|
||||
@@ -0,0 +1,62 @@
|
||||
// Specialized AI for metroid simplemobs.
|
||||
// Unlike the parent AI code, this will probably break a lot of things if you put it on something that isn't /mob/living/simple_mob/metroid/juvenile
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid
|
||||
hostile = TRUE
|
||||
cooperative = TRUE
|
||||
firing_lanes = TRUE
|
||||
mauling = TRUE // They need it to get the most out of monkeys.
|
||||
conserve_ammo = TRUE // Might help avoid 'I shoot the wall forever' cheese.
|
||||
var/closest_desired_distance = 1 // Otherwise run up to them to be able to potentially shock or punch them.
|
||||
var/always_stun = FALSE // If true, the metroid will elect to attempt to permastun the target.
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/on_engagement(atom/A)
|
||||
if(get_dist(holder, A) > closest_desired_distance)
|
||||
holder.IMove(get_step_towards(holder, A))
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/New()
|
||||
..()
|
||||
ASSERT(istype(holder, /mob/living/simple_mob/metroid/juvenile))
|
||||
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/handle_special_tactic()
|
||||
evolve_and_reproduce()
|
||||
|
||||
// Hit the correct verbs to keep the metroid species going.
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/proc/evolve_and_reproduce()
|
||||
var/mob/living/simple_mob/metroid/juvenile/my_juvenile = holder
|
||||
if(my_juvenile.nutrition >= my_juvenile.evo_point)
|
||||
// Press the correct verb when we can.
|
||||
my_juvenile.evolve() // Turns our holder into an adult metroid.
|
||||
|
||||
// The holder's attack changes based on intent. This lets the AI choose what effect is desired.
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/pre_melee_attack(atom/A)
|
||||
if(istype(A, /mob/living))
|
||||
var/mob/living/L = A
|
||||
var/mob/living/simple_mob/metroid/juvenile/my_juvenile = holder
|
||||
|
||||
if( (!L.lying && prob(30 + (my_juvenile.power_charge * 7) ) || (!L.lying && always_stun) ))
|
||||
my_juvenile.a_intent = I_DISARM // Stun them first.
|
||||
else if(my_juvenile.is_juvenile && my_juvenile.can_consume(L) && L.lying)
|
||||
my_juvenile.a_intent = I_GRAB // Then eat them.
|
||||
else
|
||||
my_juvenile.a_intent = I_HURT // Otherwise robust them.
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/closest_distance(atom/movable/AM)
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/L = AM
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(istype(H.species, /datum/species/monkey))
|
||||
return 1 // Otherwise ranged metroids will eat a lot less often.
|
||||
if(L.stat >= UNCONSCIOUS)
|
||||
return 1 // Melee (eat) the target if dead/dying, don't shoot it.
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/simple_mob/juvenile_metroid/can_attack(atom/movable/AM, var/vision_required = TRUE)
|
||||
. = ..()
|
||||
if(.) // Do some additional checks because we have Special Code(tm).
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
|
||||
return TRUE // Monkeys are always food (sorry Pun Pun).
|
||||
@@ -0,0 +1,122 @@
|
||||
// The top-level metroid defines. Xenobio slimes and feral slimes will inherit from this. Stolen from as much slime code as possible.
|
||||
|
||||
/mob/living/simple_mob/metroid
|
||||
name = "metroid"
|
||||
desc = "Some sort of person eaty thing! This is the prototype mob and shouldn't be spawned. If you see this, yell at your local dev or event manager who spawned this one >.>"
|
||||
tt_desc = "Headamus Suckumus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_state = "metroid"
|
||||
icon_living = "metroid"
|
||||
icon_dead = "metroid_dead"
|
||||
layer = MOB_LAYER + 1 // Need them on top of other mobs or it looks weird when consuming something.
|
||||
var/icon_state_override = null // Used for special slime appearances like the rainbow slime.
|
||||
gender = NEUTER
|
||||
|
||||
faction = "metroids"
|
||||
maxHealth = 25
|
||||
movement_cooldown = 1.7
|
||||
pass_flags = PASSTABLE
|
||||
makes_dirt = FALSE // Floats, mostly.
|
||||
mob_class = MOB_CLASS_SLIME //This needs to be updated in simple_mob.dm and _defines/mobs.dm
|
||||
|
||||
response_help = "pets"
|
||||
|
||||
// Atmos stuff.
|
||||
minbodytemp = T0C-30
|
||||
heat_damage_per_tick = 0
|
||||
cold_damage_per_tick = 40
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
base_attack_cooldown = 10 // One attack a second.
|
||||
attack_sound = 'sound/metroid/metroidattack.ogg'
|
||||
attacktext = list("suckulated")
|
||||
speak_emote = list("chirps")
|
||||
friendly = list("pokes")
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee
|
||||
say_list_type = /datum/say_list/metroid
|
||||
|
||||
harm_intent_damage = 5 //When someone uses fists. Default is 3
|
||||
|
||||
vore_active = 1
|
||||
vore_pounce_chance = 25
|
||||
vore_icons = SA_ICON_LIVING
|
||||
|
||||
nutrition = 1000 //This actually gets overridden further down on initialize.
|
||||
max_nutrition = 2200
|
||||
var/evo_point = 0
|
||||
var/evo_limit = 0
|
||||
var/next
|
||||
meat_type = /obj/item/toy/figure/bounty_hunter
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
can_pain_emote = TRUE
|
||||
species_sounds = "Metroid"
|
||||
pain_emote_1p = list("skree")
|
||||
pain_emote_3p = list("skrees")
|
||||
|
||||
/mob/living/simple_mob/metroid/Initialize()
|
||||
nutrition = 100 //Have them start off pretty hungry still.
|
||||
add_verb(src,/mob/living/proc/ventcrawl) //CHOMPEdit TGPanel //May not do anything at the moment.
|
||||
return ..()
|
||||
|
||||
/datum/say_list/metroid
|
||||
speak = list("Skree.", "Eree.", "Errer?")
|
||||
emote_see = list("floats about","looks around", "rubs its talons")
|
||||
emote_hear = list("chitters")
|
||||
say_understood = list("Eree.")
|
||||
say_cannot = list("Errerr.")
|
||||
say_maybe_target = list("Eree?")
|
||||
say_got_target = list("Ereet!")
|
||||
say_threaten = list("Skree!")
|
||||
say_stand_down = list("Eee.")
|
||||
say_escalate = list("SKREE!")
|
||||
threaten_sound = 'sound/metroid/metroidsee.ogg'
|
||||
stand_down_sound = 'sound/metroid/metroiddetach.ogg'
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/init_vore()
|
||||
if(!voremob_loaded)
|
||||
return
|
||||
.=..()
|
||||
var/obj/belly/B = vore_selected
|
||||
B.digest_brute = 1
|
||||
B.digest_burn = 1
|
||||
B.vore_verb = "swallow"
|
||||
B.name = "membrane" //THERE IS A RUNTIME HERE SOMEHOW
|
||||
B.desc = "The metroid positions itself above you and swoops down, lazily enveloping you through its tight mouth and sending you straight to its bulbous membrane for all to see."
|
||||
B.emote_lists[DM_HOLD] = list(
|
||||
"The metroid's cortex tentacles wriggle over you, violating and teasing you as they sopped you in viscous slime.",
|
||||
"The cortex you are forced against pulses with life, gently squeezing you between it and the stretchy membrane around you.",
|
||||
"You press your face against the transparent membrane, watching how the world distorts as it stretches over your eyes.",
|
||||
"The air around you is so thick. You struggle to breathe occasionally, choking on the heat and moisture.",
|
||||
"You struggle a bit, making the membrane swell out."
|
||||
)
|
||||
B.emote_lists[DM_DIGEST] = list(
|
||||
"The cortex tentacles are pulsating like lines of power streaking away from you as it drains you. Waves of sleepiness wash over you as the areas most closest to the tentacles are drained of energy.",
|
||||
"The air feels a tinge incendiary as the cortex you rest on heats up, fueled by your own body as the metroid draws your strenght away from you.",
|
||||
"As you grow weaker, your movements against the membrane grow weaker as well, making you feel as if the membrane is closing around you, wrapping and squeezing you, draining you for all you are worth.",
|
||||
"You feel faint as the tentacles wrapped around you sap you of your strength, seemingly eager to drain and claim you for food."
|
||||
)
|
||||
B.digest_messages_prey = list(
|
||||
"You can't stay awake anymore, the clear world around you going fuzzy until you can see it no more.",
|
||||
"The tinge of the air grows to a crescendo and then fades away, just as the rest of your body fizzles into energy for the metroid.",
|
||||
"The tentacles squeeze you one last time as the last of your energy is sapped and your body is claimed as food for the metroid.",
|
||||
"The metroid swells as it absorbs the rest of your life force and nutrients into its body, making it stronger and even hungry for more."
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/metroid/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 75, 1)
|
||||
..()
|
||||
@@ -0,0 +1,140 @@
|
||||
// Handles hunger, starvation, growth, and eatting humans.
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/adjust_nutrition(input, var/heal = 1)
|
||||
..(input)
|
||||
|
||||
if(input > 0)
|
||||
// Gain around one level per 50 nutrition.
|
||||
if(prob(input * 2))
|
||||
power_charge = min(power_charge++, 10)
|
||||
if(power_charge == 10)
|
||||
adjustToxLoss(-10)
|
||||
|
||||
// Heal 1 point of damage per 5 nutrition coming in.
|
||||
if(heal)
|
||||
adjustBruteLoss(-input * 0.2)
|
||||
adjustFireLoss(-input * 0.2)
|
||||
adjustToxLoss(-input * 0.2)
|
||||
adjustOxyLoss(-input * 0.2)
|
||||
adjustCloneLoss(-input * 0.2)
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/handle_consumption()
|
||||
if(victim && !stat)
|
||||
if(istype(victim) && consume(victim, 20))
|
||||
if(prob(25))
|
||||
to_chat(src, span_notice("You continue absorbing \the [victim]."))
|
||||
|
||||
else
|
||||
var/list/feedback = list(
|
||||
"This subject is incompatable",
|
||||
"This subject does not have a life energy",
|
||||
"This subject is empty",
|
||||
"I am not satisfied",
|
||||
"I can not feed from this subject",
|
||||
"I do not feel nourished",
|
||||
"This subject is not food"
|
||||
)
|
||||
to_chat(src, span_warning("[pick(feedback)]..."))
|
||||
stop_consumption()
|
||||
|
||||
if(victim)
|
||||
victim.updatehealth()
|
||||
|
||||
else
|
||||
stop_consumption()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/start_consuming(mob/living/L)
|
||||
if(!is_juvenile)
|
||||
return
|
||||
if(!can_consume(L))
|
||||
return
|
||||
if(!Adjacent(L))
|
||||
return
|
||||
|
||||
step_towards(src, L) // Get on top of them to feed.
|
||||
if(loc != L.loc)
|
||||
return
|
||||
|
||||
if(L.buckle_mob(src, forced = TRUE))
|
||||
victim = L
|
||||
update_icon()
|
||||
set_AI_busy(TRUE) // Don't want the AI to interfere with eatting.
|
||||
playsound(src, 'sound/metroid/metroidattach.ogg', 50, 1)
|
||||
victim.visible_message(
|
||||
span_danger("\The [src] latches onto \the [victim]!"),
|
||||
span_critical("\The [src] latches onto you!")
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/stop_consumption(mob/living/L)
|
||||
if(!victim)
|
||||
return
|
||||
playsound(src, 'sound/metroid/metroiddetach.ogg', 50, 1)
|
||||
victim.unbuckle_mob()
|
||||
victim.visible_message(
|
||||
span_notice("\The [src] slides off of [victim]!"),
|
||||
span_notice("\The [src] slides off of you!")
|
||||
)
|
||||
victim = null
|
||||
update_icon()
|
||||
spawn(30)
|
||||
set_AI_busy(FALSE) // Resume normal operations.
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/can_consume(mob/living/L)
|
||||
if(!L || !istype(L))
|
||||
to_chat(src, "This subject is incomparable...")
|
||||
return FALSE
|
||||
if(harmless)
|
||||
to_chat(src, "I am pacified... I cannot eat...")
|
||||
return FALSE
|
||||
if(L.mob_class & MOB_CLASS_SLIME)
|
||||
to_chat(src, "I cannot feed on other slimes...")
|
||||
return FALSE
|
||||
if(L.isSynthetic())
|
||||
to_chat(src, "This subject is not biological...")
|
||||
return FALSE
|
||||
if(L.getarmor(null, "bio") >= 75)
|
||||
to_chat(src, "I cannot reach this subject's biological matter...")
|
||||
return FALSE
|
||||
if(!Adjacent(L))
|
||||
to_chat(src, "This subject is too far away...")
|
||||
return FALSE
|
||||
if(L.getCloneLoss() >= L.getMaxHealth() * 1.5)
|
||||
to_chat(src, "This subject does not have an edible life energy...")
|
||||
return FALSE
|
||||
//VOREStation Addition start
|
||||
if(istype(L, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.species.flags & NO_SCAN)
|
||||
to_chat(src, "This subject's life energy is beyond my reach...")
|
||||
return FALSE
|
||||
//VOREStation Addition end
|
||||
if(L.has_buckled_mobs())
|
||||
for(var/A in L.buckled_mobs)
|
||||
if(istype(A, /mob/living/simple_mob/slime/xenobio))
|
||||
if(A != src)
|
||||
to_chat(src, "\The [A] is already feeding on this subject...")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// This does the actual damage, as well as give nutrition and heals.
|
||||
// Assuming no bio armor, calling consume(10) will result in;
|
||||
// 6 clone damage to victim
|
||||
// 4 tox damage to victim.
|
||||
// 25 nutrition for the slime.
|
||||
// 2 points of damage healed on the slime (as a result of the nutrition).
|
||||
// 50% of giving +1 charge to the slime (same as above).
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/consume(mob/living/victim, amount)
|
||||
if(can_consume(victim))
|
||||
var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1)
|
||||
var/damage_done = amount * armor_modifier
|
||||
if(damage_done > 0)
|
||||
playsound(src, 'sound/metroid/metroidattack.ogg', 100, 1)
|
||||
victim.adjustCloneLoss(damage_done * 0.6)
|
||||
victim.adjustToxLoss(damage_done * 0.4)
|
||||
adjust_nutrition(damage_done * 5)
|
||||
Beam(victim, icon_state = "slime_consume", time = 8)
|
||||
to_chat(src, span_notice("You absorb some biomaterial from \the [victim]."))
|
||||
to_chat(victim, span_danger("\The [src] consumes some of your flesh!"))
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -0,0 +1,172 @@
|
||||
//Some basic metroid specific mechanics. Lifted from slime code, but gutted all the xenobio taming stuff. Feel free to add it back in, but I recommend making a new specific subset of tamable metroids and leaving the others as wild or soemthing.
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile
|
||||
desc = "This metroid should not be spawned. Yell at your local dev or event manager."
|
||||
layer = MOB_LAYER + 1 // Need them on top of other mobs or it looks weird when consuming something.
|
||||
max_nutrition = 1000
|
||||
var/is_queen = FALSE // When the metroid is a queen, it should just be shitting out babies. Found in metAI.dm and in metTypes for the queen.
|
||||
var/maxHealth_adult = 200
|
||||
var/power_charge = 0 // Disarm attacks can shock someone if high/lucky enough.
|
||||
var/mob/living/victim = null // the person the metroid is currently feeding on
|
||||
var/amount_grown = 0 // controls how long the metroid has been overfed, if 10, grows or reproduces
|
||||
var/number = 0 // This is used to make the metroid semi-unique for indentification.
|
||||
var/harmless = FALSE // Set to true when pacified. Makes the metroid harmless, not get hungry, and not be able to grow/reproduce.
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/Destroy()
|
||||
if(victim)
|
||||
stop_consumption() // Unbuckle us from our victim.
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/handle_special()
|
||||
if(stat != DEAD)
|
||||
if(victim)
|
||||
handle_consumption()
|
||||
|
||||
handle_stuttering() // ??
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/examine(mob/user)
|
||||
. = ..()
|
||||
if(stat == DEAD)
|
||||
. += "It appears to be dead."
|
||||
else if(incapacitated(INCAPACITATION_DISABLED))
|
||||
. += "It appears to be incapacitated."
|
||||
else if(harmless)
|
||||
. += "It appears to have been pacified."
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/verb/evolve()
|
||||
set category = "metroid"
|
||||
set desc = "This will let you advance to next form."
|
||||
|
||||
if(stat)
|
||||
to_chat(src, span_warning("I must be conscious to do this..."))
|
||||
return
|
||||
|
||||
if(is_queen)
|
||||
paralysis = 7998
|
||||
playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1)
|
||||
src.visible_message(span_notice("\The [src] begins to lay an egg."))
|
||||
spawn(50)
|
||||
new /obj/effect/metroid/egg(loc, src)
|
||||
adjust_nutrition(-500)
|
||||
paralysis = 0
|
||||
return
|
||||
|
||||
if(nutrition >= evo_point && !buckled && vore_fullness == 0 && !victim)
|
||||
if(next == "/mob/living/simple_mob/metroid/juvenile/queen" && GLOB.queen_amount > 0)
|
||||
to_chat(src, span_warning("There is already a queen."))
|
||||
return
|
||||
playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1)
|
||||
paralysis = 7998
|
||||
sleep(50)
|
||||
expand_troid()
|
||||
|
||||
if(nutrition >= evo_limit && (buckled || vore_fullness == 1)) //spit dat crap out if nutrition gets too high!
|
||||
release_vore_contents()
|
||||
prey_excludes.Cut()
|
||||
stop_consumption()
|
||||
|
||||
else
|
||||
to_chat(src, span_warning("I am not ready to evolve yet..."))
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/proc/expand_troid()
|
||||
var/mob/living/L
|
||||
L = new next(get_turf(src)) //Next is a variable defined by metTypes.dm that just points to the next metroid in the evolutionary stage.
|
||||
if(mind)
|
||||
src.mind.transfer_to(L)
|
||||
visible_message(span_warning("\The [src] suddenly evolves!"))
|
||||
qdel(src)
|
||||
|
||||
// Code for metroids attacking other things.
|
||||
// metroid attacks change based on intent.
|
||||
/mob/living/simple_mob/metroid/juvenile/apply_attack(mob/living/L, damage_to_do)
|
||||
if(istype(L))
|
||||
switch(a_intent)
|
||||
if(I_HELP) // This shouldn't happen but just in case.
|
||||
return FALSE
|
||||
|
||||
if(I_DISARM)
|
||||
var/stun_power = between(0, power_charge + rand(0, 3), 10)
|
||||
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
stun_power *= max(H.species.siemens_coefficient, 0)
|
||||
|
||||
if(prob(stun_power * 10)) // Try an electric shock.
|
||||
power_charge = max(0, power_charge - 3)
|
||||
L.visible_message(
|
||||
span_danger("\The [src] has shocked \the [L]!"),
|
||||
span_danger("\The [src] has shocked you!")
|
||||
)
|
||||
playsound(src, 'sound/weapons/Egloves.ogg', 75, 1)
|
||||
L.Weaken(4)
|
||||
L.Stun(4)
|
||||
do_attack_animation(L)
|
||||
if(L.buckled)
|
||||
L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents metroids from jumping on you.
|
||||
L.stuttering = max(L.stuttering, stun_power)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, L)
|
||||
s.start()
|
||||
|
||||
if(prob(stun_power * 10) && stun_power >= 8)
|
||||
L.adjustFireLoss(power_charge * rand(1, 2))
|
||||
return FALSE
|
||||
|
||||
else if(prob(20)) // Try to do a regular disarm attack.
|
||||
L.visible_message(
|
||||
span_danger("\The [src] has pounced at \the [L]!"),
|
||||
span_danger("\The [src] has pounced at you!")
|
||||
)
|
||||
playsound(src, 'sound/weapons/thudswoosh.ogg', 75, 1)
|
||||
L.Weaken(2)
|
||||
do_attack_animation(L)
|
||||
if(L.buckled)
|
||||
L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents metroids from jumping on you.
|
||||
return FALSE
|
||||
|
||||
else // Failed to do anything this time.
|
||||
L.visible_message(
|
||||
span_warning("\The [src] has tried to pounce at \the [L]!"),
|
||||
span_warning("\The [src] has tried to pounce at you!")
|
||||
)
|
||||
playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
|
||||
do_attack_animation(L)
|
||||
return FALSE
|
||||
|
||||
if(I_GRAB)
|
||||
start_consuming(L)
|
||||
return FALSE
|
||||
|
||||
if(I_HURT)
|
||||
return ..() // Regular stuff.
|
||||
else
|
||||
return ..() // Do the regular stuff if we're hitting a window/mech/etc.
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/apply_melee_effects(mob/living/L)
|
||||
if(istype(L) && a_intent == I_HURT)
|
||||
// Feed off of their flesh, if able.
|
||||
consume(L, 5)
|
||||
|
||||
//Code to remove metroid from someone
|
||||
/mob/living/simple_mob/metroid/juvenile/attack_hand(mob/living/L)
|
||||
if(victim) // Are we eating someone?
|
||||
var/fail_odds = 30
|
||||
if(victim == L) // Harder to get the metroid off if it's you that is being eatten.
|
||||
fail_odds = 60
|
||||
|
||||
if(prob(fail_odds))
|
||||
visible_message(span_warning("\The [L] attempts to wrestle \the [name] off!"))
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
|
||||
else
|
||||
visible_message(span_warning("\The [L] manages to wrestle \the [name] off!"))
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
stop_consumption()
|
||||
step_away(src, L)
|
||||
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
//Objects related to the Metroids.
|
||||
*/
|
||||
|
||||
//Projectile for the Metroids.
|
||||
/obj/item/projectile/energy/metroidacid
|
||||
name = "metroid acid"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 10
|
||||
damage_type = TOX
|
||||
agony = 10
|
||||
check_armour = "bio"
|
||||
armor_penetration = 50
|
||||
|
||||
//EGG! Metroid egg and its mechanics. Ripped from spiders.
|
||||
/obj/effect/metroid/egg
|
||||
name = "egg cluster"
|
||||
desc = "It seems to pulse slightly with an inner life"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_state = "egg"
|
||||
var/amount_grown = 0
|
||||
var/metroid_type = /mob/living/simple_mob/metroid/juvenile/baby
|
||||
|
||||
/obj/effect/metroid/egg/Initialize()
|
||||
pixel_x = rand(3,-3)
|
||||
pixel_y = rand(3,-3)
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/metroid/egg/New(var/location, var/atom/parent)
|
||||
get_light_and_color(parent)
|
||||
..()
|
||||
|
||||
/obj/effect/metroid/egg/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/metroid/egg/process()
|
||||
amount_grown += rand(0,2)
|
||||
if(amount_grown >= 100)
|
||||
new metroid_type(src.loc, src)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,669 @@
|
||||
GLOBAL_VAR_INIT(queen_amount, 0) //We only gonna want 1 queen in the world.
|
||||
|
||||
/*
|
||||
//All the REAL types of metroids!
|
||||
*/
|
||||
//Remember to add vent crawling at some point.
|
||||
|
||||
/mob/living/simple_mob/metroid/jellybrig //Security's pet
|
||||
name = "Jellybrig"
|
||||
desc = "This one scree's happily at you."
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/jellybrig //Instead of normal metroid code, this guy is basically a retaliatory punching bag.
|
||||
say_list_type = /datum/say_list/metroid
|
||||
faction = "notmetroid"
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
movement_cooldown = 6
|
||||
harm_intent_damage = 2
|
||||
armor = list(
|
||||
"melee" = 50,
|
||||
"bullet" = -90,
|
||||
"laser" = 0,
|
||||
"energy" = -50,
|
||||
"bomb" = -100,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
vore_active = 1
|
||||
vore_bump_chance = 25
|
||||
vore_capacity = 1
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 90 //Don't punch or grab this guy. He will grab you instead!
|
||||
swallowTime = 1 SECONDS //Hungry little bastards.
|
||||
vore_default_mode = DM_HOLD
|
||||
vore_digest_chance = 1 //Chance to switch to digest mode if resisted
|
||||
vore_absorb_chance = 0
|
||||
vore_escape_chance = 2 //Chance to escape if resisted.
|
||||
|
||||
/datum/ai_holder/simple_mob/jellybrig
|
||||
hostile = FALSE // The majority of simplemobs are hostile, jellybrig is nice.
|
||||
cooperative = FALSE
|
||||
retaliate = TRUE //so the monster can attack back
|
||||
returns_home = FALSE
|
||||
can_flee = FALSE
|
||||
wander = TRUE
|
||||
base_wander_delay = 9
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/mine
|
||||
name = "Mochtroid"
|
||||
desc = "Some sort of person eaty thing! But weak compared to regular Metroids!"
|
||||
tt_desc = "Headamus Suckumus Weakamus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_dead = "metroid_dead"
|
||||
icon_living = "mochtroid"
|
||||
icon_state = "mochtroid"
|
||||
movement_cooldown = 2
|
||||
next = null
|
||||
|
||||
vore_active = 1
|
||||
vore_pounce_chance = 25
|
||||
vore_icons = SA_ICON_LIVING
|
||||
|
||||
/mob/living/simple_mob/metroid/mine/init_vore()
|
||||
if(!voremob_loaded)
|
||||
return
|
||||
.=..()
|
||||
var/obj/belly/B = vore_selected
|
||||
B.digest_burn = 0.5
|
||||
B.digest_brute = 0
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/mine/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 50, 1)
|
||||
..()
|
||||
if(prob(20))
|
||||
visible_message(span_notice("\The [src] dropped some toy!"))
|
||||
new /obj/item/toy/figure/bounty_hunter(loc, src)
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile
|
||||
var/is_juvenile = FALSE
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/baby
|
||||
name = "baby metroid"
|
||||
desc = "The baby the baby the baby the baby the baby the baby the baby the baby."
|
||||
tt_desc = "Minimus Headamus Suckumus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_dead = "baby_dead"
|
||||
icon_living = "baby"
|
||||
icon_state = "baby"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 5
|
||||
melee_miss_chance = 0
|
||||
armor = list(
|
||||
"melee" = 0,
|
||||
"bullet" = -60,
|
||||
"laser" = 60,
|
||||
"energy" = 10,
|
||||
"bomb" = -100,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
|
||||
//Metroids aren't affected by most atmospheres except cold.
|
||||
minbodytemp = T0C-40
|
||||
cold_damage_per_tick = 100
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
|
||||
|
||||
|
||||
response_help = "pets"
|
||||
|
||||
evo_point = 800
|
||||
evo_limit = 1000
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/super"
|
||||
vore_active = 0
|
||||
|
||||
is_juvenile = TRUE
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/baby/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1)
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/super
|
||||
name = "super metroid"
|
||||
desc = "Some kind of head sucky thing!"
|
||||
tt_desc = "Maximus Headamus Suckumus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_dead = "metroid_dead"
|
||||
icon_living = "metroid"
|
||||
icon_state = "metroid"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid
|
||||
health = 250
|
||||
maxHealth = 250
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 9
|
||||
melee_miss_chance = 0
|
||||
armor = list(
|
||||
"melee" = 0,
|
||||
"bullet" = -50,
|
||||
"laser" = 70,
|
||||
"energy" = 10,
|
||||
"bomb" = -100,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
|
||||
//Metroids aren't affected by most atmospheres except cold.
|
||||
minbodytemp = T0C-40
|
||||
cold_damage_per_tick = 100
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
|
||||
response_help = "pets"
|
||||
|
||||
speak_emote = list(
|
||||
"Skree...",
|
||||
"Ereeeer..."
|
||||
)
|
||||
|
||||
evo_point = 1200
|
||||
evo_limit = 1600
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/alpha"
|
||||
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 1
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 25 //Metroids only eat incapacitated targets
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 1 SECONDS //Hungry little bastards.
|
||||
vore_escape_chance = 50
|
||||
|
||||
is_juvenile = TRUE
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/super/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/super/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/alpha
|
||||
name = "alpha metroid"
|
||||
desc = "Some kind of head rammy thing!"
|
||||
tt_desc = "Minimus Headamus Rammamus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_dead = "alpha_dead"
|
||||
icon_living = "alpha"
|
||||
icon_state = "alpha"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid
|
||||
health = 300
|
||||
maxHealth = 300
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
melee_miss_chance = 5
|
||||
attacktext = list("rammed")
|
||||
armor = list(
|
||||
"melee" = 40,
|
||||
"bullet" = 15,
|
||||
"laser" = 50,
|
||||
"energy" = 60,
|
||||
"bomb" = 10,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
|
||||
//Alphas lose their vulnerability to cold.
|
||||
minbodytemp = 0
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
evo_point = 1000
|
||||
evo_limit = 1500
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/gamma"
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/alpha/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/alpha/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/alpha //active noms
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 1
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 15 //Alphas will try knocking targets over since they lost their stun ability from the initial phases.
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 3 SECONDS
|
||||
vore_escape_chance = 40
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma
|
||||
name = "gamma metroid"
|
||||
desc = "Some kind of head rammy thing! This one shoots electricity!"
|
||||
tt_desc = "Maximus Headamus Rammamus"
|
||||
icon = 'icons/mob/metroid/small.dmi'
|
||||
icon_dead = "gamma_dead"
|
||||
icon_living = "gamma"
|
||||
icon_state = "gamma"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid
|
||||
movement_cooldown = 2
|
||||
health = 400
|
||||
maxHealth = 400
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 20
|
||||
melee_miss_chance = 5
|
||||
attacktext = list("rammed")
|
||||
armor = list(
|
||||
"melee" = 55,
|
||||
"bullet" = 15,
|
||||
"laser" = 50,
|
||||
"energy" = 90,
|
||||
"bomb" = 10,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
ranged_cooldown_time = 5 SECOND
|
||||
projectilesound = 'sound/weapons/taser2.ogg'
|
||||
projectiletype = /obj/item/projectile/energy/mob/electric_spider
|
||||
|
||||
//Not affected by atmos.
|
||||
minbodytemp = 0
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
var/emp_chance = 20 // Beware synths
|
||||
evo_point = 1000
|
||||
evo_limit = 1500
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/zeta"
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidgamma.ogg', 100, 1)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/gamma //active noms
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 1
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 15
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 3 SECONDS
|
||||
vore_escape_chance = 30
|
||||
|
||||
|
||||
/datum/say_list/metroid
|
||||
speak = list("Skree.", "Eree.", "Errer?")
|
||||
emote_see = list("floats about","looks around", "rubs its talons")
|
||||
emote_hear = list("chitters")
|
||||
|
||||
say_understood = list("Eree.")
|
||||
say_cannot = list("Errerr.")
|
||||
say_maybe_target = list("Eree?")
|
||||
say_got_target = list("Ereet!")
|
||||
say_threaten = list("Skree!")
|
||||
say_stand_down = list("Eee.")
|
||||
say_escalate = list("SKREE!")
|
||||
|
||||
threaten_sound = 'sound/metroid/metroidsee.ogg'
|
||||
stand_down_sound = 'sound/metroid/metroiddetach.ogg'
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/zeta
|
||||
name = "zeta metroid"
|
||||
desc = "Some kind of feet stompy thing!"
|
||||
tt_desc = "Minimus Feetamus Walkamus"
|
||||
icon = 'icons/mob/metroid/large.dmi'
|
||||
icon_dead = "zeta_dead"
|
||||
icon_living = "zeta"
|
||||
icon_state = "zeta"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid/zeta
|
||||
movement_cooldown = 2
|
||||
health = 500
|
||||
maxHealth = 500
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 25
|
||||
melee_miss_chance = 5
|
||||
ranged_cooldown_time = 5 SECOND
|
||||
attack_armor_pen = 10
|
||||
attacktext = list("slashed")
|
||||
armor = list(
|
||||
"melee" = 70,
|
||||
"bullet" = 0,
|
||||
"laser" = 50,
|
||||
"energy" = 60,
|
||||
"bomb" = 10,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
|
||||
makes_dirt = TRUE
|
||||
|
||||
projectiletype = /obj/item/projectile/energy/metroidacid //The projectiles I shoot
|
||||
projectilesound = 'sound/weapons/slashmiss.ogg' // The sound I make when I do it
|
||||
|
||||
|
||||
//Unaffected by atmos.
|
||||
minbodytemp = 0
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
pixel_x = -16
|
||||
pixel_y = -16
|
||||
old_x = -16
|
||||
old_y = -16
|
||||
evo_point = 1200
|
||||
evo_limit = 1500
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/omega"
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/zeta/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidzeta.ogg', 100, 1)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/zeta/death()
|
||||
// playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/zeta //active noms
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 1
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 20
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 3 SECONDS
|
||||
vore_escape_chance = 20
|
||||
|
||||
/datum/say_list/metroid/zeta
|
||||
speak = list("Rurrr.", "Rrerr.", "Rawr?")
|
||||
emote_see = list("stomps about","looks around", "rubs its talons")
|
||||
emote_hear = list("chitters")
|
||||
|
||||
say_understood = list("Rur.")
|
||||
say_cannot = list("Errurr.")
|
||||
say_maybe_target = list("Erurr?")
|
||||
say_got_target = list("Eruur!")
|
||||
say_threaten = list("Rrurr!")
|
||||
say_stand_down = list("Eeer.")
|
||||
say_escalate = list("RAWR!")
|
||||
|
||||
threaten_sound = 'sound/metroid/metroidzeta.ogg'
|
||||
stand_down_sound = 'sound/metroid/metroiddetach.ogg'
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega
|
||||
name = "omega metroid"
|
||||
desc = "Those are some big claws!"
|
||||
tt_desc = "Maximus Feetamus Walkamus"
|
||||
icon = 'icons/mob/metroid/large.dmi'
|
||||
icon_dead = "omega_dead"
|
||||
icon_living = "omega"
|
||||
icon_state = "omega"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid/omega
|
||||
movement_cooldown = 2.5
|
||||
health = 600
|
||||
maxHealth = 600
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 40
|
||||
melee_miss_chance = 5
|
||||
ranged_cooldown_time = 2.5 SECOND
|
||||
attack_armor_pen = 20
|
||||
attacktext = list("slashed")
|
||||
armor = list(
|
||||
"melee" = 75,
|
||||
"bullet" = 20,
|
||||
"laser" = 55,
|
||||
"energy" = 60,
|
||||
"bomb" = 10,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
makes_dirt = TRUE
|
||||
projectiletype = /obj/item/projectile/energy/mob/smalllaser
|
||||
projectilesound = 'sound/weapons/Flamer.ogg' // The sound I make when I do it
|
||||
|
||||
//Unaffected by atmos.
|
||||
minbodytemp = 0
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
|
||||
|
||||
old_x = -16
|
||||
old_y = 0
|
||||
default_pixel_x = -16
|
||||
pixel_x = -16
|
||||
pixel_y = 0
|
||||
evo_point = 1300
|
||||
evo_limit = 2000
|
||||
next = "/mob/living/simple_mob/metroid/juvenile/queen"
|
||||
|
||||
death_sound_override = list('sound/metroid/metroidomegadeath.ogg') // We override the death sound to play our custom here
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidomega.ogg', 100, 1)
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega/death()
|
||||
// playsound(src, 'sound/metroid/metroidomegadeath.ogg', 100, 1)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/omega //active noms
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 2
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 40
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 3 SECONDS
|
||||
vore_escape_chance = 10
|
||||
|
||||
/datum/say_list/metroid/omega
|
||||
speak = list("Rurrr.", "Rrerr.", "Rawr?")
|
||||
emote_see = list("stomps about","looks around", "rubs its talons")
|
||||
emote_hear = list("chitters")
|
||||
|
||||
say_understood = list("Rur.")
|
||||
say_cannot = list("Errurr.")
|
||||
say_maybe_target = list("Erurr?")
|
||||
say_got_target = list("Roar!")
|
||||
say_threaten = list("Rrurr!")
|
||||
say_stand_down = list("Eeer.")
|
||||
say_escalate = list("ROAR!")
|
||||
|
||||
threaten_sound = 'sound/metroid/metroidomega.ogg'
|
||||
stand_down_sound = 'sound/metroid/metroiddetach.ogg'
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/queen
|
||||
name = "queen metroid"
|
||||
desc = "The mother of all Metroids - allowed to have grown too far!"
|
||||
tt_desc = "Maximus Queenamus Deathamus"
|
||||
icon = 'icons/mob/metroid/queen.dmi'
|
||||
icon_dead = "queen_dead"
|
||||
icon_living = "queen"
|
||||
icon_state = "queen"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/juvenile_metroid
|
||||
say_list_type = /datum/say_list/metroid/queen
|
||||
movement_cooldown = 3
|
||||
health = 1000
|
||||
maxHealth = 1000
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 60
|
||||
melee_miss_chance = 5
|
||||
attack_armor_pen = 20
|
||||
attacktext = list("gnashed")
|
||||
armor = list(
|
||||
"melee" = 75,
|
||||
"bullet" = 40,
|
||||
"laser" = 60,
|
||||
"energy" = 90,
|
||||
"bomb" = 10,
|
||||
"bio" = 100,
|
||||
"rad" = 100)
|
||||
gender = NEUTER
|
||||
faction = "metroids"
|
||||
max_nutrition = 2200
|
||||
nutrition = 0
|
||||
makes_dirt = TRUE
|
||||
ranged_cooldown_time = 1.5 SECOND
|
||||
projectiletype = /obj/item/projectile/energy/metroidacid // The projectiles I shoot
|
||||
projectilesound = 'sound/weapons/slashmiss.ogg' // The sound I make when I do it
|
||||
|
||||
//Unaffected by atmos.
|
||||
minbodytemp = 0
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 0
|
||||
|
||||
pixel_x = -16
|
||||
pixel_y = -16
|
||||
old_x = -16
|
||||
old_y = -16
|
||||
evo_point = 1200
|
||||
evo_limit = INFINITY
|
||||
next = null
|
||||
is_queen = TRUE
|
||||
|
||||
death_sound_override = list('sound/metroid/metroidqueendeath.ogg') // We override the death sound to play our custom here
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/queen/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(src, 'sound/metroid/metroidqueen.ogg', 100, 1)
|
||||
GLOB.queen_amount++
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/queen/death()
|
||||
// playsound(src, 'sound/metroid/metroidqueendeath.ogg', 100, 1)
|
||||
GLOB.queen_amount--
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/metroid/juvenile/queen //active noms
|
||||
vore_active = 1
|
||||
vore_bump_chance = 0
|
||||
vore_capacity = 4
|
||||
vore_icons = SA_ICON_LIVING
|
||||
vore_pounce_chance = 60 //It's the queen, and it's hungry.
|
||||
vore_default_mode = DM_DIGEST
|
||||
swallowTime = 3 SECONDS
|
||||
vore_escape_chance = 0 //You're not climbing out of that neck
|
||||
|
||||
/datum/say_list/metroid/queen
|
||||
speak = list("Rurrr.", "Rrerr.", "Rawr?")
|
||||
emote_see = list("stomps about","looks around", "rubs its talons")
|
||||
emote_hear = list("chitters")
|
||||
|
||||
say_understood = list("Rur.")
|
||||
say_cannot = list("Errurr.")
|
||||
say_maybe_target = list("Erurr?")
|
||||
say_got_target = list("Roar!")
|
||||
say_threaten = list("Rrurr!")
|
||||
say_stand_down = list("Eeer.")
|
||||
say_escalate = list("ROAR!")
|
||||
|
||||
threaten_sound = 'sound/metroid/metroidqueen.ogg'
|
||||
stand_down_sound = 'sound/metroid/metroiddetach.ogg'
|
||||
@@ -0,0 +1,325 @@
|
||||
#define NUTRITION_FRUIT 250 //The amount of nutrition needed to produce a fruit
|
||||
#define NUTRITION_PITCHER 3 * NUTRITION_FRUIT //The amount of nutrition needed to produce a new pitcher
|
||||
#define NUTRITION_MEAT 50 //The amount of nutrition provided by slabs of meat
|
||||
#define PITCHER_SATED 250 //The amount of nutrition needed before the pitcher will attempt to grow fruit.
|
||||
#define PITCHER_HUNGRY 150 //The nutrition cap under which the pitcher actively attempts to lure prey.
|
||||
|
||||
GLOBAL_LIST_INIT(pitcher_plant_lure_messages, list(
|
||||
"The pitcher plant smells lovely, beckoning you closer.",
|
||||
"The sweet scent wafting from the pitcher plant makes your mouth water.",
|
||||
"You feel an urge to investigate the pitcher plant closely.",
|
||||
"You find yourself staring at the pitcher plant without really thinking about it.",
|
||||
"Doesn't the pitcher plant smell amazing?")) //Messages sent to nearby players if the pitcher is trying to lure prey. This is global to prevent a new list every time a new pitcher plant spawns.
|
||||
|
||||
//Pitcher plants, a passive carnivorous plant mob for xenobio and space vine spawning.
|
||||
//Consider making immune to space vine entangling. Check entangle_immunity in the old CHOMPstation github for an example.
|
||||
/mob/living/simple_mob/vore/pitcher_plant
|
||||
name = "pitcher plant"
|
||||
desc = "A carnivorous pitcher plant, bigger than a man."
|
||||
tt_desc = "Sarraceniaceae gigantus"
|
||||
|
||||
icon_state = "pitcher_plant"
|
||||
icon_living = "pitcher_plant"
|
||||
icon_dead = "pitcher_plant_dead"
|
||||
icon = 'modular_chomp/icons/mob/vore_ch.dmi'
|
||||
|
||||
anchored = 1 //Rooted plant. Only killing it will let you move it.
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
a_intent = I_HELP //White this is help by default I'm leaving this here as a reminder thatdisarm will prevent playersfrom swapping places with the pitcher (but interfere with vore bump).
|
||||
faction = "plants" //Makes plantbgone deadly.
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/passive/pitcher //It's a passive carnivorous plant, it can't detect or interact with people.
|
||||
|
||||
min_oxy = 0 //Immune to atmos because so are space vines. This is arbitrary and can be tweaked if desired.
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
|
||||
melee_damage_upper = 0 //This shouldn't attack people but if it does (admemes) no damage can be dealt.
|
||||
melee_damage_lower = 0
|
||||
|
||||
armor = list(
|
||||
"melee" = 0,
|
||||
"bullet" = 0,
|
||||
"laser" = -50,
|
||||
"energy" = 0,
|
||||
"bomb" = 0,
|
||||
"bio" = 0,
|
||||
"rad" = 100)
|
||||
|
||||
var/fruit = FALSE //Has the pitcher produced a fruit?
|
||||
var/meat = 0 //How many units of meat is the plant digesting? Separate from actual vore mechanics.
|
||||
var/meatspeed = 5 //How many units of meat is converted to nutrition each tick?
|
||||
var/pitcher_metabolism = 0.1 //How much nutriment does the pitcher lose every 2 seconds? 0.1 should be around 30 every 10 minutes.
|
||||
var/scent_strength = 5 //How much can a hungry pitcher confuse nearby people?
|
||||
var/last_lifechecks = 0 //Timing variable to limit vore/hungry proc calls
|
||||
var/list/pitcher_plant_lure_messages = null
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant //Putting vore variables separately because apparently that's tradition.
|
||||
vore_bump_chance = 100
|
||||
vore_bump_emote = "slurps up" //Not really a good way to make the grammar work with a passive vore plant.
|
||||
vore_active = 1
|
||||
vore_icons = 1
|
||||
vore_capacity = 1
|
||||
vore_pounce_chance = 0 //Plants only eat people who stumble into them.
|
||||
swallowTime = 3 //3 deciseconds. This is intended to be nearly instant, e.g. victim trips and falls in.
|
||||
vore_ignores_undigestable = 0
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/init_vore()
|
||||
if(!voremob_loaded)
|
||||
return
|
||||
.=..()
|
||||
var/obj/belly/B = vore_selected
|
||||
B.desc = "You leaned a little too close to the pitcher plant, stumbling over the lip and splashing into a puddle of liquid filling the bottom of the cramped pitcher. You squirm madly, righting yourself and scrabbling at the walls in vain as the slick surface offers no purchase. The dim light grows dark as the pitcher's cap lowers, silently sealing the exit. With a sinking feeling you realize you won't be able to push the exit open even if you could somehow climb that high, leaving you helplessly trapped in the slick, tingling fluid. ((You can't escape this mob without help but you may use OOC Escape if you wish.))"
|
||||
B.digest_burn = 0.5
|
||||
B.digest_brute = 0
|
||||
B.vore_verb = "trip"
|
||||
B.name = "pitcher"
|
||||
B.mode_flags = DM_FLAG_THICKBELLY
|
||||
B.wet_loop = 0 //As nice as the fancy internal sounds are this is a plant.
|
||||
B.digestchance = 0
|
||||
B.escapechance = 0
|
||||
B.fancy_vore = 1
|
||||
B.vore_sound = "Squish2"
|
||||
B.release_sound = "Pred Escape"
|
||||
B.contamination_color = "purple"
|
||||
B.contamination_flavor = "Wet"
|
||||
//Why is it we have all these customizeable belly options which nobody ever alters for mobs?
|
||||
|
||||
B.emote_lists[DM_HOLD] = list(
|
||||
"Slick fluid trickles over you, carrying threads of sweetness.",
|
||||
"Everything is still, dark, and quiet. Your breaths echo quietly.",
|
||||
"The surrounding air feels thick and humid.")
|
||||
|
||||
B.emote_lists[DM_DIGEST] = list(
|
||||
"The slimy puddle stings faintly. It seems the plant has no need to quickly break down victims.",
|
||||
"The humid air settles in your lungs, keeping each breath more labored than the last.",
|
||||
"Fluid drips onto you, burning faintly as your body heat warms it."
|
||||
)
|
||||
|
||||
B.emote_lists[DM_DRAIN] = list(
|
||||
"Each bead of slick fluid running down your body leaves you feeling weaker.",
|
||||
"It's cramped and dark, the air thick and heavy. Your limbs feel like lead.",
|
||||
"Strength drains from your frame. The cramped chamber feels easier to settle into with each passing moment.")
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/Life()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
var/lastmeat = meat //If Life procs every 2 seconds that means it takes 20 seconds to digest a steak
|
||||
meat = max(0,meat - meatspeed) //Clamp it to zero
|
||||
adjust_nutrition(lastmeat - meat) //If there's no meat, this will just be zero.
|
||||
if(nutrition >= PITCHER_SATED + NUTRITION_FRUIT)
|
||||
if(prob(10)) //Should be about once every 20 seconds.
|
||||
grow_fruit()
|
||||
var/lastnutrition = nutrition
|
||||
adjust_nutrition(-pitcher_metabolism)
|
||||
adjustBruteLoss(nutrition - lastnutrition)
|
||||
adjustToxLoss((nutrition - lastnutrition) * 3)
|
||||
if(nutrition < pitcher_metabolism)
|
||||
adjustToxLoss(pitcher_metabolism)
|
||||
if(world.time > last_lifechecks + 30 SECONDS)
|
||||
last_lifechecks = world.time
|
||||
vore_checks()
|
||||
handle_hungry()
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/Initialize(mapload)
|
||||
. = ..()
|
||||
pitcher_plant_lure_messages = GLOB.pitcher_plant_lure_messages
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/death()
|
||||
..()
|
||||
anchored = 0
|
||||
if(fruit)
|
||||
new /obj/item/reagent_containers/food/snacks/pitcher_fruit(get_turf(src))
|
||||
fruit = FALSE
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/proc/grow_fruit() //This proc handles the pitcher turning nutrition into fruit (and new pitchers).
|
||||
if(!fruit)
|
||||
if(nutrition >= PITCHER_SATED + NUTRITION_FRUIT)
|
||||
fruit = TRUE
|
||||
adjust_nutrition(-NUTRITION_FRUIT)
|
||||
return
|
||||
else
|
||||
return
|
||||
if(fruit)
|
||||
if(nutrition >= PITCHER_SATED + NUTRITION_PITCHER)
|
||||
var/turf/T = safepick(circleviewturfs(src, 2))
|
||||
if(T.density) //No spawning in walls
|
||||
return
|
||||
else if(src.loc ==T)
|
||||
return
|
||||
else
|
||||
new /mob/living/simple_mob/vore/pitcher_plant(get_turf(T))
|
||||
fruit = FALSE //No admeming this to spawn endless pitchers.
|
||||
adjust_nutrition(-NUTRITION_PITCHER)
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/attack_hand(mob/living/user)
|
||||
if(user.a_intent == I_HELP)
|
||||
if(fruit)
|
||||
to_chat(user, "You pick a fruit from \the [src].")
|
||||
var/obj/F = new /obj/item/reagent_containers/food/snacks/pitcher_fruit(get_turf(user)) //Drops at the user's feet if put_in_hands fails
|
||||
fruit = FALSE
|
||||
user.put_in_hands(F)
|
||||
else
|
||||
to_chat(user, "The [src] hasn't grown any fruit yet!")
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/examine(mob/user)
|
||||
. = ..()
|
||||
if(fruit)
|
||||
. += "A plump fruit glistens beneath \the [src]'s cap."
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/attackby(obj/item/O, mob/user)
|
||||
if(istype(O, /obj/item/reagent_containers/food/snacks/meat))
|
||||
if(meat > NUTRITION_FRUIT - NUTRITION_MEAT) //Can't exceed 250
|
||||
to_chat(user, "The [src] is full!")
|
||||
return
|
||||
else
|
||||
meat += NUTRITION_MEAT
|
||||
qdel(O)
|
||||
return
|
||||
if(istype(O, /obj/item/stack/cable_coil)) //How to free people without killing the pitcher. I guess cable is ss13 rope.
|
||||
var/mob/living/carbon/human/H
|
||||
var/N = 0
|
||||
for(H in vore_selected.contents) //Only works for carbons, RIP mice. Should pick the first human the code finds.
|
||||
user.visible_message("[user] tries to fish somebody out of \the [src].", "You try to snag somebody trapped in \the [src]...")
|
||||
if(do_after(user, rand(3 SECONDS, 7 SECONDS))) //You can just spam click to stack attempts if you feel like abusing it.
|
||||
if(prob(15))
|
||||
user.visible_message("[user] tugs a sticky [H] free from \the [src].", "You heft [H] free from \the [src].")
|
||||
LAZYSET(prey_excludes, H, world.time)
|
||||
vore_selected.release_specific_contents(H)
|
||||
N = 1
|
||||
addtimer(CALLBACK(src, PROC_REF(removeMobFromPreyExcludes), WEAKREF(H)), 1 MINUTES)
|
||||
break
|
||||
else
|
||||
to_chat(user, "The victim slips from your grasp!")
|
||||
N = 1
|
||||
break //We need to terminate the loop after each outcome or this could loop through multiple bellies. Of course, there should only be one belly.
|
||||
if(!N)
|
||||
to_chat(user, "The pitcher is empty.")
|
||||
if(istype(O, /obj/item/newspaper))
|
||||
return //Can't newspaper people to freedom.
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/proc/vore_checks()
|
||||
if(ckey) //This isn't intended to be a playable mob but skip all of this if it's player-controlled.
|
||||
return
|
||||
if(vore_selected && vore_selected.contents.len) //Looping through all (potential) vore bellies would be more thorough but probably not worth the processing power if this check happens every 30 seconds.
|
||||
var/mob/living/L
|
||||
var/N = 0
|
||||
var/hasdigestable = 0
|
||||
var/hasindigestable = 0
|
||||
for(L in vore_selected.contents)
|
||||
if(istype(L, /mob/living/carbon/human/monkey))
|
||||
L.nutrition = 0 //No stuffing monkeys with protein shakes for massive nutrition.
|
||||
if(!L.digestable)
|
||||
vore_selected.digest_mode = DM_DRAIN
|
||||
N = 1
|
||||
hasindigestable = 1
|
||||
continue
|
||||
else
|
||||
vore_selected.digest_mode = DM_DIGEST
|
||||
N = 1
|
||||
hasdigestable = 1
|
||||
continue
|
||||
if(hasdigestable && hasindigestable)
|
||||
vore_selected.digest_mode = DM_DIGEST //Let's digest until we digest all the digestable prey, then move onto draining indigestable prey.
|
||||
if(!N)
|
||||
vore_selected.release_all_contents() //If there's no prey, spit out everything.
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/pitcher_plant/proc/handle_hungry() //Let's run this check every 30 seconds. This is how a hungry pitcher tries to lure prey.
|
||||
if(nutrition <= PITCHER_HUNGRY) //Is sanity check another way to say redundancy?
|
||||
var/turf/T = get_turf(src)
|
||||
var/cardinal_turfs = T.CardinalTurfs()
|
||||
|
||||
for(var/mob/living/carbon/human/H in oview(2, src))
|
||||
if(!istype(H) || !isliving(H) || H.stat == DEAD) //Living mobs only
|
||||
continue
|
||||
if(isSynthetic(H) || !H.species.breath_type || H.internal) //Exclude species which don't breathe or have internals.
|
||||
continue
|
||||
if(src.Adjacent(H)) //If they can breathe and are next to the pitcher, confuse them.
|
||||
to_chat(H,span_red("The sweet, overwhelming scent from \the [src] makes your senses reel!"))
|
||||
H.Confuse(scent_strength)
|
||||
continue
|
||||
else
|
||||
to_chat(H, span_red("[pick(pitcher_plant_lure_messages)]"))
|
||||
|
||||
for(var/turf/simulated/TR in cardinal_turfs)
|
||||
TR.wet_floor(1) //Same effect as water. Slip into plant, get ate.
|
||||
else
|
||||
return
|
||||
/mob/living/simple_mob/vore/pitcher_plant/Crossed(atom/movable/AM as mob|obj) //Yay slipnoms
|
||||
if(AM.is_incorporeal())
|
||||
return
|
||||
if(istype(AM, /mob/living) && will_eat(AM) && !istype(AM, type) && prob(vore_bump_chance) && !ckey)
|
||||
animal_nom(AM)
|
||||
..()
|
||||
|
||||
/datum/ai_holder/simple_mob/passive/pitcher
|
||||
wander = 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pitcher_fruit //As much as I want to tie hydroponics harvest code to the mob, this is simpler (albeit kinda hacky).
|
||||
name = "squishy fruit"
|
||||
desc = "A tender, fleshy fruit with a thin skin."
|
||||
icon = 'icons/obj/hydroponics_products.dmi'
|
||||
icon_state = "treefruit-product"
|
||||
color = "#a839a2"
|
||||
trash = /obj/item/seeds/pitcherseed
|
||||
nutriment_amt = 1
|
||||
nutriment_desc = list("pineapple" = 1)
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/datum/seed/seed = null
|
||||
var/obj/item/seeds/pit = null
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pitcher_fruit/Initialize(mapload)
|
||||
. = ..()
|
||||
reagents.add_reagent(REAGENT_ID_PITCHERNECTAR, 5)
|
||||
bitesize = 4
|
||||
pit = new /obj/item/seeds/pitcherseed(src.contents)
|
||||
seed = pit.seed
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pitcher_fruit/afterattack(obj/O as obj, mob/user as mob, proximity)
|
||||
if(istype(O,/obj/machinery/microwave))
|
||||
return ..()
|
||||
if(istype (O, /obj/machinery/seed_extractor))
|
||||
pit.loc = O.loc //1 seed, perhaps balanced because you can get the reagents and the seed. Can be increased if desirable.
|
||||
qdel(src)
|
||||
if(!(proximity && O.is_open_container()))
|
||||
return
|
||||
to_chat(user, span_notice("You squeeze \the [src], juicing it into \the [O]."))
|
||||
reagents.trans_to(O, reagents.total_volume)
|
||||
user.drop_from_inventory(src)
|
||||
pit.loc = user.loc
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pitcher_fruit/attack_self(mob/user)
|
||||
to_chat(user, span_notice("You plant the fruit."))
|
||||
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed)
|
||||
GLOB.seed_planted_shift_roundstat++
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
#undef NUTRITION_FRUIT
|
||||
#undef NUTRITION_PITCHER
|
||||
#undef NUTRITION_MEAT
|
||||
#undef PITCHER_SATED
|
||||
#undef PITCHER_HUNGRY
|
||||
@@ -50,7 +50,7 @@ GLOBAL_VAR_INIT(dynamic_sector_master, null)
|
||||
shuttle_landmarks[i] = spawn_directions
|
||||
generated_z = TRUE
|
||||
|
||||
/obj/effect/overmap/visitable/dynamic/Initialize()
|
||||
/obj/effect/overmap/visitable/dynamic/Initialize(mapload)
|
||||
if(!GLOB.dynamic_sector_master)
|
||||
GLOB.dynamic_sector_master = src
|
||||
. = ..()
|
||||
@@ -141,7 +141,7 @@ GLOBAL_VAR_INIT(dynamic_sector_master, null)
|
||||
var/loaded = FALSE
|
||||
var/my_index = 0 // Tracks which z-level we're using in the parent. Corresponds to index in parent's active_pois[]
|
||||
|
||||
/obj/effect/overmap/visitable/dynamic/poi/Initialize()
|
||||
/obj/effect/overmap/visitable/dynamic/poi/Initialize(mapload)
|
||||
if(!global.using_map.use_overmap)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user