Merge pull request #93 from VOREStation/voremobs

Issue #30 - Added icons and code for vore animals.
This commit is contained in:
Leshana
2016-05-17 19:45:02 -04:00
15 changed files with 1091 additions and 1 deletions
@@ -0,0 +1,308 @@
/mob/living/simple_animal/fox
name = "Fox"
desc = "It's a fox. I wonder what it says?"
icon = 'icons/mob/fox_vr.dmi'
icon_state = "fox"
icon_living = "fox"
icon_dead = "fox_dead"
speak = list("Ack-Ack","Ack-Ack-Ack-Ackawoooo","Awoo","Tchoff")
speak_emote = list("geckers", "barks")
emote_hear = list("howls","barks")
emote_see = list("shakes its head", "shivers", "geckers")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/fox
response_help = "scritches"
response_disarm = "gently pushes aside"
response_harm = "kicks"
var/turns_since_scan = 0
var/mob/living/simple_animal/mouse/movement_target
var/mob/flee_target
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
mob_size = MOB_TINY
/mob/living/simple_animal/fox/New()
if(!vore_organs.len)
var/datum/belly/B = new /datum/belly(src)
B.immutable = 1
B.name = "Stomach"
B.inside_flavor = "Slick foxguts. Cute on the outside, slimy on the inside!"
B.human_prey_swallow_time = swallowTime
B.nonhuman_prey_swallow_time = swallowTime
vore_organs[B.name] = B
vore_selected = B.name
B.emote_lists[DM_HOLD] = list(
"The foxguts knead and churn around you harmlessly.",
"With a loud glorp, some air shifts inside the belly.",
"A thick drop of warm bellyslime drips onto you from above.",
"The fox turns suddenly, causing you to shift a little.",
"During a moment of relative silence, you can hear the fox breathing.",
"The slimey stomach walls squeeze you lightly, then relax.")
B.emote_lists[DM_DIGEST] = list(
"The guts knead at you, trying to work you into thick soup.",
"You're ground on by the slimey walls, treated like a mouse.",
"The acrid air is hard to breathe, and stings at your lungs.",
"You can feel the acids coating you, ground in by the slick walls.",
"The fox's stomach churns hungrily over your form, trying to take you.",
"With a loud glorp, the stomach spills more acids onto you.")
..()
// All them complicated fox procedures.
/mob/living/simple_animal/fox/Life()
//MICE!
if((loc) && isturf(loc))
if(!stat && !resting && !buckled)
for(var/mob/living/simple_animal/mouse/M in loc)
if(isPredator) //If the fox is a predator,
movement_target = null
custom_emote(1, "greedily stuffs [M] into their gaping maw!")
if(M in oview(1, src))
animal_nom(M)
else
M << "You just manage to slip away from [src]'s jaws before you can be sent to a fleshy prison!"
break
else
if(!M.stat)
M.splat()
visible_emote(pick("bites \the [M]!","toys with \the [M].","chomps on \the [M]!"))
movement_target = null
stop_automated_movement = 0
break
..()
for(var/mob/living/simple_animal/mouse/snack in oview(src,5))
if(snack.stat < DEAD && prob(15))
audible_emote(pick("hunkers down!","acts stealthy!","eyes [snack] hungrily."))
break
if(!stat && !resting && !buckled) //SEE A MICRO AND ARE A PREDATOR, EAT IT!
for(var/mob/living/carbon/human/food in oview(src, 5))
if(food.size_multiplier <= RESIZE_A_SMALLTINY)
if(prob(10))
custom_emote(1, pick("eyes [food] hungrily!","licks their lips and turns towards [food] a little!","pants as they imagine [food] being in their belly."))
break
else
if(prob(5))
movement_target = food
break
for(var/mob/living/carbon/human/bellyfiller in oview(1, src))
if(bellyfiller in src.prey_excludes)
continue
if(bellyfiller.size_multiplier <= RESIZE_A_SMALLTINY && isPredator)
movement_target = null
custom_emote(1, pick("slurps [bellyfiller] with their slimey tongue.","looms over [bellyfiller] with their maw agape.","sniffs at [bellyfiller], their belly grumbling hungrily."))
sleep(10)
custom_emote(1, "starts to scoop [bellyfiller] into their maw!")
if(bellyfiller in oview(1, src))
animal_nom(bellyfiller)
else
bellyfiller << "You just manage to slip away from [src]'s jaws before you can be sent to a fleshy prison!"
break
if(!stat && !resting && !buckled)
turns_since_scan++
if (turns_since_scan > 5)
walk_to(src,0)
turns_since_scan = 0
if (flee_target) //fleeing takes precendence
handle_flee_target()
else
handle_movement_target()
/mob/living/simple_animal/fox/proc/handle_movement_target()
//if our target is neither inside a turf or inside a human(???), stop
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
//if we have no target or our current one is out of sight/too far away
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
movement_target = null
stop_automated_movement = 0
for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target
if(isturf(snack.loc) && !snack.stat)
movement_target = snack
break
if(movement_target)
stop_automated_movement = 1
walk_to(src,movement_target,0,10)
/mob/living/simple_animal/fox/proc/handle_flee_target()
//see if we should stop fleeing
if (flee_target && !(flee_target.loc in view(src)))
flee_target = null
stop_automated_movement = 0
if (flee_target)
if(prob(25)) say("GRRRRR!")
stop_automated_movement = 1
walk_away(src, flee_target, 7, 2)
/mob/living/simple_animal/fox/proc/set_flee_target(atom/A)
if(A)
flee_target = A
turns_since_scan = 5
/mob/living/simple_animal/fox/attackby(var/obj/item/O, var/mob/user)
. = ..()
if(O.force)
set_flee_target(user? user : src.loc)
/mob/living/simple_animal/fox/attack_hand(mob/living/carbon/human/M as mob)
. = ..()
if(M.a_intent == "hurt")
set_flee_target(M)
/mob/living/simple_animal/fox/ex_act()
. = ..()
set_flee_target(src.loc)
/mob/living/simple_animal/fox/bullet_act(var/obj/item/projectile/proj)
. = ..()
set_flee_target(proj.firer? proj.firer : src.loc)
/mob/living/simple_animal/fox/hitby(atom/movable/AM)
. = ..()
set_flee_target(AM.thrower? AM.thrower : src.loc)
/mob/living/simple_animal/fox/MouseDrop(atom/over_object)
var/mob/living/carbon/H = over_object
if(!istype(H) || !Adjacent(H)) return ..()
if(H.a_intent == "help")
get_scooped(H)
return
else
return ..()
/mob/living/simple_animal/fox/get_scooped(var/mob/living/carbon/grabber)
if (stat >= DEAD)
return //since the holder icon looks like a living cat
..()
//Basic friend AI
/mob/living/simple_animal/fox/fluff
var/mob/living/carbon/human/friend
var/befriend_job = null
/mob/living/simple_animal/fox/fluff/handle_movement_target()
if (friend)
var/follow_dist = 5
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
follow_dist = 1
else if (friend.stat || friend.health <= 50) //danger or just sleeping
follow_dist = 2
var/near_dist = max(follow_dist - 2, 1)
var/current_dist = get_dist(src, friend)
if (movement_target != friend)
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src)))
//stop existing movement
walk_to(src,0)
turns_since_scan = 0
//walk to friend
stop_automated_movement = 1
movement_target = friend
walk_to(src, movement_target, near_dist, 4)
//already following and close enough, stop
else if (current_dist <= near_dist)
walk_to(src,0)
movement_target = null
stop_automated_movement = 0
if (prob(10))
say("Yap!")
if (!friend || movement_target != friend)
..()
/mob/living/simple_animal/fox/fluff/Life()
..()
if (stat || !friend)
return
if (get_dist(src, friend) <= 1)
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
if (prob((friend.stat < DEAD)? 50 : 15))
var/verb = pick("huffs", "whines", "yowls")
audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
else
if (prob(5))
visible_emote(pick("nips [friend] affectionately.",
"yaps at [friend].",
"looks at [friend], wagging.",
"wags happily."))
else if (friend.health <= 50)
if (prob(10))
var/verb = pick("huffs", "whines", "yowls")
audible_emote("[verb] anxiously.")
/mob/living/simple_animal/fox/fluff/verb/friend()
set name = "Become Friends"
set category = "IC"
set src in view(1)
if(friend && usr == friend)
set_dir(get_dir(src, friend))
say("Yap!")
return
if (!(ishuman(usr) && befriend_job && usr.job == befriend_job))
usr << "<span class='notice'>[src] ignores you.</span>"
return
friend = usr
set_dir(get_dir(src, friend))
say("Yap!")
/obj/item/weapon/reagent_containers/food/snacks/meat/fox
name = "Fox meat"
desc = "The fox doesn't say a god damn thing, now."
//Captain fox
/mob/living/simple_animal/fox/fluff/Renault
name = "Renault"
desc = "Renault, the Captain's trustworthy fox. I wonder what it says?"
isPredator = 1
befriend_job = "Captain"
/mob/living/simple_animal/fox/fluff/Renault/New()
if(!vore_organs.len)
var/datum/belly/B = new /datum/belly(src)
B.immutable = 1
B.name = "Stomach"
B.inside_flavor = "Slick foxguts. They seem somehow more regal than perhaps other foxes!"
B.human_prey_swallow_time = swallowTime
B.nonhuman_prey_swallow_time = swallowTime
vore_organs[B.name] = B
vore_selected = B.name
B.emote_lists[DM_HOLD] = list(
"Renault's stomach walls squeeze around you more tightly for a moment, before relaxing, as if testing you a bit.",
"There's a sudden squeezing as Renault presses a forepaw against his gut over you, squeezng you against the slick walls.",
"The 'head fox' has a stomach that seems to think you belong to it. It might be hard to argue, as it kneads at your form.",
"If being in the captain's fox is a promotion, it might not feel like one. The belly just coats you with more thick foxslime.",
"It doesn't seem like Renault wants to let you out. The stomach and owner possessively squeeze around you.",
"Renault's stomach walls squeeze closer, as he belches quietly, before swallowing more air. Does he do that on purpose?")
B.emote_lists[DM_DIGEST] = list(
"Renault's stomach walls grind hungrily inwards, kneading acids against your form, and treating you like any other food.",
"The captain's fox impatiently kneads and works acids against you, trying to claim your body for fuel.",
"The walls knead in firmly, squeezing and tossing you around briefly in disorienting aggression.",
"Renault belches, letting the remaining air grow more acrid. It burns your lungs with each breath.",
"A thick glob of acids drip down from above, adding to the pool of caustic fluids in Renault's belly.",
"There's a loud gurgle as the stomach declares the intent to make you a part of Renault.")
..()
@@ -0,0 +1,55 @@
/mob/living/simple_animal/snake
name = "Snake"
desc = "A big thick snake."
icon = 'icons/mob/snake_vr.dmi'
icon_state = "snake"
icon_living = "snake"
icon_dead = "snake_dead"
speak_emote = list("hisses")
health = 20
maxHealth = 20
attacktext = "bites"
melee_damage_lower = 3
melee_damage_upper = 5
response_help = "pets"
response_disarm = "shoos"
response_harm = "kicks"
turns_per_move = 8 // SLOW-ASS MUTHAFUCKA
//NOODLE IS HERE! SQUEEEEEEEE~
/mob/living/simple_animal/snake/Noodle
name = "Noodle"
desc = "This snake is particularly chubby and demands nothing but the finest of treats."
isPredator = 1
//Special snek-snax for Noodle!
obj/item/weapon/reagent_containers/food/snacks/snakesnack
name = "Sugar mouse"
desc = "A little mouse treat made of coloured sugar. Noodle loves these!"
var/snack_colour
icon = 'icons/mob/snake_vr.dmi'
icon_state = "snack_yellow"
obj/item/weapon/reagent_containers/food/snacks/snakesnack/New()
..()
if(!snack_colour)
snack_colour = pick( list("yellow","green","pink","blue") )
icon_state = "snack_[snack_colour]"
desc = "A little mouse treat made of coloured sugar. Noodle loves these! This one is [snack_colour]."
obj/item/weapon/storage/box/fluff/snakesnackbox
name = "Box of Snake Snax"
desc = "A box containing Noodle's special sugermouse treats."
icon = 'icons/mob/snake_vr.dmi'
icon_state = "sneksnakbox"
storage_slots = 7
New()
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
..()
return
@@ -106,7 +106,7 @@
/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
var/list/L = hearers(src, dist)
var/list/L = view(src, dist) //hearers(src, dist) <- This shit was broken and bad and caused a lot of lag because mobs would chase targets they can't see. -Spades
for (var/obj/mecha/M in mechas_list)
if (M.z == src.z && get_dist(src, M) <= dist)
@@ -0,0 +1,95 @@
/mob/living/simple_animal/hostile/vore/alien
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/alien.dmi'
icon_state = "xenohunter"
icon_living = "xenohunter"
icon_dead = "xenohunter-dead"
icon_gib = "gibbed-a"
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = -1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
a_intent = "harm"
attack_sound = 'sound/weapons/bladeslice.ogg'
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 = 15
faction = "alien"
environment_smash = 1
status_flags = CANPUSH
minbodytemp = 0
heat_damage_per_tick = 20
capacity = 1
/mob/living/simple_animal/hostile/vore/alien/drone
name = "alien drone"
icon_state = "xenodrone"
icon_living = "xenodrone"
icon_dead = "xenodrone-dead"
health = 60
melee_damage_lower = 15
melee_damage_upper = 15
/mob/living/simple_animal/hostile/vore/alien/sentinel
name = "alien sentinel"
icon_state = "xenosentinel"
icon_living = "xenosentinel"
icon_dead = "xenosentinel-dead"
health = 120
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
/mob/living/simple_animal/hostile/vore/alien/queen
name = "alien queen"
icon_state = "xenoqueen"
icon_living = "xenoqueen"
icon_dead = "xenoqueen-dead"
maxHealth = 250
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
/mob/living/simple_animal/hostile/vore/alien/queen/large
name = "alien empress"
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
move_to_delay = 4
maxHealth = 400
health = 400
pixel_x = -16
capacity = 3
/obj/item/projectile/neurotox
damage = 30
icon_state = "toxin"
/mob/living/simple_animal/hostile/vore/alien/death()
..()
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
@@ -0,0 +1,170 @@
//Space bears!
/mob/living/simple_animal/hostile/vore/bear
name = "space bear"
desc = "RawrRawr!!"
icon_state = "spacebear"
icon_living = "spacebear"
icon_dead = "spacebear-dead"
icon_gib = "bear-gib"
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
stop_automated_movement_when_pulled = 0
maxHealth = 60
health = 60
melee_damage_lower = 20
melee_damage_upper = 30
//Space bears aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
var/stance_step = 0
faction = "russian"
/mob/living/simple_animal/hostile/vore/bear/brown
name = "space bear"
desc = "RawrRawr!!"
icon_state = "brownbear"
icon_living = "brownbear"
icon_dead = "brownbear-dead"
icon_gib = "bear-gib"
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
/mob/living/simple_animal/hostile/vore/bear/Hudson
name = "Hudson"
desc = ""
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
/mob/living/simple_animal/hostile/vore/bear/Life()
. =..()
if(!.)
return
/*
if(loc && istype(loc,/turf/space))
icon_state = "bear"
else
icon_state = "bearfloor"
*/
switch(stance)
if(HOSTILE_STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(target_mob && target_mob in ListTargets(10))
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
stance = HOSTILE_STANCE_IDLE
if(HOSTILE_STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
if(target_mob && target_mob in ListTargets(10))
if(!(SA_attackable(target_mob)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
if(!found_mob)
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
stance = HOSTILE_STANCE_IDLE
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
stance = HOSTILE_STANCE_ATTACK
if(HOSTILE_STANCE_ATTACKING)
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
custom_emote(1, "is worn out and needs to rest." )
stance = HOSTILE_STANCE_TIRED
stance_step = 0
walk(src, 0) //This stops the bear's walking
return
/mob/living/simple_animal/hostile/vore/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
target_mob = user
..()
/mob/living/simple_animal/hostile/vore/bear/attack_hand(mob/living/carbon/human/M as mob)
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
target_mob = M
..()
/*
/mob/living/simple_animal/hostile/vore/bear/Process_Spacemove(var/check_drift = 0)
return //No drifting in space for space bears!
*/
/mob/living/simple_animal/hostile/vore/bear/FindTarget() // TODO: Make it so if the target is laying down, the bear actually won't bother them.
. = ..()
if(.)
custom_emote(1,"stares alertly at [.]")
stance = HOSTILE_STANCE_ALERT
/mob/living/simple_animal/hostile/vore/bear/LoseTarget()
..(5)
/mob/living/simple_animal/hostile/vore/bear/AttackingTarget()
// Need to snowflake the vode in the bear code here because of the snowflakey way bears work.
if(isliving(target_mob.loc)) //They're inside a mob, maybe us, ignore!
return
if(!isliving(target_mob)) //Can't eat 'em if they ain't alive. Prevents eating borgs/bots.
..()
return
if(picky && target_mob.digestable && target_mob.lying && target_mob.size_multiplier >= min_size && target_mob.size_multiplier <= max_size && !(target_mob in prey_exclusions))
if(capacity)
var/check_size = target_mob.size_multiplier + fullness
if(check_size <= capacity)
animal_nom(target_mob)
else
animal_nom(target_mob)
return
// Original bear attack code.
if(!Adjacent(target_mob))
return
custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
var/damage = rand(20,30)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
@@ -0,0 +1,86 @@
/mob/living/simple_animal/hostile/vore/carp
name = "space carp"
desc = "A voracious, fang-bearing creature that resembles a fish."
icon = 'icons/mob/animal.dmi'
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
speak_chance = 0
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speed = 4
maxHealth = 25
health = 25
harm_intent_damage = 8
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
capacity = 1
max_size = 0.5
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
break_stuff_probability = 15
faction = "carp"
/mob/living/simple_animal/hostile/vore/carp/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/vore/carp/FindTarget()
. = ..()
if(.)
custom_emote(1,"nashes at [.]")
/mob/living/simple_animal/hostile/vore/carp/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
// ---------- Great White Carp ---------- //
/mob/living/simple_animal/hostile/vore/large/carp
name = "great white carp"
desc = "You're going to need a bigger ship."
icon_dead = "megacarp-dead"
icon_living = "megacarp"
icon_state = "megacarp"
pixel_y = -16 // Center this completely since it's in space.
maxHealth = 600 // Boss
health = 600
speed = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
meat_amount = 10
faction = "carp"
capacity = 2
max_size = 2
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
break_stuff_probability = 15
@@ -0,0 +1,19 @@
/mob/living/simple_animal/hostile/vore/creature
name = "creature"
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/critter.dmi'
speak_emote = list("gibbers")
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
health = 80
maxHealth = 80
melee_damage_lower = 25
melee_damage_upper = 50
attacktext = "chomped"
attack_sound = 'sound/weapons/bite.ogg'
faction = "creature"
speed = 4
capacity = 0
max_size = 2 // Max: 2
min_size = 0.25 // Min: 0.25
@@ -0,0 +1,197 @@
//
// Abstract Class
//
/mob/living/simple_animal/hostile/vore/mimic
name = "crate"
desc = "A rectangular steel crate."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
icon_living = "crate"
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
response_help = "touches"
response_disarm = "pushes"
response_harm = "hits"
speed = 4
maxHealth = 250
health = 250
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "attacked"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
capacity = 0
faction = "mimic"
move_to_delay = 8
/mob/living/simple_animal/hostile/vore/mimic/FindTarget()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/vore/mimic/death()
..()
del(src)
//
// Crate Mimic
//
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
/mob/living/simple_animal/hostile/vore/mimic/crate
attacktext = "bitten"
stop_automated_movement = 1
wander = 0
var/attempt_open = 0
// Pickup loot
/mob/living/simple_animal/hostile/vore/mimic/crate/New()
..()
for(var/obj/item/I in loc)
I.loc = src
/mob/living/simple_animal/hostile/vore/mimic/crate/DestroySurroundings()
..()
if(prob(90))
icon_state = "[initial(icon_state)]open"
else
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/vore/mimic/crate/ListTargets()
if(attempt_open)
return ..()
return view(src, 1)
/mob/living/simple_animal/hostile/vore/mimic/crate/FindTarget()
. = ..()
if(.)
trigger()
/mob/living/simple_animal/hostile/vore/mimic/crate/AttackingTarget()
. = ..()
if(.)
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/vore/mimic/crate/proc/trigger()
if(!attempt_open)
visible_message("<b>[src]</b> starts to move!")
attempt_open = 1
/mob/living/simple_animal/hostile/vore/mimic/crate/adjustBruteLoss(var/damage)
trigger()
..(damage)
/mob/living/simple_animal/hostile/vore/mimic/crate/LoseTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/vore/mimic/crate/LostTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/vore/mimic/crate/death()
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
O.loc = C
..()
/mob/living/simple_animal/hostile/vore/mimic/crate/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(2)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
//
// Copy Mimic
//
// var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
// List now defined in projectile/animate.dm
/mob/living/simple_animal/hostile/vore/mimic/copy
health = 100
maxHealth = 100
var/mob/living/creator = null // the creator
var/destroy_objects = 0
var/knockdown_people = 0
/mob/living/simple_animal/hostile/vore/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
..(loc)
CopyObject(copy, creator)
/mob/living/simple_animal/hostile/vore/mimic/copy/death()
for(var/atom/movable/M in src)
M.loc = get_turf(src)
..()
/mob/living/simple_animal/hostile/vore/mimic/copy/ListTargets()
// Return a list of targets that isn't the creator
. = ..()
return . - creator
/mob/living/simple_animal/hostile/vore/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
O.loc = src
name = O.name
desc = O.desc
icon = O.icon
icon_state = O.icon_state
icon_living = icon_state
if(istype(O, /obj/structure))
health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
knockdown_people = 1
melee_damage_lower *= 2
melee_damage_upper *= 2
else if(istype(O, /obj/item))
var/obj/item/I = O
health = 15 * I.w_class
melee_damage_lower = 2 + I.force
melee_damage_upper = 2 + I.force
move_to_delay = 2 * I.w_class
maxHealth = health
if(creator)
src.creator = creator
faction = "\ref[creator]" // very unique
return 1
return
/mob/living/simple_animal/hostile/vore/mimic/copy/DestroySurroundings()
if(destroy_objects)
..()
/mob/living/simple_animal/hostile/vore/mimic/copy/AttackingTarget()
. =..()
if(knockdown_people)
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(1)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -0,0 +1,148 @@
/*
--------------
NOTES FOR DEVS
--------------
If your predator has a limited capacity, it should have sprites for every interval of its size, rounded to the nearest whole number.
Example: If I have a snake predator who has a capacity of 3, I need sprites for snake-1, snake-2, and snake-3.
Capacity should always be a whole number.
Also max_size and min_size should never exceed capacity or the icon will break.
Don't use ranged mobs for vore mobs.
*/
/mob/living/simple_animal/hostile/vore
name = "voracious lizard"
desc = "These gluttonous little bastards used to be regular lizards that were mutated by long-term exposure to phoron!"
icon_dead = "dino-dead"
icon_living = "dino"
icon_state = "dino"
icon = 'icons/mob/vore.dmi'
var/capacity = 1 // Zero is infinite. Do not set higher than you have icons to update.
var/max_size = 1 // Max: 2
var/min_size = 0.25 // Min: 0.25
var/picky = 1 // Won't eat undigestable prey by default
var/fullness = 0
swallowTime = 10 // Hungry little bastards.
// By default, this is what most vore mobs are capable of.
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
speed = 4
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 25
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
minbodytemp = 270
maxbodytemp = 370
heat_damage_per_tick = 15
cold_damage_per_tick = 10
unsuitable_atoms_damage = 10
/mob/living/simple_animal/hostile/vore/update_icons()
if(stat == DEAD)
return
if(capacity)
fullness = 0
for(var/I in vore_organs)
var/datum/belly/B = vore_organs[I]
for(var/mob/living/M in B.internal_contents)
fullness += M.size_multiplier
fullness = round(fullness, 1) // Because intervals of 0.25 are going to make sprite artists cry.
if(fullness)
if (fullness > capacity) // Player controlled.
icon_state = "[initial(icon_state)]-[capacity]"
else
icon_state = "[initial(icon_state)]-[fullness]"
else
icon_state = initial(icon_state)
..()
/mob/living/simple_animal/hostile/vore/New()
if(!vore_organs.len)
var/datum/belly/B = new /datum/belly(src)
B.immutable = 1
B.name = "Stomach"
B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [name]."
if (faction == "neutral")
B.digest_mode = "Hold" // Friendly slime-spawned mobs are neutral faction.
else
B.digest_mode = "Digest" // Though this usually doesn't happen.
vore_organs[B.name] = B
vore_selected = "Stomach"
B.vore_verb = "swallow"
B.emote_lists[DM_HOLD] = list(
"The insides knead at you gently for a moment.",
"The guts glorp wetly around you as some air shifts.",
"Your predator takes a deep breath and sighs, shifting you somewhat.",
"The stomach squeezes you tight for a moment, then relaxes.",
"During a moment of quiet, breathing becomes the most audible thing.",
"The warm slickness surrounds and kneads on you.")
B.emote_lists[DM_DIGEST] = list(
"The caustic acids eat away at your form.",
"The acrid air burns at your lungs.",
"Without a thought for you, the stomach grinds inwards painfully.",
"The guts treat you like food, squeezing to press more acids against you.",
"The onslaught against your body doesn't seem to be letting up; you're food now.",
"The insides work on you like they would any other food.")
..()
/mob/living/simple_animal/hostile/vore/AttackingTarget()
if(isliving(target_mob.loc)) //They're inside a mob, maybe us, ignore!
return
if(!isliving(target_mob)) //Can't eat 'em if they ain't alive. Prevents eating borgs/bots.
..()
return
if(picky && !target_mob.digestable) //Don't eat people with nogurgle prefs
..()
return
if(target_mob.lying && target_mob.size_multiplier >= min_size && target_mob.size_multiplier <= max_size && !(target_mob in prey_exclusions))
if(capacity)
var/check_size = target_mob.size_multiplier + fullness
if(check_size <= capacity)
animal_nom(target_mob)
target_mob = null
else
animal_nom(target_mob)
target_mob = null
..()
/mob/living/simple_animal/hostile/vore/death()
for(var/I in vore_organs)
var/datum/belly/B = vore_organs[I]
B.release_all_contents() // When your stomach is empty
..() // then you have my permission to die.
// ------- Big Preds ------- //
/mob/living/simple_animal/hostile/vore/large
name = "giant snake"
desc = "Snakes. Why did it have to be snakes?"
icon = 'icons/mob/vore64x64.dmi'
icon_dead = "snake-dead"
icon_living = "snake"
icon_state = "snake"
pixel_x = -16
maxHealth = 200
health = 200
@@ -0,0 +1,3 @@
/mob/living/simple_animal
// List of targets excluded (for now) from being eaten by this mob.
var/list/prey_exclusions = list()
Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+9
View File
@@ -1499,6 +1499,7 @@
#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
#include "code\modules\mob\living\simple_animal\simple_animal_vr.dm"
#include "code\modules\mob\living\simple_animal\worm.dm"
#include "code\modules\mob\living\simple_animal\borer\borer.dm"
#include "code\modules\mob\living\simple_animal\borer\borer_captive.dm"
@@ -1511,10 +1512,12 @@
#include "code\modules\mob\living\simple_animal\friendly\corgi_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
#include "code\modules\mob\living\simple_animal\friendly\fox_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\lizard.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\mushroom.dm"
#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
#include "code\modules\mob\living\simple_animal\friendly\snake_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
@@ -1534,6 +1537,12 @@
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\alien.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\bear.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\carp.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\creature.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\mimic.dm"
#include "code\modules\mob\living\simple_animal\hostile\vore\vore.dm"
#include "code\modules\mob\living\voice\voice.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"