diff --git a/code/_onclick/hud/_defines_vr.dm b/code/_onclick/hud/_defines_vr.dm new file mode 100644 index 0000000000..e72150b44c --- /dev/null +++ b/code/_onclick/hud/_defines_vr.dm @@ -0,0 +1,2 @@ +#define ui_shadekin_dark_display "EAST-1:28,CENTER-3:15" +#define ui_shadekin_energy_display "EAST-1:28,CENTER-4:15" \ No newline at end of file diff --git a/code/_onclick/hud/hud_vr.dm b/code/_onclick/hud/hud_vr.dm new file mode 100644 index 0000000000..e5d8289576 --- /dev/null +++ b/code/_onclick/hud/hud_vr.dm @@ -0,0 +1,3 @@ + + var/obj/screen/lingchemdisplay + var/obj/screen/wiz_instability_display \ No newline at end of file diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 1c903700b0..f1aba60b10 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -293,6 +293,18 @@ mymob.nutrition_icon.screen_loc = ui_nutrition hud_elements |= mymob.nutrition_icon + //VOREStation Addition begin + mymob.shadekin_dark_display = new /obj/screen/shadekin/darkness() + mymob.shadekin_dark_display.screen_loc = ui_shadekin_dark_display + mymob.shadekin_dark_display.icon_state = "dark" + hud_elements |= mymob.shadekin_dark_display + + mymob.shadekin_energy_display = new /obj/screen/shadekin/energy() + mymob.shadekin_energy_display.screen_loc = ui_shadekin_energy_display + mymob.shadekin_energy_display.icon_state = "energy0" + hud_elements |= mymob.shadekin_energy_display + //VOREStation Addition end + mymob.ling_chem_display = new /obj/screen/ling/chems() mymob.ling_chem_display.screen_loc = ui_ling_chemical_display mymob.ling_chem_display.icon_state = "ling_chems" diff --git a/code/_onclick/hud/screen_objects_vr.dm b/code/_onclick/hud/screen_objects_vr.dm index ea6b72cd10..c1fbd99448 100644 --- a/code/_onclick/hud/screen_objects_vr.dm +++ b/code/_onclick/hud/screen_objects_vr.dm @@ -1,16 +1,19 @@ -/obj/screen/proc/Click_vr(location, control, params) //VORESTATION AI TEMPORARY REMOVAL +/obj/screen/proc/Click_vr(location, control, params) if(!usr) return 1 switch(name) //Shadekin if("darkness") - var/mob/living/simple_mob/shadekin/sk = usr - var/turf/T = get_turf(sk) + var/turf/T = get_turf(usr) var/darkness = round(1 - T.get_lumcount(),0.1) to_chat(usr,"Darkness: [darkness]") if("energy") - var/mob/living/simple_mob/shadekin/sk = usr - to_chat(usr,"Energy: [sk.energy] ([sk.dark_gains])") + var/mob/living/simple_mob/shadekin/SK = usr + if(istype(SK)) + to_chat(usr,"Energy: [SK.energy] ([SK.dark_gains])") + var/mob/living/carbon/human/H = usr + if(istype(H) && istype(H.species, /datum/species/shadekin)) + to_chat(usr,"Energy: [H.shadekin_get_energy(H)]") diff --git a/code/modules/catalogue/catalogue_data_vr.dm b/code/modules/catalogue/catalogue_data_vr.dm index ff370bca92..861e22afe9 100644 --- a/code/modules/catalogue/catalogue_data_vr.dm +++ b/code/modules/catalogue/catalogue_data_vr.dm @@ -60,6 +60,11 @@ desc = "" value = CATALOGUER_REWARD_TRIVIAL +/datum/category_item/catalogue/fauna/shadekin + name = "Sapients - Shadekin" + desc = "" + value = CATALOGUER_REWARD_EASY + /datum/category_item/catalogue/fauna/custom_species name = "Sapients - Other" desc = "Remote frontiers require people of all sorts of life...\ diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm index fc2d5c48c2..fc092d48bc 100644 --- a/code/modules/clothing/clothing_vr.dm +++ b/code/modules/clothing/clothing_vr.dm @@ -132,3 +132,7 @@ standing.pixel_x = -16 standing.layer = BODY_LAYER + 15 // 15 is above tail layer, so will not be covered by taurbody. return standing + +//Underclothes +/obj/item/clothing/under + species_restricted = list("exclude", SPECIES_SHADEKIN) \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous_vr.dm b/code/modules/clothing/under/miscellaneous_vr.dm index 0644eb476c..eb95b123b4 100644 --- a/code/modules/clothing/under/miscellaneous_vr.dm +++ b/code/modules/clothing/under/miscellaneous_vr.dm @@ -1,3 +1,7 @@ +/obj/item/clothing/under/harness + species_restricted = null + + /obj/item/clothing/var/hides_bulges = FALSE // OwO wats this? /obj/item/clothing/under/permit @@ -6,6 +10,7 @@ icon = 'icons/obj/card.dmi' icon_state = "guest" body_parts_covered = 0 + species_restricted = null sprite_sheets = list() diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index dcc2136672..e496bb95f6 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -68,21 +68,32 @@ colour = "enochian" //So fancy key = "i" syllables = list("salve","sum","loqui","operatur","iusta","et","permittit","facere","effercio","pluribus","enim","hoc", - "mihi","wan","six","salve","tartu") + "mihi","wan","six","tartu") machine_understands = FALSE /datum/language/bug - name = LANGUAGE_VESPINAE - desc = "A jarring and clicky language developed and used by Vasilissans, it is designed for use with mouthparts and as a result has become a common language for various arthropod species." - speech_verb = "clicks" - ask_verb = "chitters" - exclaim_verb = "rasps" - colour = "bug" - key = "x" - syllables = list("vaur","uyek","uyit","avek","sc'theth","k'ztak","teth","wre'ge","lii","dra'","zo'","ra'","kax'","zz","vh","ik","ak", + name = LANGUAGE_VESPINAE + desc = "A jarring and clicky language developed and used by Vasilissans, it is designed for use with mouthparts and as a result has become a common language for various arthropod species." + speech_verb = "clicks" + ask_verb = "chitters" + exclaim_verb = "rasps" + colour = "bug" + key = "x" + syllables = list("vaur","uyek","uyit","avek","sc'theth","k'ztak","teth","wre'ge","lii","dra'","zo'","ra'","kax'","zz","vh","ik","ak", "uhk","zir","sc'orth","sc'er","thc'yek","th'zirk","th'esk","k'ayek","ka'mil","sc'","ik'yir","yol","kig","k'zit","'","'","zrk","krg","isk'yet","na'k", "sc'azz","th'sc","nil","n'ahk","sc'yeth","aur'sk","iy'it","azzg","a'","i'","o'","u'","a","i","o","u","zz","kr","ak","nrk","tzzk","bz","xic'","k'lax'","histh") +/datum/language/shadekin + name = LANGUAGE_SHADEKIN + desc = "Shadekin seem to always know what the others are thinking. This is probably why." + speech_verb = "mars" + ask_verb = "mars" + exclaim_verb = "mars" + colour = "changeling" + key = "m" + machine_understands = FALSE + flags = WHITELISTED | HIVEMIND + /datum/language/unathi flags = 0 /datum/language/tajaran diff --git a/code/modules/mob/living/carbon/human/human_defines_vr.dm b/code/modules/mob/living/carbon/human/human_defines_vr.dm index f856e4ab39..131f5be1f1 100644 --- a/code/modules/mob/living/carbon/human/human_defines_vr.dm +++ b/code/modules/mob/living/carbon/human/human_defines_vr.dm @@ -7,3 +7,45 @@ var/flapping = 0 var/vantag_pref = VANTAG_NONE //What's my status? var/impersonate_bodytype //For impersonating a bodytype + var/ability_flags = 0 //Shadekin stoof + +/mob/living/carbon/human/proc/shadekin_get_energy() + var/datum/species/shadekin/SK = species + + if(!istype(SK)) + return 0 + + return SK.get_energy(src) + +/mob/living/carbon/human/proc/shadekin_get_max_energy() + var/datum/species/shadekin/SK = species + + if(!istype(SK)) + return 0 + + return SK.get_max_energy(src) + +/mob/living/carbon/human/proc/shadekin_set_energy(var/new_energy) + var/datum/species/shadekin/SK = species + + if(!istype(SK)) + return 0 + + SK.set_energy(src, new_energy) + +/mob/living/carbon/human/proc/shadekin_set_max_energy(var/new_max_energy) + var/datum/species/shadekin/SK = species + + if(!istype(SK)) + return 0 + + SK.set_max_energy(src, new_max_energy) + +/mob/living/carbon/human/proc/shadekin_adjust_energy(var/amount) + var/datum/species/shadekin/SK = species + + if(!istype(SK)) + return 0 + + var/new_amount = SK.get_energy(src) + amount + SK.set_energy(src, new_amount) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_species_vr.dm b/code/modules/mob/living/carbon/human/human_species_vr.dm index ed27c12e62..3cb59aa38a 100644 --- a/code/modules/mob/living/carbon/human/human_species_vr.dm +++ b/code/modules/mob/living/carbon/human/human_species_vr.dm @@ -26,6 +26,9 @@ /mob/living/carbon/human/protean/New(var/new_loc) ..(new_loc, "Protean") - /mob/living/carbon/human/alraune/New(var/new_loc) ..(new_loc, "Alraune") + +/mob/living/carbon/human/shadekin/New(var/new_loc) + h_style = "Bald" + ..(new_loc, SPECIES_SHADEKIN) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 32cc8939bc..4697bbec06 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -283,6 +283,12 @@ if(core) return + //VOREStation Addition start: shadekin + var/obj/item/organ/internal/brain/shadekin/s_brain = locate() in internal_organs + if(s_brain) + return + //VOREStation Addition end: shadekin + var/damage = 0 radiation -= 1 * RADIATION_SPEED_COEFFICIENT if(prob(25)) diff --git a/code/modules/mob/living/carbon/human/species/shadekin/_defines.dm b/code/modules/mob/living/carbon/human/species/shadekin/_defines.dm new file mode 100644 index 0000000000..1567134c4d --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/shadekin/_defines.dm @@ -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 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm index 1717506313..f6eaf16722 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm @@ -1,18 +1,21 @@ /datum/species/shadekin name = SPECIES_SHADEKIN name_plural = "Shadekin" + blurb = "Waow! A shaadefluffer!" + catalogue_data = list(/datum/category_item/catalogue/fauna/shadekin) //default_language = "Xenomorph" - language = "Shadekin Empathy" + language = LANGUAGE_SHADEKIN assisted_langs = list() unarmed_types = list() //TODO: shadekin-unique pawbings - hud_type = /datum/hud_data/shadekin //TODO: shadekin hud + hud_type = /datum/hud_data/shadekin rarity_value = 15 //INTERDIMENSIONAL FLUFFERS has_fine_manipulation = 0 siemens_coefficient = 0 - slowdown = -2 + slowdown = -1 + item_slowdown_mod = 0.5 brute_mod = 0.7 // Naturally sturdy. burn_mod = 1.2 // Furry @@ -27,42 +30,63 @@ cold_level_2 = -1 cold_level_3 = -1 - flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT | NO_INFECT + heat_level_1 = 850 //Resistant to heat + heat_level_2 = 1000 + heat_level_3 = 1150 + + flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_MINOR_CUT | NO_INFECT spawn_flags = SPECIES_IS_RESTRICTED //reagent_tag = IS_SHADEKIN - blood_color = "#05EE05" - flesh_color = "#282846" - gibbed_anim = "gibbed-a" - dusted_anim = "dust-a" + flesh_color = "#34AF10" //TODO: set colors + blood_color = "#b3cbc3" + base_color = "#066000" + + has_glowing_eyes = TRUE + death_message = "lets out a waning guttural screech, green blood bubbling from its maw." //death_sound = 'sound/voice/hiss6.ogg' + male_cough_sounds = null + female_cough_sounds = null + male_sneeze_sound = null + female_sneeze_sound = null //speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') //speech_chance = 100 + speech_bubble_appearance = "ghost" + + genders = list(PLURAL, NEUTER) //no sexual dymorphism + ambiguous_genders = TRUE //but just in case + virus_immune = 1 breath_type = null poison_type = null vision_flags = SEE_SELF|SEE_MOBS + appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_SKIN_COLOR | HAS_EYE_COLOR + + move_trail = /obj/effect/decal/cleanable/blood/tracks/paw has_organ = list( - O_HEART = /obj/item/organ/internal/heart, - O_BRAIN = /obj/item/organ/internal/brain/xeno, - O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel, - O_HIVE = /obj/item/organ/internal/xenos/hivenode, - O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_LUNGS = /obj/item/organ/internal/lungs, + O_VOICE = /obj/item/organ/internal/voicebox, + O_LIVER = /obj/item/organ/internal/liver, + O_KIDNEYS = /obj/item/organ/internal/kidneys, + O_BRAIN = /obj/item/organ/internal/brain/shadekin, + O_EYES = /obj/item/organ/internal/eyes ) - //SHADEKIN STUFF GOES HERE + //SHADEKIN-UNIQUE STUFF GOES HERE + var/shadekin_eye_color = BLUE_EYES has_limbs = list( BP_TORSO = list("path" = /obj/item/organ/external/chest), BP_GROIN = list("path" = /obj/item/organ/external/groin), - BP_HEAD = list("path" = /obj/item/organ/external/head), + BP_HEAD = list("path" = /obj/item/organ/external/head/shadekin), BP_L_ARM = list("path" = /obj/item/organ/external/arm), BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), BP_L_LEG = list("path" = /obj/item/organ/external/leg), @@ -73,23 +97,107 @@ BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) -/datum/species/xenos/get_bodytype() +/datum/species/shadekin/get_bodytype() return SPECIES_SHADEKIN -/datum/species/xenos/get_random_name() +/datum/species/shadekin/get_random_name() return "shadekin" +/datum/species/shadekin/handle_environment_special(var/mob/living/carbon/human/H) + handle_shade(H) -/mob/living/carbon/human/shadekin/New(var/new_loc) - h_style = "Bald" - ..(new_loc, SPECIES_SHADEKIN) +/datum/species/shadekin/can_breathe_water() + return TRUE //they dont quite breathe +/datum/species/shadekin/proc/get_shadekin_eyecolor() + return shadekin_eye_color +/datum/species/shadekin/proc/handle_shade(var/mob/living/carbon/human/H) + //Shifted kin don't gain/lose energy (and save time if we're at the cap) + var/darkness = 1 + var/dark_gains = 0 + var/turf/T = get_turf(H) + if(!T) + dark_gains = 0 + return + var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0 + darkness = 1-brightness //Invert + + if(H.ability_flags & AB_PHASE_SHIFTED) + dark_gains = 0 + else + //Heal (very) slowly in good darkness + if(darkness >= 0.75) + H.adjustFireLoss(-0.05) + H.adjustBruteLoss(-0.05) + H.adjustToxLoss(-0.05) + + switch(get_shadekin_eyecolor()) + //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 + + set_energy(H, get_energy(H) + dark_gains) + + //Update huds + update_shadekin_hud() + +/datum/species/shadekin/proc/get_energy(var/mob/living/carbon/human/H) + var/obj/item/organ/internal/brain/shadekin/shade_organ = H.internal_organs_by_name[O_BRAIN] + + if(!istype(shade_organ)) + return 0 + + return shade_organ.dark_energy + +/datum/species/shadekin/proc/get_max_energy(var/mob/living/carbon/human/H) + var/obj/item/organ/internal/brain/shadekin/shade_organ = H.internal_organs_by_name[O_BRAIN] + + if(!istype(shade_organ)) + return 0 + + return shade_organ.max_dark_energy + +/datum/species/shadekin/proc/set_energy(var/mob/living/carbon/human/H, var/new_energy) + var/obj/item/organ/internal/brain/shadekin/shade_organ = H.internal_organs_by_name[O_BRAIN] + + if(!istype(shade_organ)) + return + + shade_organ.dark_energy = CLAMP(new_energy, 0, get_max_energy(H)) + +/datum/species/shadekin/proc/set_max_energy(var/mob/living/carbon/human/H, var/new_max_energy) + var/obj/item/organ/internal/brain/shadekin/shade_organ = H.internal_organs_by_name[O_BRAIN] + + if(!istype(shade_organ)) + return 0 + + shade_organ.max_dark_energy = new_max_energy + +/datum/species/shadekin/proc/update_shadekin_hud() + return /datum/hud_data/shadekin - icon = 'icons/mob/shadekin_hud.dmi' has_a_intent = 1 has_m_intent = 1 @@ -104,11 +212,25 @@ has_internals = 0 gear = list( - "head" = list("loc" = ui_shoes, "name" = "Hat", "slot" = slot_head, "state" = "hair"), - "suit storage" = list("loc" = ui_sstore1, "name" = "Suit Storage", "slot" = slot_w_uniform, "state" = "center"), + "head" = list("loc" = ui_shoes, "name" = "Hat", "slot" = slot_head, "state" = "hair", "toggle" = 1), + "suit storage" = list("loc" = ui_sstore1, "name" = "Uniform", "slot" = slot_w_uniform, "state" = "center", "toggle" = 1), "id" = list("loc" = ui_id, "name" = "ID", "slot" = slot_wear_id, "state" = "id"), "belt" = list("loc" = ui_belt, "name" = "Belt", "slot" = slot_belt, "state" = "belt"), "back" = list("loc" = ui_back, "name" = "Back", "slot" = slot_back, "state" = "back"), "storage1" = list("loc" = ui_storage1, "name" = "Left Pocket", "slot" = slot_l_store, "state" = "pocket"), "storage2" = list("loc" = ui_storage2, "name" = "Right Pocket", "slot" = slot_r_store, "state" = "pocket") - ) \ No newline at end of file + ) + +/obj/screen/shadekin + icon = 'icons/mob/shadekin_hud.dmi' + invisibility = 101 + +/obj/screen/shadekin/darkness + name = "darkness" + icon_state = "dark" + alpha = 150 + +/obj/screen/shadekin/energy + name = "energy" + icon_state = "energy0" + alpha = 150 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_objects.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_objects.dm new file mode 100644 index 0000000000..02bdd61400 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_objects.dm @@ -0,0 +1,169 @@ +/obj/effect/shadekin_ability + name = "" + desc = "" + icon = 'icons/mob/screen_spells.dmi' + var/ability_name = "FIX ME" + var/cost = 50 + var/mob/living/carbon/human/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,"[name] (Cost: [cost]%) - [desc]") + else + do_ability(my_kin) + +/obj/effect/shadekin_ability/proc/do_ability() + if(my_kin.stat) + to_chat(my_kin,"Can't use that ability in your state!") + return FALSE + if(!istype(my_kin.species, datum/species/shadekin)) + to_chat(my_kin,"Only shadekin can use this!") + return FALSE + var/current_energy = my_kin.species.get_energy(my_kin) + if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED)) + to_chat(my_kin,"Can't use that ability while phase shifted!") + return FALSE + else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED)) + to_chat(my_kin,"Can only use that ability while phase shifted!") + return FALSE + else if(current_energy < cost) + to_chat(my_kin,"Not enough energy for that ability!") + return FALSE + + my_kin.species.set_energy(my_kin, current_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 = "Sparkles begin to appear around you, and all your ills seem to fade away." + on_expired_text = "The sparkles have faded, although you feel much healthier than before." + 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 = "You drag part of The Dark into realspace, enveloping yourself." + on_expired_text = "You lose your grasp on The Dark and realspace reasserts itself." + 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 +*/ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_procs.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_procs.dm new file mode 100644 index 0000000000..42d97d17b2 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_ability_procs.dm @@ -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(src,T) || loc != T) + to_chat(src,"You can't use that here!") + 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,"\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!") + + // 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,"Nobody nearby to mend!") + 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("\The [src] gently places a hand on \the [target]...") + face_atom(target) + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 0dfda17a28..0d15d19bbc 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -28,7 +28,7 @@ flesh_color = "#5F7BB0" base_color = "#001144" tail = "seromitail" - //tail_hair = "feathers" //TESHARI TEMPORARY REMOVAL + //tail_hair = "feathers" //VORESTATION TESHARI TEMPORARY REMOVAL reagent_tag = IS_TESHARI move_trail = /obj/effect/decal/cleanable/blood/tracks/paw diff --git a/code/modules/mob/living/carbon/human/species/station/station_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_vr.dm index d0d6548ec2..15a65fc7f2 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_vr.dm @@ -47,7 +47,7 @@ has_limbs = list( BP_TORSO = list("path" = /obj/item/organ/external/chest), BP_GROIN = list("path" = /obj/item/organ/external/groin), - BP_HEAD = list("path" = /obj/item/organ/external/head/vr/sergal), + BP_HEAD = list("path" = /obj/item/organ/external/head/sergal), BP_L_ARM = list("path" = /obj/item/organ/external/arm), BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), BP_L_LEG = list("path" = /obj/item/organ/external/leg), diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm index 64c636a620..b702e51f2e 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm @@ -1,8 +1,3 @@ -/datum/category_item/catalogue/fauna/shadekin //TODO: VIRGO_LORE_WRITING_WIP - name = "Sapients - Shadekin" - desc = "" - value = CATALOGUER_REWARD_EASY - /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." @@ -449,14 +444,3 @@ say_maybe_target = list("...mar?") say_got_target = list("MAR!!!") //reactions = list("Mar?" = "Marrr!", "Mar!" = "Marrr???", "Mar." = "Marrr.") - -/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 diff --git a/code/modules/mob/mob_defines_vr.dm b/code/modules/mob/mob_defines_vr.dm index 806da9a317..70cd778e8e 100644 --- a/code/modules/mob/mob_defines_vr.dm +++ b/code/modules/mob/mob_defines_vr.dm @@ -4,3 +4,6 @@ var/mob/temporary_form // For holding onto a temporary form var/disconnect_time = null //Time of client loss, set by Logout(), for timekeeping + + var/obj/screen/shadekin/darkness/shadekin_dark_display = null + var/obj/screen/shadekin/energy/shadekin_energy_display = null \ No newline at end of file diff --git a/code/modules/organs/subtypes/shadekin.dm b/code/modules/organs/subtypes/shadekin.dm new file mode 100644 index 0000000000..afba564a1d --- /dev/null +++ b/code/modules/organs/subtypes/shadekin.dm @@ -0,0 +1,7 @@ +/obj/item/organ/internal/brain/shadekin + can_assist = FALSE + + var/dark_energy = 100 + var/max_dark_energy = 100 + + organ_verbs = list() \ No newline at end of file diff --git a/code/modules/organs/subtypes/standard_vr.dm b/code/modules/organs/subtypes/standard_vr.dm index 57e205466b..85aa025d08 100644 --- a/code/modules/organs/subtypes/standard_vr.dm +++ b/code/modules/organs/subtypes/standard_vr.dm @@ -1,58 +1,11 @@ -//For custom heads with custom parts since the base code is restricted to a single icon file. - -/obj/item/organ/external/head/vr/get_icon() - - ..() - overlays.Cut() - if(!owner || !owner.species) - return - - for(var/M in markings) - var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") - mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode) - overlays |= mark_s //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons - icon_cache_key += "[M][markings[M]["color"]]" - - if(owner.should_have_organ(O_EYES))//Moved on top of markings. - var/obj/item/organ/internal/eyes/eyes = owner.internal_organs_by_name[O_EYES] - if(eye_icon) - var/icon/eyes_icon = new/icon(eye_icons_vr, eye_icon_vr) - if(eyes) - eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) - else - eyes_icon.Blend(rgb(128,0,0), ICON_ADD) - mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon - - if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS))) - var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon - mob_icon.Blend(lip_icon, ICON_OVERLAY) - - if(owner.f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] - if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype(owner) in facial_hair_style.species_allowed)) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) - overlays |= facial_s - - if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] - if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed)) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) - hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_MULTIPLY) - overlays |= hair_s - - return mob_icon - -/obj/item/organ/external/head/vr - var/eye_icons_vr = 'icons/mob/human_face_vr.dmi' - var/eye_icon_vr = "blank_eyes" +/obj/item/organ/external/head/blankeyes + eye_icon_location = 'icons/mob/human_face_vr.dmi' eye_icon = "blank_eyes" -/obj/item/organ/external/head/vr/sergal - eye_icon_vr = "eyes_sergal" +/obj/item/organ/external/head/sergal + eye_icon_location = 'icons/mob/human_face_vr.dmi' + eye_icon = "eyes_sergal" + +/obj/item/organ/external/head/shadekin + eye_icon_location = 'icons/mob/human_face_vr.dmi' + eye_icon = "eyes_shadekin_blue" \ No newline at end of file diff --git a/icons/mob/human_face_vr.dmi b/icons/mob/human_face_vr.dmi index 80c2d6a317..a8b2845194 100644 Binary files a/icons/mob/human_face_vr.dmi and b/icons/mob/human_face_vr.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 35f5c66c3f..6ba2363d9d 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -131,6 +131,7 @@ #include "code\_onclick\rig.dm" #include "code\_onclick\telekinesis.dm" #include "code\_onclick\hud\_defines.dm" +#include "code\_onclick\hud\_defines_vr.dm" #include "code\_onclick\hud\ability_screen_objects.dm" #include "code\_onclick\hud\action.dm" #include "code\_onclick\hud\ai.dm" @@ -2198,6 +2199,7 @@ #include "code\modules\mob\living\carbon\human\species\outsider\shadow.dm" #include "code\modules\mob\living\carbon\human\species\outsider\skeleton.dm" #include "code\modules\mob\living\carbon\human\species\outsider\vox.dm" +#include "code\modules\mob\living\carbon\human\species\shadekin\_defines.dm" #include "code\modules\mob\living\carbon\human\species\shadekin\shadekin.dm" #include "code\modules\mob\living\carbon\human\species\station\alraune.dm" #include "code\modules\mob\living\carbon\human\species\station\blank_vr.dm" @@ -2432,12 +2434,10 @@ #include "code\modules\mob\living\simple_mob\subtypes\vore\wolf.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\wolfgirl.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\zz_vore_overrides.dm" -#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\_defines.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_objects.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_procs.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\shadekin.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\types.dm" -#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\~defines.dm" #include "code\modules\mob\living\voice\voice.dm" #include "code\modules\mob\new_player\login.dm" #include "code\modules\mob\new_player\logout.dm" @@ -2523,6 +2523,7 @@ #include "code\modules\organs\subtypes\nano.dm" #include "code\modules\organs\subtypes\replicant.dm" #include "code\modules\organs\subtypes\seromi.dm" +#include "code\modules\organs\subtypes\shadekin.dm" #include "code\modules\organs\subtypes\slime.dm" #include "code\modules\organs\subtypes\standard.dm" #include "code\modules\organs\subtypes\standard_vr.dm"