mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 03:02:54 +00:00
Shifts vore mobs to proper locations, cleans loose folder
also attempts a Travis complaint fix The command "awk -f tools/indentation.awk **/*.dm" exited with 1.
This commit is contained in:
@@ -1,53 +1,53 @@
|
|||||||
/mob/living/simple_mob/vore/cookiegirl
|
/mob/living/simple_mob/vore/cookiegirl
|
||||||
name = "cookiegirl"
|
name = "cookiegirl"
|
||||||
desc = "A woman made with a combination of, well... Whatever you put in a cookie. What were the chefs thinking?"
|
desc = "A woman made with a combination of, well... Whatever you put in a cookie. What were the chefs thinking?"
|
||||||
|
|
||||||
icon_state = "cookiegirl"
|
icon_state = "cookiegirl"
|
||||||
icon_living = "cookiegirl"
|
icon_living = "cookiegirl"
|
||||||
icon_rest = "cookiegirl_rest"
|
icon_rest = "cookiegirl_rest"
|
||||||
icon_dead = "cookiegirl-dead"
|
icon_dead = "cookiegirl-dead"
|
||||||
icon = 'icons/mob/vore.dmi'
|
icon = 'icons/mob/vore.dmi'
|
||||||
|
|
||||||
maxHealth = 10
|
maxHealth = 10
|
||||||
health = 10
|
health = 10
|
||||||
|
|
||||||
harm_intent_damage = 2
|
harm_intent_damage = 2
|
||||||
melee_damage_lower = 5
|
melee_damage_lower = 5
|
||||||
melee_damage_upper = 10
|
melee_damage_upper = 10
|
||||||
|
|
||||||
say_list_type = /datum/say_list/cookiegirl
|
say_list_type = /datum/say_list/cookiegirl
|
||||||
ai_holder_type = /datum/ai_holder/simple_mob/passive/cookiegirl
|
ai_holder_type = /datum/ai_holder/simple_mob/passive/cookiegirl
|
||||||
|
|
||||||
// Activate Noms!
|
// Activate Noms!
|
||||||
/mob/living/simple_mob/vore/cookiegirl
|
/mob/living/simple_mob/vore/cookiegirl
|
||||||
vore_active = 1
|
vore_active = 1
|
||||||
vore_bump_chance = 2
|
vore_bump_chance = 2
|
||||||
vore_pounce_chance = 25
|
vore_pounce_chance = 25
|
||||||
vore_standing_too = 1
|
vore_standing_too = 1
|
||||||
vore_ignores_undigestable = 0 // Do they look like they care?
|
vore_ignores_undigestable = 0 // Do they look like they care?
|
||||||
vore_default_mode = DM_HOLD // They're cookiepeople, what do you expect?
|
vore_default_mode = DM_HOLD // They're cookiepeople, what do you expect?
|
||||||
vore_digest_chance = 10 // Gonna become as sweet as sugar, soon.
|
vore_digest_chance = 10 // Gonna become as sweet as sugar, soon.
|
||||||
vore_icons = SA_ICON_LIVING | SA_ICON_REST
|
vore_icons = SA_ICON_LIVING | SA_ICON_REST
|
||||||
|
|
||||||
/datum/ai_holder/simple_mob/passive/cookiegirl/on_hear_say(mob/living/speaker, message)
|
/datum/ai_holder/simple_mob/passive/cookiegirl/on_hear_say(mob/living/speaker, message)
|
||||||
|
|
||||||
if(!speaker.client)
|
if(!speaker.client)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(findtext(message, "Can I eat you?"))
|
if(findtext(message, "Can I eat you?"))
|
||||||
delayed_say(pick("Do you really wanna eat someone as sweet as me~?"), speaker)
|
delayed_say(pick("Do you really wanna eat someone as sweet as me~?"), speaker)
|
||||||
|
|
||||||
if(findtext(message, "You look tasty."))
|
if(findtext(message, "You look tasty."))
|
||||||
delayed_say(pick("Awww, thank you~!"), speaker)
|
delayed_say(pick("Awww, thank you~!"), speaker)
|
||||||
|
|
||||||
if(findtext(message, "Can I serve you to the crew?"))
|
if(findtext(message, "Can I serve you to the crew?"))
|
||||||
delayed_say(pick("If I have a backup, sure!"), speaker)
|
delayed_say(pick("If I have a backup, sure!"), speaker)
|
||||||
|
|
||||||
/datum/say_list/cookiegirl
|
/datum/say_list/cookiegirl
|
||||||
speak = list("Hi!","Are you hungry?","Got milk~?","What to do, what to do...")
|
speak = list("Hi!","Are you hungry?","Got milk~?","What to do, what to do...")
|
||||||
emote_hear = list("hums","whistles")
|
emote_hear = list("hums","whistles")
|
||||||
emote_see = list("shakes her head","shivers", "picks a bit of crumb off of her body and sticks it in her mouth.")
|
emote_see = list("shakes her head","shivers", "picks a bit of crumb off of her body and sticks it in her mouth.")
|
||||||
|
|
||||||
/datum/ai_holder/simple_mob/passive/cookiegirl
|
/datum/ai_holder/simple_mob/passive/cookiegirl
|
||||||
base_wander_delay = 8
|
base_wander_delay = 8
|
||||||
intelligence_level = AI_NORMAL //not sure why we have this, but I'm just porting.
|
intelligence_level = AI_NORMAL //not sure why we have this, but I'm just porting.
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
/mob/living/simple_mob/vore/fennix
|
/mob/living/simple_mob/vore/fennix
|
||||||
name = "Fennix"
|
name = "Fennix"
|
||||||
desc = "A feral fennix, Warm to the touch"
|
desc = "A feral fennix, Warm to the touch"
|
||||||
tt_desc = "Incaendium Faeles Vulpes"
|
tt_desc = "Incaendium Faeles Vulpes"
|
||||||
|
|
||||||
icon_state = "fennix"
|
icon_state = "fennix"
|
||||||
icon_living = "fennix"
|
icon_living = "fennix"
|
||||||
icon_dead = "fennix_dead"
|
icon_dead = "fennix_dead"
|
||||||
icon = 'icons/mob/vore.dmi'
|
icon = 'icons/mob/vore.dmi'
|
||||||
|
|
||||||
faction = "fennec" // Will protec other fenfens
|
faction = "fennec" // Will protec other fenfens
|
||||||
maxHealth = 60
|
maxHealth = 60
|
||||||
health = 60
|
health = 60
|
||||||
|
|
||||||
response_help = "pats the"
|
response_help = "pats the"
|
||||||
response_disarm = "gently pushes aside the"
|
response_disarm = "gently pushes aside the"
|
||||||
response_harm = "hits the"
|
response_harm = "hits the"
|
||||||
|
|
||||||
harm_intent_damage = 20
|
harm_intent_damage = 20
|
||||||
melee_damage_lower = 1
|
melee_damage_lower = 1
|
||||||
melee_damage_upper = 5
|
melee_damage_upper = 5
|
||||||
attacktext = list("Bites")
|
attacktext = list("Bites")
|
||||||
|
|
||||||
say_list_type = /datum/say_list/fennix
|
say_list_type = /datum/say_list/fennix
|
||||||
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative
|
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative
|
||||||
|
|
||||||
/datum/say_list/fennix
|
/datum/say_list/fennix
|
||||||
speak = list("SQUEL!","SQEL?","Skree.")
|
speak = list("SQUEL!","SQEL?","Skree.")
|
||||||
emote_hear = list("Screeeeecheeeeessss!","Chirrup.")
|
emote_hear = list("Screeeeecheeeeessss!","Chirrup.")
|
||||||
emote_see = list("earflicks","pats at the ground")
|
emote_see = list("earflicks","pats at the ground")
|
||||||
400
code/modules/mob/living/simple_mob/subtypes/vore/otie.dm
Normal file
400
code/modules/mob/living/simple_mob/subtypes/vore/otie.dm
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
// ToDo: Make this code not a fucking snowflaky horrible broken mess. Do not use until it's actually fixed. It's miserably bad right now.
|
||||||
|
// Also ToDo: Dev-to-dev communication to ensure responsible parties (if available. In this case, yes.) are aware of what's going on and what's broken.
|
||||||
|
// Probably easier to troubleshoot when we ain't breaking the server by spawning a buttload of heavily extra feature coded snowflake mobs to the wilderness as mass cannonfodder.
|
||||||
|
// Also ToDo: An actual "simple" mob for that purpose if necessary :v
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie //Spawn this one only if you're looking for a bad time. Not friendly.
|
||||||
|
name = "otie"
|
||||||
|
desc = "The classic bioengineered longdog."
|
||||||
|
tt_desc = "Otus robustus"
|
||||||
|
icon = 'icons/mob/vore64x32.dmi'
|
||||||
|
icon_state = "otie"
|
||||||
|
icon_living = "otie"
|
||||||
|
icon_dead = "otie-dead"
|
||||||
|
icon_rest = "otie_rest"
|
||||||
|
faction = "otie"
|
||||||
|
recruitable = 1
|
||||||
|
maxHealth = 150
|
||||||
|
health = 150
|
||||||
|
minbodytemp = 200
|
||||||
|
move_to_delay = 4
|
||||||
|
hostile = 1
|
||||||
|
investigates = 1
|
||||||
|
reacts = 1
|
||||||
|
animal = 1
|
||||||
|
specific_targets = 1
|
||||||
|
run_at_them = 0
|
||||||
|
attack_same = 0
|
||||||
|
speak_chance = 4
|
||||||
|
speak = list("Boof.","Waaf!","Prurr.","Bork!","Rurrr..","Arf.")
|
||||||
|
speak_emote = list("growls", "roars", "yaps", "Awoos")
|
||||||
|
emote_hear = list("rurrs", "rumbles", "rowls", "groans softly", "murrs", "sounds hungry", "yawns")
|
||||||
|
emote_see = list("stares ferociously", "snarls", "licks their chops", "stretches", "yawns")
|
||||||
|
say_maybe_target = list("Ruh?", "Waf?")
|
||||||
|
say_got_target = list("Rurrr!", "ROAR!", "MARR!", "RERR!", "RAHH!", "RAH!", "WARF!")
|
||||||
|
melee_damage_lower = 5
|
||||||
|
melee_damage_upper = 15 //Don't break my bones bro
|
||||||
|
response_help = "pets the"
|
||||||
|
response_disarm = "bops the"
|
||||||
|
response_harm = "hits the"
|
||||||
|
attacktext = list("mauled")
|
||||||
|
friendly = list("nuzzles", "slobberlicks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on")
|
||||||
|
meat_amount = 6
|
||||||
|
old_x = -16
|
||||||
|
old_y = 0
|
||||||
|
default_pixel_x = -16
|
||||||
|
pixel_x = -16
|
||||||
|
pixel_y = 0
|
||||||
|
|
||||||
|
max_buckled_mobs = 1 //Yeehaw
|
||||||
|
can_buckle = TRUE
|
||||||
|
buckle_movable = TRUE
|
||||||
|
buckle_lying = FALSE
|
||||||
|
mount_offset_y = 10
|
||||||
|
|
||||||
|
var/glowyeyes = FALSE
|
||||||
|
var/image/eye_layer = null
|
||||||
|
var/eyetype
|
||||||
|
var/mob/living/carbon/human/friend
|
||||||
|
var/tamed = 0
|
||||||
|
var/tame_chance = 50 //It's a fiddy-fiddy default you may get a buddy pal or you may get mauled and ate. Win-win!
|
||||||
|
|
||||||
|
// Activate Noms!
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie
|
||||||
|
vore_active = 1
|
||||||
|
vore_capacity = 1
|
||||||
|
vore_pounce_chance = 20
|
||||||
|
vore_icons = SA_ICON_LIVING | SA_ICON_REST
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/feral //gets the pet2tame feature. starts out hostile tho so get gamblin'
|
||||||
|
name = "mutated feral otie"
|
||||||
|
desc = "The classic bioengineered longdog. No pets. Only bite. This one has mutated from too much time out on the surface of Virgo-3B."
|
||||||
|
tt_desc = "Otus phoronis"
|
||||||
|
icon_state = "siftusian"
|
||||||
|
icon_living = "siftusian"
|
||||||
|
icon_dead = "siftusian-dead"
|
||||||
|
icon_rest = "siftusian_rest"
|
||||||
|
faction = "virgo3b"
|
||||||
|
tame_chance = 5 // Only a 1 in 20 chance of success. It's feral. What do you expect?
|
||||||
|
melee_damage_lower = 10
|
||||||
|
melee_damage_upper = 25
|
||||||
|
// Lazy way of making sure this otie survives outside.
|
||||||
|
min_oxy = 0
|
||||||
|
max_oxy = 0
|
||||||
|
min_tox = 0
|
||||||
|
max_tox = 0
|
||||||
|
min_co2 = 0
|
||||||
|
max_co2 = 0
|
||||||
|
min_n2 = 0
|
||||||
|
max_n2 = 0
|
||||||
|
glowyeyes = TRUE
|
||||||
|
eyetype = "photie"
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/red
|
||||||
|
name = "feral red otie"
|
||||||
|
desc = "Seems this ominous looking longdog has been infused with wicked infernal forces."
|
||||||
|
tt_desc = "Otus infernalis"
|
||||||
|
icon_state = "hotie"
|
||||||
|
icon_living = "hotie"
|
||||||
|
icon_dead = "hotie-dead"
|
||||||
|
icon_rest = "hotie_rest"
|
||||||
|
faction = "cult"
|
||||||
|
tame_chance = 20
|
||||||
|
melee_damage_lower = 10
|
||||||
|
melee_damage_upper = 25
|
||||||
|
// Lazy way of making sure this otie survives outside.
|
||||||
|
min_oxy = 0
|
||||||
|
max_oxy = 0
|
||||||
|
min_tox = 0
|
||||||
|
max_tox = 0
|
||||||
|
min_co2 = 0
|
||||||
|
max_co2 = 0
|
||||||
|
min_n2 = 0
|
||||||
|
max_n2 = 0
|
||||||
|
glowyeyes = TRUE
|
||||||
|
eyetype = "hotie"
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/red/friendly //gets the pet2tame feature and doesn't kill you right away
|
||||||
|
name = "red otie"
|
||||||
|
desc = "Seems this ominous looking longdog has been infused with wicked infernal forces. This one seems rather peaceful though."
|
||||||
|
faction = "neutral"
|
||||||
|
tamed = 1
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/friendly //gets the pet2tame feature and doesn't kill you right away
|
||||||
|
name = "otie"
|
||||||
|
desc = "The classic bioengineered longdog. This one might even tolerate you!"
|
||||||
|
faction = "neutral"
|
||||||
|
tamed = 1
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/cotie //same as above but has a little collar :v
|
||||||
|
name = "tamed otie"
|
||||||
|
desc = "The classic bioengineered longdog. This one has a nice little collar on its neck. However a proper domesticated otie is an oxymoron and the collar is likely just a decoration."
|
||||||
|
icon_state = "cotie"
|
||||||
|
icon_living = "cotie"
|
||||||
|
icon_rest = "cotie_rest"
|
||||||
|
faction = "neutral"
|
||||||
|
tamed = 1
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/cotie/phoron //friendly phoron pup with collar
|
||||||
|
name = "mutated otie"
|
||||||
|
desc = "Looks like someone did manage to domesticate one of those wild phoron mutants. What a badass."
|
||||||
|
tt_desc = "Otus phoronis"
|
||||||
|
icon_state = "pcotie"
|
||||||
|
icon_living = "pcotie"
|
||||||
|
icon_rest = "pcotie_rest"
|
||||||
|
icon_dead = "siftusian-dead"
|
||||||
|
min_oxy = 0
|
||||||
|
max_oxy = 0
|
||||||
|
min_tox = 0
|
||||||
|
max_tox = 0
|
||||||
|
min_co2 = 0
|
||||||
|
max_co2 = 0
|
||||||
|
min_n2 = 0
|
||||||
|
max_n2 = 0
|
||||||
|
glowyeyes = TRUE
|
||||||
|
eyetype = "photie"
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho.
|
||||||
|
name = "guard otie"
|
||||||
|
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs."
|
||||||
|
icon_state = "sotie"
|
||||||
|
icon_living = "sotie"
|
||||||
|
icon_rest = "sotie_rest"
|
||||||
|
icon_dead = "sotie-dead"
|
||||||
|
faction = "neutral"
|
||||||
|
maxHealth = 200 //armored or something
|
||||||
|
health = 200
|
||||||
|
tamed = 1
|
||||||
|
glowyeyes = TRUE
|
||||||
|
eyetype = "sotie"
|
||||||
|
loot_list = list(/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/suit/armor/vest/alt)
|
||||||
|
vore_pounce_chance = 60 // Good boys don't do too much police brutality.
|
||||||
|
|
||||||
|
var/check_records = 0 // If true, arrests people without a record.
|
||||||
|
var/check_arrest = 1 // If true, arrests people who are set to arrest.
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/phoron
|
||||||
|
name = "mutated guard otie"
|
||||||
|
desc = "An extra rare phoron resistant version of the VARMAcorp trained snowflake guard dogs."
|
||||||
|
tt_desc = "Otus phoronis"
|
||||||
|
icon_state = "sifguard"
|
||||||
|
icon_living = "sifguard"
|
||||||
|
icon_rest = "sifguard_rest"
|
||||||
|
icon_dead = "sifguard-dead"
|
||||||
|
melee_damage_lower = 10
|
||||||
|
melee_damage_upper = 25
|
||||||
|
min_oxy = 0
|
||||||
|
max_oxy = 0
|
||||||
|
min_tox = 0
|
||||||
|
max_tox = 0
|
||||||
|
min_co2 = 0
|
||||||
|
max_co2 = 0
|
||||||
|
min_n2 = 0
|
||||||
|
max_n2 = 0
|
||||||
|
glowyeyes = TRUE
|
||||||
|
eyetype = "sotie"
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/PunchTarget()
|
||||||
|
if(istype(target_mob,/mob/living/simple_mob/mouse))
|
||||||
|
return EatTarget()
|
||||||
|
else ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/Found(var/atom/found_atom)
|
||||||
|
if(!SA_attackable(found_atom))
|
||||||
|
return null
|
||||||
|
if(istype(found_atom,/mob/living/simple_mob/mouse))
|
||||||
|
return found_atom
|
||||||
|
else if(ismob(found_atom))
|
||||||
|
var/mob/found_mob = found_atom
|
||||||
|
if(found_mob.faction == faction)
|
||||||
|
return null
|
||||||
|
else if(friend == found_atom)
|
||||||
|
return null
|
||||||
|
else if(tamed == 1 && ishuman(found_atom))
|
||||||
|
return null
|
||||||
|
else if(tamed == 1 && isrobot(found_atom))
|
||||||
|
return null
|
||||||
|
else
|
||||||
|
if(resting)
|
||||||
|
lay_down()
|
||||||
|
return found_atom
|
||||||
|
else
|
||||||
|
return null
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/Found(var/atom/found_atom)
|
||||||
|
if(check_threat(found_atom) >= 4)
|
||||||
|
if(resting)
|
||||||
|
lay_down()
|
||||||
|
return found_atom
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/attackby(var/obj/item/O, var/mob/user) // Trade donuts for bellybrig victims.
|
||||||
|
if(istype(O, /obj/item/weapon/reagent_containers/food))
|
||||||
|
qdel(O)
|
||||||
|
playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
|
||||||
|
if(ai_inactive)//No autobarf on player control.
|
||||||
|
return
|
||||||
|
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/donut) && istype(src, /mob/living/simple_mob/otie/security))
|
||||||
|
to_chat(user,"<span class='notice'>The guard pup accepts your offer for their catch.</span>")
|
||||||
|
release_vore_contents()
|
||||||
|
else if(prob(2)) //Small chance to get prey out from non-sec oties.
|
||||||
|
to_chat(user,"<span class='notice'>The pup accepts your offer for their catch.</span>")
|
||||||
|
release_vore_contents()
|
||||||
|
return
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) // Make the gut start out safe for bellybrigging.
|
||||||
|
if(ishuman(prey))
|
||||||
|
vore_selected.digest_mode = DM_HOLD
|
||||||
|
if(check_threat(prey) >= 4)
|
||||||
|
global_announcer.autosay("[src] has detained suspect <b>[target_name(prey)]</b> in <b>[get_area(src)]</b>.", "SmartCollar oversight", "Security")
|
||||||
|
if(istype(prey,/mob/living/simple_mob/mouse))
|
||||||
|
vore_selected.digest_mode = DM_DIGEST
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/proc/check_threat(var/mob/living/M)
|
||||||
|
if(!M || !ishuman(M) || M.stat == DEAD || src == M)
|
||||||
|
return 0
|
||||||
|
return M.assess_perp(0, 0, 0, check_records, check_arrest)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/set_target(var/mob/M)
|
||||||
|
ai_log("SetTarget([M])",2)
|
||||||
|
if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob)
|
||||||
|
ai_log("SetTarget() can't set it again so soon",3)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/turf/seen = get_turf(M)
|
||||||
|
|
||||||
|
if(investigates && (annoyed < 10))
|
||||||
|
try_say_list(say_maybe_target)
|
||||||
|
face_atom(seen)
|
||||||
|
annoyed += 14
|
||||||
|
sleep(1 SECOND) //For realism
|
||||||
|
|
||||||
|
if(M in ListTargets(view_range))
|
||||||
|
try_say_list(say_got_target)
|
||||||
|
target_mob = M
|
||||||
|
last_target_time = world.time
|
||||||
|
if(check_threat(M) >= 4)
|
||||||
|
global_announcer.autosay("[src] is attempting to detain suspect <b>[target_name(M)]</b> in <b>[get_area(src)]</b>.", "SmartCollar oversight", "Security")
|
||||||
|
return M
|
||||||
|
else if(investigates)
|
||||||
|
spawn(1)
|
||||||
|
WanderTowards(seen)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/security/proc/target_name(mob/living/T)
|
||||||
|
if(ishuman(T))
|
||||||
|
var/mob/living/carbon/human/H = T
|
||||||
|
return H.get_id_name("unidentified person")
|
||||||
|
return "unidentified lifeform"
|
||||||
|
|
||||||
|
//Basic friend AI
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/Life()
|
||||||
|
. = ..()
|
||||||
|
if(!. || ai_inactive) return
|
||||||
|
|
||||||
|
if(prob(5) && (stance == STANCE_IDLE))
|
||||||
|
lay_down()
|
||||||
|
|
||||||
|
if(!friend) return
|
||||||
|
|
||||||
|
var/friend_dist = get_dist(src,friend)
|
||||||
|
|
||||||
|
if (friend_dist <= 4)
|
||||||
|
if(stance == STANCE_IDLE)
|
||||||
|
if(set_follow(friend))
|
||||||
|
handle_stance(STANCE_FOLLOW)
|
||||||
|
if(resting)
|
||||||
|
lay_down()
|
||||||
|
|
||||||
|
if (friend_dist <= 1)
|
||||||
|
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
|
||||||
|
if (prob((friend.stat < DEAD)? 50 : 15))
|
||||||
|
var/verb = pick("whines", "yelps", "whimpers")
|
||||||
|
audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
|
||||||
|
else
|
||||||
|
if (prob(5))
|
||||||
|
visible_emote(pick("nuzzles [friend].",
|
||||||
|
"brushes against [friend].",
|
||||||
|
"rubs against [friend].",
|
||||||
|
"noses at [friend].",
|
||||||
|
"slobberlicks [friend].",
|
||||||
|
"murrs contently.",
|
||||||
|
"leans on [friend].",
|
||||||
|
"nibbles affectionately on [friend]."))
|
||||||
|
else if (friend.health <= 50)
|
||||||
|
if (prob(10))
|
||||||
|
var/verb = pick("whines", "yelps", "whimpers")
|
||||||
|
audible_emote("[verb] anxiously.")
|
||||||
|
|
||||||
|
//Pet 4 friendly
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/attack_hand(mob/living/carbon/human/M as mob)
|
||||||
|
|
||||||
|
switch(M.a_intent)
|
||||||
|
if(I_HELP)
|
||||||
|
if(health > 0)
|
||||||
|
M.visible_message("<span class='notice'>[M] [response_help] \the [src].</span>")
|
||||||
|
if(ai_inactive)
|
||||||
|
return
|
||||||
|
LoseTarget()
|
||||||
|
handle_stance(STANCE_IDLE)
|
||||||
|
if(prob(tame_chance))
|
||||||
|
friend = M
|
||||||
|
if(tamed != 1)
|
||||||
|
tamed = 1
|
||||||
|
faction = M.faction
|
||||||
|
sleep(1 SECOND)
|
||||||
|
|
||||||
|
if(I_GRAB)
|
||||||
|
if(health > 0)
|
||||||
|
if(ai_inactive)
|
||||||
|
return
|
||||||
|
audible_emote("growls disapprovingly at [M].")
|
||||||
|
if(M == friend)
|
||||||
|
friend = null
|
||||||
|
return
|
||||||
|
else
|
||||||
|
..()
|
||||||
|
|
||||||
|
else
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/proc/add_eyes()
|
||||||
|
if(!eye_layer)
|
||||||
|
eye_layer = image(icon, "[eyetype]-eyes")
|
||||||
|
eye_layer.plane = PLANE_LIGHTING_ABOVE
|
||||||
|
add_overlay(eye_layer)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/proc/remove_eyes()
|
||||||
|
cut_overlay(eye_layer)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/New()
|
||||||
|
if(glowyeyes)
|
||||||
|
add_eyes()
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/update_icon()
|
||||||
|
. = ..()
|
||||||
|
remove_eyes()
|
||||||
|
if(glowyeyes && stat == CONSCIOUS && !resting)
|
||||||
|
add_eyes()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/otie/death(gibbed, deathmessage = "dies!")
|
||||||
|
.=..()
|
||||||
|
resting = 0
|
||||||
|
icon_state = icon_dead
|
||||||
|
|
||||||
|
/mob/living/simple_animal/otie/Login()
|
||||||
|
. = ..()
|
||||||
|
if(!riding_datum)
|
||||||
|
riding_datum = new /datum/riding/simple_animal(src)
|
||||||
|
verbs |= /mob/living/simple_animal/proc/animal_mount
|
||||||
|
|
||||||
|
/mob/living/simple_animal/otie/MouseDrop_T(mob/living/M, mob/living/user)
|
||||||
|
return
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#define NOT_WHILE_SHIFTED 1
|
||||||
|
#define ONLY_WHILE_SHIFTED 2
|
||||||
|
#define SHIFTED_OR_NOT 3
|
||||||
|
|
||||||
|
#define BLUE_EYES 1
|
||||||
|
#define RED_EYES 2
|
||||||
|
#define PURPLE_EYES 3
|
||||||
|
#define YELLOW_EYES 4
|
||||||
|
#define GREEN_EYES 5
|
||||||
|
#define ORANGE_EYES 6
|
||||||
|
|
||||||
|
#define AB_PHASE_SHIFTED 0x1
|
||||||
|
#define AB_SHADE_REGEN 0x2
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/obj/effect/shadekin_ability
|
||||||
|
name = ""
|
||||||
|
desc = ""
|
||||||
|
icon = 'icons/mob/screen_spells.dmi'
|
||||||
|
var/ability_name = "FIX ME"
|
||||||
|
var/cost = 50
|
||||||
|
var/mob/living/simple_mob/shadekin/my_kin
|
||||||
|
var/shift_mode = NOT_WHILE_SHIFTED
|
||||||
|
var/ab_sound
|
||||||
|
|
||||||
|
/obj/effect/shadekin_ability/New(var/new_kin)
|
||||||
|
..()
|
||||||
|
my_kin = new_kin
|
||||||
|
loc = null
|
||||||
|
|
||||||
|
/obj/effect/shadekin_ability/Destroy()
|
||||||
|
my_kin = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/shadekin_ability/proc/atom_button_text()
|
||||||
|
var/shift_denial
|
||||||
|
|
||||||
|
if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED))
|
||||||
|
shift_denial = "Physical Only"
|
||||||
|
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED))
|
||||||
|
shift_denial = "Shifted Only"
|
||||||
|
|
||||||
|
if(shift_denial)
|
||||||
|
name = shift_denial
|
||||||
|
else
|
||||||
|
name = my_kin.energy >= cost ? "Activate" : "No Energy"
|
||||||
|
return src
|
||||||
|
|
||||||
|
/obj/effect/shadekin_ability/Click(var/location, var/control, var/params)
|
||||||
|
if(my_kin.stat) return
|
||||||
|
|
||||||
|
var/list/clickprops = params2list(params)
|
||||||
|
var/opts = clickprops["shift"]
|
||||||
|
|
||||||
|
if(opts)
|
||||||
|
to_chat(my_kin,"<span class='notice'><b>[name]</b> (Cost: [cost]%) - [desc]</span>")
|
||||||
|
else
|
||||||
|
do_ability(my_kin)
|
||||||
|
|
||||||
|
/obj/effect/shadekin_ability/proc/do_ability()
|
||||||
|
if(my_kin.stat)
|
||||||
|
to_chat(my_kin,"<span class='warning'>Can't use that ability in your state!</span>")
|
||||||
|
return FALSE
|
||||||
|
if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED))
|
||||||
|
to_chat(my_kin,"<span class='warning'>Can't use that ability while phase shifted!</span>")
|
||||||
|
return FALSE
|
||||||
|
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED))
|
||||||
|
to_chat(my_kin,"<span class='warning'>Can only use that ability while phase shifted!</span>")
|
||||||
|
return FALSE
|
||||||
|
else if(my_kin.energy < cost)
|
||||||
|
to_chat(my_kin,"<span class='warning'>Not enough energy for that ability!</span>")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
my_kin.energy -= cost
|
||||||
|
if(ab_sound)
|
||||||
|
playsound(src,ab_sound,75,1)
|
||||||
|
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/obj/effect/shadekin_ability/phase_shift
|
||||||
|
ability_name = "Phase Shift"
|
||||||
|
desc = "Shift yourself out of alignment with realspace to travel quickly between dark areas (or light areas, with a price)."
|
||||||
|
icon_state = "tech_passwall"
|
||||||
|
cost = 100
|
||||||
|
shift_mode = SHIFTED_OR_NOT
|
||||||
|
ab_sound = 'sound/effects/stealthoff.ogg'
|
||||||
|
/obj/effect/shadekin_ability/phase_shift/do_ability()
|
||||||
|
if(!..())
|
||||||
|
return
|
||||||
|
my_kin.phase_shift()
|
||||||
|
if(my_kin.ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
cost = 0 //Shifting back is free (but harmful in light)
|
||||||
|
else
|
||||||
|
cost = initial(cost)
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/obj/effect/shadekin_ability/heal_boop
|
||||||
|
ability_name = "Regenerate Other"
|
||||||
|
desc = "Spend energy to heal physical wounds in another creature."
|
||||||
|
icon_state = "tech_biomedaura"
|
||||||
|
cost = 50
|
||||||
|
shift_mode = NOT_WHILE_SHIFTED
|
||||||
|
ab_sound = 'sound/effects/EMPulse.ogg'
|
||||||
|
/obj/effect/shadekin_ability/heal_boop/do_ability()
|
||||||
|
if(!..())
|
||||||
|
return
|
||||||
|
if(!my_kin.mend_other())
|
||||||
|
my_kin.energy += cost //Refund due to abort
|
||||||
|
|
||||||
|
/datum/modifier/shadekin/heal_boop
|
||||||
|
name = "Shadekin Regen"
|
||||||
|
desc = "You feel serene and well rested."
|
||||||
|
mob_overlay_state = "green_sparkles"
|
||||||
|
|
||||||
|
on_created_text = "<span class='notice'>Sparkles begin to appear around you, and all your ills seem to fade away.</span>"
|
||||||
|
on_expired_text = "<span class='notice'>The sparkles have faded, although you feel much healthier than before.</span>"
|
||||||
|
stacks = MODIFIER_STACK_EXTEND
|
||||||
|
|
||||||
|
/datum/modifier/shadekin/heal_boop/tick()
|
||||||
|
if(!holder.getBruteLoss() && !holder.getFireLoss() && !holder.getToxLoss() && !holder.getOxyLoss() && !holder.getCloneLoss()) // No point existing if the spell can't heal.
|
||||||
|
expire()
|
||||||
|
return
|
||||||
|
holder.adjustBruteLoss(-2)
|
||||||
|
holder.adjustFireLoss(-2)
|
||||||
|
holder.adjustToxLoss(-2)
|
||||||
|
holder.adjustOxyLoss(-2)
|
||||||
|
holder.adjustCloneLoss(-2)
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/obj/effect/shadekin_ability/create_shade
|
||||||
|
ability_name = "Create Shade"
|
||||||
|
desc = "Create a field of darkness that follows you."
|
||||||
|
icon_state = "tech_dispelold"
|
||||||
|
cost = 25
|
||||||
|
shift_mode = NOT_WHILE_SHIFTED
|
||||||
|
ab_sound = 'sound/effects/bamf.ogg'
|
||||||
|
/obj/effect/shadekin_ability/create_shade/do_ability()
|
||||||
|
if(!..())
|
||||||
|
return
|
||||||
|
my_kin.add_modifier(/datum/modifier/shadekin/create_shade,20 SECONDS)
|
||||||
|
/datum/modifier/shadekin/create_shade
|
||||||
|
name = "Shadekin Shadegen"
|
||||||
|
desc = "Darkness envelops you."
|
||||||
|
mob_overlay_state = ""
|
||||||
|
|
||||||
|
on_created_text = "<span class='notice'>You drag part of The Dark into realspace, enveloping yourself.</span>"
|
||||||
|
on_expired_text = "<span class='warning'>You lose your grasp on The Dark and realspace reasserts itself.</span>"
|
||||||
|
stacks = MODIFIER_STACK_EXTEND
|
||||||
|
var/mob/living/simple_mob/shadekin/my_kin
|
||||||
|
|
||||||
|
/datum/modifier/shadekin/create_shade/tick()
|
||||||
|
if(my_kin.ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
expire()
|
||||||
|
|
||||||
|
/datum/modifier/shadekin/create_shade/on_applied()
|
||||||
|
my_kin = holder
|
||||||
|
holder.glow_toggle = TRUE
|
||||||
|
holder.glow_range = 8
|
||||||
|
holder.glow_intensity = -10
|
||||||
|
holder.glow_color = "#FFFFFF"
|
||||||
|
holder.set_light(8, -10, "#FFFFFF")
|
||||||
|
|
||||||
|
/datum/modifier/shadekin/create_shade/on_expire()
|
||||||
|
holder.glow_toggle = initial(holder.glow_toggle)
|
||||||
|
holder.glow_range = initial(holder.glow_range)
|
||||||
|
holder.glow_intensity = initial(holder.glow_intensity)
|
||||||
|
holder.glow_color = initial(holder.glow_color)
|
||||||
|
holder.set_light(0)
|
||||||
|
my_kin = null
|
||||||
|
/*
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/obj/effect/shadekin_ability/energy_feast
|
||||||
|
ability_name = "Devour Energy"
|
||||||
|
desc = "Devour the energy from another creature (potentially fatal)."
|
||||||
|
icon_state = "gen_eat"
|
||||||
|
cost = 25
|
||||||
|
shift_mode = NOT_WHILE_SHIFTED
|
||||||
|
/obj/effect/shadekin_ability/energy_feast/do_ability()
|
||||||
|
if(!..())
|
||||||
|
return
|
||||||
|
*/
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
// Phase shifting procs (and related procs)
|
||||||
|
/mob/living/simple_mob/shadekin/proc/phase_shift()
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
if(!T.CanPass(null,T) || loc != T)
|
||||||
|
to_chat(src,"<span class='warning'>You can't use that here!</span>")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
forceMove(T)
|
||||||
|
var/original_canmove = canmove
|
||||||
|
SetStunned(0)
|
||||||
|
SetWeakened(0)
|
||||||
|
if(buckled)
|
||||||
|
buckled.unbuckle_mob()
|
||||||
|
if(pulledby)
|
||||||
|
pulledby.stop_pulling()
|
||||||
|
stop_pulling()
|
||||||
|
canmove = FALSE
|
||||||
|
|
||||||
|
//Shifting in
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
ability_flags &= ~AB_PHASE_SHIFTED
|
||||||
|
name = real_name
|
||||||
|
for(var/belly in vore_organs)
|
||||||
|
var/obj/belly/B = belly
|
||||||
|
B.escapable = initial(B.escapable)
|
||||||
|
|
||||||
|
overlays.Cut()
|
||||||
|
alpha = initial(alpha)
|
||||||
|
invisibility = initial(invisibility)
|
||||||
|
see_invisible = initial(see_invisible)
|
||||||
|
incorporeal_move = initial(incorporeal_move)
|
||||||
|
density = initial(density)
|
||||||
|
force_max_speed = initial(force_max_speed)
|
||||||
|
|
||||||
|
//Cosmetics mostly
|
||||||
|
flick("tp_in",src)
|
||||||
|
custom_emote(1,"phases in!")
|
||||||
|
sleep(5) //The duration of the TP animation
|
||||||
|
canmove = original_canmove
|
||||||
|
|
||||||
|
//Potential phase-in vore
|
||||||
|
if(can_be_drop_pred) //Toggleable in vore panel
|
||||||
|
var/list/potentials = living_mobs(0)
|
||||||
|
if(potentials.len)
|
||||||
|
var/mob/living/target = pick(potentials)
|
||||||
|
if(istype(target) && vore_selected)
|
||||||
|
target.forceMove(vore_selected)
|
||||||
|
to_chat(target,"<span class='warning'>\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!</span>")
|
||||||
|
|
||||||
|
// Do this after the potential vore, so we get the belly
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
//Affect nearby lights
|
||||||
|
var/destroy_lights = 0
|
||||||
|
if(eye_state == RED_EYES)
|
||||||
|
destroy_lights = 80
|
||||||
|
if(eye_state == PURPLE_EYES)
|
||||||
|
destroy_lights = 25
|
||||||
|
|
||||||
|
for(var/obj/machinery/light/L in machines)
|
||||||
|
if(L.z != z || get_dist(src,L) > 10)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if(prob(destroy_lights))
|
||||||
|
spawn(rand(5,25))
|
||||||
|
L.broken()
|
||||||
|
else
|
||||||
|
L.flicker(10)
|
||||||
|
|
||||||
|
//Shifting out
|
||||||
|
else
|
||||||
|
ability_flags |= AB_PHASE_SHIFTED
|
||||||
|
custom_emote(1,"phases out!")
|
||||||
|
real_name = name
|
||||||
|
name = "Something"
|
||||||
|
|
||||||
|
for(var/belly in vore_organs)
|
||||||
|
var/obj/belly/B = belly
|
||||||
|
B.escapable = FALSE
|
||||||
|
|
||||||
|
overlays.Cut()
|
||||||
|
flick("tp_out",src)
|
||||||
|
sleep(5)
|
||||||
|
invisibility = INVISIBILITY_LEVEL_TWO
|
||||||
|
see_invisible = INVISIBILITY_LEVEL_TWO
|
||||||
|
update_icon()
|
||||||
|
alpha = 127
|
||||||
|
|
||||||
|
canmove = original_canmove
|
||||||
|
incorporeal_move = TRUE
|
||||||
|
density = FALSE
|
||||||
|
force_max_speed = TRUE
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/UnarmedAttack()
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
return FALSE //Nope.
|
||||||
|
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/can_fall()
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
return FALSE //Nope!
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/zMove(direction)
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
|
||||||
|
if(destination)
|
||||||
|
forceMove(destination)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
// Healing others
|
||||||
|
/mob/living/simple_mob/shadekin/proc/mend_other()
|
||||||
|
//I hate to crunch a view() but I only want ones I can see
|
||||||
|
var/list/viewed = oview(1)
|
||||||
|
var/list/targets = list()
|
||||||
|
for(var/mob/living/L in viewed)
|
||||||
|
targets += L
|
||||||
|
if(!targets.len)
|
||||||
|
to_chat(src,"<span class='warning'>Nobody nearby to mend!</span>")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
var/mob/living/target = input(src,"Pick someone to mend:","Mend Other") as null|anything in targets
|
||||||
|
if(!target)
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
target.add_modifier(/datum/modifier/shadekin/heal_boop,1 MINUTE)
|
||||||
|
visible_message("<span class='notice'>\The [src] gently places a hand on \the [target]...</span>")
|
||||||
|
face_atom(target)
|
||||||
|
return TRUE
|
||||||
@@ -0,0 +1,447 @@
|
|||||||
|
/mob/living/simple_mob/shadekin //Spawning the prototype spawns a random one, see initialize()
|
||||||
|
name = "shadekin"
|
||||||
|
desc = "Some sort of fluffer. Big ears, long tail."
|
||||||
|
icon = 'icons/mob/vore_shadekin.dmi'
|
||||||
|
icon_state = "map_example"
|
||||||
|
icon_living = "map_example"
|
||||||
|
faction = "shadekin"
|
||||||
|
ui_icons = 'icons/mob/shadekin_hud.dmi'
|
||||||
|
intelligence_level = SA_HUMANOID
|
||||||
|
|
||||||
|
maxHealth = 200
|
||||||
|
health = 200
|
||||||
|
|
||||||
|
move_to_delay = 2
|
||||||
|
speed = -1
|
||||||
|
see_in_dark = 10 //SHADEkin
|
||||||
|
has_hands = TRUE //Pawbs
|
||||||
|
seedarkness = FALSE //SHAAAADEkin
|
||||||
|
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||||
|
has_langs = list(LANGUAGE_GALCOM,LANGUAGE_SHADEKIN)
|
||||||
|
|
||||||
|
investigates = TRUE
|
||||||
|
reacts = TRUE
|
||||||
|
run_at_them = FALSE
|
||||||
|
cooperative = FALSE
|
||||||
|
|
||||||
|
melee_damage_lower = 10
|
||||||
|
melee_damage_upper = 20
|
||||||
|
|
||||||
|
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
|
||||||
|
maxbodytemp = 900
|
||||||
|
|
||||||
|
speak_chance = 2
|
||||||
|
speak = list("Marrr.", "Marrr?", "Marrr!")
|
||||||
|
emote_hear = list("chrrrrrs", "wurbles", "wrrrrbles")
|
||||||
|
emote_see = list("tailtwitches", "earflicks")
|
||||||
|
say_maybe_target = list("...mar?")
|
||||||
|
say_got_target = list("MAR!!!")
|
||||||
|
response_help = "pets the"
|
||||||
|
response_disarm = "bops the"
|
||||||
|
response_harm = "hits the"
|
||||||
|
attacktext = list("mauled","slashed","clawed")
|
||||||
|
friendly = list("boops", "pawbs", "mars softly at", "sniffs on")
|
||||||
|
reactions = list("Mar?" = "Marrr!", "Mar!" = "Marrr???", "Mar." = "Marrr.")
|
||||||
|
|
||||||
|
vore_active = TRUE
|
||||||
|
vore_pounce_chance = 10
|
||||||
|
vore_icons = SA_ICON_LIVING
|
||||||
|
swallowTime = 2 SECONDS
|
||||||
|
vore_escape_chance = 25
|
||||||
|
|
||||||
|
//None, they stay as their defaults.
|
||||||
|
vore_digest_chance = 0
|
||||||
|
vore_absorb_chance = 0
|
||||||
|
vore_bump_chance = 0 //They follow people, this would be DENGEROUS
|
||||||
|
|
||||||
|
var/eye_state = RED_EYES //Eye color/energy gain/loss mode
|
||||||
|
var/eye_icon_state = null //Default, changed in init
|
||||||
|
var/eye_desc //Eye color description added to examine
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/henlo_human //Human we're stalking currently
|
||||||
|
|
||||||
|
//Behavior
|
||||||
|
var/stalker = TRUE //Do we creep up on humans
|
||||||
|
var/shy_approach = FALSE //Do we creep up slowly on humans to boop them
|
||||||
|
|
||||||
|
//Icon handling
|
||||||
|
var/image/tailimage //Cached tail image
|
||||||
|
|
||||||
|
//Darknesssss
|
||||||
|
var/energy = 100 //For abilities
|
||||||
|
var/energy_adminbuse = FALSE //For adminbuse infinite energy
|
||||||
|
var/dark_gains = 0 //Last tick's change in energy
|
||||||
|
var/ability_flags = 0 //Flags for active abilities
|
||||||
|
var/obj/screen/darkhud //Holder to update this icon
|
||||||
|
var/obj/screen/energyhud //Holder to update this icon
|
||||||
|
|
||||||
|
var/list/shadekin_abilities
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/initialize()
|
||||||
|
//You spawned the prototype, and want a totally random one.
|
||||||
|
if(type == /mob/living/simple_mob/shadekin)
|
||||||
|
|
||||||
|
//I'm told by VerySoft these are the liklihood values
|
||||||
|
var/list/sk_types = list(
|
||||||
|
/mob/living/simple_mob/shadekin/red = 20, //Actively seek people out to nom, so fairly common to see (relatively speaking),
|
||||||
|
/mob/living/simple_mob/shadekin/blue = 15, //Explorers that like to interact with people, so still fairly common,
|
||||||
|
/mob/living/simple_mob/shadekin/purple = 15, //Also explorers that may or may not homf people,
|
||||||
|
/mob/living/simple_mob/shadekin/yellow = 1 //Very rare, usually never leaves their home
|
||||||
|
)
|
||||||
|
var/new_type = pickweight(sk_types)
|
||||||
|
|
||||||
|
new new_type(loc)
|
||||||
|
initialized = TRUE
|
||||||
|
return INITIALIZE_HINT_QDEL
|
||||||
|
|
||||||
|
if(icon_state == "map_example")
|
||||||
|
icon_state = pick("white","dark","brown")
|
||||||
|
|
||||||
|
icon_living = icon_state
|
||||||
|
|
||||||
|
switch(eye_state)
|
||||||
|
if(BLUE_EYES)
|
||||||
|
eye_icon_state = "e_blue"
|
||||||
|
if(RED_EYES)
|
||||||
|
eye_icon_state = "e_red"
|
||||||
|
if(PURPLE_EYES)
|
||||||
|
eye_icon_state = "e_purple"
|
||||||
|
if(YELLOW_EYES)
|
||||||
|
eye_icon_state = "e_yellow"
|
||||||
|
if(GREEN_EYES)
|
||||||
|
eye_icon_state = "e_green"
|
||||||
|
if(ORANGE_EYES)
|
||||||
|
eye_icon_state = "e_orange"
|
||||||
|
else
|
||||||
|
eye_icon_state = "e_red"
|
||||||
|
|
||||||
|
tailimage = image('icons/mob/vore_shadekin64.dmi',null,icon_state)
|
||||||
|
tailimage.pixel_x = -16
|
||||||
|
|
||||||
|
if(eye_desc)
|
||||||
|
desc += " This one has [eye_desc]!"
|
||||||
|
|
||||||
|
var/list/ability_types = subtypesof(/obj/effect/shadekin_ability)
|
||||||
|
shadekin_abilities = list()
|
||||||
|
for(var/type in ability_types)
|
||||||
|
shadekin_abilities += new type(src)
|
||||||
|
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/Destroy()
|
||||||
|
QDEL_NULL_LIST(shadekin_abilities)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/init_vore()
|
||||||
|
if(LAZYLEN(vore_organs))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/obj/belly/B = new /obj/belly(src)
|
||||||
|
vore_selected = B
|
||||||
|
B.immutable = 1
|
||||||
|
B.name = vore_stomach_name ? vore_stomach_name : "stomach"
|
||||||
|
B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
|
||||||
|
B.digest_mode = vore_default_mode
|
||||||
|
B.escapable = vore_escape_chance > 0
|
||||||
|
B.escapechance = vore_escape_chance
|
||||||
|
B.digestchance = vore_digest_chance
|
||||||
|
B.absorbchance = vore_absorb_chance
|
||||||
|
B.human_prey_swallow_time = swallowTime
|
||||||
|
B.nonhuman_prey_swallow_time = swallowTime
|
||||||
|
B.vore_verb = "swallow"
|
||||||
|
// TODO - Customizable per mob
|
||||||
|
B.emote_lists[DM_HOLD] = list(
|
||||||
|
"The walls gently squeeze against you. The wet sounds of shifting flesh against your form fill the air.",
|
||||||
|
"The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxing again.",
|
||||||
|
"Your body is soaked in the fluids that cling to the churning walls. They squeeze across your form gently, conforming to your shape.",
|
||||||
|
"You can feel the world around you shift and sway as the creature moves! The flesh is stretchy, doughy. You can sink into it a little ways before it bounces back, curling you into a small shape."
|
||||||
|
)
|
||||||
|
B.emote_lists[DM_DIGEST] = list(
|
||||||
|
"The walls slop thick slime across your body! It tingles briefly before the sting and ache sets in!",
|
||||||
|
"The sound of your body slipping and sliding against the powerfully churning stomach fills the air!",
|
||||||
|
"The grip of that stomach is harsh. Eagerly mushing and rubbing that slime into your body in attempts to break you down!",
|
||||||
|
"The intense churning and grinding jostles your around within the thick slime as you're slowly broken down!"
|
||||||
|
)
|
||||||
|
B.emote_lists[DM_ABSORB] = list(
|
||||||
|
"The walls cling to you awfully close... It's almost like you're sinking into them.",
|
||||||
|
"You can feel the walls press in tightly against you, clinging to you posessively!",
|
||||||
|
"It almost feels like you're sinking into the soft, doughy flesh!",
|
||||||
|
"You can feel the walls press in around you. Almost molten, so squishy!!"
|
||||||
|
)
|
||||||
|
B.emote_lists[DM_DRAIN] = list(
|
||||||
|
"The walls churn down on you heavily!! It's hard to move!",
|
||||||
|
"You can feel yourself getting weaker with every moment! The doughy walls sap your strength!",
|
||||||
|
"You're practically smothered in the oppressive heat of the creature's stomach!",
|
||||||
|
"It's hot, wet and tight!"
|
||||||
|
)
|
||||||
|
B.emote_lists[DM_HEAL] = list(
|
||||||
|
"The walls pulse against you almost rhythmically. It feels nice, almost like a massage.",
|
||||||
|
"You're gently squeezed in pleasant warmth, softly churned.",
|
||||||
|
"The doughy feel of the heavy flesh clinging to you makes you feel a little stronger with every passing moment.",
|
||||||
|
"The flesh caresses across your body gently as you're held."
|
||||||
|
)
|
||||||
|
B.digest_messages_prey = list(
|
||||||
|
"Your body is steadily softened more and more over time! Eventually you pass out. The creature's stomach rumbles powerfully as you are reduced to paste, processed for energy!",
|
||||||
|
"The creature's slimy gut lets out a heavy groan as you're slowly melted away. Gushing deeper through the creature.",
|
||||||
|
"The stinging and aching gives way to numbness as you're slowly smothered out. Your body is steadily reduced to nutrients and energy for the creature to continue on its way.",
|
||||||
|
"The chaos of being digested fades as you're snuffed out by a harsh clench! You're steadily broken down into a thick paste, processed and absorbed by the predator!"
|
||||||
|
)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/Life()
|
||||||
|
. = ..()
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
density = FALSE
|
||||||
|
|
||||||
|
//Convert spare nutrition into energy at a certain ratio
|
||||||
|
if(. && nutrition > initial(nutrition) && energy < 100)
|
||||||
|
nutrition = max(0, nutrition-5)
|
||||||
|
energy = min(100,energy+1)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/update_icon()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
cut_overlay(tailimage)
|
||||||
|
|
||||||
|
tailimage.icon_state = icon_state
|
||||||
|
|
||||||
|
add_overlay(tailimage)
|
||||||
|
add_overlay(eye_icon_state)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/Stat()
|
||||||
|
. = ..()
|
||||||
|
if(statpanel("Shadekin"))
|
||||||
|
abilities_stat()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/proc/abilities_stat()
|
||||||
|
for(var/A in shadekin_abilities)
|
||||||
|
var/obj/effect/shadekin_ability/ability = A
|
||||||
|
stat("[ability.ability_name]",ability.atom_button_text())
|
||||||
|
|
||||||
|
//They phase back to the dark when killed
|
||||||
|
/mob/living/simple_mob/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!")
|
||||||
|
overlays = list()
|
||||||
|
icon_state = ""
|
||||||
|
flick("tp_out",src)
|
||||||
|
spawn(1 SECOND)
|
||||||
|
qdel(src) //Back from whence you came!
|
||||||
|
|
||||||
|
. = ..(FALSE, deathmessage)
|
||||||
|
|
||||||
|
//Blue-eyes want to nom people to heal them
|
||||||
|
/mob/living/simple_mob/shadekin/Found(var/atom/A)
|
||||||
|
if(specific_targets && isliving(A)) //Healing!
|
||||||
|
var/mob/living/L = A
|
||||||
|
var/health_percent = (L.health/L.maxHealth)*100
|
||||||
|
if(health_percent <= 50 && will_eat(A))
|
||||||
|
return A
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
//They reach nutritional equilibrium (important for blue-eyes healbelly)
|
||||||
|
/mob/living/simple_mob/shadekin/Life()
|
||||||
|
if((. = ..()))
|
||||||
|
handle_shade()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/proc/handle_shade()
|
||||||
|
//Shifted kin don't gain/lose energy (and save time if we're at the cap)
|
||||||
|
var/darkness = 1
|
||||||
|
|
||||||
|
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
if(!T)
|
||||||
|
dark_gains = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0
|
||||||
|
darkness = 1-brightness //Invert
|
||||||
|
|
||||||
|
if(ability_flags & AB_PHASE_SHIFTED)
|
||||||
|
dark_gains = 0
|
||||||
|
else
|
||||||
|
//Heal (very) slowly in good darkness
|
||||||
|
if(darkness >= 0.75)
|
||||||
|
adjustFireLoss(-0.05)
|
||||||
|
adjustBruteLoss(-0.05)
|
||||||
|
adjustToxLoss(-0.05)
|
||||||
|
|
||||||
|
switch(eye_state)
|
||||||
|
//Blue has constant, steady (slow) regen and ignores darkness.
|
||||||
|
if(BLUE_EYES)
|
||||||
|
dark_gains = 0.5
|
||||||
|
//Red has extremely tiny energy buildup in dark, none in light, and hunts for energy.
|
||||||
|
if(RED_EYES)
|
||||||
|
if(darkness >= 0.75)
|
||||||
|
dark_gains = 0.25
|
||||||
|
//Purple eyes have moderate gains in darkness and loss in light.
|
||||||
|
if(PURPLE_EYES)
|
||||||
|
dark_gains = round((darkness - 0.5) * 2, 0.1)
|
||||||
|
//Yellow has extreme gains in darkness and loss in light.
|
||||||
|
if(YELLOW_EYES)
|
||||||
|
dark_gains = round((darkness - 0.5) * 4, 0.1)
|
||||||
|
//Similar to blues, but passive is less, and affected by dark
|
||||||
|
if(GREEN_EYES)
|
||||||
|
dark_gains = 0.25
|
||||||
|
dark_gains += round((darkness - 0.5), 0.1)
|
||||||
|
//More able to get energy out of the dark, worse attack gains tho
|
||||||
|
if(ORANGE_EYES)
|
||||||
|
if(darkness >= 0.65)
|
||||||
|
dark_gains = 0.30
|
||||||
|
|
||||||
|
energy = max(0,min(initial(energy),energy + dark_gains))
|
||||||
|
|
||||||
|
if(energy_adminbuse)
|
||||||
|
energy = 100
|
||||||
|
|
||||||
|
//Update turf darkness hud
|
||||||
|
if(darkhud)
|
||||||
|
switch(darkness)
|
||||||
|
if(0.80 to 1.00)
|
||||||
|
darkhud.icon_state = "dark2"
|
||||||
|
if(0.60 to 0.80)
|
||||||
|
darkhud.icon_state = "dark1"
|
||||||
|
if(0.40 to 0.60)
|
||||||
|
darkhud.icon_state = "dark"
|
||||||
|
if(0.20 to 0.40)
|
||||||
|
darkhud.icon_state = "dark-1"
|
||||||
|
if(0.00 to 0.20)
|
||||||
|
darkhud.icon_state = "dark-2"
|
||||||
|
|
||||||
|
//Update energy storage hud
|
||||||
|
if(energyhud)
|
||||||
|
switch(energy)
|
||||||
|
if(80 to INFINITY)
|
||||||
|
energyhud.icon_state = "energy0"
|
||||||
|
if(60 to 80)
|
||||||
|
energyhud.icon_state = "energy1"
|
||||||
|
if(40 to 60)
|
||||||
|
energyhud.icon_state = "energy2"
|
||||||
|
if(20 to 40)
|
||||||
|
energyhud.icon_state = "energy3"
|
||||||
|
if(0 to 20)
|
||||||
|
energyhud.icon_state = "energy4"
|
||||||
|
|
||||||
|
//Friendly ones wander towards people, maybe shy-ly if they are set to shy
|
||||||
|
/mob/living/simple_mob/shadekin/handle_wander_movement()
|
||||||
|
if(isturf(src.loc) && !resting && !buckled && canmove)
|
||||||
|
lifes_since_move++
|
||||||
|
if(lifes_since_move >= turns_per_move)
|
||||||
|
if(!(stop_when_pulled && pulledby))
|
||||||
|
var/moving_to
|
||||||
|
|
||||||
|
if(stalker)
|
||||||
|
//Sniff sniff.
|
||||||
|
var/list/humans = human_mobs(world.view)
|
||||||
|
|
||||||
|
//Can we see the last person we were following?
|
||||||
|
if(henlo_human && !(henlo_human in humans))
|
||||||
|
henlo_human = null
|
||||||
|
|
||||||
|
//Can we find a new person to follow?
|
||||||
|
if(!henlo_human)
|
||||||
|
while(!henlo_human && humans.len)
|
||||||
|
henlo_human = pick(humans)
|
||||||
|
if(!isturf(henlo_human.loc))
|
||||||
|
humans -= henlo_human
|
||||||
|
henlo_human = null
|
||||||
|
|
||||||
|
//Boopable hunam?
|
||||||
|
if(henlo_human)
|
||||||
|
moving_to = get_dir(src,henlo_human)
|
||||||
|
|
||||||
|
if((get_dist(src,henlo_human) <= 1))
|
||||||
|
dir = moving_to
|
||||||
|
if(prob(speak_chance))
|
||||||
|
visible_message("<span class='notice'>\The [src] [pick(friendly)] \the [henlo_human].</span>")
|
||||||
|
shy_approach = FALSE //ACCLIMATED
|
||||||
|
lifes_since_move = 0
|
||||||
|
return //No need to move
|
||||||
|
|
||||||
|
if(shy_approach)
|
||||||
|
var/them_to_us = turn(moving_to,180)
|
||||||
|
if(abs(dir2angle(henlo_human.dir) - dir2angle(them_to_us)) <= 90)
|
||||||
|
dir = them_to_us
|
||||||
|
return //AAA!
|
||||||
|
|
||||||
|
dir = moving_to
|
||||||
|
|
||||||
|
//Random walk
|
||||||
|
if(!moving_to)
|
||||||
|
moving_to = pick(cardinal)
|
||||||
|
dir = moving_to
|
||||||
|
|
||||||
|
var/turf/T = get_step(src,moving_to)
|
||||||
|
if(avoid_turf(T))
|
||||||
|
return
|
||||||
|
Move(T)
|
||||||
|
lifes_since_move = 0
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/speech_bubble_appearance()
|
||||||
|
return "ghost"
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/DoPunch(var/atom/A)
|
||||||
|
. = ..(A)
|
||||||
|
if(isliving(A)) //We punched something!
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(L.stat != DEAD)
|
||||||
|
var/gains = 0
|
||||||
|
switch(eye_state)
|
||||||
|
if(RED_EYES)
|
||||||
|
gains = 8
|
||||||
|
if(BLUE_EYES)
|
||||||
|
gains = 1
|
||||||
|
if(PURPLE_EYES)
|
||||||
|
gains = 4
|
||||||
|
if(YELLOW_EYES)
|
||||||
|
gains = 3
|
||||||
|
if(GREEN_EYES)
|
||||||
|
gains = 1
|
||||||
|
if(ORANGE_EYES)
|
||||||
|
gains = 5
|
||||||
|
|
||||||
|
energy += gains
|
||||||
|
|
||||||
|
//Special hud elements for darkness and energy gains
|
||||||
|
/mob/living/simple_mob/shadekin/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements)
|
||||||
|
//Darkness hud
|
||||||
|
darkhud = new /obj/screen()
|
||||||
|
darkhud.icon = ui_style
|
||||||
|
darkhud.icon_state = "dark"
|
||||||
|
darkhud.name = "darkness"
|
||||||
|
darkhud.screen_loc = "CENTER-2:16,SOUTH:5" //Left of the left hand
|
||||||
|
darkhud.alpha = 150
|
||||||
|
hud_elements |= darkhud
|
||||||
|
|
||||||
|
//Energy hud
|
||||||
|
energyhud = new /obj/screen()
|
||||||
|
energyhud.icon = ui_style
|
||||||
|
energyhud.icon_state = "energy0"
|
||||||
|
energyhud.name = "energy"
|
||||||
|
energyhud.screen_loc = "CENTER+1:16,SOUTH:5" //Right of the right hand
|
||||||
|
energyhud.alpha = 150
|
||||||
|
hud_elements |= energyhud
|
||||||
|
|
||||||
|
// When someone clicks us with an empty hand
|
||||||
|
/mob/living/simple_mob/shadekin/attack_hand(mob/living/carbon/human/M as mob)
|
||||||
|
. = ..()
|
||||||
|
if(M.a_intent == I_HELP)
|
||||||
|
shy_approach = FALSE //ACCLIMATED
|
||||||
|
|
||||||
|
/datum/language/shadekin
|
||||||
|
name = "Shadekin Empathy"
|
||||||
|
desc = "Shadekin seem to always know what the others are thinking. This is probably why."
|
||||||
|
colour = "changeling"
|
||||||
|
speech_verb = "mars"
|
||||||
|
ask_verb = "mars"
|
||||||
|
exclaim_verb = "mars"
|
||||||
|
key = "m"
|
||||||
|
machine_understands = 0
|
||||||
|
flags = WHITELISTED | HIVEMIND
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/red
|
||||||
|
name = "red-eyed shadekin"
|
||||||
|
eye_state = RED_EYES
|
||||||
|
hostile = TRUE
|
||||||
|
animal = TRUE
|
||||||
|
stop_when_pulled = FALSE
|
||||||
|
destroy_surroundings = TRUE
|
||||||
|
armor = list(
|
||||||
|
"melee" = 30,
|
||||||
|
"bullet" = 20,
|
||||||
|
"laser" = 20,
|
||||||
|
"energy" = 50,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "red eyes"
|
||||||
|
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||||
|
slippery gullet of the creature. It's warm, and the air is thick. You can hear \
|
||||||
|
its body squelch and shift around you as you settle into its stomach! Thick digestive \
|
||||||
|
enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \
|
||||||
|
the doughy walls press in around you instantly, churning you up as you begin to digest!"
|
||||||
|
|
||||||
|
player_msg = "You hunt for energy to fuel yourself, not minding in the least \
|
||||||
|
if you strip it off unsuspecting prey. You're stronger than other shadekin, faster, and more capable in \
|
||||||
|
a brawl, but you barely generate any of your own energy. You can stand in a dark spot to gather scraps \
|
||||||
|
of energy in a pinch, but otherwise need to take it, by force if necessary."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/red/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/red/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/red/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/blue
|
||||||
|
name = "blue-eyed shadekin"
|
||||||
|
eye_state = BLUE_EYES
|
||||||
|
health = 100
|
||||||
|
hostile = FALSE
|
||||||
|
animal = FALSE
|
||||||
|
stop_when_pulled = TRUE
|
||||||
|
specific_targets = TRUE //For finding injured people
|
||||||
|
destroy_surroundings = FALSE
|
||||||
|
vore_default_mode = DM_HEAL
|
||||||
|
vore_escape_chance = 75
|
||||||
|
vore_standing_too = 1
|
||||||
|
vore_pounce_chance = 100
|
||||||
|
swallowTime = 4 SECONDS //A little longer to compensate for the above
|
||||||
|
vore_ignores_undigestable = FALSE
|
||||||
|
attacktext = list("shoved")
|
||||||
|
armor = list(
|
||||||
|
"melee" = 5,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 5,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "blue eyes"
|
||||||
|
shy_approach = TRUE
|
||||||
|
stalker = TRUE
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||||
|
slippery gullet of the creature. It's warm, and the air is thick. You can hear its body \
|
||||||
|
squelch and shift around you as you settle into its stomach! It's oddly calm, and very dark. \
|
||||||
|
The doughy flesh rolls across your form in gentle waves. The aches and pains across your form slowly begin to \
|
||||||
|
diminish, your body is healing much faster than normal! You're also soon soaked in harmless slime."
|
||||||
|
|
||||||
|
player_msg = "You've chosen to generate your own energy rather than taking \
|
||||||
|
it from others. Most of the time, anyway. You don't have a need to steal energy from others, and gather it up \
|
||||||
|
without doing so, albeit slowly. Dark and light are irrelevant to you, they are just different places to explore and \
|
||||||
|
discover new things and new people."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/blue/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/blue/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/blue/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/purple
|
||||||
|
name = "purple-eyed shadekin"
|
||||||
|
eye_state = PURPLE_EYES
|
||||||
|
health = 150
|
||||||
|
hostile = FALSE
|
||||||
|
animal = TRUE
|
||||||
|
stop_when_pulled = FALSE
|
||||||
|
destroy_surroundings = TRUE
|
||||||
|
vore_default_mode = DM_HOLD
|
||||||
|
vore_digest_chance = 25
|
||||||
|
vore_absorb_chance = 25
|
||||||
|
armor = list(
|
||||||
|
"melee" = 15,
|
||||||
|
"bullet" = 15,
|
||||||
|
"laser" = 15,
|
||||||
|
"energy" = 15,
|
||||||
|
"bomb" = 15,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "purple eyes"
|
||||||
|
shy_approach = TRUE
|
||||||
|
stalker = TRUE
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet of the creature. \
|
||||||
|
It's warm, and the air is thick. You can hear its body squelch and shift around you as you settle into its stomach! \
|
||||||
|
It's relatively calm inside the dark organ. Wet and almost molten for how gooey your surroundings feel. \
|
||||||
|
You can feel the doughy walls cling to you posessively... It's almost like you could sink into them. \
|
||||||
|
There is also an ominous gurgling from somewhere nearby..."
|
||||||
|
|
||||||
|
player_msg = "You're familiar with generating your own energy, but occasionally \
|
||||||
|
steal it from others when it suits you. You generate energy at a moderate pace in dark areas, and staying in well-lit \
|
||||||
|
areas is taxing on your energy. You can harvest energy from others in a fight, but since you don't need to, you may \
|
||||||
|
just choose to simply not fight."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/purple/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/purple/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/purple/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/yellow
|
||||||
|
name = "yellow-eyed shadekin"
|
||||||
|
eye_state = YELLOW_EYES
|
||||||
|
health = 100
|
||||||
|
hostile = FALSE
|
||||||
|
animal = TRUE
|
||||||
|
stop_when_pulled = FALSE
|
||||||
|
destroy_surroundings = TRUE
|
||||||
|
vore_default_mode = DM_DRAIN
|
||||||
|
vore_digest_chance = 5
|
||||||
|
vore_ignores_undigestable = FALSE
|
||||||
|
armor = list(
|
||||||
|
"melee" = 5,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 5,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "yellow eyes"
|
||||||
|
stalker = FALSE
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \
|
||||||
|
of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \
|
||||||
|
as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \
|
||||||
|
you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \
|
||||||
|
harder and harder to move as those walls press in on you insistently!"
|
||||||
|
|
||||||
|
player_msg = "Your kind rarely ventures into realspace. Being in any well-lit \
|
||||||
|
area is very taxing on you, but you gain energy extremely fast in any very dark area. You're weaker than other \
|
||||||
|
shadekin, but your fast energy generation in the dark allows you to phase shift more often."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/yellow/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/yellow/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/yellow/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/green
|
||||||
|
name = "green-eyed shadekin"
|
||||||
|
eye_state = GREEN_EYES
|
||||||
|
health = 125
|
||||||
|
hostile = FALSE
|
||||||
|
animal = TRUE
|
||||||
|
stop_when_pulled = FALSE
|
||||||
|
destroy_surroundings = TRUE
|
||||||
|
vore_default_mode = DM_DRAIN
|
||||||
|
vore_digest_chance = 0
|
||||||
|
vore_ignores_undigestable = FALSE
|
||||||
|
armor = list(
|
||||||
|
"melee" = 5,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 5,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "green eyes"
|
||||||
|
stalker = TRUE
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \
|
||||||
|
of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \
|
||||||
|
as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \
|
||||||
|
you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \
|
||||||
|
harder and harder to move as those walls press in on you insistently!"
|
||||||
|
|
||||||
|
player_msg = "Your kind rarely ventures into realspace. Being in any well-lit area is very taxing on you, but you \
|
||||||
|
have more experience than your yellow-eyed cousins. You gain energy decently fast in any very dark area. You're weaker than other \
|
||||||
|
shadekin, but your slight energy generation constnatly, and especially in the dark allows for a good mix of uses."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/green/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/green/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/green/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/mob/living/simple_mob/shadekin/orange
|
||||||
|
name = "orange-eyed shadekin"
|
||||||
|
eye_state = ORANGE_EYES
|
||||||
|
health = 175
|
||||||
|
hostile = TRUE
|
||||||
|
animal = TRUE
|
||||||
|
stop_when_pulled = FALSE
|
||||||
|
destroy_surroundings = TRUE
|
||||||
|
armor = list(
|
||||||
|
"melee" = 20,
|
||||||
|
"bullet" = 15,
|
||||||
|
"laser" = 15,
|
||||||
|
"energy" = 25,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100)
|
||||||
|
|
||||||
|
eye_desc = "orange eyes"
|
||||||
|
|
||||||
|
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||||
|
slippery gullet of the creature. It's warm, and the air is thick. You can hear \
|
||||||
|
its body squelch and shift around you as you settle into its stomach! Thick digestive \
|
||||||
|
enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \
|
||||||
|
the doughy walls press in around you instantly, churning you up as you begin to digest!"
|
||||||
|
|
||||||
|
player_msg = "You usually hunt for energy to fuel yourself, though not as often as your red-eyed cousins. \
|
||||||
|
You're stronger than most shadekin, faster, and more capable in a brawl, but you don't generate much of your own energy. \
|
||||||
|
You can stand in a dark spot to gather some energy, but otherwise need to take it, by force if necessary."
|
||||||
|
|
||||||
|
/mob/living/simple_mob/shadekin/orange/white
|
||||||
|
icon_state = "white"
|
||||||
|
/mob/living/simple_mob/shadekin/orange/dark
|
||||||
|
icon_state = "dark"
|
||||||
|
/mob/living/simple_mob/shadekin/orange/brown
|
||||||
|
icon_state = "brown"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
//Fluffy specific fluffer
|
||||||
|
/mob/living/simple_mob/shadekin/blue/rivyr
|
||||||
|
name = "Rivyr"
|
||||||
|
desc = "She appears to be a fluffer of some sort. Deep blue eyes and curious attitude."
|
||||||
|
icon_state = "rivyr"
|
||||||
|
eye_desc = ""
|
||||||
|
vore_stomach_flavor = "Blue flesh gleams in the fading light as you slip down the little mar's gullet! \
|
||||||
|
Gooey flesh and heat surrounds your form as you're tucked away into the darkness of her stomach! Thick slimes cling \
|
||||||
|
to you, but they seem to be harmless. The organ gently churns around you, clinging to your shape and forcing \
|
||||||
|
you to curl up a bit. You can feel her rub at you some through the layers of flesh and fluff, while aches \
|
||||||
|
and pains begin to fade away across your body."
|
||||||
|
player_msg = "Mar? Mar mar. Mar mar mar. Mar. Mar mar? Mar! Mar. Marrrr."
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#undef NOT_WHILE_SHIFTED
|
||||||
|
#undef ONLY_WHILE_SHIFTED
|
||||||
|
#undef SHIFTED_OR_NOT
|
||||||
|
|
||||||
|
#undef BLUE_EYES
|
||||||
|
#undef RED_EYES
|
||||||
|
#undef PURPLE_EYES
|
||||||
|
#undef YELLOW_EYES
|
||||||
|
|
||||||
|
#undef AB_PHASE_SHIFTED
|
||||||
|
#undef AB_SHADE_REGEN
|
||||||
108
code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm
Normal file
108
code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
A work in progress, lore will go here later.
|
||||||
|
List of things solar grubs should be able to do:
|
||||||
|
|
||||||
|
2. have three stages of growth depending on time. (Or energy drained altho that seems like a hard one to code)
|
||||||
|
3. be capable of eating people that get knocked out. (also be able to shock attackers that don’t wear insulated gloves.)
|
||||||
|
5. ((potentially use digested people to reproduce))
|
||||||
|
6. add glow?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SINK_POWER 1
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/space/solargrub
|
||||||
|
name = "juvenile solargrub"
|
||||||
|
desc = "A young sparkling solargrub"
|
||||||
|
icon = 'icons/mob/vore.dmi' //all of these are placeholders
|
||||||
|
icon_state = "solargrub"
|
||||||
|
icon_living = "solargrub"
|
||||||
|
icon_dead = "solargrub-dead"
|
||||||
|
|
||||||
|
faction = "grubs"
|
||||||
|
maxHealth = 50 //grubs can take a lot of harm
|
||||||
|
health = 50
|
||||||
|
|
||||||
|
melee_damage_lower = 1
|
||||||
|
melee_damage_upper = 5
|
||||||
|
|
||||||
|
speed = 2
|
||||||
|
|
||||||
|
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat
|
||||||
|
|
||||||
|
response_help = "pokes"
|
||||||
|
response_disarm = "pushes"
|
||||||
|
response_harm = "roughly pushes"
|
||||||
|
|
||||||
|
var/poison_per_bite = 5 //grubs cause a shock when they bite someone
|
||||||
|
var/poison_type = "shockchem"
|
||||||
|
var/poison_chance = 50
|
||||||
|
var/datum/powernet/PN // Our powernet
|
||||||
|
var/obj/structure/cable/attached // the attached cable
|
||||||
|
var/emp_chance = 20 // Beware synths
|
||||||
|
|
||||||
|
/datum/say_list/solargrub
|
||||||
|
emote_see = list("squelches", "squishes")
|
||||||
|
/* //Commented out pending reworks - 2/2/19
|
||||||
|
/mob/living/simple_mob/animal/solargrub/PunchTarget()
|
||||||
|
if(target_mob&& prob(emp_chance))
|
||||||
|
target_mob.emp_act(4) //The weakest strength of EMP
|
||||||
|
visible_message("<span class='danger'>The grub releases a powerful shock!</span>")
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/solargrub/Life()
|
||||||
|
. = ..()
|
||||||
|
if(!. || ai_inactive) return
|
||||||
|
|
||||||
|
if(stance == STANCE_IDLE)
|
||||||
|
//first, check for potential cables nearby to powersink
|
||||||
|
var/turf/S = loc
|
||||||
|
attached = locate() in S
|
||||||
|
if(attached)
|
||||||
|
if(prob(2))
|
||||||
|
src.visible_message("<span class='notice'>\The [src] begins to sink power from the net.</span>")
|
||||||
|
if(prob(5))
|
||||||
|
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||||
|
sparks.set_up(5, 0, get_turf(src))
|
||||||
|
sparks.start()
|
||||||
|
anchored = 1
|
||||||
|
PN = attached.powernet
|
||||||
|
PN.draw_power(100000) // previous value 150000
|
||||||
|
var/apc_drain_rate = 750 //Going to see if grubs are better as a minimal bother. previous value : 4000
|
||||||
|
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||||
|
if(istype(T.master, /obj/machinery/power/apc))
|
||||||
|
var/obj/machinery/power/apc/A = T.master
|
||||||
|
if(A.operating && A.cell)
|
||||||
|
var/cur_charge = A.cell.charge / CELLRATE
|
||||||
|
var/drain_val = min(apc_drain_rate, cur_charge)
|
||||||
|
A.cell.use(drain_val * CELLRATE)
|
||||||
|
else if(!attached && anchored)
|
||||||
|
anchored = 0
|
||||||
|
PN = null
|
||||||
|
*/
|
||||||
|
/mob/living/simple_mob/animal/solargrub //active noms
|
||||||
|
vore_bump_chance = 50
|
||||||
|
vore_bump_emote = "applies minimal effort to try and slurp up"
|
||||||
|
vore_active = 1
|
||||||
|
vore_capacity = 1
|
||||||
|
vore_pounce_chance = 0 //grubs only eat incapacitated targets
|
||||||
|
vore_default_mode = DM_DIGEST
|
||||||
|
/*
|
||||||
|
/mob/living/simple_mob/animal/solargrub/PunchTarget()
|
||||||
|
. = ..()
|
||||||
|
if(isliving(.))
|
||||||
|
var/mob/living/L = .
|
||||||
|
if(L.reagents)
|
||||||
|
if(prob(poison_chance))
|
||||||
|
L << "<span class='warning'>You feel a shock rushing through your veins.</span>"
|
||||||
|
L.reagents.add_reagent(poison_type, poison_per_bite) */
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/solargrub/death()
|
||||||
|
src.anchored = 0
|
||||||
|
set_light(0)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/solargrub/handle_light()
|
||||||
|
. = ..()
|
||||||
|
if(. == 0 && !is_dead())
|
||||||
|
set_light(2.5, 1, COLOR_YELLOW)
|
||||||
|
return 1
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
var/global/list/grub_machine_overlays = list()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva
|
||||||
|
name = "solargrub larva"
|
||||||
|
desc = "A tiny wormy thing that can grow to massive sizes under the right conditions."
|
||||||
|
icon = 'icons/mob/vore.dmi'
|
||||||
|
icon_state = "grublarva"
|
||||||
|
icon_living = "grublarva"
|
||||||
|
icon_dead = "grublarva-dead"
|
||||||
|
|
||||||
|
health = 5
|
||||||
|
maxHealth = 5
|
||||||
|
|
||||||
|
meat_amount = 2
|
||||||
|
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat
|
||||||
|
|
||||||
|
faction = "grubs"
|
||||||
|
|
||||||
|
response_help = "pats"
|
||||||
|
response_disarm = "nudges"
|
||||||
|
response_harm = "stomps on"
|
||||||
|
|
||||||
|
mob_size = MOB_MINISCULE
|
||||||
|
pass_flags = PASSTABLE
|
||||||
|
can_pull_size = ITEMSIZE_TINY
|
||||||
|
can_pull_mobs = MOB_PULL_NONE
|
||||||
|
density = 0
|
||||||
|
|
||||||
|
stop_when_pulled = 0
|
||||||
|
|
||||||
|
var/static/list/ignored_machine_types = list(
|
||||||
|
/obj/machinery/atmospherics/unary/vent_pump,
|
||||||
|
/obj/machinery/atmospherics/unary/vent_scrubber,
|
||||||
|
/obj/machinery/door/firedoor
|
||||||
|
)
|
||||||
|
|
||||||
|
var/obj/machinery/atmospherics/unary/vent_pump/target_vent
|
||||||
|
|
||||||
|
var/datum/effect/effect/system/spark_spread/sparks
|
||||||
|
var/image/machine_effect
|
||||||
|
|
||||||
|
var/obj/machinery/abstract_grub_machine/powermachine
|
||||||
|
var/power_drained = 0
|
||||||
|
var/forced_out = 0
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/New()
|
||||||
|
..()
|
||||||
|
powermachine = new(src)
|
||||||
|
sparks = new(src)
|
||||||
|
sparks.set_up()
|
||||||
|
sparks.attach(src)
|
||||||
|
verbs += /mob/living/proc/ventcrawl
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/death()
|
||||||
|
powermachine.draining = 0
|
||||||
|
set_light(0)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/Destroy()
|
||||||
|
QDEL_NULL(powermachine)
|
||||||
|
QDEL_NULL(sparks)
|
||||||
|
QDEL_NULL(machine_effect)
|
||||||
|
target_vent = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/Life()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
if(machine_effect && !istype(loc, /obj/machinery))
|
||||||
|
QDEL_NULL(machine_effect)
|
||||||
|
|
||||||
|
if(!. || ai_inactive)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(power_drained >= 7 MEGAWATTS && prob(5))
|
||||||
|
expand_grub()
|
||||||
|
return
|
||||||
|
|
||||||
|
if(istype(loc, /obj/machinery))
|
||||||
|
if(machine_effect && air_master.current_cycle%30)
|
||||||
|
for(var/mob/M in player_list)
|
||||||
|
M << machine_effect
|
||||||
|
if(prob(10))
|
||||||
|
sparks.start()
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stance == STANCE_IDLE)
|
||||||
|
if(forced_out)
|
||||||
|
forced_out = Clamp(0, forced_out--, forced_out)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(target_vent)
|
||||||
|
if(Adjacent(target_vent))
|
||||||
|
spawn()
|
||||||
|
do_ventcrawl(target_vent)
|
||||||
|
target_vent = null
|
||||||
|
else
|
||||||
|
target_vent = null
|
||||||
|
stop_automated_movement = 0
|
||||||
|
walk(src, 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(prob(20))
|
||||||
|
var/list/possible_machines = list()
|
||||||
|
for(var/obj/machinery/M in orange(1,src))
|
||||||
|
if(!Adjacent(M))
|
||||||
|
continue
|
||||||
|
if(istype(M, /obj/machinery/power/apc) || istype(M, /obj/machinery/power/smes)) //APCs and SMES units don't actually use power, but it's too thematic to ignore them
|
||||||
|
possible_machines += M
|
||||||
|
continue
|
||||||
|
if(is_type_in_list(M, ignored_machine_types))
|
||||||
|
continue
|
||||||
|
if(!M.idle_power_usage && !M.active_power_usage) //If it can't use power at all, ignore it
|
||||||
|
continue
|
||||||
|
possible_machines += M
|
||||||
|
if(possible_machines.len)
|
||||||
|
enter_machine(pick(possible_machines))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(prob(10))
|
||||||
|
var/list/vents = list()
|
||||||
|
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in view(7,src))
|
||||||
|
if(vent.welded)
|
||||||
|
continue
|
||||||
|
vents += vent
|
||||||
|
if(vents.len)
|
||||||
|
var/picked = pick(vents)
|
||||||
|
target_vent = picked
|
||||||
|
WanderTowards(get_turf(picked))
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/proc/enter_machine(var/obj/machinery/M)
|
||||||
|
if(!istype(M))
|
||||||
|
return
|
||||||
|
forceMove(M)
|
||||||
|
powermachine.draining = 2
|
||||||
|
visible_message("<span class='warning'>\The [src] finds an opening and crawls inside \the [M].</span>")
|
||||||
|
if(!(M.type in grub_machine_overlays))
|
||||||
|
generate_machine_effect(M)
|
||||||
|
machine_effect = image(grub_machine_overlays[M.type], M) //Can't do this the reasonable way with an overlay,
|
||||||
|
for(var/mob/L in player_list) //because nearly every machine updates its icon by removing all overlays first
|
||||||
|
L << machine_effect
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/proc/generate_machine_effect(var/obj/machinery/M)
|
||||||
|
var/icon/I = new /icon(M.icon, M.icon_state)
|
||||||
|
I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD)
|
||||||
|
I.Blend(new /icon('icons/effects/alert.dmi', "_red"),ICON_MULTIPLY)
|
||||||
|
grub_machine_overlays[M.type] = I
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/proc/eject_from_machine(var/obj/machinery/M)
|
||||||
|
if(!M)
|
||||||
|
if(istype(loc, /obj/machinery))
|
||||||
|
M = loc
|
||||||
|
else
|
||||||
|
return
|
||||||
|
forceMove(get_turf(M))
|
||||||
|
sparks.start()
|
||||||
|
if(machine_effect)
|
||||||
|
QDEL_NULL(machine_effect)
|
||||||
|
forced_out += rand(5,15)
|
||||||
|
powermachine.draining = 1
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/proc/do_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent)
|
||||||
|
if(!vent)
|
||||||
|
return
|
||||||
|
var/obj/machinery/atmospherics/unary/vent_pump/end_vent = get_safe_ventcrawl_target(vent)
|
||||||
|
if(!end_vent)
|
||||||
|
return
|
||||||
|
forceMove(vent)
|
||||||
|
playsound(vent, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
|
||||||
|
vent.visible_message("\The [src] wiggles into \the [vent]!")
|
||||||
|
var/redirect_attempts = 3
|
||||||
|
while(redirect_attempts)
|
||||||
|
var/travel_time = round(get_dist(get_turf(src), get_turf(end_vent)) / 2)
|
||||||
|
sleep(travel_time)
|
||||||
|
if(end_vent.welded)
|
||||||
|
end_vent = get_safe_ventcrawl_target(vent)
|
||||||
|
if(!end_vent)
|
||||||
|
forceMove(get_turf(vent))
|
||||||
|
return
|
||||||
|
redirect_attempts--
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
playsound(end_vent, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
|
||||||
|
forceMove(get_turf(end_vent))
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/proc/expand_grub()
|
||||||
|
eject_from_machine()
|
||||||
|
visible_message("<span class='warning'>\The [src] suddenly balloons in size!</span>")
|
||||||
|
new /mob/living/simple_mob/animal/solargrub(get_turf(src))
|
||||||
|
// var/mob/living/simple_mob/animal/solargrub/grub = new(get_turf(src))
|
||||||
|
// grub.power_drained = power_drained //TODO
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/solargrub_larva/handle_light()
|
||||||
|
. = ..()
|
||||||
|
if(. == 0 && !is_dead())
|
||||||
|
set_light(1.5, 1, COLOR_YELLOW)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
/obj/machinery/abstract_grub_machine
|
||||||
|
var/total_active_power_usage = 45 KILOWATTS
|
||||||
|
var/list/active_power_usages = list(15 KILOWATTS, 15 KILOWATTS, 15 KILOWATTS)
|
||||||
|
var/total_idle_power_usage = 3 KILOWATTS
|
||||||
|
var/list/idle_power_usages = list(1 KILOWATTS, 1 KILOWATTS, 1 KILOWATTS)
|
||||||
|
var/draining = 1
|
||||||
|
var/mob/living/simple_mob/solargrub_larva/grub
|
||||||
|
|
||||||
|
/obj/machinery/abstract_grub_machine/New()
|
||||||
|
..()
|
||||||
|
shuffle_power_usages()
|
||||||
|
grub = loc
|
||||||
|
if(!istype(grub))
|
||||||
|
grub = null
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/obj/machinery/abstract_grub_machine/Destroy()
|
||||||
|
grub = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/machinery/abstract_grub_machine/process()
|
||||||
|
if(!draining)
|
||||||
|
return
|
||||||
|
var/area/A = get_area(src)
|
||||||
|
if(!A)
|
||||||
|
return
|
||||||
|
var/list/power_list
|
||||||
|
switch(draining)
|
||||||
|
if(1)
|
||||||
|
power_list = idle_power_usages
|
||||||
|
if(2)
|
||||||
|
power_list = active_power_usages
|
||||||
|
for(var/i = 1 to power_list.len)
|
||||||
|
if(A.powered(i))
|
||||||
|
use_power(power_list[i], i)
|
||||||
|
grub.power_drained += power_list[i]
|
||||||
|
if(prob(5))
|
||||||
|
shuffle_power_usages()
|
||||||
|
|
||||||
|
/obj/machinery/abstract_grub_machine/proc/shuffle_power_usages()
|
||||||
|
total_active_power_usage = rand(30 KILOWATTS, 60 KILOWATTS)
|
||||||
|
total_idle_power_usage = rand(1 KILOWATTS, 5 KILOWATTS)
|
||||||
|
active_power_usages = split_into_3(total_active_power_usage)
|
||||||
|
idle_power_usages = split_into_3(total_idle_power_usage)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/device/multitool/afterattack(obj/O, mob/user, proximity)
|
||||||
|
if(proximity)
|
||||||
|
if(istype(O, /obj/machinery))
|
||||||
|
var/mob/living/simple_mob/solargrub_larva/grub = locate() in O
|
||||||
|
if(grub)
|
||||||
|
grub.eject_from_machine(O)
|
||||||
|
to_chat(user, "<span class='warning'>You disturb a grub nesting in \the [O]!</span>")
|
||||||
|
return
|
||||||
|
return ..()
|
||||||
@@ -9,10 +9,10 @@ var/list/ventcrawl_machinery = list(
|
|||||||
/obj/item/device/radio/borg,
|
/obj/item/device/radio/borg,
|
||||||
/obj/item/weapon/holder,
|
/obj/item/weapon/holder,
|
||||||
/obj/machinery/camera,
|
/obj/machinery/camera,
|
||||||
///mob/living/simple_mob/borer, //VORESTATION AI TEMPORARY REMOVAL //VOREStation Edit
|
/obj/belly, //VOREStation Edit
|
||||||
/obj/belly, //VOREStation Edit,
|
|
||||||
/obj/screen
|
/obj/screen
|
||||||
)
|
)
|
||||||
|
//mob/living/simple_mob/borer, //VORESTATION AI TEMPORARY REMOVAL REPLACE BACK IN LIST WHEN RESOLVED //VOREStation Edit
|
||||||
|
|
||||||
/mob/living/var/list/icon/pipes_shown = list()
|
/mob/living/var/list/icon/pipes_shown = list()
|
||||||
/mob/living/var/last_played_vent
|
/mob/living/var/last_played_vent
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
/mob/living/simple_mob/animal/giant_spider/nurse,
|
/mob/living/simple_mob/animal/giant_spider/nurse,
|
||||||
/mob/living/simple_mob/animal/space/alien,
|
/mob/living/simple_mob/animal/space/alien,
|
||||||
/mob/living/simple_mob/animal/space/bear,
|
/mob/living/simple_mob/animal/space/bear,
|
||||||
// /mob/living/simple_mob/carp, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL
|
|
||||||
/mob/living/simple_mob/creature,
|
/mob/living/simple_mob/creature,
|
||||||
/mob/living/simple_mob/slime/xenobio)
|
/mob/living/simple_mob/slime/xenobio)
|
||||||
|
// /mob/living/simple_mob/carp, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL, REPLACE BACK IN LIST WHEN FIXED
|
||||||
else
|
else
|
||||||
spawn_type = pick(\
|
spawn_type = pick(\
|
||||||
/mob/living/simple_mob/animal/passive/cat,
|
/mob/living/simple_mob/animal/passive/cat,
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
/obj/item/roller,
|
/obj/item/roller,
|
||||||
/obj/structure/closet/crate,
|
/obj/structure/closet/crate,
|
||||||
/obj/structure/closet/acloset,
|
/obj/structure/closet/acloset,
|
||||||
// /mob/living/simple_mob/mimic/crate, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL
|
|
||||||
/mob/living/simple_mob/mechanical/viscerator,
|
/mob/living/simple_mob/mechanical/viscerator,
|
||||||
/mob/living/simple_mob/mechanical/hivebot,
|
/mob/living/simple_mob/mechanical/hivebot,
|
||||||
/obj/item/device/analyzer,
|
/obj/item/device/analyzer,
|
||||||
@@ -65,6 +64,7 @@
|
|||||||
/obj/item/weapon/grenade/chem_grenade/cleaner,
|
/obj/item/weapon/grenade/chem_grenade/cleaner,
|
||||||
/obj/item/weapon/grenade/chem_grenade/metalfoam)
|
/obj/item/weapon/grenade/chem_grenade/metalfoam)
|
||||||
|
|
||||||
|
// /mob/living/simple_mob/mimic/crate, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL, REPLACE BACK IN LIST WHEN FIXED
|
||||||
var/quantity = rand(5, 15)
|
var/quantity = rand(5, 15)
|
||||||
for(var/i=0, i<quantity, i++)
|
for(var/i=0, i<quantity, i++)
|
||||||
var/button_desc = "a [pick("yellow","purple","green","blue","red","orange","white")], "
|
var/button_desc = "a [pick("yellow","purple","green","blue","red","orange","white")], "
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
/turf/simulated/floor/water,
|
/turf/simulated/floor/water,
|
||||||
/area/submap/spa)
|
/area/submap/spa)
|
||||||
"ak" = (
|
"ak" = (
|
||||||
/mob/living/simple_mob/fox,
|
/mob/living/simple_mob/animal/fox,
|
||||||
/turf/simulated/floor/grass,
|
/turf/simulated/floor/grass,
|
||||||
/area/submap/spa)
|
/area/submap/spa)
|
||||||
"al" = (
|
"al" = (
|
||||||
@@ -623,7 +623,7 @@
|
|||||||
},
|
},
|
||||||
/area/space)
|
/area/space)
|
||||||
"bW" = (
|
"bW" = (
|
||||||
/mob/living/simple_mob/redpanda,
|
/mob/living/simple_mob/animal/redpanda,
|
||||||
/turf/simulated/floor/grass,
|
/turf/simulated/floor/grass,
|
||||||
/area/submap/spa)
|
/area/submap/spa)
|
||||||
"bX" = (
|
"bX" = (
|
||||||
|
|||||||
@@ -2344,6 +2344,7 @@
|
|||||||
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\discipline.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\discipline.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\subtypes.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\subtypes.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\xenobio.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\xenobio.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\vore\redpanda.dm"
|
||||||
#include "code\modules\mob\living\voice\voice.dm"
|
#include "code\modules\mob\living\voice\voice.dm"
|
||||||
#include "code\modules\mob\new_player\login.dm"
|
#include "code\modules\mob\new_player\login.dm"
|
||||||
#include "code\modules\mob\new_player\logout.dm"
|
#include "code\modules\mob\new_player\logout.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user