mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2026-08-23 12:47:13 +01:00
@@ -170,3 +170,211 @@
|
||||
name = "Phoebe"
|
||||
icon = 'modular_splurt/icons/mob/hair.dmi'
|
||||
icon_state = "hair_phoebe"
|
||||
|
||||
|
||||
/datum/sprite_accessory/hair/teshari
|
||||
name = "Teshari Default"
|
||||
icon_state = "teshari_default"
|
||||
icon = 'modular_splurt/icons/mob/hair.dmi'
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/altdefault
|
||||
name = "Teshari Alt. Default"
|
||||
icon_state = "teshari_ears"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/tight
|
||||
name = "Teshari Tight"
|
||||
icon_state = "teshari_tight"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/excited
|
||||
name = "Teshari Spiky"
|
||||
icon_state = "teshari_spiky"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/spike
|
||||
name = "Teshari Spike"
|
||||
icon_state = "teshari_spike"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/long
|
||||
name = "Teshari Overgrown"
|
||||
icon_state = "teshari_long"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/burst
|
||||
name = "Teshari Starburst"
|
||||
icon_state = "teshari_burst"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/shortburst
|
||||
name = "Teshari Short Starburst"
|
||||
icon_state = "teshari_burst_short"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/mohawk
|
||||
name = "Teshari Mohawk"
|
||||
icon_state = "teshari_mohawk"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/pointy
|
||||
name = "Teshari Pointy"
|
||||
icon_state = "teshari_pointy"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/upright
|
||||
name = "Teshari Upright"
|
||||
icon_state = "teshari_upright"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/mane
|
||||
name = "Teshari Mane"
|
||||
icon_state = "teshari_mane"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/droopy
|
||||
name = "Teshari Droopy"
|
||||
icon_state = "teshari_droopy"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/mushroom
|
||||
name = "Teshari Mushroom"
|
||||
icon_state = "teshari_mushroom"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/twies
|
||||
name = "Teshari Twies"
|
||||
icon_state = "teshari_twies"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/backstrafe
|
||||
name = "Teshari Backstrafe"
|
||||
icon_state = "teshari_backstrafe"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/_longway
|
||||
name = "Teshari Long way"
|
||||
icon_state = "teshari_longway"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/tree
|
||||
name = "Teshari Tree"
|
||||
icon_state = "teshari_tree"
|
||||
|
||||
/datum/sprite_accessory/hair/teshari/fluffymohawk
|
||||
name = "Teshari Fluffy Mohawk"
|
||||
icon_state = "teshari_fluffymohawk"
|
||||
|
||||
//Teshari face things
|
||||
/datum/sprite_accessory/facial_hair/teshari
|
||||
name = "Teshari Beard"
|
||||
icon_state = "teshari_chin"
|
||||
gender = NEUTER
|
||||
icon = 'modular_splurt/icons/mob/hair.dmi'
|
||||
|
||||
/datum/sprite_accessory/facial_hair/teshari/scraggly
|
||||
name = "Teshari Scraggly"
|
||||
icon_state = "teshari_scraggly"
|
||||
|
||||
/datum/sprite_accessory/facial_hair/teshari/chops
|
||||
name = "Teshari Chops"
|
||||
icon_state = "teshari_gap"
|
||||
|
||||
/datum/sprite_accessory/ears/mam_ears/teshari
|
||||
name = "Teshari (COLORABLE)"
|
||||
|
||||
icon_state = "teshari"
|
||||
color_src = MUTCOLORS2
|
||||
icon = 'modular_splurt/icons/mob/ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/mam_ears/tesharihigh
|
||||
name = "Teshari upper ears (COLORABLE)"
|
||||
|
||||
icon_state = "tesharihigh"
|
||||
color_src = MUTCOLORS
|
||||
icon = 'modular_splurt/icons/mob/ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/mam_ears/tesharilow
|
||||
name = "Teshari lower ears (COLORABLE)"
|
||||
|
||||
icon_state = "tesharilow"
|
||||
color_src = MUTCOLORS
|
||||
icon = 'modular_splurt/icons/mob/ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tails/teshari
|
||||
icon = 'modular_splurt/icons/mob/tail.dmi'
|
||||
recommended_species = list("teshari")
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tails/teshari/tesharitailhc
|
||||
name = "teshari tail, colorable"
|
||||
icon_state = "tesharicolorable"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tails/teshari/tesharitailfeatheredhc
|
||||
name = "teshari tail w/ feathers, colorable"
|
||||
icon_state = "tesharifeatherscolorable"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/tesh_feathers
|
||||
name = "Teshari Feathers"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_feathers"
|
||||
covered_limbs = list("Left Foot" = MATRIX_GREEN, "Right Foot" = MATRIX_GREEN, "Left Hand" = MATRIX_GREEN, "Right Hand" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/teshi_small_feathers
|
||||
name = "Teshari small wingfeathers"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_sf"
|
||||
covered_limbs = list("Left Foot" = MATRIX_GREEN, "Right Foot" = MATRIX_GREEN, "Left Hand" = MATRIX_GREEN, "Right Hand" = MATRIX_GREEN, "Chest" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/tesh_skull
|
||||
name = "Teshari Skull Face"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_skull"
|
||||
covered_limbs = list("Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_teshari_large_eyes
|
||||
name = "Teshari large eyes"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "teshlarge_eyes"
|
||||
covered_limbs = list("Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_teshari_coat
|
||||
name = "Teshari coat"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_coat"
|
||||
covered_limbs = list("Left Leg" = MATRIX_GREEN, "Right Leg" = MATRIX_GREEN, "Left Arm" = MATRIX_GREEN, "Right Arm" = MATRIX_GREEN, "Chest" = MATRIX_GREEN, "Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_teshari_pattern_male
|
||||
name = "Teshari male pattern"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_pattern_male"
|
||||
covered_limbs = list("Left Leg" = MATRIX_GREEN, "Right Leg" = MATRIX_GREEN, "Left Arm" = MATRIX_GREEN, "Right Arm" = MATRIX_GREEN, "Left Hand" = MATRIX_GREEN, "Right Hand" = MATRIX_GREEN, "Chest" = MATRIX_GREEN, "Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_teshari_pattern_female
|
||||
name = "Teshari female pattern"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_pattern_fem"
|
||||
covered_limbs = list("Left Leg" = MATRIX_GREEN, "Right Leg" = MATRIX_GREEN, "Left Hand" = MATRIX_GREEN, "Right Hand" = MATRIX_GREEN, "Chest" = MATRIX_GREEN, "Groin" = MATRIX_GREEN, "Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_tesh_beak
|
||||
name = "Teshari beak, pointed"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_beak"
|
||||
covered_limbs = list("Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/vr_tesh_beak_alt
|
||||
name = "Teshari beak, rounded"
|
||||
icon = 'modular_splurt/icons/mob/mam_markings.dmi'
|
||||
icon_state = "tesh_beak_alt"
|
||||
covered_limbs = list("Head" = MATRIX_GREEN)
|
||||
recommended_species = list("teshari")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
/mob/living/carbon/human/species/mammal/shadekin
|
||||
race = /datum/species/mammal/shadekin
|
||||
|
||||
/mob/living/carbon/human/species/mammal/teshari
|
||||
race = /datum/species/mammal/teshari
|
||||
|
||||
/mob/living/carbon/human/species/mammal/vox
|
||||
race = /datum/species/vox
|
||||
|
||||
/mob/living/carbon/human/is_literate()
|
||||
// Check for D4C craving
|
||||
if(HAS_TRAIT(src, TRAIT_DUMB_CUM_CRAVE))
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/datum/species
|
||||
var/icon_accessories
|
||||
var/icon_back
|
||||
var/icon_belt
|
||||
var/icon_ears
|
||||
var/icon_eyes
|
||||
var/icon_feet
|
||||
var/icon_feet64
|
||||
var/icon_hands
|
||||
var/icon_head
|
||||
var/icon_mask
|
||||
var/icon_neck
|
||||
var/icon_suit
|
||||
var/icon_uniform
|
||||
|
||||
|
||||
/datum/species/althelp(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target && istype(user))
|
||||
if(HAS_TRAIT(user, TRAIT_FLOORED))
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
#define TESHARI_TEMP_OFFSET -30 // K, added to comfort/damage limit etc
|
||||
#define TESHARI_BURNMOD 1.25 // They take more damage from practically everything
|
||||
#define TESHARI_BRUTEMOD 1.2
|
||||
#define TESHARI_HEATMOD 1.3
|
||||
#define TESHARI_COLDMOD 0.67 // Except cold.
|
||||
|
||||
|
||||
/datum/species/mammal/teshari
|
||||
name = "Teshari"
|
||||
id = SPECIES_TESHARI
|
||||
say_mod = "mars"
|
||||
eye_type = "teshari"
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "mam_tail" = "teshari tail, colorable", "mam_ears" = "None", "mam_body_markings" = list())
|
||||
allowed_limb_ids = null
|
||||
override_bp_icon = 'modular_splurt/icons/mob/teshari.dmi'
|
||||
damage_overlay_type = "teshari"
|
||||
species_language_holder = /datum/language_holder/teshari
|
||||
exotic_blood_color = "#D514F7"
|
||||
disliked_food = GROSS | GRAIN
|
||||
liked_food = MEAT
|
||||
payday_modifier = 0.75
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
ass_image = 'icons/ass/asslizard.png'
|
||||
|
||||
species_traits = list(MUTCOLORS,
|
||||
EYECOLOR,
|
||||
NO_UNDERWEAR,
|
||||
HAIR,
|
||||
FACEHAIR,
|
||||
MARKINGS
|
||||
)
|
||||
|
||||
coldmod = TESHARI_COLDMOD
|
||||
heatmod = TESHARI_HEATMOD
|
||||
brutemod = TESHARI_BRUTEMOD
|
||||
burnmod = TESHARI_BURNMOD
|
||||
|
||||
|
||||
/datum/species/mammal/teshari/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load)
|
||||
if(ishuman(C))
|
||||
C.verbs += /mob/living/carbon/human/proc/sonar_ping
|
||||
C.verbs += /mob/living/carbon/human/proc/hide
|
||||
C.setMaxHealth(50)
|
||||
C.physiology.hunger_mod *= 2
|
||||
C.add_movespeed_modifier(/datum/movespeed_modifier/teshari)
|
||||
|
||||
/datum/movespeed_modifier/teshari
|
||||
multiplicative_slowdown = -0.2
|
||||
|
||||
/datum/emote/sound/teshari
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/language_holder/teshari
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/schechi = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/schechi = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language/schechi
|
||||
|
||||
/datum/emote/living/audio/teshari/teshsqueak
|
||||
key = "surprised"
|
||||
key_third_person = "surprised"
|
||||
message = "chirps in surprise!"
|
||||
message_mime = "lets out an <b>inaudible</b> chirp!"
|
||||
emote_sound = 'modular_splurt/sound/voice/teshsqueak.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
|
||||
emote_cooldown = 2.1 SECONDS
|
||||
|
||||
/datum/emote/living/audio/teshari/teshsqueak/run_emote(mob/user, params)
|
||||
var/datum/dna/D = user.has_dna()
|
||||
if(D.species.name != "Teshari")
|
||||
return
|
||||
// Return normally
|
||||
. = ..()
|
||||
|
||||
/datum/emote/living/audio/teshari/teshchirp
|
||||
key = "tchirp"
|
||||
key_third_person = "tchirp"
|
||||
message = "chirps!"
|
||||
message_mime = "lets out an <b>inaudible</b> chirp!"
|
||||
emote_sound = 'modular_splurt/sound/voice/teshchirp.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
|
||||
emote_cooldown = 2.1 SECONDS
|
||||
|
||||
/datum/emote/living/audio/teshari/teshchirp/run_emote(mob/user, params)
|
||||
var/datum/dna/D = user.has_dna()
|
||||
if(D.species.name != "Teshari")
|
||||
return
|
||||
// Return normally
|
||||
. = ..()
|
||||
|
||||
/datum/emote/living/audio/teshari/trill
|
||||
key = "trill"
|
||||
key_third_person = "trill"
|
||||
message = "trills!"
|
||||
message_mime = "lets out an <b>inaudible</b> chirp!"
|
||||
emote_sound = 'modular_splurt/sound/voice/teshtrill.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
|
||||
emote_cooldown = 2.1 SECONDS
|
||||
|
||||
/datum/emote/living/audio/teshari/trill/run_emote(mob/user, params)
|
||||
var/datum/dna/D = user.has_dna()
|
||||
if(D.species.name != "Teshari")
|
||||
return
|
||||
// Return normally
|
||||
. = ..()
|
||||
|
||||
/datum/emote/living/audio/teshari/teshscream
|
||||
key = "teshscream"
|
||||
key_third_person = "teshscream"
|
||||
message = "screams!"
|
||||
message_mime = "lets out an <b>inaudible</b> screams!"
|
||||
emote_sound = 'modular_splurt/sound/voice/teshscream.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
|
||||
emote_cooldown = 2.1 SECONDS
|
||||
|
||||
/datum/emote/living/audio/teshari/teshscream/run_emote(mob/user, params)
|
||||
var/datum/dna/D = user.has_dna()
|
||||
if(D.species.name != "Teshari")
|
||||
return
|
||||
// Return normally
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/next_sonar_ping = 0
|
||||
var/hiding = 0
|
||||
|
||||
/mob/living/carbon/human/proc/hide()
|
||||
set name = "Hide"
|
||||
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
|
||||
set category = "Abilities"
|
||||
|
||||
if(stat == DEAD || restrained() || buckled|| has_buckled_mobs()) //VORE EDIT: Check for has_buckled_mobs() (taur riding)
|
||||
return
|
||||
|
||||
if(hiding)
|
||||
plane = initial(plane)
|
||||
layer = initial(layer)
|
||||
to_chat(usr, "<span class='notice'>You have stopped hiding.</span>")
|
||||
hiding = 0
|
||||
else
|
||||
hiding = 1
|
||||
layer = BELOW_OBJ_LAYER //Just above cables with their 2.44
|
||||
plane = GAME_PLANE
|
||||
to_chat(src,"<span class='notice'>You are now hiding.</span>")
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/sonar_ping()
|
||||
set name = "Listen In"
|
||||
set desc = "Allows you to listen in to movement and noises around you."
|
||||
set category = "Abilities"
|
||||
|
||||
if(incapacitated())
|
||||
to_chat(src, "<span class='warning'>You need to recover before you can use this ability.</span>")
|
||||
return
|
||||
if(world.time < next_sonar_ping)
|
||||
to_chat(src, "<span class='warning'>You need another moment to focus.</span>")
|
||||
return
|
||||
var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS)
|
||||
if(ears.deaf > 0)
|
||||
to_chat(src, "<span class='warning'>You are for all intents and purposes currently deaf!</span>")
|
||||
return
|
||||
next_sonar_ping += 10 SECONDS
|
||||
var/heard_something = FALSE
|
||||
to_chat(src, "<span class='notice'>You take a moment to listen in to your environment...</span>")
|
||||
for(var/mob/living/L in range(client.view, src))
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || L == src || L.stat == DEAD)
|
||||
continue
|
||||
heard_something = TRUE
|
||||
var/feedback = list()
|
||||
feedback += "<span class='notice'>There are noises of movement "
|
||||
var/direction = get_dir(src, L)
|
||||
if(direction)
|
||||
feedback += "towards the [dir2text(direction)], "
|
||||
switch(get_dist(src, L) / 7)
|
||||
if(0 to 0.2)
|
||||
feedback += "very close by."
|
||||
if(0.2 to 0.4)
|
||||
feedback += "close by."
|
||||
if(0.4 to 0.6)
|
||||
feedback += "some distance away."
|
||||
if(0.6 to 0.8)
|
||||
feedback += "further away."
|
||||
else
|
||||
feedback += "far away."
|
||||
else // No need to check distance if they're standing right on-top of us
|
||||
feedback += "right on top of you."
|
||||
feedback += "</span>"
|
||||
to_chat(src,jointext(feedback,null))
|
||||
if(!heard_something)
|
||||
to_chat(src, "<span class='notice'>You hear no movement but your own.</span>")
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/datum/species/vox
|
||||
name = "Vox"
|
||||
id = SPECIES_VOX
|
||||
override_bp_icon = 'modular_splurt/icons/mob/vox.dmi'
|
||||
species_language_holder = /datum/language_holder/vox
|
||||
|
||||
|
||||
breathid = "tox"
|
||||
|
||||
mutantlungs = /obj/item/organ/lungs/vox
|
||||
|
||||
species_traits = list(MUTCOLORS,
|
||||
EYECOLOR,
|
||||
NO_UNDERWEAR,
|
||||
HAIR,
|
||||
FACEHAIR,
|
||||
MARKINGS
|
||||
)
|
||||
|
||||
exotic_blood_color = "#9066BD"
|
||||
//flesh_color = "#808D11"
|
||||
|
||||
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
say_mod = "shrieks"
|
||||
eye_type = "vox"
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "mam_tail" = "teshari tail, colorable", "mam_ears" = "None", "mam_body_markings" = list())
|
||||
allowed_limb_ids = null
|
||||
damage_overlay_type = "vox"
|
||||
|
||||
/datum/species/vox/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/datum/outfit/vox/O = new /datum/outfit/vox
|
||||
H.equipOutfit(O, visualsOnly)
|
||||
H.internal = H.get_item_for_held_index(2)
|
||||
H.update_internals_hud_icon(1)
|
||||
return 0
|
||||
|
||||
/datum/species/vox/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load)
|
||||
if(ishuman(C))
|
||||
C.add_movespeed_modifier(/datum/movespeed_modifier/vox)
|
||||
..()
|
||||
|
||||
/datum/movespeed_modifier/vox
|
||||
multiplicative_slowdown = -0.2
|
||||
|
||||
|
||||
/datum/language_holder/vox
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/schechi = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/schechi = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language/vox
|
||||
|
||||
/datum/emote/sound/vox
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
|
||||
/datum/emote/living/audio/vox/shriek
|
||||
key = "shriek"
|
||||
key_third_person = "shrieks"
|
||||
message = "shrieks!"
|
||||
message_mime = "lets out an <b>inaudible</b> shriek!"
|
||||
emote_sound = 'modular_splurt/sound/voice/shriek1.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
|
||||
emote_cooldown = 2.1 SECONDS
|
||||
|
||||
/datum/emote/living/audio/vox/shriek/run_emote(mob/user, params)
|
||||
var/datum/dna/D = user.has_dna()
|
||||
if(D.species.name != "Vox")
|
||||
return
|
||||
// Return normally
|
||||
. = ..()
|
||||
@@ -0,0 +1,281 @@
|
||||
// Xenochimera thing mostly
|
||||
#define REVIVING_NOW -1
|
||||
#define REVIVING_DONE 0
|
||||
#define REVIVING_READY 1
|
||||
|
||||
|
||||
/datum/species/mammal/xenochimera
|
||||
name = "Xenochimera"
|
||||
id = SPECIES_XENOCHIMERA
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "mam_snouts" = "None", "mam_tail" = "None", "mam_ears" = "None", "deco_wings" = "None",
|
||||
"taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,WINGCOLOR,HAS_FLESH,HAS_BONE)
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision
|
||||
brutemod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though.
|
||||
burnmod = 1.15 //As vulnerable to burn as a Tajara.
|
||||
|
||||
/datum/species/mammal/xenochimera/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load)
|
||||
if(ishuman(C))
|
||||
C.verbs += /mob/living/carbon/human/proc/reconstitute_form
|
||||
C.verbs += /mob/living/carbon/human/proc/sonar_ping
|
||||
C.verbs += /mob/living/carbon/human/proc/tie_hair
|
||||
C.add_movespeed_modifier(/datum/movespeed_modifier/xenochimera)
|
||||
|
||||
/datum/species/mammal/xenochimera/spec_life(mob/living/carbon/human/H)
|
||||
//If they're KO'd/dead, or reviving, they're probably not thinking a lot about much of anything.
|
||||
//if(!H.stat || !(H.revive_ready == REVIVING_NOW || H.revive_ready == REVIVING_DONE))
|
||||
// handle_feralness(H)
|
||||
|
||||
//While regenerating
|
||||
if(H.revive_ready == REVIVING_NOW || H.revive_ready == REVIVING_DONE)
|
||||
H.Paralyze(1000)
|
||||
var/regen_sounds = list(
|
||||
'modular_splurt/sound/effects/regen_1.ogg',
|
||||
'modular_splurt/sound/effects/regen_2.ogg',
|
||||
'modular_splurt/sound/effects/regen_4.ogg',
|
||||
'modular_splurt/sound/effects/regen_3.ogg',
|
||||
'modular_splurt/sound/effects/regen_5.ogg'
|
||||
)
|
||||
if(prob(2)) // 2% chance of playing squelchy noise while reviving, which is run roughly every 2 seconds/tick while regenerating.
|
||||
playsound(H, pick(regen_sounds), 30)
|
||||
H.visible_message("<span class='danger'><p><font size=4>[H.name]'s motionless form shudders grotesquely, rippling unnaturally.</font></p></span>")
|
||||
|
||||
//Cold/pressure effects when not regenerating
|
||||
else
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
var/pressure2 = environment.return_pressure()
|
||||
var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2)
|
||||
|
||||
//Very low pressure damage
|
||||
if(adjusted_pressure2 <= 20)
|
||||
H.take_overall_damage(LOW_PRESSURE_DAMAGE, 0)
|
||||
|
||||
|
||||
//Cold hurts and gives them pain messages, eventually weakening and paralysing, but doesn't damage or trigger feral.
|
||||
//NB: 'body_temperature' used here is the 'setpoint' species var
|
||||
var/body_temperature = 310.15
|
||||
var/temp_diff = body_temperature - H.bodytemperature
|
||||
if(temp_diff >= 50)
|
||||
H.eye_blurry = max(5,H.eye_blurry)
|
||||
|
||||
/datum/movespeed_modifier/xenochimera
|
||||
multiplicative_slowdown = -0.1
|
||||
|
||||
/mob/living/carbon/human/proc/reconstitute_form() //Scree's race ability.in exchange for: No cloning.
|
||||
set name = "Reconstitute Form"
|
||||
set category = "Abilities"
|
||||
|
||||
// Sanity is mostly handled in chimera_regenerate()
|
||||
if(stat == DEAD)
|
||||
var/confirm = tgui_alert(usr, "Are you sure you want to regenerate your corpse? This process can take up to thirty minutes.", "Confirm Regeneration", list("Yes", "No"))
|
||||
if(confirm == "Yes")
|
||||
chimera_regenerate()
|
||||
else if (quickcheckuninjured())
|
||||
var/confirm = tgui_alert(usr, "Are you sure you want to regenerate? As you are uninjured this will only take 30 seconds and match your appearance to your character slot.", "Confirm Regeneration", list("Yes", "No"))
|
||||
if(confirm == "Yes")
|
||||
chimera_regenerate()
|
||||
else
|
||||
var/confirm = tgui_alert(usr, "Are you sure you want to completely reconstruct your form? This process can take up to fifteen minutes, depending on how hungry you are, and you will be unable to move.", "Confirm Regeneration", list("Yes", "No"))
|
||||
if(confirm == "Yes")
|
||||
chimera_regenerate()
|
||||
|
||||
/mob/living/carbon/human/proc/tie_hair()
|
||||
set name = "Tie Hair"
|
||||
set desc = "Style your hair."
|
||||
set category = "IC"
|
||||
|
||||
if(incapacitated())
|
||||
to_chat(src, "<span class='warning'>You can't mess with your hair right now!</span>")
|
||||
return
|
||||
|
||||
if(hair_style)
|
||||
var/selected_string
|
||||
var/list/datum/sprite_accessory/hair/valid_hairstyles = list()
|
||||
for(var/hair_string in GLOB.hair_styles_list)
|
||||
valid_hairstyles.Add(hair_string)
|
||||
selected_string = tgui_input_list(usr, "Select a new hairstyle", "Your hairstyle", valid_hairstyles)
|
||||
if(incapacitated())
|
||||
to_chat(src, "<span class='warning'>You can't mess with your hair right now!</span>")
|
||||
return
|
||||
else if(selected_string && hair_style != selected_string)
|
||||
hair_style = selected_string
|
||||
regenerate_icons()
|
||||
visible_message("<span class='notice'>[src] pauses a moment to style their hair.</span>")
|
||||
else
|
||||
to_chat(src, "<span class ='notice'>You're already using that style.</span>")
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/revive_ready = REVIVING_READY // Only used for creatures that have the xenochimera regen ability, so far.
|
||||
var/revive_finished = 0 // Only used for xenochimera regen, allows us to find out when the regen will finish.
|
||||
|
||||
/mob/living/carbon/human/proc/chimera_regenerate()
|
||||
//If they're already regenerating
|
||||
switch(revive_ready)
|
||||
if(REVIVING_NOW)
|
||||
to_chat(src, "You are already reconstructing, just wait for the reconstruction to finish!")
|
||||
return
|
||||
if(REVIVING_DONE)
|
||||
to_chat(src, "Your reconstruction is done, but you need to hatch now.")
|
||||
return
|
||||
if(revive_ready > world.time)
|
||||
to_chat(src, "You can't use that ability again so soon!")
|
||||
return
|
||||
|
||||
var/time = min(900, (120+780/(1 + nutrition/100))) //capped at 15 mins, roughly 6 minutes at 250 (yellow) nutrition, 4.1 minutes at 500 (grey), cannot be below 2 mins
|
||||
if (quickcheckuninjured()) //if you're completely uninjured, then you get a speedymode - check health first for quickness
|
||||
time = 30
|
||||
|
||||
//Clicked regen while dead.
|
||||
if(stat == DEAD)
|
||||
|
||||
//reviving from dead takes extra nutriment to be provided from outside OR takes twice as long and consumes extra at the end
|
||||
if(!nutrition > 0)
|
||||
time = time*2
|
||||
|
||||
to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.")
|
||||
|
||||
//Scary spawnerization.
|
||||
revive_ready = REVIVING_NOW
|
||||
revive_finished = (world.time + time SECONDS) // When do we finish reviving? Allows us to find out when we're done, called by the alert currently.
|
||||
throw_alert("regen", /atom/movable/screen/alert/xenochimera/reconstitution)
|
||||
spawn(time SECONDS)
|
||||
// check to see if they've been fixed by outside forces in the meantime such as defibbing
|
||||
if(stat != DEAD)
|
||||
to_chat(src, "<span class='notice'>Your body has recovered from its ordeal, ready to regenerate itself again.</span>")
|
||||
revive_ready = REVIVING_READY //reset their cooldown
|
||||
clear_alert("regen")
|
||||
throw_alert("hatch", /atom/movable/screen/alert/xenochimera/readytohatch)
|
||||
|
||||
// Was dead, still dead.
|
||||
else
|
||||
to_chat(src, "<span class='notice'>Consciousness begins to stir as your new body awakens, ready to hatch.</span>")
|
||||
verbs |= /mob/living/carbon/human/proc/hatch
|
||||
revive_ready = REVIVING_DONE
|
||||
clear_alert("regen")
|
||||
throw_alert("hatch", /atom/movable/screen/alert/xenochimera/readytohatch)
|
||||
|
||||
|
||||
//Clicked regen while NOT dead
|
||||
else
|
||||
to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.")
|
||||
|
||||
//Waiting for regen after being alive
|
||||
revive_ready = REVIVING_NOW
|
||||
revive_finished = (world.time + time SECONDS) // When do we finish reviving? Allows us to find out when we're done, called by the alert currently.
|
||||
throw_alert("regen", /atom/movable/screen/alert/xenochimera/reconstitution)
|
||||
spawn(time SECONDS)
|
||||
|
||||
//Slightly different flavour messages
|
||||
if(stat != DEAD || nutrition > 0)
|
||||
to_chat(src, "<span class='notice'>Consciousness begins to stir as your new body awakens, ready to hatch..</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Consciousness begins to stir as your battered body struggles to recover from its ordeal..</span>")
|
||||
verbs |= /mob/living/carbon/human/proc/hatch
|
||||
revive_ready = REVIVING_DONE
|
||||
|
||||
clear_alert("regen")
|
||||
throw_alert("hatch", /atom/movable/screen/alert/xenochimera/readytohatch)
|
||||
|
||||
/mob/living/carbon/human/proc/hatch()
|
||||
set name = "Hatch"
|
||||
set category = "Abilities"
|
||||
|
||||
if(revive_ready != REVIVING_DONE)
|
||||
//Hwhat?
|
||||
verbs -= /mob/living/carbon/human/proc/hatch
|
||||
return
|
||||
|
||||
var/confirm = tgui_alert(usr, "Are you sure you want to hatch right now? This will be very obvious to anyone in view.", "Confirm Regeneration", list("Yes", "No"))
|
||||
if(confirm == "Yes")
|
||||
|
||||
//Dead when hatching
|
||||
if(stat == DEAD)
|
||||
|
||||
//Reviving from ded takes extra nutrition - if it isn't provided from outside sources, it comes from you
|
||||
if(!nutrition > 0)
|
||||
nutrition=nutrition * 0.75
|
||||
chimera_hatch()
|
||||
|
||||
visible_message("<span class='warning'><p><font size=4>The former corpse staggers to its feet, all its former wounds having vanished...</font></p></span>") //Bloody hell...
|
||||
clear_alert("hatch")
|
||||
return
|
||||
|
||||
//Alive when hatching
|
||||
else
|
||||
chimera_hatch()
|
||||
|
||||
visible_message("<span class='warning'><p><font size=4>[src] rises to \his feet.</font></p></span>") //Bloody hell...
|
||||
clear_alert("hatch")
|
||||
|
||||
/mob/living/carbon/human/proc/chimera_hatch()
|
||||
verbs -= /mob/living/carbon/human/proc/hatch
|
||||
to_chat(src, "<span class='notice'>Your new body awakens, bursting free from your old skin.</span>")
|
||||
//Modify and record values (half nutrition and braindamage)
|
||||
var/old_nutrition = nutrition
|
||||
var/uninjured=quickcheckuninjured()
|
||||
//I did have special snowflake code, but this is easier.
|
||||
revive()
|
||||
cure_husk()
|
||||
|
||||
|
||||
if(!uninjured)
|
||||
nutrition = old_nutrition * 0.5
|
||||
//Drop everything
|
||||
for(var/obj/item/W in src)
|
||||
dropItemToGround(W, 1)
|
||||
//Visual effects
|
||||
var/T = get_turf(src)
|
||||
|
||||
new /obj/effect/gibspawner/human(T, src)
|
||||
visible_message("<span class='danger'><p><font size=4>The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.</font></p></span>") //Bloody hell...
|
||||
|
||||
else //lower cost for doing a quick cosmetic revive
|
||||
nutrition = old_nutrition * 0.9
|
||||
|
||||
//Unfreeze some things
|
||||
//does_not_breathe = FALSE
|
||||
//update_canmove()
|
||||
//weakened = 2
|
||||
SetParalyzed(0)
|
||||
revive_ready = world.time + 10 MINUTES //set the cooldown CHOMPEdit: Reduced this to 10 minutes, you're playing with fire if you're reviving that often.
|
||||
|
||||
|
||||
/atom/movable/screen/alert/xenochimera/reconstitution
|
||||
name = "Reconstructing Form"
|
||||
desc = "You're still rebuilding your body! Click the alert to find out how long you have left."
|
||||
icon_state = "regenerating"
|
||||
|
||||
// Commenting this out for now, will revisit later once I can figure out how to override Click() appropriately.
|
||||
/atom/movable/screen/alert/xenochimera/reconstitution/Click()
|
||||
if(ishuman(usr)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(istype(H.dna.species, /datum/species/mammal/xenochimera))
|
||||
if(H.revive_ready == REVIVING_NOW)
|
||||
to_chat(usr, "We are currently reviving, and will be done in [(H.revive_finished - world.time) / 10] seconds.")
|
||||
else if(H.revive_ready == REVIVING_DONE)
|
||||
to_chat(usr, "You should have a notification + alert for this! Bug report that this is still here!")
|
||||
|
||||
|
||||
/atom/movable/screen/alert/xenochimera/readytohatch
|
||||
name = "Ready to Hatch"
|
||||
desc = "You're done reconstructing your cells! Click me to Hatch!"
|
||||
icon_state = "hatch_ready"
|
||||
|
||||
// Commenting this out for now, will revisit later once I can figure out how to override Click() appropriately.
|
||||
/atom/movable/screen/alert/xenochimera/readytohatch/Click()
|
||||
if(ishuman(usr)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(istype(H.dna.species, /datum/species/mammal/xenochimera))
|
||||
if(H.revive_ready == REVIVING_DONE) // Sanity check.
|
||||
H.hatch() // Hatch.
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/quickcheckuninjured()
|
||||
if (getBruteLoss() || getFireLoss() || getToxLoss() || getOxyLoss()) //fails if they have any of the main damage types
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
#undef REVIVING_NOW
|
||||
#undef REVIVING_DONE
|
||||
#undef REVIVING_READY
|
||||
|
||||
Reference in New Issue
Block a user