mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-26 13:39:16 +01:00
Adds space mobs. Mimic, snake(noodle), Gaslamp.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
LORE:
|
||||
Gaslamps are a phoron-based life form endemic to the world of Virgo-3B. They are
|
||||
a sort of fungal organism with physical ties to Diona and Vox, deriving energy
|
||||
for movement from a gentle combustion-like reaction in their bodies using
|
||||
atmospheric phoron, carefully filtered trace oxygen, and captured meat products.
|
||||
Over-exposure to oxygen causes their insides to burn too hot and eventually
|
||||
kills them.
|
||||
|
||||
TODO: Make them light up and heat the air when exposed to oxygen.
|
||||
*/
|
||||
|
||||
/mob/living/simple_mob/animal/space/gaslamp
|
||||
name = "gaslamp"
|
||||
desc = "Some sort of floaty alien with a warm glow. This creature is endemic to Virgo-3B."
|
||||
tt_desc = "Semaeostomeae virginus"
|
||||
|
||||
icon_state = "gaslamp"
|
||||
icon_living = "gaslamp"
|
||||
icon_dead = "gaslamp-dead"
|
||||
icon = 'icons/mob/vore32x64.dmi'
|
||||
|
||||
faction = "virgo3b"
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
movement_cooldown = 12
|
||||
|
||||
say_list_type = /datum/say_list/gaslamp
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/gaslamp
|
||||
|
||||
//speed = 2 not sure what this is, guessing animation, but it conflicts with new system.
|
||||
|
||||
melee_damage_lower = 30 // Because fuck anyone who hurts this sweet, innocent creature.
|
||||
melee_damage_upper = 30
|
||||
attacktext = list("thrashed")
|
||||
friendly = "caressed"
|
||||
|
||||
response_help = "brushes" // If clicked on help intent
|
||||
response_disarm = "pushes" // If clicked on disarm intent
|
||||
response_harm = "swats" // If clicked on harm intent
|
||||
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 350
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 5 // Does not like oxygen very much.
|
||||
min_tox = 1 // Needs phoron to survive.
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
|
||||
/datum/say_list/gaslamp
|
||||
emote_see = list("looms", "sways gently")
|
||||
|
||||
/datum/ai_holder/simple_mob/gaslamp
|
||||
hostile = FALSE // The majority of simplemobs are hostile, gaslamps are nice.
|
||||
cooperative = FALSE
|
||||
retaliate = TRUE //so the monster can attack back
|
||||
returns_home = FALSE
|
||||
can_flee = FALSE
|
||||
speak_chance = 1
|
||||
wander = TRUE
|
||||
base_wander_delay = 9
|
||||
|
||||
// Activate Noms!
|
||||
/mob/living/simple_mob/animal/space/gaslamp
|
||||
vore_active = 1
|
||||
vore_capacity = 2
|
||||
vore_bump_chance = 90 //they're frickin' jellyfish anenome filterfeeders, get tentacled
|
||||
vore_bump_emote = "lazily wraps its tentacles around"
|
||||
vore_standing_too = 1 // Defaults to trying to give you that big tentacle hug.
|
||||
vore_ignores_undigestable = 0 // they absorb rather than digest, you're going in either way
|
||||
vore_default_mode = DM_HOLD
|
||||
vore_digest_chance = 0 // Chance to switch to digest mode if resisted
|
||||
vore_absorb_chance = 20 // BECOME A PART OF ME.
|
||||
vore_pounce_chance = 5 // Small chance to punish people who abuse their nomming behaviour to try and kite them forever with repeated melee attacks.
|
||||
vore_stomach_name = "internal chamber"
|
||||
vore_stomach_flavor = "You are squeezed into the tight embrace of the alien creature's warm and cozy insides."
|
||||
vore_icons = SA_ICON_LIVING
|
||||
@@ -0,0 +1,244 @@
|
||||
//
|
||||
// Abstract Class
|
||||
//
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic
|
||||
name = "crate"
|
||||
desc = "A rectangular steel crate."
|
||||
|
||||
icon_state = "crate"
|
||||
icon_living = "crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
|
||||
faction = "mimic"
|
||||
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
//speed = 4 no idea what this is, conflicts with new AI update.
|
||||
movement_cooldown = 10 //slow crate.
|
||||
|
||||
response_help = "touches"
|
||||
response_disarm = "pushes"
|
||||
response_harm = "hits"
|
||||
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 8
|
||||
melee_damage_upper = 12
|
||||
attacktext = list("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
|
||||
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
|
||||
|
||||
say_list_type = /datum/say_list/mimic
|
||||
ai_holder_type = /datum/ai_holder/mimic
|
||||
|
||||
var/knockdown_chance = 15 //Stubbing your toe on furniture hurts.
|
||||
|
||||
showvoreprefs = 0 //VOREStation Edit - Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle.
|
||||
|
||||
/datum/say_list/mimic
|
||||
say_got_target = list("growls")
|
||||
|
||||
/datum/ai_holder/mimic
|
||||
wander = FALSE
|
||||
hostile = TRUE
|
||||
threaten = TRUE
|
||||
threaten_timeout = 5 SECONDS
|
||||
threaten_delay = 1 SECONDS //not a threat, more of a delay.
|
||||
|
||||
/mob/living/simple_mob/animal/space/carp/apply_melee_effects(var/atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(prob(knockdown_chance))
|
||||
L.Weaken(3)
|
||||
L.visible_message(span("danger", "\The [src] knocks down \the [L]!"))
|
||||
|
||||
/* should be covered by my "growls" say thing, but keeping it just in case.
|
||||
/mob/living/simple_mob/animal/space/mimic/set_target()
|
||||
. = ..()
|
||||
if(.)
|
||||
audible_emote("growls at [.]")
|
||||
*/
|
||||
/mob/living/simple_mob/animal/space/mimic/death()
|
||||
..()
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/will_show_tooltip()
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/death()
|
||||
var/obj/structure/closet/crate/C = new(get_turf(src))
|
||||
// Put loot in crate
|
||||
for(var/obj/O in src)
|
||||
if(isbelly(O)) //VOREStation edit
|
||||
continue
|
||||
O.forceMove(C)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/I in loc)
|
||||
I.forceMove(src)
|
||||
/* I honestly have no idea what's happening down there so I'm just taking the essentials and yeeting.
|
||||
//
|
||||
// Crate Mimic
|
||||
//
|
||||
|
||||
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
|
||||
/mob/living/simple_mob/animal/space/mimic/crate
|
||||
|
||||
attacktext = list("bitten")
|
||||
|
||||
// stop_automated_movement = 1 we don't need these
|
||||
// wander = 0
|
||||
var/attempt_open = 0
|
||||
|
||||
// Pickup loot
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/I in loc)
|
||||
I.forceMove(src)
|
||||
/* I can't find an equivilant to this, don't know why we really have it even so...
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/DestroySurroundings()
|
||||
..()
|
||||
if(prob(90))
|
||||
icon_state = "[initial(icon_state)]open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
*/
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/ListTargets()
|
||||
if(attempt_open)
|
||||
return ..()
|
||||
else
|
||||
return ..(1)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/set_target()
|
||||
. = ..()
|
||||
if(.)
|
||||
trigger()
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/PunchTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/proc/trigger()
|
||||
if(!attempt_open)
|
||||
visible_message("<b>[src]</b> starts to move!")
|
||||
attempt_open = 1
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/adjustBruteLoss(var/damage)
|
||||
trigger()
|
||||
..(damage)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/LoseTarget()
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/LostTarget()
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/death()
|
||||
var/obj/structure/closet/crate/C = new(get_turf(src))
|
||||
// Put loot in crate
|
||||
for(var/obj/O in src)
|
||||
if(isbelly(O)) //VOREStation edit
|
||||
continue
|
||||
O.forceMove(C)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/crate/PunchTarget()
|
||||
. =..()
|
||||
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)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/copy
|
||||
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
var/mob/living/creator = null // the creator
|
||||
var/destroy_objects = 0
|
||||
var/knockdown_people = 0
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
|
||||
..(loc)
|
||||
CopyObject(copy, creator)
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/copy/death()
|
||||
|
||||
for(var/atom/movable/M in src)
|
||||
if(isbelly(M)) //VOREStation edit
|
||||
continue
|
||||
M.forceMove(get_turf(src))
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/copy/ListTargets()
|
||||
// Return a list of targets that isn't the creator
|
||||
. = ..()
|
||||
return . - creator
|
||||
|
||||
/mob/living/simple_mob/animal/space/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.forceMove(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_mob/animal/space/mimic/copy/DestroySurroundings()
|
||||
if(destroy_objects)
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/mimic/copy/PunchTarget()
|
||||
. =..()
|
||||
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,173 @@
|
||||
/mob/living/simple_mob/animal/space/snake
|
||||
name = "snake"
|
||||
desc = "A big thick snake."
|
||||
|
||||
icon_state = "snake"
|
||||
icon_living = "snake"
|
||||
icon_dead = "snake_dead"
|
||||
icon = 'icons/mob/snake_vr.dmi'
|
||||
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
movement_cooldown = 8 // SLOW-ASS MUTHAFUCKA, I hope.
|
||||
|
||||
response_help = "pets"
|
||||
response_disarm = "shoos"
|
||||
response_harm = "kicks"
|
||||
|
||||
melee_damage_lower = 3
|
||||
melee_damage_upper = 5
|
||||
attacktext = list("bitten")
|
||||
|
||||
say_list_type = /datum/say_list/snake
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee
|
||||
|
||||
/datum/say_list/snake
|
||||
emote_hear = list("hisses")
|
||||
|
||||
//NOODLE IS HERE! SQUEEEEEEEE~
|
||||
/mob/living/simple_mob/animal/space/snake/noodle
|
||||
name = "Noodle"
|
||||
desc = "This snake is particularly chubby and demands nothing but the finest of treats."
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/passive
|
||||
|
||||
var/turns_since_scan = 0
|
||||
var/obj/movement_target
|
||||
|
||||
/datum/ai_holder/simple_mob/passive
|
||||
base_wander_delay = 11 //Them pets better be slow to not push us around
|
||||
|
||||
/datum/ai_holder/simple_mob/passive
|
||||
hostile = FALSE
|
||||
can_flee = TRUE
|
||||
violent_breakthrough = FALSE
|
||||
|
||||
/mob/living/simple_mob/animal/space/snake/noodle/Life()
|
||||
..()
|
||||
|
||||
//Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically.
|
||||
|
||||
//Feeding, chasing food, FOOOOODDDD
|
||||
if(!stat && !resting && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
turns_since_scan = 0
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
|
||||
movement_target = null
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/snakesnack/S in oview(src,3))
|
||||
if(isturf(S.loc) || ishuman(S.loc))
|
||||
movement_target = S
|
||||
visible_emote("turns towards \the [movement_target] and slithers towards it.")
|
||||
break
|
||||
if(movement_target)
|
||||
step_to(src,movement_target,1)
|
||||
sleep(3)
|
||||
step_to(src,movement_target,1)
|
||||
sleep(3)
|
||||
step_to(src,movement_target,1)
|
||||
|
||||
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
|
||||
if (movement_target.loc.x < src.x)
|
||||
set_dir(WEST)
|
||||
else if (movement_target.loc.x > src.x)
|
||||
set_dir(EAST)
|
||||
else if (movement_target.loc.y < src.y)
|
||||
set_dir(SOUTH)
|
||||
else if (movement_target.loc.y > src.y)
|
||||
set_dir(NORTH)
|
||||
else
|
||||
set_dir(SOUTH)
|
||||
|
||||
if(isturf(movement_target.loc) )
|
||||
UnarmedAttack(movement_target)
|
||||
else if(ishuman(movement_target.loc) && prob(20))
|
||||
visible_emote("stares at the [movement_target] that [movement_target.loc] has with an unknowable reptilian gaze.")
|
||||
|
||||
/* old eating code, couldn't figure out how to make the "swallows food" thing so I'm keeping this here incase someone wants legacy"
|
||||
/mob/living/simple_mob/animal/space/snake/noodle/Life() //stolen from Ian in corgi.dm
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
if(!stat && !resting && !buckled && !ai_inactive)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
turns_since_scan = 0
|
||||
if(movement_target && !(isturf(movement_target.loc) || ishuman(movement_target.loc)))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if(!movement_target || !(movement_target.loc in oview(src, 5)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/snakesnack/S in oview(src,3))
|
||||
if(isturf(S.loc))
|
||||
movement_target = S
|
||||
visible_emote("turns towards \the [movement_target] and slithers towards it.")
|
||||
break
|
||||
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src, movement_target, 0, 5)
|
||||
spawn(10)
|
||||
if(Adjacent(movement_target))
|
||||
visible_message("<span class='notice'>[src] swallows the [movement_target] whole!</span>")
|
||||
qdel(movement_target)
|
||||
walk(src,0)
|
||||
else if(ishuman(movement_target.loc) && prob(20))
|
||||
visible_emote("stares at the [movement_target] that [movement_target.loc] has with an unknowable reptilian gaze.")
|
||||
*/
|
||||
|
||||
/mob/living/simple_mob/animal/space/snake/noodle/apply_melee_effects(var/atom/A)
|
||||
if(ismouse(A))
|
||||
var/mob/living/simple_mob/animal/passive/mouse/mouse = A
|
||||
if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something.
|
||||
mouse.splat()
|
||||
visible_emote(pick("swallows \the [mouse] whole!"))
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/snake/noodle/attackby(var/obj/item/O, var/mob/user)
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/snakesnack))
|
||||
visible_message("<span class='notice'>[user] feeds \the [O] to [src].</span>")
|
||||
qdel(O)
|
||||
else
|
||||
return ..()
|
||||
|
||||
//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"
|
||||
nutriment_amt = 1
|
||||
nutriment_desc = list("sugar" = 1)
|
||||
|
||||
/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]."
|
||||
reagents.add_reagent("sugar", 2)
|
||||
|
||||
/obj/item/weapon/storage/box/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
|
||||
|
||||
/obj/item/weapon/storage/box/snakesnackbox/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)
|
||||
..()
|
||||
Reference in New Issue
Block a user