diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index c18a3cecc0a..127d9f1712b 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -161,6 +161,8 @@ #define NOBLOODOVERLAY 20 ///No augments, for monkeys in specific because they will turn into fucking freakazoids https://cdn.discordapp.com/attachments/326831214667235328/791313258912153640/102707682-fa7cad80-4294-11eb-8f13-8c689468aeb0.png #define NOAUGMENTS 21 +///will be assigned a universal vampire themed last name shared by their department. this is preferenced! +#define BLOOD_CLANS 22 //organ slots #define ORGAN_SLOT_ADAMANTINE_RESONATOR "adamantine_resonator" diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index 5fd4b59b1c3..b36312439fd 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -32,5 +32,6 @@ GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt")) GLOBAL_LIST_INIT(gross_adjectives, world.file2list("strings/names/gross_adjectives.txt")) GLOBAL_LIST_INIT(hive_names, world.file2list("strings/names/hive_names.txt")) GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt")) +GLOBAL_LIST_INIT(vampire_house_names, world.file2list("strings/names/vampire_house_names.txt")) //loaded on startup because of " //would include in rsc if ' was used diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index a68a74916eb..3a5537d97b0 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -15,8 +15,11 @@ /// The priority at which names are decided, needed for proper randomization. #define PREFERENCE_PRIORITY_NAMES 5 +/// Preferences that aren't names, but change the name changes set by PREFERENCE_PRIORITY_NAMES. +#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 6 + /// The maximum preference priority, keep this updated, but don't use it for `priority`. -#define MAX_PREFERENCE_PRIORITY PREFERENCE_PRIORITY_NAMES +#define MAX_PREFERENCE_PRIORITY PREFERENCE_PRIORITY_NAME_MODIFICATIONS /// For choiced preferences, this key will be used to set display names in constant data. #define CHOICED_PREFERENCE_DISPLAY_NAMES "display_names" diff --git a/code/modules/client/preferences/species_features/vampire.dm b/code/modules/client/preferences/species_features/vampire.dm new file mode 100644 index 00000000000..462b7ce099d --- /dev/null +++ b/code/modules/client/preferences/species_features/vampire.dm @@ -0,0 +1,48 @@ +/datum/preference/choiced/vampire_status + savefile_key = "feature_vampire_status" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_FEATURES + priority = PREFERENCE_PRIORITY_NAME_MODIFICATIONS //this will be overwritten by names otherwise + main_feature_name = "Vampire status" + should_generate_icons = TRUE + relevant_species_trait = BLOOD_CLANS + +/datum/preference/choiced/vampire_status/create_default_value() + return "Inoculated" //eh, have em try out the mechanic first + +/datum/preference/choiced/vampire_status/init_possible_values() + var/list/values = list() + + values["Inoculated"] = icon('icons/obj/drinks.dmi', "bloodglass") + values["Outcast"] = icon('icons/obj/bloodpack.dmi', "generic_bloodpack") + + return values + +///list that stores a vampire house name for each department +GLOBAL_LIST_EMPTY(vampire_houses) + +/datum/preference/choiced/vampire_status/apply_to_human(mob/living/carbon/human/target, value) + if(value != "Inoculated") + return + + //find and setup the house (department) this vampire is joining + var/datum/job_department/vampire_house + var/datum/job/vampire_job = SSjob.GetJob(target.job) + if(!vampire_job) //no job or no mind LOSERS + return + var/list/valid_departments = (SSjob.joinable_departments.Copy()) - list(/datum/job_department/silicon, /datum/job_department/undefined) + for(var/datum/job_department/potential_house as anything in valid_departments) + if(vampire_job in potential_house.department_jobs) + vampire_house = potential_house + break + if(!vampire_house) //sillycones + return + if(!GLOB.vampire_houses[vampire_house.department_name]) + GLOB.vampire_houses[vampire_house.department_name] = pick(GLOB.vampire_house_names) + var/house_name = GLOB.vampire_houses[vampire_house.department_name] + + //modify name (Platos Syrup > Platos de Lioncourt) + var/first_space_index = findtextEx(target.real_name, " ") + var/new_name = copytext(target.real_name, 1, first_space_index + 1) + new_name += house_name + target.fully_replace_character_name(target.real_name, new_name) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 4676f78c103..d633f517e2d 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -409,6 +409,8 @@ var/require_human = CONFIG_GET(flag/enforce_human_authority) && (job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) + src.job = job.title + if(fully_randomize) if(require_human) player_client.prefs.randomise_appearance_prefs(~RANDOMIZE_SPECIES) diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 3a9586e3fda..2baa07d5dde 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -1,8 +1,23 @@ + +///how many vampires exist in each house +#define VAMPIRES_PER_HOUSE 5 +///maximum a vampire will drain, they will drain less if they hit their cap +#define VAMP_DRAIN_AMOUNT 50 + /datum/species/vampire name = "Vampire" id = SPECIES_VAMPIRE default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD, HAS_FLESH, HAS_BONE) + species_traits = list( + EYECOLOR, + HAIR, + FACEHAIR, + LIPS, + DRINKSBLOOD, + HAS_FLESH, + HAS_BONE, + BLOOD_CLANS, + ) inherent_traits = list( TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP, @@ -18,51 +33,42 @@ mutanttongue = /obj/item/organ/tongue/vampire limbs_id = SPECIES_HUMAN skinned_type = /obj/item/stack/sheet/animalhide/human + ///some starter text sent to the vampire initially, because vampires have shit to do to stay alive var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." - var/obj/effect/proc_holder/spell/targeted/shapeshift/bat/batform //attached to the datum itself to avoid cloning memes, and other duplicates /datum/species/vampire/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE return ..() -/datum/species/vampire/on_species_gain(mob/living/carbon/human/C, datum/species/old_species) +/datum/species/vampire/on_species_gain(mob/living/carbon/human/new_vampire, datum/species/old_species) . = ..() - to_chat(C, "[info_text]") - C.skin_tone = "albino" - C.update_body(0) - if(isnull(batform)) - batform = new - C.AddSpell(batform) - C.set_safe_hunger_level() + to_chat(new_vampire, "[info_text]") + new_vampire.skin_tone = "albino" + new_vampire.update_body(0) + new_vampire.set_safe_hunger_level() -/datum/species/vampire/on_species_loss(mob/living/carbon/C) +/datum/species/vampire/spec_life(mob/living/carbon/human/vampire, delta_time, times_fired) . = ..() - if(!isnull(batform)) - C.RemoveSpell(batform) - QDEL_NULL(batform) - -/datum/species/vampire/spec_life(mob/living/carbon/human/C, delta_time, times_fired) - . = ..() - if(istype(C.loc, /obj/structure/closet/crate/coffin)) - C.heal_overall_damage(2 * delta_time, 2 * delta_time, 0, BODYPART_ORGANIC) - C.adjustToxLoss(-2 * delta_time) - C.adjustOxyLoss(-2 * delta_time) - C.adjustCloneLoss(-2 * delta_time) + if(istype(vampire.loc, /obj/structure/closet/crate/coffin)) + vampire.heal_overall_damage(2 * delta_time, 2 * delta_time, 0, BODYPART_ORGANIC) + vampire.adjustToxLoss(-2 * delta_time) + vampire.adjustOxyLoss(-2 * delta_time) + vampire.adjustCloneLoss(-2 * delta_time) return - C.blood_volume -= 0.125 * delta_time - if(C.blood_volume <= BLOOD_VOLUME_SURVIVE) - to_chat(C, span_danger("You ran out of blood!")) - var/obj/shapeshift_holder/H = locate() in C - if(H) - H.shape.dust() //make sure we're killing the bat if you are out of blood, if you don't it creates weird situations where the bat is alive but the caster is dusted. - C.dust() - var/area/A = get_area(C) + vampire.blood_volume -= 0.125 * delta_time + if(vampire.blood_volume <= BLOOD_VOLUME_SURVIVE) + to_chat(vampire, span_danger("You ran out of blood!")) + var/obj/shapeshift_holder/holder = locate() in vampire + if(holder) + holder.shape.dust() //vampires do not have batform anymore, but this would still lead to very weird stuff with other shapeshift holders + vampire.dust() + var/area/A = get_area(vampire) if(istype(A, /area/service/chapel)) - to_chat(C, span_warning("You don't belong here!")) - C.adjustFireLoss(10 * delta_time) - C.adjust_fire_stacks(3 * delta_time) - C.IgniteMob() + to_chat(vampire, span_warning("You don't belong here!")) + vampire.adjustFireLoss(10 * delta_time) + vampire.adjust_fire_stacks(3 * delta_time) + vampire.IgniteMob() /datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker) if(istype(weapon, /obj/item/nullrod/whip)) @@ -75,8 +81,6 @@ color = "#1C1C1C" COOLDOWN_DECLARE(drain_cooldown) -#define VAMP_DRAIN_AMOUNT 50 - /datum/action/item_action/organ_action/vampire name = "Drain Victim" desc = "Leech blood from any carbon victim you are passively grabbing." @@ -121,18 +125,9 @@ if(!victim.blood_volume) to_chat(H, span_notice("You finish off [victim]'s blood supply.")) -#undef VAMP_DRAIN_AMOUNT - - /obj/item/organ/heart/vampire name = "vampire heart" color = "#1C1C1C" - -/obj/effect/proc_holder/spell/targeted/shapeshift/bat - name = "Bat Form" - desc = "Take on the shape a space bat." - invocation = "Squeak!" - charge_max = 50 - cooldown_min = 50 - shapeshift_type = /mob/living/simple_animal/hostile/retaliate/bat +#undef VAMPIRES_PER_HOUSE +#undef VAMP_DRAIN_AMOUNT diff --git a/icons/obj/bloodpack.dmi b/icons/obj/bloodpack.dmi index efcf670da59..fdbc5bceb9e 100644 Binary files a/icons/obj/bloodpack.dmi and b/icons/obj/bloodpack.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 4fe4048d43c..d0dade81bab 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/strings/names/vampire_house_names.txt b/strings/names/vampire_house_names.txt new file mode 100644 index 00000000000..53cf631c6f6 --- /dev/null +++ b/strings/names/vampire_house_names.txt @@ -0,0 +1,60 @@ +Aundae +Banu Haqim +Berne +Bounts +Brando +Brujah +Brunestud +Cross +Cruz +Culebra +Cullen +Czimisce +de Jund +de Lioncourt +de Ministry +de Spingbabble +der Catwalk +Derosso +Dimetrescu +Dimir +Dracula +Ego +Gangrel +Gilbert +Guine +Hecata +LaCroix +Lasombra +Malack +Malkavian +Markov +Maryam +Maximov +Munster +Myotis +Nosferatu +Quarra +Ravencroft +Ravnos +Salubri +San'layn +Sanguine +Scarlet +Selene +Sepperin +Strauss +Toga +Toreador +Tremere +Valentine +Valvatorez +Ventrue +Victoria +Voermann +von Block +von Count +von Ghoulist +von Grout +von Sport +Yakshi diff --git a/tgstation.dme b/tgstation.dme index 79c4a6625b0..21e7b1de2a0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2255,6 +2255,7 @@ #include "code\modules\client\preferences\species_features\lizard.dm" #include "code\modules\client\preferences\species_features\moth.dm" #include "code\modules\client\preferences\species_features\mutants.dm" +#include "code\modules\client\preferences\species_features\vampire.dm" #include "code\modules\client\verbs\ooc.dm" #include "code\modules\client\verbs\ping.dm" #include "code\modules\client\verbs\reset_held_keys.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/species_features.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/species_features.tsx index dab61934472..c4b9d80764a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/species_features.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/species_features.tsx @@ -60,3 +60,8 @@ export const underwear_color: Feature = { name: "Underwear color", component: FeatureColorInput, }; + +export const feature_vampire_status: Feature = { + name: "Vampire status", + component: FeatureDropdownInput, +};