[MIRROR] [READY] Vatgrowing: Third time's the charm (#508)

* Merge pull request #53020 from Qustinnus/fatgrowing

[READY] Vatgrowing: Third time's the charm

* [READY] Vatgrowing: Third time's the charm

Co-authored-by: 81Denton <32391752+81Denton@users.noreply.github.com>
This commit is contained in:
SkyratBot
2020-08-25 01:36:10 +02:00
committed by GitHub
co-authored by 81Denton
parent f733bc21a8
commit 7bbe8ec530
98 changed files with 3070 additions and 792 deletions
@@ -46,6 +46,10 @@
/mob/living/simple_animal/pet/cat/Initialize()
. = ..()
verbs += /mob/living/proc/lay_down
add_cell_sample()
/mob/living/simple_animal/pet/cat/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CAT, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/pet/cat/update_mobility()
..()
@@ -80,6 +84,8 @@
unique_pet = TRUE
held_state = "original"
/mob/living/simple_animal/pet/cat/original/add_cell_sample()
return
/mob/living/simple_animal/pet/cat/kitten
name = "kitten"
desc = "D'aaawwww."
@@ -261,6 +267,9 @@
deathsound = "bodyfall"
held_state = "cak"
/mob/living/simple_animal/pet/cat/cak/add_cell_sample()
return
/mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts)
..()
var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
@@ -24,6 +24,10 @@
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/pet/dog/Initialize()
. = ..()
add_cell_sample()
/mob/living/simple_animal/pet/dog/Life()
..()
@@ -98,6 +102,9 @@
var/shaved = FALSE
var/nofur = FALSE //Corgis that have risen past the material plane of existence.
/mob/living/simple_animal/pet/dog/corgi/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CORGI, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/pet/dog/corgi/Destroy()
QDEL_NULL(inventory_head)
QDEL_NULL(inventory_back)
@@ -128,6 +135,9 @@
collar_type = "pug"
held_state = "pug"
/mob/living/simple_animal/pet/dog/pug/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_PUG, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/pet/dog/pug/mcgriff
name = "McGriff"
desc = "This dog can tell someting smells around here, and that something is CRIME!"
@@ -149,8 +149,12 @@
/mob/living/simple_animal/cow/Initialize()
udder = new()
add_cell_sample()
. = ..()
/mob/living/simple_animal/cow/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_COW, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/cow/Destroy()
qdel(udder)
udder = null
@@ -274,6 +278,10 @@
. = ..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
add_cell_sample()
/mob/living/simple_animal/chick/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/chick/Life()
. =..()
@@ -342,6 +350,10 @@
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
++chicken_count
add_cell_sample()
/mob/living/simple_animal/chicken/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/chicken/Destroy()
--chicken_count
@@ -40,7 +40,10 @@
icon_state = "mouse_[body_color]"
icon_living = "mouse_[body_color]"
icon_dead = "mouse_[body_color]_dead"
add_cell_sample()
/mob/living/simple_animal/mouse/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10)
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
@@ -177,6 +180,10 @@
foodtype = GROSS | MEAT | RAW
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/liquidgibs = 5)
/obj/item/reagent_containers/food/snacks/deadmouse/Initialize()
. = ..()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10)
/obj/item/reagent_containers/food/snacks/deadmouse/examine(mob/user)
. = ..()
if (reagents?.has_reagent(/datum/reagent/yuck) || reagents?.has_reagent(/datum/reagent/fuel))
@@ -39,6 +39,12 @@
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
/mob/living/simple_animal/hostile/retaliate/poison/snake/Initialize()
. = ..()
add_cell_sample()
/mob/living/simple_animal/hostile/retaliate/poison/snake/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_SNAKE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/hostile/retaliate/poison/snake/ListTargets(atom/the_target)
. = oview(vision_range, targets_from) //get list of things in vision range
@@ -51,6 +51,10 @@
/mob/living/simple_animal/hostile/bear/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
add_cell_sample()
/mob/living/simple_animal/hostile/bear/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_BEAR, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/hostile/bear/Life()
. = ..()
@@ -147,6 +151,9 @@
attack_sound = 'sound/weapons/slap.ogg'
attack_verb_continuous = "slaps"
/mob/living/simple_animal/hostile/bear/butter/add_cell_sample()
return //You cannot grow a real bear from butter.
/mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage.
if(stat)
return
@@ -74,6 +74,10 @@
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
carp_randomify(rarechance)
update_icons()
add_cell_sample()
/mob/living/simple_animal/hostile/carp/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CARP, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/hostile/carp/proc/carp_randomify(rarechance)
if(random_color)
@@ -163,6 +167,9 @@
tame_chance = 0
bonus_tame_chance = 0
/mob/living/simple_animal/hostile/carp/holocarp/add_cell_sample()
return
/mob/living/simple_animal/hostile/carp/megacarp
icon = 'icons/mob/broadMobs.dmi'
name = "Mega Space Carp"
@@ -195,6 +202,10 @@
melee_damage_upper += rand(10,20)
maxHealth += rand(30,60)
move_to_delay = rand(3,7)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MEGACARP, CELL_VIRUS_TABLE_GENERIC_MOB)
/mob/living/simple_animal/hostile/carp/megacarp/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MEGACARP, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/hostile/carp/megacarp/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
@@ -33,6 +33,13 @@
faction = list("neutral")
var/squish_chance = 50
/mob/living/simple_animal/hostile/cockroach/Initialize()
. = ..()
add_cell_sample()
/mob/living/simple_animal/hostile/cockroach/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_COCKROACH, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 7)
/obj/projectile/glockroachbullet
damage = 10 //same damage as a hivebot
damage_type = BRUTE
@@ -328,7 +328,7 @@
FindTarget()
/mob/living/simple_animal/hostile/proc/AttackingTarget()
/mob/living/simple_animal/hostile/proc/AttackingTarget(atom/attacked_target)
SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target)
in_melee = TRUE
return target.attack_animal(src)
@@ -0,0 +1,506 @@
///Oozes are slime-esque creatures, they are highly gluttonous creatures primarily intended for player controll.
/mob/living/simple_animal/hostile/ooze
name = "Ooze"
icon = 'icons/mob/vatgrowing.dmi'
icon_state = "gelatinous"
icon_dead = "gelatinous_dead"
mob_biotypes = MOB_ORGANIC
pass_flags = PASSTABLE | PASSGRILLE
ventcrawler = VENTCRAWLER_ALWAYS
gender = NEUTER
emote_see = list("jiggles", "bounces in place")
speak_emote = list("blorbles")
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
hud_type = /datum/hud/ooze
minbodytemp = 250
maxbodytemp = INFINITY
faction = list("slime")
melee_damage_lower = 10
melee_damage_upper = 10
health = 200
maxHealth = 200
attack_verb_continuous = "slimes"
attack_verb_simple = "slime"
attack_sound = 'sound/effects/blobattack.ogg'
a_intent = INTENT_HARM
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
mob_size = MOB_SIZE_LARGE
initial_language_holder = /datum/language_holder/slime
///Oozes have their own nutrition. Changes based on them eating
var/ooze_nutrition = 50
var/ooze_nutrition_loss = -0.15
var/ooze_metabolism_modifier = 2
/mob/living/simple_animal/hostile/ooze/Initialize()
. = ..()
create_reagents(300)
add_cell_sample()
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 7.5)
/mob/living/simple_animal/hostile/ooze/attacked_by(obj/item/I, mob/living/user)
if(!check_edible(I))
return ..()
eat_atom(I)
/mob/living/simple_animal/hostile/ooze/AttackingTarget(atom/attacked_target)
if(!check_edible(attacked_target))
return ..()
eat_atom(attacked_target)
/mob/living/simple_animal/hostile/ooze/UnarmedAttack(atom/A)
if(!check_edible(A))
return ..()
eat_atom(A)
///Handles nutrition gain/loss of mob and also makes it take damage if it's too low on nutrition, only happens for sentient mobs.
/mob/living/simple_animal/hostile/ooze/Life()
. = ..()
if(!mind && stat != DEAD)//no mind no change
return
var/nutrition_change = ooze_nutrition_loss
//Eat a bit of all the reagents we have. Gaining nutrition for actual nutritional ones.
for(var/i in reagents.reagent_list)
var/datum/reagent/reagent = i
var/consumption_amount = min(reagents.get_reagent_amount(reagent.type), ooze_metabolism_modifier * REAGENTS_METABOLISM)
if(istype(reagent, /datum/reagent/consumable))
var/datum/reagent/consumable/consumable = reagent
nutrition_change += consumption_amount * consumable.nutriment_factor
reagents.remove_reagent(reagent.type, consumption_amount)
adjust_ooze_nutrition(nutrition_change)
if(ooze_nutrition <= 0)
adjustBruteLoss(0.5)
///Returns whether or not the supplied movable atom is edible.
/mob/living/simple_animal/hostile/ooze/proc/check_edible(atom/movable/potential_food)
if(ismob(potential_food))
return FALSE
if(istype(potential_food, /obj/item/reagent_containers/food))
var/obj/item/reagent_containers/food/meal = potential_food
return (meal.foodtype & MEAT) //Dont forget to add edible component compat here later
///Does ooze_nutrition + supplied amount and clamps it within 0 and 500
/mob/living/simple_animal/hostile/ooze/proc/adjust_ooze_nutrition(amount)
ooze_nutrition = clamp(ooze_nutrition + amount, 0, 500)
updateNutritionDisplay()
///Tries to transfer the atoms reagents then delete it
/mob/living/simple_animal/hostile/ooze/proc/eat_atom(obj/item/eaten_atom)
eaten_atom.reagents.trans_to(src, eaten_atom.reagents.total_volume, transfered_by = src)
src.visible_message("<span class='warning>[src] eats [eaten_atom]!</span>", "<span class='notice'>You eat [eaten_atom].</span>")
playsound(loc,'sound/items/eatfood.ogg', rand(30,50), TRUE)
qdel(eaten_atom)
///Updates the display that shows the mobs nutrition
/mob/living/simple_animal/hostile/ooze/proc/updateNutritionDisplay()
if(hud_used) //clientless oozes
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='green'>[round(ooze_nutrition)]</font></div>"
///* Gelatinious Ooze code below *\\\\
///Its good stats and high mobility makes this a good assasin type creature. It's vulnerabilites against cold, shotguns and
/mob/living/simple_animal/hostile/ooze/gelatinous
name = "Gelatinous Cube"
desc = "A cubic ooze native to Sholus VII.\nSince the advent of space travel this species has established itself in the waste treatment facilities of several space colonies.\nIt is often considered to be the third most infamous invasive species due to its highly agressive and predatory nature."
speed = 1
damage_coeff = list(BRUTE = 1, BURN = 0.6, TOX = 0.5, CLONE = 1.5, STAMINA = 0, OXY = 1)
melee_damage_lower = 20
melee_damage_upper = 20
armour_penetration = 15
obj_damage = 20
deathmessage = "collapses into a pile of goo!"
///The ability to give yourself a metabolic speed boost which raises heat
var/datum/action/cooldown/metabolicboost/boost
///The ability to consume mobs
var/datum/action/consume/consume
///Initializes the mobs abilities and gives them to the mob
/mob/living/simple_animal/hostile/ooze/gelatinous/Initialize()
. = ..()
boost = new
boost.Grant(src)
consume = new
consume.Grant(src)
/mob/living/simple_animal/hostile/ooze/gelatinous/Destroy()
. = ..()
QDEL_NULL(boost)
QDEL_NULL(consume)
///If this mob gets resisted by something, its trying to escape consumption.
/mob/living/simple_animal/hostile/ooze/gelatinous/container_resist_act(mob/living/user)
. = ..()
if(!do_after(user, 6 SECONDS)) //6 second struggle
return FALSE
consume.stop_consuming()
/mob/living/simple_animal/hostile/ooze/gelatinous/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_GELATINOUS, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
///This ability lets the gelatinious ooze speed up for a little bit
/datum/action/cooldown/metabolicboost
name = "Metabolic boost"
desc = "Gain a temporary speed boost. Costs 10 nutrition and slowly raises your temperature"
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "metabolic_boost"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
cooldown_time = 24 SECONDS
var/nutrition_cost = 10
var/active = FALSE
///Mob needs to have enough nutrition
/datum/action/cooldown/metabolicboost/IsAvailable()
. = ..()
var/mob/living/simple_animal/hostile/ooze/ooze = owner
if(!.)
return FALSE
return (ooze.ooze_nutrition >= nutrition_cost && !active)
///Give the mob a speed boost, heat it up every second, and end the ability in 6 seconds
/datum/action/cooldown/metabolicboost/Trigger()
. = ..()
if(!.)
return
var/mob/living/simple_animal/hostile/ooze/ooze = owner
ooze.add_movespeed_modifier(/datum/movespeed_modifier/metabolicboost)
var/timerid = addtimer(CALLBACK(src, .proc/HeatUp), 1 SECONDS, TIMER_STOPPABLE | TIMER_LOOP) //Heat up every second
addtimer(CALLBACK(src, .proc/FinishSpeedup, timerid), 6 SECONDS)
to_chat(ooze, "<span class='notice'>You start feel a lot quicker.</span>")
active = TRUE
ooze.adjust_ooze_nutrition(-10)
///Heat up the mob a little
/datum/action/cooldown/metabolicboost/proc/HeatUp()
var/mob/living/simple_animal/hostile/ooze/ooze = owner
ooze.adjust_bodytemperature(50)
///Remove the speed modifier and delete the timer for heating up
/datum/action/cooldown/metabolicboost/proc/FinishSpeedup(timerid)
var/mob/living/simple_animal/hostile/ooze/ooze = owner
ooze.remove_movespeed_modifier(/datum/movespeed_modifier/metabolicboost)
to_chat(ooze, "<span class='notice'>You start slowing down again.</span>")
deltimer(timerid)
active = FALSE
StartCooldown()
///This action lets you consume the mob you're currently pulling. I'M GONNA CONSUUUUUME (this is considered one of the funny memes in the 2019-2020 era)
/datum/action/consume
name = "Consume"
desc = "Consume a mob that you are dragging to gain nutrition from them"
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "consume"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
///The mob thats being consumed by this creature
var/mob/living/vored_mob
///Register for owner death
/datum/action/consume/New(Target)
. = ..()
RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/on_owner_death)
RegisterSignal(owner, COMSIG_PARENT_PREQDELETED, .proc/handle_mob_deletion)
/datum/action/consume/proc/handle_mob_deletion()
stop_consuming() //Shit out the vored mob before u go go
///Try to consume the pulled mob
/datum/action/consume/Trigger()
. = ..()
if(!.)
return
var/mob/living/simple_animal/hostile/ooze/gelatinous/ooze = owner
if(!isliving(ooze.pulling))
to_chat(src, "<span class='warning'>You need to be pulling a creature for this to work!</span>")
return FALSE
if(vored_mob)
to_chat(src, "<span class='warning'>You are already consuming another creature!</span>")
return FALSE
owner.visible_message("<span class='warning>[ooze] starts attempting to devour [target]!</span>", "<span class='notice'>You start attempting to devour [target].</span>")
if(!do_after(ooze, 15, target = ooze.pulling))
return FALSE
var/mob/living/eat_target = ooze.pulling
if(!(eat_target.mob_biotypes & MOB_ORGANIC) || eat_target.stat == DEAD)
to_chat(src, "<span class='warning'>This creature isn't to my tastes!</span>")
return FALSE
start_consuming(eat_target)
///Start allowing this datum to process to handle the damage done to this mob.
/datum/action/consume/proc/start_consuming(mob/living/target)
vored_mob = target
vored_mob.forceMove(owner) ///AAAAAAAAAAAAAAAAAAAAAAHHH!!!
RegisterSignal(vored_mob, COMSIG_PARENT_PREQDELETED, .proc/handle_mob_deletion)
playsound(owner,'sound/items/eatfood.ogg', rand(30,50), TRUE)
owner.visible_message("<span class='warning>[src] devours [target]!</span>", "<span class='notice'>You devour [target].</span>")
START_PROCESSING(SSprocessing, src)
///Stop consuming the mob; dump them on the floor
/datum/action/consume/proc/stop_consuming()
STOP_PROCESSING(SSprocessing, src)
vored_mob.forceMove(get_turf(owner))
playsound(get_turf(owner), 'sound/effects/splat.ogg', 50, TRUE)
owner.visible_message("<span class='warning>[owner] pukes out [vored_mob]!</span>", "<span class='notice'>You puke out [vored_mob].</span>")
UnregisterSignal(vored_mob, COMSIG_PARENT_PREQDELETED)
vored_mob = null
///Gain health for the consumption and dump some clone loss on the target.
/datum/action/consume/process()
var/mob/living/simple_animal/hostile/ooze/gelatinous/ooze = owner
vored_mob.adjustBruteLoss(5)
ooze.heal_ordered_damage((ooze.maxHealth * 0.03), list(BRUTE, BURN, OXY)) ///Heal 6% of these specific damage types each process
ooze.adjust_ooze_nutrition(3)
///Dump em at 200 cloneloss.
if(vored_mob.getBruteLoss() >= 200)
stop_consuming()
///On owner death dump the current vored mob
/datum/action/consume/proc/on_owner_death()
SIGNAL_HANDLER
stop_consuming()
///* Gelatinious Grapes code below *\\\\
///Child of the ooze mob which is orientated at being a healer type creature.
/mob/living/simple_animal/hostile/ooze/grapes
name = "Sholean grapes"
desc = "A botryoidal ooze from Sholus VII.\nXenobiologists consider it to be one of the calmer and more agreeable species on the planet, but so far little is known about its behaviour in the wild.\nIt undulates in a comforting manner."
icon_state = "grapes"
icon_dead = "grapes_dead"
speed = 1
health = 200
maxHealth = 200
damage_coeff = list(BRUTE = 1, BURN = 0.8, TOX = 0.5, CLONE = 1.5, STAMINA = 0, OXY = 1)
melee_damage_lower = 12
melee_damage_upper = 12
obj_damage = 15
deathmessage = "deflates and spills its vital juices!"
///The ability lets you envelop a carbon in a healing cocoon. Useful for saving critical carbons.
var/datum/action/cooldown/gel_cocoon/gel_cocoon
///The ability to shoot a mending globule, a sticky projectile that heals over time.
var/obj/effect/proc_holder/globules/globules
/mob/living/simple_animal/hostile/ooze/grapes/Initialize()
. = ..()
globules = new
AddAbility(globules)
gel_cocoon = new
gel_cocoon.Grant(src)
/mob/living/simple_animal/hostile/ooze/grapes/Destroy()
. = ..()
QDEL_NULL(gel_cocoon)
QDEL_NULL(globules)
/mob/living/simple_animal/hostile/ooze/grapes/check_edible(atom/movable/potential_food)
if(ismob(potential_food))
return FALSE
var/foodtype
if(istype(potential_food, /obj/item/reagent_containers/food))
var/obj/item/reagent_containers/food/meal = potential_food
foodtype = meal.foodtype
return foodtype & MEAT || foodtype & VEGETABLES //Dont forget to add edible component compat here later
/mob/living/simple_animal/hostile/ooze/grapes/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_GRAPE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
///Ability that allows the owner to fire healing globules at mobs, targetting specific limbs.
/obj/effect/proc_holder/globules
name = "Fire Mending globule"
desc = "Fires a mending globule at someone, healing a specific limb of theirs."
active = FALSE
action_icon = 'icons/mob/actions/actions_slime.dmi'
action_icon_state = "globules"
action_background_icon_state = "bg_hive"
var/cooldown = 5 SECONDS
var/current_cooldown = 0
/obj/effect/proc_holder/globules/Click(location, control, params)
. = ..()
if(!isliving(usr))
return TRUE
var/mob/living/user = usr
fire(user)
/obj/effect/proc_holder/globules/fire(mob/living/carbon/user)
var/message
if(current_cooldown > world.time)
to_chat(user, "<span class='notice'>This ability is still on cooldown.</span>")
return
if(active)
message = "<span class='notice'>You stop preparing your mending globules.</span>"
remove_ranged_ability(message)
else
message = "<span class='notice'>You prepare to launch a mending globule. <B>Left-click to fire at a target!</B></span>"
add_ranged_ability(user, message, TRUE)
/obj/effect/proc_holder/globules/InterceptClickOn(mob/living/caller, params, atom/target)
. = ..()
if(.)
return
if(!istype(ranged_ability_user, /mob/living/simple_animal/hostile/ooze) || ranged_ability_user.stat)
remove_ranged_ability()
return
var/mob/living/simple_animal/hostile/ooze/ooze = ranged_ability_user
if(ooze.ooze_nutrition < 5)
to_chat(ooze, "<span class='warning'>You need at least 5 nutrition to launch a mending globule.</span>")
remove_ranged_ability()
return
ooze.visible_message("<span class='nicegreen>[ooze] launches a mending globule!</span>", "<span class='notice'>You launch a mending globule.</span>")
var/obj/projectile/globule/globule = new (ooze.loc)
globule.preparePixelProjectile(target, ooze, params)
globule.def_zone = ooze.zone_selected
globule.fire()
ooze.adjust_ooze_nutrition(-5)
remove_ranged_ability()
current_cooldown = world.time + cooldown
return TRUE
/obj/effect/proc_holder/globules/on_lose(mob/living/carbon/user)
remove_ranged_ability()
///This projectile embeds into mobs and heals them over time.
/obj/projectile/globule
name = "mending globule"
icon_state = "glob_projectile"
shrapnel_type = /obj/item/mending_globule
embedding = list("embed_chance" = 100, ignore_throwspeed_threshold = TRUE, "pain_mult" = 0, "jostle_pain_mult" = 0, "fall chance" = 0.5)
nodamage = TRUE
damage = 0
///This item is what is embedded into the mob, and actually handles healing of mending globules
/obj/item/mending_globule
name = "mending globule"
desc = "It somehow heals those who touch it."
icon = 'icons/obj/xenobiology/vatgrowing.dmi'
icon_state = "globule"
embedding = list("embed_chance" = 100, ignore_throwspeed_threshold = TRUE, "pain_mult" = 0, "jostle_pain_mult" = 0, "fall chance" = 0.5)
var/obj/item/bodypart/bodypart
var/heals_left = 35
/obj/item/mending_globule/Destroy()
. = ..()
bodypart = null
/obj/item/mending_globule/embedded(mob/living/carbon/human/embedded_mob, obj/item/bodypart/part)
. = ..()
if(!istype(part))
return
bodypart = part
START_PROCESSING(SSobj, src)
/obj/item/mending_globule/unembedded()
. = ..()
bodypart = null
STOP_PROCESSING(SSobj, src)
///Handles the healing of the mending globule
/obj/item/mending_globule/process()
if(!bodypart) //this is fucked
return FALSE
bodypart.heal_damage(1,1)
heals_left--
if(heals_left <= 0)
qdel(src)
///This action lets you put a mob inside of a cacoon that will inject it with some chemicals.
/datum/action/cooldown/gel_cocoon
name = "Gel Cocoon"
desc = "Puts a mob inside of a cocoon, allowing it to slowly heal."
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "gel_cocoon"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
cooldown_time = 10 SECONDS
///Try to put the pulled mob in a cocoon
/datum/action/cooldown/gel_cocoon/Trigger()
. = ..()
if(!.)
return
var/mob/living/simple_animal/hostile/ooze/grapes/ooze = owner
if(!iscarbon(ooze.pulling))
to_chat(src, "<span class='warning'>You need to be pulling an intelligent enough creature to assist it with a cocoon!</span>")
return FALSE
owner.visible_message("<span class='nicegreen>[ooze] starts attempting to put [target] into a gel cocoon!</span>", "<span class='notice'>You start attempting to put [target] into a gel cocoon.</span>")
if(!do_after(ooze, 1.5 SECONDS, target = ooze.pulling))
return FALSE
put_in_cocoon(ooze.pulling)
ooze.adjust_ooze_nutrition(-30)
///Mob needs to have enough nutrition
/datum/action/cooldown/gel_cocoon/IsAvailable()
. = ..()
if(!.)
return
var/mob/living/simple_animal/hostile/ooze/ooze = owner
return ooze.ooze_nutrition >= 30
///Puts the mob in the new cocoon
/datum/action/cooldown/gel_cocoon/proc/put_in_cocoon(mob/living/carbon/target)
var/obj/structure/gel_cocoon/cocoon = new /obj/structure/gel_cocoon(get_turf(target))
cocoon.insert_target(target)
owner.visible_message("<span class='nicegreen>[owner] has put [target] into a gel cocoon!</span>", "<span class='notice'>You put [target] into a gel cocoon.</span>")
StartCooldown()
/obj/structure/gel_cocoon
name = "gel cocoon"
desc = "It looks gross, but helpful."
icon = 'icons/obj/xenobiology/vatgrowing.dmi'
icon_state = "gel_cocoon"
max_integrity = 50
var/mob/living/carbon/inhabitant
/obj/structure/gel_cocoon/Destroy()
if(inhabitant)
dump_inhabitant(FALSE)
return ..()
/obj/structure/gel_cocoon/container_resist_act(mob/living/user)
. = ..()
user.visible_message("<span class='notice'>You see [user] breaking out of [src]!</span>", \
"<span class='notice'>You start tearing the soft tissue of the gel cocoon</span>")
if(!do_after(user, 1.5 SECONDS, target = src))
return FALSE
dump_inhabitant()
///This proc handles the insertion of a person into the cocoon
/obj/structure/gel_cocoon/proc/insert_target(target)
inhabitant = target
inhabitant.forceMove(src)
START_PROCESSING(SSobj, src)
///This proc dumps the mob and handles associated audiovisual feedback
/obj/structure/gel_cocoon/proc/dump_inhabitant(destroy_after = TRUE)
inhabitant.forceMove(get_turf(src))
playsound(get_turf(inhabitant), 'sound/effects/splat.ogg', 50, TRUE)
inhabitant.Paralyze(10)
inhabitant.visible_message("<span class='warning>[inhabitant] falls out of [src]!</span>", "<span class='notice'>You fall out of [src].</span>")
if(destroy_after)
qdel(src)
/obj/structure/gel_cocoon/process()
if(inhabitant.reagents.get_reagent_amount(/datum/reagent/medicine/atropine) < 5)
inhabitant.reagents.add_reagent(/datum/reagent/medicine/atropine, 0.5)
if(inhabitant.reagents.get_reagent_amount(/datum/reagent/medicine/salglu_solution) < 15)
inhabitant.reagents.add_reagent(/datum/reagent/medicine/salglu_solution, 1.5)
if(inhabitant.reagents.get_reagent_amount(/datum/reagent/consumable/milk) < 20)
inhabitant.reagents.add_reagent(/datum/reagent/consumable/milk, 2)
@@ -44,6 +44,10 @@
var/is_tree = TRUE
/mob/living/simple_animal/hostile/tree/Initialize()
. = ..()
add_cell_sample()
/mob/living/simple_animal/hostile/tree/Life()
..()
if(is_tree && isopenturf(loc))
@@ -65,6 +69,9 @@
C.visible_message("<span class='danger'>\The [src] knocks down \the [C]!</span>", \
"<span class='userdanger'>\The [src] knocks you down!</span>")
/mob/living/simple_animal/hostile/tree/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_PINE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
/mob/living/simple_animal/hostile/tree/festivus
name = "festivus pole"
desc = "Serenity now... SERENITY NOW!"
@@ -95,3 +102,6 @@
for(var/obj/machinery/power/apc/A in range(2, get_turf(src)))
if(A.cell)
A.cell.give(75)
/mob/living/simple_animal/hostile/tree/festivus/add_cell_sample()
return
@@ -0,0 +1,109 @@
///Vatbeasts are creatures from vatgrowing and are literaly a beast in a vat, yup. They are designed to be a powerful mount roughly equal to a gorilla in power.
/mob/living/simple_animal/hostile/vatbeast
name = "vatbeast"
desc = "A strange molluscoidal creature carrying a busted growing vat.\nYou wonder if this burden is a voluntary undertaking in order to achieve comfort and protection, or simply because the creature is fused to its metal shell?"
icon = 'icons/mob/vatgrowing.dmi'
icon_state = "vat_beast"
icon_dead = "vat_beast_dead"
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mob_size = MOB_SIZE_LARGE
gender = NEUTER
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
speak_emote = list("roars")
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
health = 250
maxHealth = 250
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 1, CLONE = 2, STAMINA = 0, OXY = 1)
melee_damage_lower = 25
melee_damage_upper = 25
obj_damage = 40
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
attack_sound = 'sound/weapons/punch3.ogg'
attack_verb_continuous = "slaps"
attack_verb_simple = "slap"
food_type = list(/obj/item/reagent_containers/food/snacks/fries, /obj/item/reagent_containers/food/snacks/cheesyfries, /obj/item/reagent_containers/food/snacks/cornchips, /obj/item/reagent_containers/food/snacks/carrotfries)
tame_chance = 30
var/obj/effect/proc_holder/tentacle_slap/tentacle_slap
/mob/living/simple_animal/hostile/vatbeast/Initialize()
. = ..()
tentacle_slap = new
AddAbility(tentacle_slap)
add_cell_sample()
/mob/living/simple_animal/hostile/vatbeast/Destroy()
. = ..()
QDEL_NULL(tentacle_slap)
/mob/living/simple_animal/hostile/vatbeast/tamed()
. = ..()
can_buckle = TRUE
buckle_lying = FALSE
var/datum/component/riding/riding = LoadComponent(/datum/component/riding)
riding.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 15), TEXT_SOUTH = list(0, 15), TEXT_EAST = list(-10, 15), TEXT_WEST = list(10, 15)))
riding.set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
riding.set_vehicle_dir_layer(NORTH, OBJ_LAYER)
riding.set_vehicle_dir_layer(EAST, OBJ_LAYER)
riding.set_vehicle_dir_layer(WEST, OBJ_LAYER)
riding.drive_verb = "ride"
riding.override_allow_spacemove = TRUE
faction = list("neutral")
/mob/living/simple_animal/hostile/vatbeast/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_VATBEAST, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
///Ability that allows the owner to slap other mobs a short distance away
/obj/effect/proc_holder/tentacle_slap
name = "Tentacle slap"
desc = "Slap a creature with your tentacles."
active = FALSE
action_icon = 'icons/mob/actions/actions_animal.dmi'
action_icon_state = "tentacle_slap"
action_background_icon_state = "bg_revenant"
ranged_mousepointer = 'icons/effects/mouse_pointers/supplypod_target.dmi'
var/cooldown = 12 SECONDS
var/current_cooldown = 0
/obj/effect/proc_holder/tentacle_slap/Click(location, control, params)
. = ..()
if(!isliving(usr))
return TRUE
fire(usr)
/obj/effect/proc_holder/tentacle_slap/fire(mob/living/carbon/user)
if(current_cooldown > world.time)
to_chat(user, "<span class='notice'>This ability is still on cooldown.</span>")
return
if(active)
remove_ranged_ability("<span class='notice'>You stop preparing to tentacle slap.</span>")
else
add_ranged_ability(user, "<span class='notice'>You prepare your pimp-tentacle. <B>Left-click to slap a target!</B></span>", TRUE)
/obj/effect/proc_holder/tentacle_slap/InterceptClickOn(mob/living/caller, params, atom/target)
. = ..()
if(.)
return
if(!istype(ranged_ability_user, /mob/living/simple_animal/hostile/vatbeast) || ranged_ability_user.stat)
remove_ranged_ability()
return
if(!caller.Adjacent(target))
return
if(!isliving(target))
return
var/mob/living/living_target = target
var/mob/living/simple_animal/hostile/vatbeast/vatbeast = ranged_ability_user
vatbeast.visible_message("<span class='warning>[vatbeast] slaps [living_target] with its tentacle!</span>", "<span class='notice'>You slap [living_target] with your tentacle.</span>")
playsound(vatbeast, 'sound/effects/assslap.ogg', 90)
var/atom/throw_target = get_edge_target_turf(target, vatbeast.dir)
living_target.throw_at(throw_target, 6, 4, vatbeast)
living_target.apply_damage(30)
current_cooldown = world.time + cooldown
remove_ranged_ability()
return TRUE
@@ -702,3 +702,7 @@
if (AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src
toggle_ai(initial(AIStatus))
///This proc is used for adding the swabbale element to mobs so that they are able to be biopsied and making sure holograpic and butter-based creatures don't yield viable cells samples.
/mob/living/simple_animal/proc/add_cell_sample()
return
@@ -101,6 +101,7 @@
. = ..()
set_nutrition(700)
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 7.5)
add_cell_sample()
/mob/living/simple_animal/slime/Destroy()
for (var/A in actions)
@@ -496,3 +497,6 @@
/mob/living/simple_animal/slime/random/Initialize(mapload, new_colour, new_is_adult)
. = ..(mapload, pick(slime_colours), prob(50))
/mob/living/simple_animal/slime/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_SLIME, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)