"
dat += "Clothing & Equipment"
dat += "Underwear:[underwear]"
@@ -1284,14 +1336,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(jobban_isbanned(user, rank))
HTML += "[rank] | BANNED |
"
continue
- //Hyperstation Edit - Whitelisted roles
if((rank in GLOB.silly_positions) && (!sillyroles))
HTML += "[rank] WHITELIST | "
continue
- if((rank in GLOB.important_positions) && (!importantroles)) //TODO: make whitelists a bit more accurate than "silly" and "important"
- HTML += "[rank] WHITELIST | "
- continue
- //Hyperstation Edit end
var/required_playtime_remaining = job.required_playtime_remaining(user.client)
if(required_playtime_remaining)
HTML += "[rank] \[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \] | "
@@ -1903,8 +1950,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
grad_style = previous_list_item(grad_style, GLOB.hair_gradients_list)
- if("cycle_bg")
- bgstate = next_list_item(bgstate, bgstate_options)
+ if("select_bg")
+ var/new_bg = input(user, "Select a background:", "Character Preference") as null|anything in bgstate_options
+ if(new_bg)
+ bgstate = new_bg
if("underwear")
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list
@@ -2293,6 +2342,81 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list
if(new_dors)
features["xenodorsal"] = new_dors
+
+ // HYPER EDIT: Cosmetic body parts
+ if("cosmetic_head")
+ var/list/selectable_parts = list()
+ for(var/path in GLOB.cosmetic_heads)
+ var/datum/cosmetic_part/possible_part = GLOB.cosmetic_heads[path]
+ var/list/supported_species = possible_part.supported_species
+ if(!show_mismatched_markings && supported_species && !supported_species.Find(pref_species.id))
+ continue
+ selectable_parts[possible_part.name] = path
+ if(!selectable_parts.len)
+ to_chat(user, "There are no valid alt heads for this species!")
+ var/new_cosmetic_part
+ var/question = "Choose your character's alt head style:"
+ new_cosmetic_part = input(user, question, "Character Preference") as null|anything in selectable_parts
+ if(new_cosmetic_part)
+ features["cosmetic_head"] = GLOB.cosmetic_heads[selectable_parts[new_cosmetic_part]]
+ update_preview_icon()
+
+ if("cosmetic_chest")
+ var/list/selectable_parts = list()
+ for(var/path in GLOB.cosmetic_chests)
+ var/datum/cosmetic_part/possible_part = GLOB.cosmetic_chests[path]
+ var/list/supported_species = possible_part.supported_species
+ if(!show_mismatched_markings && supported_species && !supported_species.Find(pref_species.id))
+ continue
+ selectable_parts[possible_part.name] = path
+ if(!selectable_parts.len)
+ to_chat(user, "There are no valid alt chests for this species!")
+ var/new_cosmetic_part
+ var/question = "Choose your character's alt chest style:"
+ new_cosmetic_part = input(user, question, "Character Preference") as null|anything in selectable_parts
+ if(new_cosmetic_part)
+ features["cosmetic_chest"] = GLOB.cosmetic_chests[selectable_parts[new_cosmetic_part]]
+ update_preview_icon()
+
+ // currently symmetrical
+ if("cosmetic_arms")
+ var/list/selectable_parts = list()
+ for(var/path in GLOB.cosmetic_arms)
+ var/datum/cosmetic_part/possible_part = GLOB.cosmetic_arms[path]
+ var/list/supported_species = possible_part.supported_species
+ if(!show_mismatched_markings && supported_species && !supported_species.Find(pref_species.id))
+ continue
+ selectable_parts[possible_part.name] = path
+ if(!selectable_parts.len)
+ to_chat(user, "There are no valid alt arms for this species!")
+ var/new_cosmetic_part
+ var/question = "Choose your character's alt arms style:"
+ new_cosmetic_part = input(user, question, "Character Preference") as null|anything in selectable_parts
+ if(new_cosmetic_part)
+ features["cosmetic_l_arm"] = GLOB.cosmetic_arms[selectable_parts[new_cosmetic_part]]
+ features["cosmetic_r_arm"] = GLOB.cosmetic_arms[selectable_parts[new_cosmetic_part]]
+ update_preview_icon()
+
+ if("cosmetic_legs")
+ var/list/selectable_parts = list()
+ for(var/path in GLOB.cosmetic_legs)
+ var/datum/cosmetic_part/possible_part = GLOB.cosmetic_legs[path]
+ var/list/supported_species = possible_part.supported_species
+ if(!show_mismatched_markings && supported_species && !supported_species.Find(pref_species.id))
+ continue
+ selectable_parts[possible_part.name] = path
+ if(!selectable_parts.len)
+ to_chat(user, "There are no valid alt legs for this species!")
+ var/new_cosmetic_part
+ var/question = "Choose your character's alt legs style:"
+ new_cosmetic_part = input(user, question, "Character Preference") as null|anything in selectable_parts
+ if(new_cosmetic_part)
+ features["cosmetic_l_leg"] = GLOB.cosmetic_legs[selectable_parts[new_cosmetic_part]]
+ features["cosmetic_r_leg"] = GLOB.cosmetic_legs[selectable_parts[new_cosmetic_part]]
+ update_preview_icon()
+
+ // End hyper edit
+
//Genital code
if("cock_color")
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
@@ -2440,9 +2564,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["belly_size"] = clamp(new_bellysize, BELLY_MIN_SIZE, BELLY_MAX_SIZE)
if("butt_size")
- var/new_buttsize = input(user, "Butt size :\n([BUTT_MIN_SIZE]-[BUTT_MAX_SIZE])", "Character Preference") as num|null
+ var/new_buttsize = input(user, "Butt size :\n([BUTT_MIN_SIZE]-[BUTT_MAX_SIZE_SELECTABLE])", "Character Preference") as num|null
if(new_buttsize != null)
- features["butt_size"] = clamp(new_buttsize, BUTT_MIN_SIZE, BUTT_MAX_SIZE)
+ features["butt_size"] = clamp(new_buttsize, BUTT_MIN_SIZE, BUTT_MAX_SIZE_SELECTABLE)
+ //Restricted to 5 in menu, because we have chems to make them big IC, like with breasts and what not.
if("vag_shape")
var/new_shape
@@ -2692,6 +2817,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("all")
be_random_body = !be_random_body
+ if("cosmetic_markings")
+ features["cosmetic_markings"] = !features["cosmetic_markings"]
+
if("hear_midis")
toggles ^= SOUND_MIDI
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 80fab69e6..a77f504f8 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -576,6 +576,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
all_quirks -= V
cit_character_pref_load(S)
+ hyper_character_pref_load(S)
return 1
@@ -671,6 +672,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["all_quirks"] , all_quirks)
cit_character_pref_save(S)
+ hyper_character_pref_save(S)
return 1
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 6e002119b..b56cb7a95 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -28,46 +28,6 @@
allowed = list (/obj/item/gun/energy/laser/redtag)
resistance_flags = NONE
-/*
- * Posshim's Corpus atire
- */
-/obj/item/clothing/suit/hooded/corpus/
- name = "Standard Voidsuit"
- desc = "Standard issue voidsuit in the name of Grofit!"
- icon_state = "corpus"
- item_state = "armor"
- body_parts_covered = CHEST|GROIN|LEGS|ARMS|FEET|HANDS
- hoodtype = /obj/item/clothing/head/hooded/corpus
- flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT //"Hide shoes" but digi shoes dont get hidden, too bad!
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- mutantrace_variation = NO_MUTANTRACE_VARIATION //There is no need for a digi variant, it's a costume
-
-/obj/item/clothing/suit/hooded/corpus/s //sec
- name = "Enforcer Voidsuit"
- desc = "Delux issue grofit voidsuit. Let the middle class know You're in charge."
- icon_state = "corpuss"
- hoodtype = /obj/item/clothing/head/hooded/corpus/s //Enjoy this nice red outfit Kinaris! There is NO NEED for a pink one! xoxo -VivI Fanteriso
-
-/obj/item/clothing/suit/hooded/corpus/c //command
- name = "Commander Voidsuit"
- desc = "Premium issue correctional worker attire. Grease the gears of production."
- icon_state = "corpusc"
- hoodtype = /obj/item/clothing/head/hooded/corpus/c
-
-/obj/item/clothing/head/hooded/corpus
- name = "Voidsuit helmet"
- desc = "galvanized reinforced helm to protect against the elements"
- icon_state = "corpus"
- body_parts_covered = HEAD
- flags_inv = HIDEHAIR|HIDEEARS|HIDEFACIALHAIR|HIDEFACE|HIDEMASK|HIDESNOUT|HIDENECK //hide your ugly face with this one simple trick!
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
-
-/obj/item/clothing/head/hooded/corpus/s //sec
- icon_state = "corpuss"
-
-/obj/item/clothing/head/hooded/corpus/c //command
- icon_state = "corpusc"
-
/*
* Costume
*/
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index e01b770ba..7e0d0a31a 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -461,6 +461,120 @@
tastes = list("meat" = 2, "dough" = 2, "laziness" = 1)
foodtype = GRAIN | ANTITOXIC
+/obj/item/reagent_containers/food/snacks/donkpocket/taco
+ name = "\improper Taco-pocket"
+ desc = "Es hora de adentrarse en el espacio de bolsillo más salvaje jamás conocido. ¡jajaja!"
+ icon_state = "donkpockettaco"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/taco
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "spice" = 2, "vegetables" = 2, "cheese" = 2)
+ foodtype = GRAIN | VEGETABLES | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/taco
+ name = "warm Taco-pocket"
+ desc = "Es hora de adentrarse en el espacio de bolsillo más salvaje jamás conocido. ¡jajaja!"
+ icon_state = "donkpockettaco"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2)
+ tastes = list("meat" = 2, "dough" = 2, "spice" = 2, "vegetables" = 2, "cheese" = 2)
+ foodtype = GRAIN | VEGETABLES | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/plasma
+ name = "\improper Poison-pocket"
+ desc = "NOTE: WARNING. For slime species consumption only. Call ###-##-### if injested"
+ icon_state = "donkpocketplasma"
+ list_reagents = list(/datum/reagent/toxin/carpotoxin = 2, /datum/reagent/toxin/plasma = 2, /datum/reagent/fuel = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/plasma
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "poison" = 2, "welding fuel" = 2)
+ foodtype = GRAIN | TOXIC | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/plasma
+ name = "warm Poison-pocket"
+ desc = "NOTE: WARNING. For slime species consumption only. Call ###-##-### if injested"
+ icon_state = "donkpocketplasma"
+ bonus_reagents = list(/datum/reagent/toxin/carpotoxin = 2, /datum/reagent/toxin/plasma = 2, /datum/reagent/fuel = 2)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("meat" = 2, "dough" = 2, "poison" = 2, "welding fuel" = 2)
+ foodtype = GRAIN | TOXIC | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/breakfast
+ name = "\improper Breakfast-pocket"
+ desc = "Now for all you early morning Joes!."
+ icon_state = "donkpocketbreakfast"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/breakfast
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "eggs" =2, "bacon" =2)
+ foodtype = GRAIN | DAIRY | MEAT | BREAKFAST
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/breakfast //IT'S BEEN ELEVEN FUCKING HOURS I HATE BYOND I HATE BYOND I HATE BEYOND!!!
+ name = "warm Breakfast-pocket"
+ desc = "Now for all you early morning Joes!."
+ icon_state = "donkpocketbreakfast"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("meat" = 2, "dough" = 2, "eggs" = 2, "bacon" = 2)
+ foodtype = GRAIN | DAIRY | MEAT | BREAKFAST | ANTITOXIC
+
+/obj/item/reagent_containers/food/snacks/donkpocket/moth
+ name = "\improper Moth-pocket"
+ desc = "Donk Corp is now reaching out to all species! Dig in moths one and all."
+ icon_state = "donkpocketmoth"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/moth
+ filling_color = "#CD853F"
+ tastes = list("lint" = 2, "dough" = 2, "felt" = 2)
+ foodtype = GRAIN | DAIRY | CLOTH
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/moth
+ name = "warm Moth-pocket"
+ desc = "Donk Corp is now reaching out to all species! Dig in moths one and all."
+ icon_state = "donkpocketmoth"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("lint" = 2, "dough" = 2, "felt" = 2)
+ foodtype = GRAIN | DAIRY | CLOTH
+
+/obj/item/reagent_containers/food/snacks/donkpocket/vegan
+ name = "\improper Vegan-pocket"
+ desc = "For all you Animal Rights Consortium members out there!."
+ icon_state = "donkpocketvegan"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/vegan
+ filling_color = "#CD853F"
+ tastes = list("vegetables" = 2, "dough" = 2)
+ foodtype = GRAIN | VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/vegan
+ name = "warm Vegan-pocket"
+ desc = "For all you Animal Rights Consortium members out there!."
+ icon_state = "donkpocketvegan"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 3)
+ tastes = list("vegetables" = 2, "dough" = 2)
+ foodtype = GRAIN | VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/donkpocket/sm
+ name = "\improper Super-pocket"
+ desc = "You're probably not in a good spot if you're laying eyes on this."
+ icon_state = "donkpocketsm"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 99)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/sm
+ filling_color = "#CD853F"
+ tastes = list("white-noise" = 2)
+ foodtype = TOXIC
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/sm
+ name = "warm Super-pocket"
+ desc = "You're probably not in a good spot if you're laying eyes on this."
+ icon_state = "donkpocketsm"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 99)
+ tastes = list("white-noise" = 2)
+ foodtype = TOXIC
+
/obj/item/reagent_containers/food/snacks/dankpocket
name = "\improper Dank-pocket"
desc = "The food of choice for the seasoned botanist."
@@ -554,7 +668,7 @@
cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/berry
filling_color = "#CD853F"
tastes = list("dough" = 2, "jam" = 2)
- foodtype = GRAIN
+ foodtype = GRAIN | SUGAR
/obj/item/reagent_containers/food/snacks/donkpocket/warm/berry
name = "warm Berry-pocket"
@@ -563,7 +677,7 @@
bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/berryjuice = 3)
tastes = list("dough" = 2, "warm jam" = 2)
- foodtype = GRAIN
+ foodtype = GRAIN | SUGAR
/obj/item/reagent_containers/food/snacks/donkpocket/gondola
name = "\improper Gondola-pocket"
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
index 7c34fc8c2..9100bab34 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
@@ -362,6 +362,159 @@ datum/crafting_recipe/food/donut/meat
tastes = list("meat" = 2, "dough" = 2)
foodtype = GRAIN | VEGETABLES
+/datum/crafting_recipe/food/donkpocket/taco
+ time = 15
+ name = "Taco-pocket"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1,
+ /obj/item/reagent_containers/food/snacks/meatball = 1,
+ /obj/item/reagent_containers/food/snacks/grown/carrot = 1,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/lime = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/donkpocket/taco
+ subcategory = CAT_PASTRY
+
+/obj/item/reagent_containers/food/snacks/donkpocket/taco
+ name = "\improper Taco-pocket"
+ desc = "Es hora de adentrarse en el espacio de bolsillo más salvaje jamás conocido. ¡jajaja!"
+ icon_state = "donkpockettaco"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/taco
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "spice" = 2, "vegetables" = 2, "cheese" = 2)
+ foodtype = GRAIN | VEGETABLES | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/taco
+ name = "warm Taco-pocket"
+ desc = "Es hora de adentrarse en el espacio de bolsillo más salvaje jamás conocido. ¡jajaja!"
+ icon_state = "donkpockettaco"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2)
+ tastes = list("meat" = 2, "dough" = 2, "spice" = 2, "vegetables" = 2, "cheese" = 2)
+ foodtype = GRAIN | VEGETABLES | MEAT
+
+/datum/crafting_recipe/food/donkpocket/plasma
+ time = 15
+ name = "Plasma-pocket"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1,
+ /obj/item/reagent_containers/food/snacks/meatball = 1,
+ /datum/reagent/fuel = 1,
+ /datum/reagent/toxin/plasma = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/donkpocket/plasma
+ subcategory = CAT_PASTRY
+
+/obj/item/reagent_containers/food/snacks/donkpocket/plasma
+ name = "\improper Poison-pocket"
+ desc = "NOTE: WARNING. For slime species consumption only. Call ###-##-### if injested"
+ icon_state = "donkpocketplasma"
+ list_reagents = list(/datum/reagent/toxin/carpotoxin = 2, /datum/reagent/toxin/plasma = 2, /datum/reagent/fuel = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/plasma
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "poison" = 2, "welding fuel" = 2)
+ foodtype = GRAIN | TOXIC | MEAT
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/plasma
+ name = "warm Poison-pocket"
+ desc = "NOTE: WARNING. For slime species consumption only. Call ###-##-### if injested"
+ icon_state = "donkpocketplasma"
+ bonus_reagents = list(/datum/reagent/toxin/carpotoxin = 2, /datum/reagent/toxin/plasma = 2, /datum/reagent/fuel = 2)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("meat" = 2, "dough" = 2, "poison" = 2, "welding fuel" = 2)
+ foodtype = GRAIN | TOXIC | MEAT
+
+/datum/crafting_recipe/food/donkpocket/breakfast
+ time = 15
+ name = "Breakfast-pocket"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 1,
+ /obj/item/reagent_containers/food/snacks/friedegg = 1,
+ /obj/item/reagent_containers/food/snacks/meat/cutlet = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/donkpocket/breakfast
+ subcategory = CAT_PASTRY
+
+/obj/item/reagent_containers/food/snacks/donkpocket/breakfast
+ name = "\improper Breakfast-pocket"
+ desc = "Now for all you early morning Joes!."
+ icon_state = "donkpocketbreakfast"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/breakfast
+ filling_color = "#CD853F"
+ tastes = list("meat" = 2, "dough" = 2, "eggs" = 2, "bacon" = 2)
+ foodtype = GRAIN | DAIRY | MEAT | BREAKFAST
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/breakfast
+ name = "warm Breakfast-pocket"
+ desc = "Now for all you early morning Joes!."
+ icon_state = "donkpocketbreakfast"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("meat" = 2, "dough" = 2, "eggs" = 2, "bacon" = 2)
+ foodtype = GRAIN | DAIRY | MEAT | BREAKFAST | ANTITOXIC
+
+/datum/crafting_recipe/food/donkpocket/moth
+ time = 15
+ name = "Moth-pocket"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 1,
+ /obj/item/stack/sheet/cloth = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/donkpocket/moth
+ subcategory = CAT_PASTRY
+
+/obj/item/reagent_containers/food/snacks/donkpocket/moth
+ name = "\improper Moth-pocket"
+ desc = "Donk Corp is now reaching out to all species! Dig in moths one and all."
+ icon_state = "donkpocketmoth"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/moth
+ filling_color = "#CD853F"
+ tastes = list("lint" = 2, "dough" = 2, "felt" = 2)
+ foodtype = GRAIN | DAIRY | CLOTH
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/moth
+ name = "warm Moth-pocket"
+ desc = "Donk Corp is now reaching out to all species! Dig in moths one and all."
+ icon_state = "donkpocketmoth"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
+ tastes = list("lint" = 2, "dough" = 2, "felt" = 2)
+ foodtype = GRAIN | DAIRY | CLOTH
+
+/datum/crafting_recipe/food/donkpocket/vegan
+ time = 15
+ name = "Vegan-pocket"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1,
+ /obj/item/reagent_containers/food/snacks/grown/cabbage = 1,
+ /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/donkpocket/vegan
+ subcategory = CAT_PASTRY
+
+/obj/item/reagent_containers/food/snacks/donkpocket/vegan
+ name = "\improper Vegan-pocket"
+ desc = "For all you Animal Rights Consortium members out there!."
+ icon_state = "donkpocketvegan"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 2)
+ cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/vegan
+ filling_color = "#CD853F"
+ tastes = list("vegetables" = 2, "dough" = 2)
+ foodtype = GRAIN | VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/donkpocket/warm/vegan
+ name = "warm Vegan-pocket"
+ desc = "For all you Animal Rights Consortium members out there!."
+ icon_state = "donkpocketvegan"
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 3)
+ tastes = list("vegetables" = 2, "dough" = 2)
+ foodtype = GRAIN | VEGETABLES
+
/datum/crafting_recipe/food/donkpocket/spicy
time = 15
name = "Spicy-pocket"
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 5895c6de3..330744ebf 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -33,6 +33,9 @@
// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
seed = new seed()
seed.adjust_potency(50-seed.potency)
+ else if(!seed)
+ stack_trace("Grown initialized without seed. Okay.")
+ return INITIALIZE_HINT_QDEL
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
@@ -40,13 +43,11 @@
if(dried_type == -1)
dried_type = src.type
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_new(src, loc)
- seed.prepare_result(src)
- transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
- add_juice()
-
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_new(src, loc)
+ seed.prepare_result(src)
+ AddElement(/datum/element/item_scaling, TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5, 1) //Makes the resulting produce's sprite larger or smaller based on potency!
+ add_juice()
/obj/item/reagent_containers/food/snacks/grown/proc/add_juice()
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index fe8414b80..cd8ac3df9 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -127,13 +127,13 @@
return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_BAR)
/proc/get_all_accesses()
- return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT,
+ return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_RD,
ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_CHEMISTRY, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS,
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD,
ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_HEADS, ACCESS_CAPTAIN, ACCESS_ALL_PERSONAL_LOCKERS,
ACCESS_TECH_STORAGE, ACCESS_CHAPEL_OFFICE, ACCESS_ATMOSPHERICS, ACCESS_KITCHEN,
- ACCESS_BAR, ACCESS_JANITOR, ACCESS_CREMATORIUM, ACCESS_ROBOTICS, ACCESS_CARGO, ACCESS_CONSTRUCTION, ACCESS_BARISTA, ACCESS_BARBER,
+ ACCESS_BAR, ACCESS_JANITOR, ACCESS_CREMATORIUM, ACCESS_ROBOTICS, ACCESS_CARGO, ACCESS_CONSTRUCTION,
ACCESS_HYDROPONICS, ACCESS_LIBRARY, ACCESS_LAWYER, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_QM, ACCESS_SURGERY,
ACCESS_THEATRE, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_MAILSORTING, ACCESS_WEAPONS,
ACCESS_VAULT, ACCESS_MINING_STATION, ACCESS_XENOBIOLOGY, ACCESS_CE, ACCESS_HOP, ACCESS_HOS, ACCESS_RC_ANNOUNCE,
@@ -161,9 +161,9 @@
if(0)
return get_all_accesses()
if(1) //station general
- return list(ACCESS_KITCHEN,ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_LAWYER, ACCESS_BARISTA, ACCESS_BARBER)
+ return list(ACCESS_KITCHEN,ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_LAWYER)
if(2) //security
- return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT)
+ return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP)
if(3) //medbay
return list(ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CMO, ACCESS_PSYCH)
if(4) //research
@@ -224,10 +224,6 @@
return "RD Office"
if(ACCESS_BAR)
return "Bar"
- if(ACCESS_BARBER)
- return "Barber"
- if(ACCESS_BARISTA)
- return "Barista"
if(ACCESS_JANITOR)
return "Custodial Closet"
if(ACCESS_ENGINE)
@@ -326,8 +322,6 @@
return "Prison Turnstile Entrance"
if(ACCESS_LEAVE_GENPOP)
return "Prison Turnstile Exit"
- if(ACCESS_LAMBENT)
- return "Lambent's Quarters"
if(ACCESS_MINERAL_STOREROOM)
return "Mineral Storage"
if(ACCESS_MINISAT)
@@ -363,10 +357,10 @@
return "Code Scotch"
/proc/get_all_jobs()
- return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Barista", "Barber", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
+ return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
"Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer", "Engineering Intern",
"Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist", "Psychologist", "Medical Resident",
- "Research Director", "Scientist", "Roboticist", "Research Student", "Head of Security", "Warden", "Detective", "Security Officer", "Rookie", "Lambent")
+ "Research Director", "Scientist", "Roboticist", "Research Student", "Head of Security", "Warden", "Detective", "Security Officer", "Rookie")
/proc/get_all_job_icons() //For all existing HUD icons
return get_all_jobs() + list("Prisoner")
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index 92652190c..f568378c1 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -65,7 +65,7 @@ Captain
satchel = /obj/item/storage/backpack/satchel/cap
duffelbag = /obj/item/storage/backpack/duffelbag/captain
- implants = list(/obj/item/implant/mindshield)
+ implants = list(/obj/item/implant/mindshield, /obj/item/implant/kinaris)
accessory = /obj/item/clothing/accessory/medal/gold/captain
chameleon_extras = list(/obj/item/gun/energy/e_gun, /obj/item/stamp/captain)
@@ -100,13 +100,13 @@ Head of Personnel
outfit = /datum/outfit/job/hop
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
- ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS, ACCESS_BARISTA, ACCESS_BARBER,
+ ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MAILSORTING, ACCESS_QM, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_PSYCH)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
- ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS, ACCESS_BARISTA, ACCESS_BARBER,
+ ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MAILSORTING, ACCESS_QM, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm
index 9480cc9ae..9dec1a40a 100644
--- a/code/modules/jobs/job_types/cargo_service.dm
+++ b/code/modules/jobs/job_types/cargo_service.dm
@@ -170,7 +170,7 @@ Bartender
outfit = /datum/outfit/job/bartender
- access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM)
+ access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_BAR, ACCESS_MINERAL_STOREROOM)
@@ -183,7 +183,7 @@ Bartender
ears = /obj/item/radio/headset/headset_srv
uniform = /obj/item/clothing/under/rank/bartender
suit = /obj/item/clothing/suit/armor/vest
- backpack_contents = list(/obj/item/book/granter/action/drink_fling=1)
+ backpack_contents = list(/obj/item/storage/box/beanbag=1,/obj/item/book/granter/action/drink_fling=1)
shoes = /obj/item/clothing/shoes/laceup
/*
@@ -195,7 +195,7 @@ Cook
department_head = list("Head of Personnel")
department_flag = CIVILIAN
faction = "Station"
- total_positions = 1
+ total_positions = 2
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#bbe291"
diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm
index 0a0c83508..c199641ff 100644
--- a/code/modules/jobs/job_types/security.dm
+++ b/code/modules/jobs/job_types/security.dm
@@ -27,11 +27,11 @@ Head of Security
outfit = /datum/outfit/job/hos
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
- ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
+ ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
- ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
+ ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
@@ -62,7 +62,7 @@ Head of Security
duffelbag = /obj/item/storage/backpack/duffelbag/sec
box = /obj/item/storage/box/security
- implants = list(/obj/item/implant/mindshield)
+ implants = list(/obj/item/implant/mindshield, /obj/item/implant/kinaris)
chameleon_extras = list(/obj/item/gun/energy/e_gun/hos, /obj/item/stamp/hos)
diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm
index 92afee693..267680408 100644
--- a/code/modules/jobs/jobs.dm
+++ b/code/modules/jobs/jobs.dm
@@ -1,6 +1,5 @@
GLOBAL_LIST_INIT(command_positions, list(
"Captain",
- "Lambent",
"Head of Personnel",
"Head of Security",
"Chief Engineer",
@@ -38,8 +37,6 @@ GLOBAL_LIST_INIT(supply_positions, list(
GLOBAL_LIST_INIT(civilian_positions, list(
"Head of Personnel",
- "Barista",
- "Barber",
"Bartender",
"Botanist",
"Cook",
@@ -63,9 +60,6 @@ GLOBAL_LIST_INIT(nonhuman_positions, list(
"Cyborg",
ROLE_PAI))
-GLOBAL_LIST_INIT(important_positions, list(
- "Lambent"))
-
GLOBAL_LIST_INIT(silly_positions, list(
"Clown",
"Mime"))
diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm
index acd966416..c691b799d 100644
--- a/code/modules/mob/dead/new_player/login.dm
+++ b/code/modules/mob/dead/new_player/login.dm
@@ -43,7 +43,14 @@
S.cd = "/"
var/slot
S["default_slot"] >> slot
+ var/differing_version_notification = 0
if(slot)
S.cd = "/character[slot]"
- if(S["version"] < SAVEFILE_VERSION_MAX)
- to_chat(src, "Your characters are outdated from recent updates. Please make sure if everything is within reasonable levels.")
+ var/slot_version = 0
+ S["version"] >> slot_version
+ if(slot_version && slot_version < SAVEFILE_VERSION_MAX)
+ S.cd = "/"
+ S["new_differences_notification"] >> differing_version_notification
+ if(!differing_version_notification || differing_version_notification <= slot_version)
+ S["new_differences_notification"] << slot_version
+ to_chat(src, "There were recent changes with characters, and your savefiles are outdated. Your characters may not look the same depending on what changed.")
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 168b31410..c436e5808 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -487,6 +487,9 @@
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return 1
+ if(!has_mouth())
+ return 1
+
if(nutrition < 100 && !blood)
if(message)
visible_message("[src] dry heaves!", \
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 92ad4fa08..1765e6873 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -5,30 +5,24 @@
icon_state = "caucasian_m"
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
+
/mob/living/carbon/human/Initialize()
add_verb(src, /mob/living/proc/mob_sleep)
add_verb(src, /mob/living/proc/lay_down)
time_initialized = world.time
-
//initialize limbs first
create_bodyparts()
-
//initialize dna. for spawned humans; overwritten by other code
create_dna(src)
randomize_human(src)
dna.initialize_dna()
-
if(dna.species)
set_species(dna.species.type)
-
//initialise organs
create_internal_organs() //most of it is done in set_species now, this is only for parent call
physiology = new()
-
AddComponent(/datum/component/personal_crafting)
-
. = ..()
-
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /mob/living/carbon/human/clean_blood)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index a036dbb7f..287dd4d29 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -318,15 +318,24 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/mob/living/carbon/human/H = C
if(NOGENITALS in H.dna.species.species_traits)
H.give_genitals(TRUE) //call the clean up proc to delete anything on the mob then return.
-
// EDIT ENDS
+ if(NOMOUTH in species_traits)
+ for(var/obj/item/bodypart/head/head in C.bodyparts)
+ head.mouth = FALSE
+
+
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
if(!new_species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
else
C.dna.blood_type = new_species.exotic_bloodtype
+
+ if(NOMOUTH in species_traits)
+ for(var/obj/item/bodypart/head/head in C.bodyparts)
+ head.mouth = TRUE
+
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
for(var/X in inherent_traits)
@@ -502,6 +511,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/list/standing = list()
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
+ H.handle_cosmetic_parts()
if(HD && !(HAS_TRAIT(H, TRAIT_HUSK)))
// lipstick
@@ -594,6 +604,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//CITADEL EDIT - Do not forget to add this to relevent_layers list just above too!
H.remove_overlay(BODY_TAUR_LAYER)
//END EDIT
+ H.handle_cosmetic_parts()
if(!mutant_bodyparts)
return
@@ -678,21 +689,17 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if("mam_tail" in mutant_bodyparts)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "mam_tail"
-
if("mam_waggingtail" in mutant_bodyparts)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "mam_waggingtail"
else if ("mam_tail" in mutant_bodyparts)
bodyparts_to_add -= "mam_waggingtail"
-
if("mam_ears" in mutant_bodyparts)
if(!H.dna.features["mam_ears"] || H.dna.features["mam_ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || HD.status == BODYPART_ROBOTIC)
bodyparts_to_add -= "mam_ears"
-
if("mam_snouts" in mutant_bodyparts) //Take a closer look at that snout!
if((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || HD.status == BODYPART_ROBOTIC)
bodyparts_to_add -= "mam_snouts"
-
if("taur" in mutant_bodyparts)
if(!H.dna.features["taur"] || H.dna.features["taur"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
bodyparts_to_add -= "taur"
@@ -1647,8 +1654,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
)
if (target.canbearoused)
target.adjustArousalLoss(5)
- if (target.getArousalLoss() >= 100 && ishuman(target) && HAS_TRAIT(target, TRAIT_MASO) && target.has_dna())
- target.mob_climax(forced_climax=TRUE)
+ if (HAS_TRAIT(target, TRAIT_MASO))
+ target.mob_climax_instant()
if (!HAS_TRAIT(target, TRAIT_NYMPHO))
stop_wagging_tail(target)
@@ -2005,8 +2012,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.update_damage_overlays()
if(HAS_TRAIT(H, TRAIT_MASO))
H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
- if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna())
- H.mob_climax(forced_climax=TRUE)
+ H.mob_climax_instant()
else//no bodypart, we deal damage with a more general method.
H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 4c224a515..6b68f3b8a 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -690,6 +690,8 @@ generate/load female uniform sprites matching all previously decided variables
. += "-[BP.digitigrade_type]"
if(BP.dmg_overlay_type)
. += "-[BP.dmg_overlay_type]"
+ if(BP.cosmetic_icon)
+ . += "-cosm[BP.cosmetic_icon]"
if(BP.body_markings)
. += "-[BP.body_markings]"
else
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index ca11c14d0..fc3c25c15 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -77,8 +77,7 @@
var/mob/living/carbon/human/B = src
if(HAS_TRAIT(B, TRAIT_CHOKE_SLUT))
B.adjustArousalLoss(7)
- if (B.getArousalLoss() >= 100 && ishuman(B) && B.has_dna())
- B.mob_climax(forced_climax=TRUE)
+ B.mob_climax_instant()
else
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
else
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 585a882bb..8cb24c86e 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -200,6 +200,10 @@
INVOKE_ASYNC(RM, .proc/do_transform_animation)
SEND_SIGNAL(R, COMSIG_CYBORG_MODULE_CHANGE) //hyperstation edit
qdel(src)
+ //Skyrat change start
+ R.radio.extra_channels = RM.added_channels
+ R.radio.recalculateChannels()
+ //Skyrat change stop
return RM
/obj/item/robot_module/proc/be_transformed_to(obj/item/robot_module/old_module)
@@ -459,7 +463,7 @@
/obj/item/paint/anycolor,
/obj/item/cookiesynth,
/obj/item/pneumatic_cannon/pie/selfcharge/cyborg,
- ///obj/item/razor, //killbait material
+ /obj/item/razor, //killbait material
/obj/item/lipstick/purple,
/obj/item/soap/nanotrasen,
/obj/item/reagent_containers/spray/waterflower/cyborg,
@@ -493,7 +497,7 @@
/obj/item/toy/crayon/spraycan/borg,
/obj/item/extinguisher/mini,
/obj/item/hand_labeler/borg,
- ///obj/item/razor,
+ /obj/item/razor,
/obj/item/crowbar/cyborg,
/obj/item/instrument/violin,
/obj/item/soap/nanotrasen,
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 11907e54a..f2f218368 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -132,7 +132,7 @@
if(inventory_back)
armorval += inventory_back.armor.getRating(type)
return armorval*0.5
-/*
+
/mob/living/simple_animal/pet/dog/corgi/attackby(obj/item/O, mob/user, params)
if (istype(O, /obj/item/razor))
if (shaved)
@@ -155,7 +155,7 @@
return
..()
update_corgi_fluff()
-*/
+
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
usr << browse(null, "window=mob[REF(src)]")
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 0d37b98c1..3fc7e3c11 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -57,7 +57,9 @@
var/datum/callback/CB = foo
CB.Invoke()
- mind?.hide_ckey = client?.prefs?.hide_ckey
+ if(client.prefs)
+ mind?.hide_ckey = client.prefs.hide_ckey
+ client.fps = client.prefs.clientfps
log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP)
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
client.init_verbs()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index b291a295c..ac9a37eb2 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -104,6 +104,8 @@
var/icon_update_needed = FALSE
var/obj/machinery/computer/apc_control/remote_control = null
+ var/obj/effect/light/lighteffect //light effect
+
/obj/machinery/power/apc/unlocked
locked = FALSE
@@ -185,6 +187,8 @@
addtimer(CALLBACK(src, .proc/update), 5)
/obj/machinery/power/apc/Destroy()
+ if(lighteffect)
+ lighteffect.Del()
GLOB.apcs_list -= src
if(malfai && operating)
@@ -320,6 +324,13 @@
// And now, separately for cleanness, the lighting changing
if(update_state & UPSTATE_ALLGOOD)
+ if(!lighteffect)//make the light
+ lighteffect = new/obj/effect/light
+ lighteffect.loc = src.loc
+ lighteffect.alpha = 50
+ lighteffect.pixel_x = pixel_x
+ lighteffect.pixel_y = pixel_y
+
switch(charging)
if(APC_NOT_CHARGING)
light_color = LIGHT_COLOR_RED
@@ -328,6 +339,7 @@
if(APC_FULLY_CHARGED)
light_color = LIGHT_COLOR_GREEN
set_light(lon_range)
+ lighteffect.color = light_color
else if(update_state & UPSTATE_BLUESCREEN)
light_color = LIGHT_COLOR_BLUE
set_light(lon_range)
@@ -336,6 +348,10 @@
icon_update_needed = FALSE
+/obj/machinery/power/apc/Move()
+ if(lighteffect)
+ lighteffect.loc = src.loc //move the light overlay
+
/obj/machinery/power/apc/proc/check_updates()
var/last_update_state = update_state
var/last_update_overlay = update_overlay
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 39072d5b4..0db3695fc 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -223,6 +223,9 @@
var/bulb_emergency_pow_mul = 0.75 // the multiplier for determining the light's power in emergency mode
var/bulb_emergency_pow_min = 0.5 // the minimum value for the light's power in emergency mode
+ var/obj/effect/light/lighteffect //light effect
+
+
/obj/machinery/light/broken
status = LIGHT_BROKEN
icon_state = "tube-broken"
@@ -242,6 +245,8 @@
icon_state = "bulb-broken"
/obj/machinery/light/Move()
+ if(lighteffect)
+ lighteffect.loc = src.loc
if(status != LIGHT_BROKEN)
break_light_tube(1)
return ..()
@@ -285,6 +290,8 @@
/obj/machinery/light/Destroy()
var/area/A = get_area(src)
+ if(lighteffect)
+ lighteffect.Del()
if(A)
on = FALSE
// A.update_lights()
@@ -292,24 +299,35 @@
return ..()
/obj/machinery/light/update_icon()
+ if(!lighteffect) //dont have a light bloom, make it.
+ lighteffect = new/obj/effect/light/large
+ lighteffect.loc = src.loc
cut_overlays()
switch(status) // set icon_states
if(LIGHT_OK)
var/area/A = get_area(src)
if(emergency_mode || (A && A.fire))
icon_state = "[base_state]_emergency"
+ lighteffect.alpha = 0
else
icon_state = "[base_state]"
if(on)
+ lighteffect.alpha = CLAMP(light_power*35, 5, 100)
+ lighteffect.color = light_color
var/mutable_appearance/glowybit = mutable_appearance(overlayicon, base_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
glowybit.alpha = CLAMP(light_power*250, 30, 200)
add_overlay(glowybit)
if(LIGHT_EMPTY)
icon_state = "[base_state]-empty"
+ lighteffect.alpha = 0
if(LIGHT_BURNED)
icon_state = "[base_state]-burned"
+ lighteffect.alpha = 0
if(LIGHT_BROKEN)
icon_state = "[base_state]-broken"
+ lighteffect.alpha = 0
+ if(!on)
+ lighteffect.alpha = 0
return
// update the icon_state and luminosity of the light depending on its state
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 66073dbd1..a3fe88a39 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -266,7 +266,7 @@
icon_state = "modkit"
w_class = WEIGHT_CLASS_SMALL
require_module = 1
- module_type = /obj/item/robot_module/miner
+ module_type = list(/obj/item/robot_module/miner, /obj/item/robot_module/orepup)
var/denied_type = null
var/maximum_of_type = 1
var/cost = 30
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 63bd0bc52..65b86570c 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -197,7 +197,10 @@
L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \
"[L] is hit by \a [src][organ_hit_text]!", null, COMBAT_MESSAGE_RANGE)
if(candink && def_zone == BODY_ZONE_HEAD)
- playsound(src, 'sound/weapons/dink.ogg', 30, 1)
+ if(prob(2))
+ playsound(src, 'hyperstation/sound/weapons/dinkalternate.ogg', 30, 0)
+ else
+ playsound(src, 'sound/weapons/dink.ogg', 30, 1)
L.on_hit(src)
var/reagent_note
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 6d93a5e13..150c9db70 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -65,6 +65,12 @@
var/who = (isnull(user) || eater == user) ? "your" : "[eater.p_their()]"
to_chat(user, "You have to remove [who] [covered] first!")
return 0
+ if(!eater.has_mouth())
+ if(eater == user)
+ to_chat(eater, "You have no mouth, and cannot eat.")
+ else
+ to_chat(user, "You can't feed [eater], because they have no mouth!")
+ return 0
return 1
/obj/item/reagent_containers/ex_act()
diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
index 18e90b3a6..5fba1aa4b 100644
--- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm
+++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
@@ -282,16 +282,16 @@
. = ..()
if(.)
return
- if(chalice_taken == 1)
+ if(chalice_taken)
to_chat(user, "You hear a voice in your head... \"My chalice has already been taken, dear. I cannot give you another...\"")
return
if(user.getArousalLoss() < 100)
to_chat(user, "You hear a voice in your head... \"You are not horny enough to receive my blessing, dear~\"")
return
- if (ishuman(user) && user.has_dna())
- user.mob_climax(forced_climax=TRUE)
- to_chat(user, "You hear a voice in your head... \"You are worth of my blessing dear~\"")
- to_chat(user, "You feel overpowering pleasure surge through your entire body.")
- var/A = new /obj/item/reagent_containers/chalice/lust
- user.put_in_hands(A)
- chalice_taken = 1
\ No newline at end of file
+ var/mob/living/carbon/user_carbon = user
+ user_carbon.mob_climax_instant()
+ to_chat(user, "You hear a voice in your head... \"You are worthy of my blessing, dear~\"")
+ to_chat(user, "You feel overpowering pleasure surge through your entire body.")
+ var/A = new /obj/item/reagent_containers/chalice/lust
+ user.put_in_hands(A)
+ chalice_taken = TRUE
\ No newline at end of file
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index 4a1bc2113..b0208f9db 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -44,6 +44,13 @@
var/skin_tone = ""
var/body_gender = ""
var/species_id = ""
+ /**
+ * HYPER: when getting the appearance of a limb, the game will check
+ * for `cosmetic_icon` first. if there is none, it will default back
+ * to `species_id`. this allows us to use custom body part types for
+ * each limb in character customization.
+ */
+ var/datum/cosmetic_part/cosmetic_icon
var/color_src
var/base_bp_icon //Overrides the icon being used for this limb. This is mainly for downstreams, implemented and maintained as a favor in return for implementing synths. And also because should_draw_* for icon overrides was pretty messy. You're welcome.
var/should_draw_gender = FALSE
@@ -391,12 +398,22 @@
else
body_markings = "plain"
auxmarking = "plain"
- markings_color = list(colorlist)
-
else
body_markings = null
auxmarking = null
+ if(cosmetic_icon && is_organic_limb())
+ if(cosmetic_icon.icon)
+ base_bp_icon = cosmetic_icon.icon
+ use_digitigrade = cosmetic_icon.support_digitigrade ? use_digitigrade : NOT_DIGITIGRADE
+ color_src = cosmetic_icon.color_src ? cosmetic_icon.color_src : MUTCOLORS
+ if(!H.dna.features["cosmetic_markings"])
+ body_markings = null
+ auxmarking = null
+
+ if((MUTCOLORS in S.species_traits) || (MUTCOLORS_PARTSONLY in S.species_traits))
+ markings_color = list(colorlist)
+
if(!dropping_limb && H.dna.check_mutation(HULK))
mutation_color = "00aa00"
else
@@ -436,6 +453,11 @@
var/image_dir = 0
var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable
+ var/is_husk = species_id == "husk"
+
+ /// HYPER: allow for custom limb icons in character customization
+ var/has_cosmetic_state = !isnull(cosmetic_icon) && !isnull(cosmetic_icon.icon_state)
+ var/limb_style = has_cosmetic_state ? cosmetic_icon.icon_state : species_id
if(dropped)
image_dir = SOUTH
@@ -464,7 +486,7 @@
if(animal_origin)
if(is_organic_limb())
limb.icon = 'icons/mob/animal_parts.dmi'
- if(species_id == "husk")
+ if(is_husk)
limb.icon_state = "[animal_origin]_husk_[body_zone]"
else
limb.icon_state = "[animal_origin]_[body_zone]"
@@ -479,21 +501,21 @@
if(is_organic_limb())
limb.icon = base_bp_icon || 'icons/mob/human_parts.dmi'
if(should_draw_gender)
- limb.icon_state = "[species_id]_[body_zone]_[icon_gender]"
+ limb.icon_state = "[limb_style]_[body_zone]_[icon_gender]"
else if (use_digitigrade)
if(base_bp_icon == DEFAULT_BODYPART_ICON_ORGANIC) //Compatibility hack for the current iconset.
limb.icon_state = "digitigrade_[use_digitigrade]_[body_zone]"
else
- limb.icon_state = "[species_id]_digitigrade_[use_digitigrade]_[body_zone]"
+ limb.icon_state = "[limb_style]_digitigrade_[use_digitigrade]_[body_zone]"
else
- limb.icon_state = "[species_id]_[body_zone]"
+ limb.icon_state = "[limb_style]_[body_zone]"
// Body markings
if(body_markings)
- if(species_id == "husk")
+ if(is_husk)
marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir)
- else if(species_id == "husk" && use_digitigrade)
+ else if(is_husk && use_digitigrade)
marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir)
else if(!use_digitigrade)
@@ -508,10 +530,10 @@
// Citadel End
if(aux_zone)
- aux = image(limb.icon, "[species_id]_[aux_zone]", -aux_layer, image_dir)
+ aux = image(limb.icon, "[limb_style]_[aux_zone]", -aux_layer, image_dir)
. += aux
if(body_markings)
- if(species_id == "husk")
+ if(is_husk)
auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir)
else
auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir)
@@ -528,16 +550,16 @@
aux = image(limb.icon, "[aux_zone]", -aux_layer, image_dir)
. += aux
if(!isnull(auxmarking))
- if(species_id == "husk")
+ if(is_husk)
auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir)
else
auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir)
. += auxmarking
if(!isnull(body_markings))
- if(species_id == "husk")
+ if(is_husk)
marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir)
- else if(species_id == "husk" && use_digitigrade)
+ else if(is_husk && use_digitigrade)
marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir)
else if(!use_digitigrade)
@@ -550,20 +572,27 @@
. += marking
return
- if(color_src) //TODO - add color matrix support for base species limbs
- var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone))
- if(draw_color)
- limb.color = "#[draw_color]"
+ if(!color_src)
+ return
+ switch(color_src)
+ if(MUTCOLORS)
+ var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone))
+ if(draw_color)
+ limb.color = "#[draw_color]"
+ if(aux_zone)
+ aux.color = "#[draw_color]"
+ if(MATRIXED)
+ limb.color = list(markings_color)
if(aux_zone)
- aux.color = "#[draw_color]"
- if(!isnull(auxmarking))
- auxmarking.color = list(markings_color)
+ aux.color = list(markings_color)
- if(!isnull(body_markings))
- if(species_id == "husk")
- marking.color = "#141414"
- else
- marking.color = list(markings_color)
+ if(!isnull(auxmarking))
+ auxmarking.color = list(markings_color)
+ if(!isnull(body_markings))
+ if(is_husk)
+ marking.color = "#141414"
+ else
+ marking.color = list(markings_color)
/obj/item/bodypart/deconstruct(disassembled = TRUE)
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index a71cc199c..45f791b3c 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -34,6 +34,9 @@
var/lip_color = "white"
//If the head is a special sprite
var/custom_head
+
+ // if head has mouth; may depend on species
+ var/mouth = TRUE
/obj/item/bodypart/head/can_dismember(obj/item/I)
if(!((owner.stat == DEAD) || owner.InFullCritical()))
diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm
index afa991ca7..1c45d5df6 100644
--- a/code/modules/surgery/organs/stomach.dm
+++ b/code/modules/surgery/organs/stomach.dm
@@ -120,6 +120,27 @@
return
owner.vomit(stun = FALSE)
-/obj/item/organ/stomach/ipc
- name = "ipc stomach"
+
+/obj/item/organ/stomach/synthliz
+ name = "synthliz stomach"
icon_state = "stomach-ipc"
+
+// ipc power cell from oracle
+/obj/item/organ/stomach/cell
+ name = "micro-cell"
+ icon_state = "microcell"
+ w_class = WEIGHT_CLASS_NORMAL
+ zone = BODY_ZONE_CHEST
+ slot = ORGAN_SLOT_STOMACH
+ status = ORGAN_ROBOTIC
+ attack_verb = list("assault and battery'd")
+ desc = "A micro-cell, for IPC use only. Do not swallow."
+
+/obj/item/organ/stomach/cell/emp_act(severity)
+ switch(severity)
+ if(1)
+ owner.nutrition = 50
+ to_chat(owner, "Alert: Heavy EMP Detected. Rebooting power cell to prevent damage.")
+ if(2)
+ owner.nutrition = 250
+ to_chat(owner, "Alert: EMP Detected. Cycling battery.")
\ No newline at end of file
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index b2d19c586..7c6fe05ca 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -581,7 +581,7 @@
for(var/V in listeners)
var/mob/living/carbon/human/H = V
if(H.canbearoused && H.has_dna() && HAS_TRAIT(H, TRAIT_NYMPHO)) // probably a redundant check but for good measure
- H.mob_climax(forced_climax=TRUE)
+ H.mob_climax_instant()
*/
else if((findtext(message, family_friendly_words)))
cooldown = COOLDOWN_MEME
@@ -1123,7 +1123,7 @@
if(E.phase > 1)
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && E.lewd) // probably a redundant check but for good measure
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "Your [E.enthrallGender] pushes you over the limit, overwhelming your body with pleasure."), 5)
- H.mob_climax(forced_climax=TRUE)
+ H.mob_climax_instant()
H.SetStun(20)
H.setArousalLoss(H.min_arousal)
E.resistanceTally = 0 //makes resistance 0, but resets arousal, resistance buildup is faster unaroused (massively so).
diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm
index 2dbaf5394..4d8b21ac2 100644
--- a/code/modules/vending/autodrobe.dm
+++ b/code/modules/vending/autodrobe.dm
@@ -8,8 +8,7 @@
vend_reply = "Thank you for using AutoDrobe!"
products = list(/obj/item/clothing/suit/chickensuit = 1,
/obj/item/clothing/head/chicken = 1,
- /obj/item/clothing/suit/hooded/corpus = 1,
- /obj/item/clothing/suit/hooded/corpus/c = 1,
+ /obj/item/clothing/suit/hooded/wintercoat/corpus = 1,
/obj/item/clothing/under/gladiator = 1,
/obj/item/clothing/head/helmet/gladiator = 1,
/obj/item/clothing/under/gimmick/rank/captain/suit = 1,
@@ -112,6 +111,9 @@
/obj/item/clothing/head/wig/random = 3,
/obj/item/clothing/suit/ran = 2,
/obj/item/clothing/head/ran = 2,
+ /obj/item/clothing/suit/threepwoodjacket = 3,
+ /obj/item/clothing/under/threepwood = 2,
+ /obj/item/clothing/shoes/threepwoodboots = 1,
/obj/item/clothing/under/vaultsuit = 3)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
@@ -120,25 +122,26 @@
/obj/item/clothing/glasses/sunglasses/blindfold = 1,
/obj/item/clothing/mask/muzzle = 2)
premium = list(/obj/item/clothing/suit/pirate/captain = 2,
- /obj/item/clothing/head/pirate/captain = 2,
- /obj/item/clothing/head/helmet/roman/fake = 1,
- /obj/item/clothing/head/helmet/roman/legionnaire/fake = 1,
- /obj/item/clothing/under/roman = 1,
- /obj/item/clothing/shoes/roman = 1,
- /obj/item/shield/riot/roman/fake = 1,
- /obj/item/clothing/head/delinquent = 1, // One per vendor, please dear god don't mass produce these.
- /obj/item/skub = 1,
- /obj/item/clothing/under/lobster = 1, // CIT CHANGES
- /obj/item/clothing/head/lobsterhat = 1,
- /obj/item/clothing/head/drfreezehat = 1,
- /obj/item/clothing/suit/dracula = 1,
- /obj/item/clothing/suit/drfreeze_coat = 1,
- /obj/item/clothing/suit/gothcoat = 2,
- /obj/item/clothing/under/draculass = 1,
- /obj/item/clothing/under/drfreeze = 1, //End of Cit Changes
+ /obj/item/clothing/head/pirate/captain = 2,
+ /obj/item/clothing/head/helmet/roman/fake = 1,
+ /obj/item/clothing/head/helmet/roman/legionnaire/fake = 1,
+ /obj/item/clothing/under/roman = 1,
+ /obj/item/clothing/shoes/roman = 1,
+ /obj/item/shield/riot/roman/fake = 1,
+ /obj/item/clothing/head/delinquent = 1, // One per vendor, please dear god don't mass produce these.
+ /obj/item/skub = 1,
+ /obj/item/clothing/under/lobster = 1, // CIT CHANGES
+ /obj/item/clothing/head/lobsterhat = 1,
+ /obj/item/clothing/head/drfreezehat = 1,
+ /obj/item/clothing/suit/dracula = 1,
+ /obj/item/clothing/suit/drfreeze_coat = 1,
+ /obj/item/clothing/suit/gothcoat = 2,
+ /obj/item/clothing/under/draculass = 1,
+ /obj/item/clothing/under/drfreeze = 1, //End of Cit Changes
/obj/item/clothing/under/wedding_dress = 1,
- /obj/item/clothing/under/tuxedo = 1,
- /obj/item/storage/belt/cummerbund = 1)
+ /obj/item/clothing/under/tuxedo = 1,
+ /obj/item/clothing/suit/hooded/wintercoat/corpus/command = 1,
+ /obj/item/storage/belt/cummerbund = 1)
refill_canister = /obj/item/vending_refill/autodrobe
/obj/machinery/vending/autodrobe/all_access
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index 0d1e1f3df..5f9dee9d4 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -19,7 +19,7 @@
/obj/item/clothing/under/rank/security/skirt = 5,
/obj/item/clothing/under/rank/security/grey = 5,
/obj/item/clothing/under/pants/khaki = 5,
- /obj/item/clothing/suit/hooded/corpus/s = 5)
+ /obj/item/clothing/suit/hooded/wintercoat/corpus/sec = 5)
premium = list(/obj/item/clothing/under/rank/security/navyblue = 5,
/obj/item/clothing/suit/security/officer = 5,
/obj/item/clothing/head/beret/sec/navyofficer = 5,
diff --git a/config/config.txt b/config/config.txt
index a481ec955..a5720a805 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -5,8 +5,6 @@ $include dbconfig.txt
$include comms.txt
$include antag_rep.txt
$include donator_groupings.txt
-# Hyperstation Configs...
-$include hyperstation/jobs.txt
# You can use the @ character at the beginning of a config option to lock it from being edited in-game
# Example usage:
diff --git a/config/hyperstation/jobs.txt b/config/hyperstation/jobs.txt
deleted file mode 100644
index f9353be69..000000000
--- a/config/hyperstation/jobs.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# Allow time off to be enabled
-## Uncomment to allow players to use their accrued time off
-## Defaults to off because this requires the database unless you want them to
-## use only what they accrued during the current round
-#TIME_OFF
-
-# Allow PTO job changes
-## Currently this is required if using the previous to allow users to change
-## jobs. This may be changed in the future and can be used to expand the functionality
-## for something such as on-the-go job changing within the department, without heads.
-## Thus it remains here.
-#PTO_JOB_CHANGE
\ No newline at end of file
diff --git a/config/jobs.txt b/config/jobs.txt
index 4ba075e30..4d00392aa 100644
--- a/config/jobs.txt
+++ b/config/jobs.txt
@@ -3,7 +3,6 @@
#Job names must be identical to the title var of each job datum
#Positions can be set to -1 to allow unlimited slots
Captain=1,1
-Lambent=1,1
Head of Personnel=1,1
Head of Security=1,1
Chief Engineer=1,1
@@ -17,9 +16,7 @@ Cargo Technician=3,2
Shaft Miner=3,3
Bartender=1,1
-Barista=1,1
-Barber=2,1
-Cook=1,1
+Cook=2,1
Botanist=3,2
Janitor=2,1
diff --git a/goon/icons/obj/fitness.dmi b/goon/icons/obj/fitness.dmi
index 9434792fc..e2675cbda 100644
Binary files a/goon/icons/obj/fitness.dmi and b/goon/icons/obj/fitness.dmi differ
diff --git a/goon/icons/obj/power.dmi b/goon/icons/obj/power.dmi
index f70f5b51c..bb787c0b3 100644
Binary files a/goon/icons/obj/power.dmi and b/goon/icons/obj/power.dmi differ
diff --git a/hyperstation/code/__DEFINES/misc.dm b/hyperstation/code/__DEFINES/misc.dm
deleted file mode 100644
index 245bcc21e..000000000
--- a/hyperstation/code/__DEFINES/misc.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-///////////////
-// PTO Types //
-///////////////
-#define PTO_COMMAND "Command"
-#define PTO_SECURITY "Security"
-#define PTO_MEDICAL "Medical"
-#define PTO_ENGINEERING "Engineering"
-#define PTO_SCIENCE "Science"
-#define PTO_CARGO "Cargo"
-#define PTO_CIVILIAN "Civilian"
-#define PTO_CYBORG "Silicon"
diff --git a/hyperstation/code/controllers/configuration/entries/timeoff.dm b/hyperstation/code/controllers/configuration/entries/timeoff.dm
deleted file mode 100644
index 04127ed37..000000000
--- a/hyperstation/code/controllers/configuration/entries/timeoff.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/// Toggles time off for jobs
-/datum/config_entry/flag/time_off
-
-/// Toggles changing jobs with PTO
-/datum/config_entry/flag/pto_job_change
-
-/// PTO hour cap
-/datum/config_entry/number/pto_cap
- config_entry_value = 100 /// Total hours
- min_val = 0 /// Minimum hourly value
- integer = FALSE /// We can be a float for partial hours
diff --git a/hyperstation/code/controllers/subsystem/job.dm b/hyperstation/code/controllers/subsystem/job.dm
deleted file mode 100644
index 998f228f8..000000000
--- a/hyperstation/code/controllers/subsystem/job.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Some modifications to the jobs subsystem, courtesy of SandPoot.
- * If we pull from upstream we should have this somewhere at some point, so it's shoehorned
- * in here for the moment.
- * Insert unhelpful comment here.
- */
-
-/datum/controller/subsystem/job/proc/get_job_name(job_name)
- if (!job_name)
- return "Unknown" // Invalid job
- //var/all_alt_titles = get_all_alt_titles()
- //if (job_name in all_alt_titles) // Check if the name is an alt title
- //return get_job_name(all_alt_titles[job_name]) // Locate the original job title and return it
- if (job_name in get_all_job_icons()) // Check if the job has a HUD icon
- return job_name
- if (job_name in get_all_centcom_jobs()) // Return the NT logo if it is a CentCom job
- return "CentCom"
- return "Unknown" // Return unknown if none of the above apply
diff --git a/hyperstation/code/effects/lighting.dm b/hyperstation/code/effects/lighting.dm
new file mode 100644
index 000000000..02e07bfcd
--- /dev/null
+++ b/hyperstation/code/effects/lighting.dm
@@ -0,0 +1,18 @@
+/obj/effect/light/
+ name = "bloom"
+ icon = 'hyperstation/icons/effects/lighting.dmi'
+ icon_state = "light"
+ plane = ABOVE_LIGHTING_PLANE
+ blend_mode = BLEND_ADD
+ mouse_opacity = 0
+ anchored = TRUE //no more flying around.
+
+/obj/effect/light/medium
+ icon = 'hyperstation/icons/effects/lightingmed.dmi'
+ pixel_x = -16
+ pixel_y = -16
+
+/obj/effect/light/large
+ icon = 'hyperstation/icons/effects/lightinglarge.dmi'
+ pixel_x = -48
+ pixel_y = -48
\ No newline at end of file
diff --git a/hyperstation/code/game/area/Space_Station_13_areas.dm b/hyperstation/code/game/area/Space_Station_13_areas.dm
deleted file mode 100644
index 2bd9ccbce..000000000
--- a/hyperstation/code/game/area/Space_Station_13_areas.dm
+++ /dev/null
@@ -1,467 +0,0 @@
-/area/barber
- name = "Barber's Shop"
- icon_state = "barber"
-
-/area/kinarisrep
- name = "Kinaris Representative Office"
-
-/area/crew_quarters/bar/cafe
- name = "Cafe"
- icon_state = "cafe"
-
-/area/crew_quarters/bar/cafe/backroom
- name = "Cafe Backroom"
- icon_state = "bar"
-
-/area/crew_quarters/bar/cafe/storage
- name = "Cafe Storage"
- icon_state = "bar"
-
-/area/artatrium
- name = "Art Atrium"
- icon_state = "library"
-
-/area/crew_quarters/spa
- name = "Spa"
- icon_state = "sauna"
-
-/area/crew_quarters/spa/sauna
- name = "Sauna"
-
-/area/security/lambent
- name = "Lambent's Quarters"
- icon_state = "detective"
-
-//In hindsight a lot of how this set up was stupid and I should probably redo it -Dahl
-//Upper Hallways
-/area/hallway/primary/aft/upper
- name = "Upper Aft Primary Hallway"
- icon_state = "hallA"
-
-/area/hallway/primary/fore/upper
- name = "Upper Fore Primary Hallway"
- icon_state = "hallF"
-
-/area/hallway/primary/starboard/upper
- name = "Upper Starboard Primary Hallway"
- icon_state = "hallS"
-
-/area/hallway/primary/starboard/aft/upper
- name = "Upper Starboard Quarter Primary Hallway"
- icon_state = "hallAS"
-
-/area/hallway/primary/starboard/fore/upper
- name = "Upper Starboard Bow Primary Hallway"
- icon_state = "hallFS"
-
-/area/hallway/primary/port/upper
- name = "Upper Port Primary Hallway"
- icon_state = "hallP"
-
-/area/hallway/primary/port/aft/upper
- name = "Upper Port Quarter Primary Hallway"
- icon_state = "hallAP"
-
-/area/hallway/primary/port/fore/upper
- name = "Upper Port Bow Primary Hallway"
- icon_state = "hallFP"
-
-/area/hallway/primary/central/upper
- name = "Upper Central Primary Hallway"
- icon_state = "hallC"
-
-/area/hallway/secondary/command/upper
- name = "Upper Command Hallway"
- icon_state = "bridge_hallway"
-
-/area/hallway/secondary/construction/upper
- name = "Upper Construction Area"
- icon_state = "construction"
-
-/area/hallway/secondary/exit/upper
- name = "Upper Escape Shuttle Hallway"
- icon_state = "escape"
-
-/area/hallway/secondary/exit/departure_lounge/upper
- name = "Upper Departure Lounge"
- icon_state = "escape_lounge"
-
-/area/hallway/secondary/entry/upper
- name = "Upper Arrival Shuttle Hallway"
- icon_state = "entry"
-
-/area/hallway/secondary/service/upper
- name = "Upper Service Hallway"
- icon_state = "hall_service"
-
-//Upper Dorms
-/area/crew_quarters/dorms/upper
- name = "Upper Dormitories"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/toilet/upper
- name = "Upper Dormitory Toilets"
- icon_state = "toilet"
-
-/area/crew_quarters/locker/upper
- name = "Upper Locker Room"
- icon_state = "locker"
-
-//Upper Medbay
-/area/medical/medbay/upper
- name = "Upper Medbay"
- icon_state = "medbay"
- music = 'sound/ambience/signal.ogg'
-
-//Upper Maints
-//Departments
-
-/area/maintenance/department/chapel/upper
- name = "Upper Chapel Maintenance"
- icon_state = "maint_chapel"
-
-/area/maintenance/department/chapel/monastery/upper
- name = "Upper Monastery Maintenance"
- icon_state = "maint_monastery"
-
-/area/maintenance/department/crew_quarters/bar/upper
- name = "Upper Bar Maintenance"
- icon_state = "maint_bar"
-
-/area/maintenance/department/crew_quarters/dorms/upper
- name = "Upper Dormitory Maintenance"
- icon_state = "maint_dorms"
-
-/area/maintenance/department/crew_quarters/locker/upper
- name = "Upper Locker Room Maintenance"
- icon_state = "maint_locker"
-
-/area/maintenance/department/eva/upper
- name = "Upper EVA Maintenance"
- icon_state = "maint_eva"
-
-/area/maintenance/department/electrical/upper
- name = "Upper Electrical Maintenance"
- icon_state = "maint_electrical"
-
-/area/maintenance/department/engine/atmos/upper
- name = "Upper Atmospherics Maintenance"
- icon_state = "maint_atmos"
-
-/area/maintenance/department/security/upper
- name = "Upper Security Maintenance"
- icon_state = "maint_sec"
-
-/area/maintenance/department/security/brig/upper
- name = "Upper Brig Maintenance"
- icon_state = "maint_brig"
-
-/area/maintenance/department/medical/upper
- name = "Upper Medbay Maintenance"
- icon_state = "medbay_maint"
-
-/area/maintenance/department/medical/morgue/upper
- name = "Upper Morgue Maintenance"
- icon_state = "morgue_maint"
-
-/area/maintenance/department/science/upper
- name = "Upper Science Maintenance"
- icon_state = "maint_sci"
-
-/area/maintenance/department/cargo/upper
- name = "Upper Cargo Maintenance"
- icon_state = "maint_cargo"
-
-/area/maintenance/department/bridge/upper
- name = "Upper Bridge Maintenance"
- icon_state = "maint_bridge"
-
-/area/maintenance/department/engine/upper
- name = "Upper Engineering Maintenance"
- icon_state = "maint_engi"
-
-/area/maintenance/department/science/xenobiology/upper
- name = "Upper Xenobiology Maintenance"
- icon_state = "xenomaint"
- xenobiology_compatible = TRUE
-
-
-//Generic
-
-/area/maintenance/arrivals/north/upper
- name = "Upper Arrivals North Maintenance"
- icon_state = "fpmaint"
-
-/area/maintenance/arrivals/north_2/upper
- name = "Upper Arrivals North Maintenance"
- icon_state = "fpmaint"
-
-/area/maintenance/aft/upper
- name = "Upper Aft Maintenance"
- icon_state = "amaint"
-
-/area/maintenance/aft/secondary/upper
- name = "Upper Aft Maintenance"
- icon_state = "amaint_2"
-
-/area/maintenance/central/upper
- name = "Upper Central Maintenance"
- icon_state = "maintcentral"
-
-/area/maintenance/central/secondary/upper
- name = "Upper Central Maintenance"
- icon_state = "maintcentral"
-
-/area/maintenance/fore/upper
- name = "Upper Fore Maintenance"
- icon_state = "fmaint"
-
-/area/maintenance/fore/secondary/upper
- name = "Upper Fore Maintenance"
- icon_state = "fmaint_2"
-
-/area/maintenance/starboard/upper
- name = "Upper Starboard Maintenance"
- icon_state = "smaint"
-
-/area/maintenance/starboard/central/upper
- name = "Upper Central Starboard Maintenance"
- icon_state = "smaint"
-
-/area/maintenance/starboard/aft/upper
- name = "Upper Starboard Quarter Maintenance"
- icon_state = "asmaint"
-
-/area/maintenance/starboard/fore/upper
- name = "Upper Starboard Bow Maintenance"
- icon_state = "fsmaint"
-
-/area/maintenance/port/upper
- name = "Upper Port Maintenance"
- icon_state = "pmaint"
-
-/area/maintenance/port/central/upper
- name = "Upper Central Port Maintenance"
- icon_state = "maintcentral"
-
-/area/maintenance/port/aft/upper
- name = "Upper Port Quarter Maintenance"
- icon_state = "apmaint"
-
-/area/maintenance/port/fore/upper
- name = "Upper Port Bow Maintenance"
- icon_state = "fpmaint"
-
-/area/maintenance/disposal/upper
- name = "Upper Waste Disposal"
- icon_state = "disposal"
-
-/area/maintenance/disposal/incinerator/upper
- name = "Upper Incinerator"
- icon_state = "disposal"
-
-//Misc Maint
-/area/maintenance/theatre
- name = "Theatre Maintenance"
- icon_state = "maintcentral"
-
-/area/maintenance/theatre/upper
- name = "Upper Theatre Maintenance"
- icon_state = "maintcentral"
-
-//Solar Maint
-
-/area/maintenance/solars/upper
- name = "Upper Solar Maintenance"
- icon_state = "yellow"
-
-/area/maintenance/solars/port/upper
- name = "Upper Port Solar Maintenance"
- icon_state = "SolarcontrolP"
-
-/area/maintenance/solars/port/aft/upper
- name = "Upper Port Quarter Solar Maintenance"
- icon_state = "SolarcontrolAP"
-
-/area/maintenance/solars/port/fore/upper
- name = "Upper Port Bow Solar Maintenance"
- icon_state = "SolarcontrolFP"
-
-/area/maintenance/solars/starboard/upper
- name = "Upper Starboard Solar Maintenance"
- icon_state = "SolarcontrolS"
-
-/area/maintenance/solars/starboard/aft/upper
- name = "Upper Starboard Quarter Solar Maintenance"
- icon_state = "SolarcontrolAS"
-
-/area/maintenance/solars/starboard/fore/upper
- name = "Upper Starboard Bow Solar Maintenance"
- icon_state = "SolarcontrolFS"
-
-/area/maintenance/solars/aux/port/upper
- name = "Upper Port Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolA"
-
-/area/maintenance/solars/aux/port/aft/upper
- name = "Upper Port Quarter Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolAP"
-
-/area/maintenance/solars/aux/port/fore/upper
- name = "Upper Port Bow Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolA"
-
-/area/maintenance/solars/aux/starboard/upper
- name = "Upper Starboard Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolA"
-
-/area/maintenance/solars/aux/starboard/aft/upper
- name = "Upper Starboard Quarter Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolA"
-
-/area/maintenance/solars/aux/starboard/fore/upper
- name = "Upper Starboard Bow Auxiliary Solar Maintenance"
- icon_state = "SolarcontrolA"
-
-//Upper Security
-/area/security/upper
- name = "Upper Security"
- icon_state = "security"
- ambientsounds = HIGHSEC
-
-/area/security/main/upper
- name = "Upper Security Office"
- icon_state = "security"
-
-/area/security/brig/upper
- name = "Upper Brig"
- icon_state = "brig"
-
-/area/security/courtroom/upper
- name = "Upper Courtroom"
- icon_state = "courtroom"
-
-/area/security/prison/upper
- name = "Upper Prison Wing"
- icon_state = "sec_prison"
-
-/area/security/processing/upper
- name = "Upper Labor Shuttle Dock"
- icon_state = "sec_prison"
-
-/area/security/processing/cremation/upper
- name = "Upper Security Crematorium"
- icon_state = "sec_prison"
-
-/area/security/warden/upper
- name = "Upper Brig Control"
- icon_state = "Warden"
-
-/area/security/armory/upper
- name = "Upper Armory"
- icon_state = "armory"
-
-/area/security/detectives_office/upper
- name = "Detective's Office"
- icon_state = "detective"
- ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
-
-/area/security/detectives_office/private_investigators_office/upper
- name = "Upper Private Investigator's Office"
- icon_state = "detective"
-
-/area/security/range/upper
- name = "Upper Firing Range"
- icon_state = "firingrange"
-
-//Misc security
-/area/security/locker
- name = "Security Locker Room"
- icon_state = "brig"
-
-/area/security/visitation
- name = "Security Visitation"
- icon_state = "brig"
-
-//Misc Dorms
-/area/crew_quarters/dorms/A
- name = "Dormitories A"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/B
- name = "Dormitories B"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/C
- name = "Dormitories C"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/D
- name = "Dormitories D"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/E
- name = "Dormitories E"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/F
- name = "Dormitories F"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/G
- name = "Dormitories G"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/dorms/H
- name = "Dormitories H"
- icon_state = "Sleep"
- safe = TRUE
-
-/area/crew_quarters/park
- name = "Park"
- icon_state = "park"
-
-/area/janitor/upper
- name = "Upper Custodial Closet"
-
-/area/storage/A
- name = "Storage Office A"
- icon_state = "storage"
-
-/area/storage/B
- name = "Storage Office B"
- icon_state = "storage"
-
-/area/storage/C
- name = "Storage Office C"
- icon_state = "storage"
-
-/area/storage/D
- name = "Storage Office D"
- icon_state = "storage"
-
-/area/theatre/blackbox
- name = "Theatre Blackbox"
- icon_state = "Theatre"
-
-//Misc cargo
-/area/quartermaster/mail
- name = "Mail Office"
- icon_state = "cargo_mail"
-
-//Misc Engineering
-/area/engine/custom
- name = "Custom Engine Room"
- icon_state = "engine"
-
-/area/engine/tether
- name = "Sky Tether Control"
- icon_state = "engine"
diff --git a/hyperstation/code/game/machinery/announcement_system.dm b/hyperstation/code/game/machinery/announcement_system.dm
deleted file mode 100644
index 63cbd87de..000000000
--- a/hyperstation/code/game/machinery/announcement_system.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/obj/machinery/announcement_system
- var/onduty = "%PERSON has moved On-Duty as %RANK."
- var/offduty = "%PERSON, %RANK, has moved Off-Duty."
diff --git a/hyperstation/code/game/machinery/computer/timeclock.dm b/hyperstation/code/game/machinery/computer/timeclock.dm
deleted file mode 100644
index 4801f2bd1..000000000
--- a/hyperstation/code/game/machinery/computer/timeclock.dm
+++ /dev/null
@@ -1,310 +0,0 @@
-/// Timeclock terminal, ported from VOREStation
-/obj/machinery/computer/timeclock
- name = "timeclock terminal" // Name of the object
- icon = 'hyperstation/icons/obj/machinery/timeclock.dmi' // Spritesheet for the object's icon
- icon_state = "timeclock" // Icon state from the spritesheet
- icon_keyboard = null // Keyboard state because this is a computer and we need to tell it to not have a keyboard
- light_color = "#0099ff" // TODO: Adjust this // Color for the light coming from the object
- light_power = 0.5 // Brightness of the light coming from the object
- layer = ABOVE_WINDOW_LAYER // Layer for the object
- density = FALSE // Density of the object, so we can walk through it
- circuit = /obj/item/circuitboard/computer/timeclock // Circuitboard for the object in case it gets destroyed
-
- var/obj/item/card/id/card // Inserted ID card
-
-/// For when we create a new timeclock
-/obj/machinery/computer/timeclock/New()
- ..() // Let's do this just to be safe.
-
-// For when a timeclock is destroyed
-/obj/machinery/computer/timeclock/Destroy()
- if (card) // If we're holding an ID and get destroyed
- card.forceMove(get_turf(src)) // Get rid of the fucker
- card = null // And make sure we know it's gone
- . = ..() // Someone's gonna ask later, refer them here.
- // This shit just sets our return value to our parent proc's return value.
-
-// Determines what icon to used based on a couple factors
-/obj/machinery/computer/timeclock/update_icon()
- if (!process()) // If we can't process
- icon_state = "[initial(icon_state)]_off" // we must be offline.
- else if (card) // If we have an ID
- icon_state = "[initial(icon_state)]_card" // display it!
- else // All else fails?
- icon_state = "[initial(icon_state)]" // We're just a clock.
-
-/// Allows the timeclock to update its icon and lighting on power change, should power go out
-/obj/machinery/computer/timeclock/power_change()
- var/old_stat = stat // Save our old stats for later
- ..() // Call the parent proc to handle the actual powernet shit
- if (old_stat != stat) // If our stat changed
- update_icon() // update our icon
- if (stat & NOPOWER) // If we no longer have power
- set_light(0) // turn off our lights
- else // Otherwise
- set_light(brightness_on) // turn on our lights
-
-/// Handle clicking with an object
-/obj/machinery/computer/timeclock/attackby(obj/I, mob/user)
- if (istype(I, /obj/item/card/id)) // If the user clicked with an ID in hand
- if (!card && user.canUnEquip(I)) // Check if we already have an ID and that the user can drop the ID
- I.forceMove(src) // Move the ID into our own location
- card = I // Set our card to the ID
- SStgui.update_uis(src) // Update all open UIs for us
- update_icon() // Update our icon to reflect the new ID
- else if (card) // There must've already been an ID inserted
- to_chat(user, "There is already an ID card inside.")
- return // Quit doing shit so we don't hit the timeclock
- . = ..() // Set our return value to that of the parent proc
-
-/// Handle user clicking
-/obj/machinery/computer/timeclock/attack_hand(var/mob/user as mob)
- if (..()) // If for some reason the parent proc returns true
- return // We won't do anything
- user.set_machine(src) // Otherwise, set the mob's machine to us
- ui_interact(user) // Provide a UI to the user
-
-/// Handle UI interactions with this arcane shit known as tee gee yew eye
-/obj/machinery/computer/timeclock/ui_interact(mob/user, datum/tgui/ui)
- ui = SStgui.try_update_ui(user, src, ui) // Attempt to update the UI
- if (!ui) // If the UI doesn't exist
- ui = new(user, src, "TimeClock", name) // Make a new one
- ui.open() // And open it for the user
-
-/// Handle UI data
-/obj/machinery/computer/timeclock/ui_data(mob/user)
- var/list/data = ..() // Call the parent object's data proc and assign that to the data list
-
- // Data for showing user's own PTO
- if (user.client) // If the client exists
- data["department_hours"] = \
- SANITIZE_LIST(user.client.department_hours) // Add the department hours list into data
- data["user_name"] = "[user]" // Set the username to the user
-
- // Data about the card we put into the timeclock
- data["card"] = null // Add card data,
- data["assignment"] = null // Assignment data,
- data["job_datum"] = null // The job datum,
- data["allow_change_job"] = null // Whether or not we can change jobs,
- data["job_choices"] = null // And the possible jobs
- if (card) // If we have a card
- data["card"] = "[card]" // Set card data,
- data["assignment"] = card.assignment // Assignment data,
- var/datum/job/job = \
- SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Create a new job datum,
- if (job) // If the job exists
- data["job_datum"] = list( // Set job datum to a list with
- "title" = job.title, // The job title,
- "departments" = \
- flags_to_english(job.department_flag, job.flag), // The job department,
- "selection_color" = job.selection_color, // The selection color,
- "timeoff_factor" = job.timeoff_factor, // The timeoff factor,
- "pto_department" = job.pto_type // And the PTO type
- )
- if (CONFIG_GET(flag/time_off) \
- && CONFIG_GET(flag/pto_job_change)) // If we allow timeoff and job changing
- data["allow_change_job"] = TRUE // Add that to the data
- if (job && job.timeoff_factor < 0) // They're off duty so we have to lookup available jobs
- data["job_choices"] = \
- get_open_on_duty_jobs(user, job.pto_type) // Set the job choices
-
- return data // Give back the data list for subprocs
-
-/// The user interacted with me? owo!
-/obj/machinery/computer/timeclock/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
- if (..()) // Check if the parent UI had anything to say
- return TRUE // If so, we don't care to do anything
-
- add_fingerprint(usr) // Add the user's fingerprint to the list so sec can find them
-
- switch (action) // Check the action completed
- if ("id") // If the ID slot was clicked
- if (card) // Check if we have an ID already
- usr.put_in_hands(card) // If so, give the user the card
- card = null // And make sure we don't have it
- else // Otherwise
- var/obj/item/I = usr.get_active_held_item() // Get the item in their active hand
- if (istype(I, /obj/item/card/id) && usr.canUnEquip(I)) // Check if it's an ID and they can unequip the ID
- I.forceMove(src) // If so, move it into us
- card = I // And make sure we know we have it
- update_icon() // Update our icon too because we did something
- return TRUE // And stop handling any UI in this run
- if ("switch-to-on-duty-rank") // If they switched to on-duty
- if (check_face()) // Check that their face is visible
- if (check_card_cooldown()) // And their card isn't on cooldown
- make_on_duty(params["switch-to-on-duty-rank"], \
- params["switch-to-on-duty-assignment"]) // Finally make them on-duty with the requested rank+assignment
- usr.put_in_hands(card) // Give them their new card
- card = null // And get it out of us
- update_icon() // Update our icon in case the card was removed
- return TRUE // And stop handling UI in this run
- if ("switch-to-off-duty") // If they switched to off-duty
- if (check_face()) // Check that their face is visible
- if (check_card_cooldown()) // And that their card isn't on cooldown
- make_off_duty() // Finally make them off-duty
- usr.put_in_hands(card) // Shit out their ID into their hand
- card = null // And get rid of that card
- update_icon() // Update our icon in case the card was removed
- return TRUE // And stop handling any UI in this run
-
-/// Gets the open on-duty jobs available to a user in a specified department
-/obj/machinery/computer/timeclock/proc/get_open_on_duty_jobs(var/mob/user, var/department)
- var/list/available_jobs = list() // Make a list of available jobs
- for (var/datum/job/job in SSjob.occupations) // For all jobs in existing occupations
- if (is_open_onduty_job(user, department, job)) // Check if the job is open and on-duty for a user and given department
- available_jobs[job.title] = list(job.title) // If it is, add it to the list of available jobs
- if (job.alt_titles) // If the job has alt-titles (Like Station Engineer->Mechanic)
- for (var/alt_job in job.alt_titles) // Go through all the alt titles
- if (alt_job != job.title) // And if it isn't the current job's title (Station Engineer's alt title of Station Engineer)
- available_jobs[job.title] += alt_job // Add it to the list under that job title
- return available_jobs // Return the newly-filled list of available jobs
-
-/// How does xenobio work again? Oh right, we're checking the user's face here to allow access and prevent ne'er-do-wells from using someone's PTO
-/obj/machinery/computer/timeclock/proc/check_face()
- if (!card) // If no card is inserted (why are we checking their face?)
- to_chat(usr, "No ID is inserted.")
- return FALSE // Face check failed
- var/mob/living/carbon/human/H = usr // Get the usr as a human data type
- if (!(istype(H))) // If they somehow aren't a human??
- to_chat(usr, "Invalid user detected. Access denied.")
- return FALSE // Face check failed
- else if ((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) \
- || (H.head && (H.head.flags_inv & HIDEFACE))) // No, you can't hide your face
- to_chat(usr, "Facial recognition scan failed due to physical obstruction. Access denied.")
- return FALSE // Face check failed
- else if (H.get_face_name() == "Unknown" \
- || !(H.real_name == card.registered_name)) // If they're unknown or their real name isn't the name on the ID
- to_chat(usr, "Facial recognition scan failed. Access denied.")
- return FALSE // Face check failed
- else // Otherwise
- return TRUE // Face check success!
-
-/// Force users to wait 10 minutes between clocking in and out
-/obj/machinery/computer/timeclock/proc/check_card_cooldown()
- if (!card) // If we don't have a card
- return FALSE // We can't check cooldown, fail the check
- var/time_left = 10 MINUTES - (world.time - card.last_job_switch) // Determine how much time is left before the next switch
- if (time_left > 0) // If there's any time left at all
- to_chat(usr, "You need to wait another [round((time_left / 10) / 60, 1)] minute\s before you can switch.")
- return FALSE // Fail the check
- return TRUE // Otherwise pass the check
-
-/// Makes the active card on-duty with a set rank and assignment
-/obj/machinery/computer/timeclock/proc/make_on_duty(var/new_rank, var/new_assignment)
- var/datum/job/old_job = \
- SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Get their old job from the card
- var/datum/job/new_job = SSjob.GetJob(new_rank) // And their new job from the rank
-
- if (!old_job \
- || !is_open_onduty_job(usr, old_job.pto_type, new_job)) // If there's no old job or it's not an open and on-duty job
- return // Do nothing
- if (new_assignment != new_job.title \
- && !(new_assignment in new_job.alt_titles)) // If the new assignment isn't the new job's title or alt-title
- return // Do nothing
- if (new_job) // As long as there's a new job
- card.access = new_job.get_access() // Set the card's access to the new job's access
- card.assignment = new_assignment // And the card's assignment to the new assignment
- card.name = text(\
- "[card.registered_name]'s ID Card ([card.assignment])") // And change the card's name
- GLOB.data_core.manifest_modify(card.registered_name, \
- card.assignment) // Apply the changes to the crew manifest
- card.last_job_switch = world.time // Set the last job switch on the card to the current world time
- new_job.current_positions++ // Add one to the current positions for the new job
- var/mob/living/carbon/human/H = usr // Get the caller as a human data type
- H.mind.assigned_role = card.assignment // Set the assigned role of the caller's mind to the assignment on the card
- if (GLOB.announcement_systems.len) // If there are any announcement systems
- var/obj/machinery/announcement_system/announcer = \
- pick(GLOB.announcement_systems) // Pick an announcer, any announcer!
- announcer.announce("ONDUTY", card.registered_name, \
- card.assignment, list()) // Make the announcement for now on-duty personnel
-
-/// Makes the active card off-duty
-/obj/machinery/computer/timeclock/proc/make_off_duty()
- var/datum/job/found_job = \
- SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Get the current job from the inserted card
- if (!found_job) // If the card somehow doesn't have a job
- return // https://www.youtube.com/watch?v=2k0SmqbBIpQ
- var/new_dept = found_job.pto_type || PTO_CIVILIAN // New department is either the department's PTO type or civilian PTO
- var/datum/job/pto_job = null // Create a new PTO job
- for (var/datum/job/job in SSjob.occupations) // For all jobs in the list of occupations
- if (job.pto_type == new_dept \
- && job.timeoff_factor < 0) // If the job is the department's PTO type and has a negative timeoff factor
- pto_job = job // That's the new PTO job
- break // And stop looking
- if (pto_job) // If a PTO job was found
- // Apparently we aren't using this? I don't fucking know
- // var/old_title = card.assignment
- card.access = pto_job.get_access() // Assign the PTO job's access to the ID
- card.assignment = pto_job.title // And the PTO job's title to the ID
- card.name = text(\
- "[card.registered_name]'s ID Card ([card.assignment])") // Set the card's new name
- GLOB.data_core.manifest_modify(card.registered_name, \
- card.assignment) // And apply that change to the crew manifest
- card.last_job_switch = world.time // Set the last job switch on the card to the world's current time
- var/mob/living/carbon/human/H = usr // Get the caller as a human data type
- H.mind.assigned_role = pto_job.title // Set their mind's assigned role to the PTO job's title
- found_job.current_positions-- // Remove one from the found job's position count since they no longer have that job
- if (GLOB.announcement_systems.len) // If there are any announcement systems
- var/obj/machinery/announcement_system/announcer = \
- pick(GLOB.announcement_systems) // Pick an announcement system, any announcement system!
- announcer.announce("OFFDUTY", card.registered_name, \
- card.assignment, list()) // Make an off-duty announcement with that system
- return // I really don't know why this return exists we always return anyways lol
-
-/// Check if a job is open and on-duty for a given user and department
-/obj/machinery/computer/timeclock/proc/is_open_onduty_job(var/mob/user, var/department, var/datum/job/job)
- return job \
- && job.current_positions <= job.total_positions \
- && !jobban_isbanned(user, SSjob.get_job_name(job.title)) \
- && job.player_old_enough(user.client) \
- && job.pto_type == department \
- && job.timeoff_factor > 0 // I feel like this requires some HEAVY explanation so here we go.
- // First we check if the job exists
- // Then we check that there are enough open slots
- // Then we check if the user is jobbanned or not and negate that because it'll return positive if they're banned
- // Then we have to check that they have enough playtime to actually join as that job
- // Then we have to check that the PTO type matches the department requested (can't join security with a PTO type of medical)
- // Then we have to check that there's a timeoff value so you can actually accrue hours of PTO by playing as that role
-
-/// Convert a department and job flag to an english phrase
-/obj/machinery/computer/timeclock/proc/flags_to_english(var/department,var/flag)
- if (department == ENGSEC) // If the department flag is engineering or security (or silicon apparently?)
- switch (flag) // Switch based on the flag
- if (CAPTAIN, HOS, WARDEN, CHIEF) // Captain, Head of Security, Warden or Chief Engineer
- return "Command" // Are all command
- if (DETECTIVE, OFFICER) // Detectives and Officers
- return "Security" // Are all security
- //if (BRIGDOC) // Brig Docs
- //return "Medsec" // Are medical and science
- if (LAMBENT) // Lambent
- return "Lambent" // Are obviously Lambent. Dunno what you expected fam
- if (ENGINEER, ATMOSTECH) // Engineers and Atmos Technicians
- return "Engineering" // Are engineering
- if (ROBOTICIST) // Roboticist is defined here but I think it was supposed to be with medsci? Just in case.
- return "Science" // They're science
- else // Technically this won't always be silicon
- return "Silicon" // But we're listing your ass as silicon anyways. Cope.
- else if (department == MEDSCI) // Otherwise, if the department flag is medical or science
- switch (flag) // Switch based on the flag (again)
- if (RD_JF, CMO_JF) // Research Director or Chief Medical Officer
- return "Command" // Are both command
- if (SCIENTIST, ROBOTICIST) // Scientists and Roboticists (this is where I think this was meant to be but it's still with ENGSEC just in case)
- return "Science" // Are obviously science
- if (CHEMIST, DOCTOR, VIROLOGIST) // Chemists, Doctors, Virologists and Paramedics
- return "Medical" // Are medical
- if (GENETICIST) // Geneticists
- return "Medsci" // Are kind of a special, middle of the road medical and science case
- else // If you're landing here you're fucked
- return "What the fuck?" // So what the fuck?
- else if (department == CIVILIAN) // Otherwise you must be civilian, right? Right???
- switch (flag) // Once again a switch based on the flag
- if (HOP, QUARTERMASTER) // Head of Personnel and Quartermaster
- return "Command" // Are command
- //if (PRISONER) // Prisoners
- //return "Prisoner" // Are... prisoners? They shouldn't be able to PTO but if they manage to break out they can access a console so no fuck you here
- if (CARGOTECH, MINER) // Cargo Technicians and Miners
- return "Cargo" // Are cargonians
- else // Otherwise
- return "Civilian" // You must be a civilian. You could be an assisstant or a clown or a bartender, I don't really care.
- else // New department combo? Wack.
- return "What the fuck?" // what the fuck?
diff --git a/hyperstation/code/game/objects/effects/landmarks.dm b/hyperstation/code/game/objects/effects/landmarks.dm
deleted file mode 100644
index 5ae0945f4..000000000
--- a/hyperstation/code/game/objects/effects/landmarks.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/effect/landmark/start/lambent
- name = "Lambent"
- icon_state = "Lambent"
-
-/obj/effect/landmark/start/barber
- name = "Barber"
- icon_state = "Barber"
-
-/obj/effect/landmark/start/barista
- name = "Barista"
- icon_state = "Barista"
diff --git a/hyperstation/code/game/objects/items/cards_ids.dm b/hyperstation/code/game/objects/items/cards_ids.dm
deleted file mode 100644
index 8ea19ec93..000000000
--- a/hyperstation/code/game/objects/items/cards_ids.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/obj/item/card/id
- var/last_job_switch /// Last job switch for card's owner
diff --git a/hyperstation/code/game/objects/items/circuitboards/computer_circuitboards.dm b/hyperstation/code/game/objects/items/circuitboards/computer_circuitboards.dm
deleted file mode 100644
index c1a843992..000000000
--- a/hyperstation/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/obj/item/circuitboard/computer/timeclock
- name = "Timeclock (Computer Board)"
- build_path = /obj/machinery/computer/timeclock
diff --git a/hyperstation/code/game/objects/items/devices/radio/radio.dm b/hyperstation/code/game/objects/items/devices/radio/radio.dm
new file mode 100644
index 000000000..67ea054ff
--- /dev/null
+++ b/hyperstation/code/game/objects/items/devices/radio/radio.dm
@@ -0,0 +1,2 @@
+/obj/item/radio
+ var/list/extra_channels = list() //Allows indivudal channels, used for borgs
diff --git a/hyperstation/code/game/objects/items/stacks/tiles/tile_types.dm b/hyperstation/code/game/objects/items/stacks/tiles/tile_types.dm
index 1faa2102b..310dea667 100644
--- a/hyperstation/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/hyperstation/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -1,4 +1,3 @@
-//Farm things
/turf/open/floor/
var/farm_quality = 0 //all tiles have a farm quality, which is for farm animals to enjoy. 0 = worse 100 = best!
@@ -27,11 +26,3 @@
icon_state = "hay"
farm_quality = 100 //the best for farming!
floor_tile = /obj/item/stack/tile/hay
-
-//Carpets
-/obj/item/stack/tile/carpet/kinaris
- name = "gilded carpet"
- icon = 'hyperstation/icons/obj/tiles.dmi'
- icon_state = "tile-carpet-kinaris"
- turf_type = /turf/open/floor/carpet/kinaris
- tableVariant = /obj/structure/table/wood/fancy/kinaris
diff --git a/hyperstation/code/game/objects/railings.dm b/hyperstation/code/game/objects/railings.dm
index 2c01a1721..8140ad908 100644
--- a/hyperstation/code/game/objects/railings.dm
+++ b/hyperstation/code/game/objects/railings.dm
@@ -16,6 +16,7 @@
var/heat_resistance = 800
var/health = 70
var/maxhealth = 70
+ layer = BELOW_MOB_LAYER
resistance_flags = ACID_PROOF
@@ -164,6 +165,14 @@
usr.visible_message("[user] climbed over \the [src]!")
usr.do_twist(targetangle = 45, timer = 8)
+/obj/structure/railing/Initialize(mapload) //mobs will show under the south railing sprite, thanks Cyanosis for helping with the fix
+ . = ..()
+ if(!mapload)
+ return
+ if(!(dir & SOUTH))
+ return
+ layer = ABOVE_MOB_LAYER
+
/obj/structure/railing/handrail
name = "handrail"
desc = "A waist high handrail, perhaps you could climb over it."
diff --git a/hyperstation/code/game/objects/structures/bench.dm b/hyperstation/code/game/objects/structures/bench.dm
index ee0369d75..ba62136ac 100644
--- a/hyperstation/code/game/objects/structures/bench.dm
+++ b/hyperstation/code/game/objects/structures/bench.dm
@@ -9,15 +9,3 @@
icon_state = "bench_left"
/obj/structure/chair/bench/right
icon_state = "bench_right"
-
-/obj/structure/chair/bench/metal
- name = "bench"
- icon_state = "bench_metal_middle"
- icon = 'hyperstation/icons/obj/bench.dmi'
- buildstackamount = 1
- buildstacktype = /obj/item/stack/sheet/metal
-
-/obj/structure/chair/bench/metal/left
- icon_state = "bench_metal_left"
-/obj/structure/chair/bench/metal/right
- icon_state = "bench_metal_right"
\ No newline at end of file
diff --git a/hyperstation/code/game/objects/structures/ghost_role_spawners.dm b/hyperstation/code/game/objects/structures/ghost_role_spawners.dm
index 1c814b77b..c25c5f9be 100644
--- a/hyperstation/code/game/objects/structures/ghost_role_spawners.dm
+++ b/hyperstation/code/game/objects/structures/ghost_role_spawners.dm
@@ -165,35 +165,3 @@
/obj/effect/mob_spawn/human/villager/special(mob/living/carbon/human/new_spawn)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
-
-
-//Prisoner
-/obj/effect/mob_spawn/human/prisoner
- name = "prisoner transfer cryoteleporter"
- mob_name = "prisoner transfer"
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper"
- job_description = "Prisoner Transfer"
- outfit = /datum/outfit/prisoner
- id_job = "Prisoner Transfer"
- assignedrole = "Prisoner Transfer"
- short_desc = "You are a transferred prisoner to Layenia. Don't break out or otherwise act like an antag."
- flavour_text = "For one reason or another, you are a prisoner. Kinaris has chosen to temporarily hold you within Layenia Station's holding area, \
- until the end of the shift. You do not permanently reside here, but you may end up in this place from shift to shift. It is highly recommended to \
- make a unique character slot for this role. Kinaris would not neuter or otherwise remove identifying features that make you who you are; such as \
- altering your name, features, or physical appearance. As a prisoner, you still uphold a decent amount of rights."
- important_info = "Do NOT attempt to break out, antagonize, or otherwise treat your role as anything to grief with. Should you find a scenario where you want to, AHELP."
- objectives = "Do NOT attempt to break out or act like an antag. Serve your time until end of shift."
- mirrorcanloadappearance = TRUE
- roundstart = FALSE
- death = FALSE
-
-/datum/outfit/prisoner
- name = "Prisoner"
- uniform = /obj/item/clothing/under/rank/prisoner
- shoes = /obj/item/clothing/shoes/sneakers/orange
- id = /obj/item/card/id/prisoner
- implants = list(/obj/item/implant/exile, /obj/item/implant/tracking)
-
-/obj/effect/mob_spawn/human/prisoner/special(mob/living/carbon/human/new_spawn)
- ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
diff --git a/hyperstation/code/game/objects/structures/tables_racks.dm b/hyperstation/code/game/objects/structures/tables_racks.dm
deleted file mode 100644
index 2fa8eadf4..000000000
--- a/hyperstation/code/game/objects/structures/tables_racks.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-/obj/structure/table/wood/fancy/kinaris
- icon = 'hyperstation/icons/obj/structures.dmi'
- icon_state = "fancy_table_kinaris"
- buildstack = /obj/item/stack/tile/carpet/kinaris
- canSmoothWith = list(/obj/structure/table/wood/fancy/kinaris)
-
-/obj/structure/table/wood/fancy/kinaris/New()
- . = ..()
- icon = 'hyperstation/icons/obj/smooth_structures/fancy_table_kinaris.dmi'
diff --git a/hyperstation/code/game/turfs/open.dm b/hyperstation/code/game/turfs/open.dm
deleted file mode 100644
index 3553557f7..000000000
--- a/hyperstation/code/game/turfs/open.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/turf/open/indestructible/layenia/sand
- name = "\improper crimson sand"
- desc = "A reddish sand."
- icon = 'hyperstation/icons/turf/floors/layeniasand.dmi'
- icon_state = "mapping"
- baseturfs = /turf/open/indestructible/layenia/crystal
- slowdown = 1
- barefootstep = FOOTSTEP_SAND
- clawfootstep = FOOTSTEP_SAND
- heavyfootstep = FOOTSTEP_GENERIC_HEAVY
- initial_gas_mix = FROZEN_ATMOS
- planetary_atmos = TRUE
- smooth = SMOOTH_TRUE | SMOOTH_BORDER | SMOOTH_MORE
- canSmoothWith = list(/turf/open/indestructible/layenia/sand)
diff --git a/hyperstation/code/game/turfs/simulated/floor/fancy_floor.dm b/hyperstation/code/game/turfs/simulated/floor/fancy_floor.dm
deleted file mode 100644
index 2cc8f61fc..000000000
--- a/hyperstation/code/game/turfs/simulated/floor/fancy_floor.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/turf/open/floor/carpet/kinaris
- icon = 'hyperstation/icons/turf/floors/carpet_kinaris.dmi'
- floor_tile = /obj/item/stack/tile/carpet/kinaris
- canSmoothWith = list(/turf/open/floor/carpet/kinaris)
diff --git a/hyperstation/code/game/turfs/simulated/wall/mineral_walls.dm b/hyperstation/code/game/turfs/simulated/wall/mineral_walls.dm
deleted file mode 100644
index 34e2604ba..000000000
--- a/hyperstation/code/game/turfs/simulated/wall/mineral_walls.dm
+++ /dev/null
@@ -1,78 +0,0 @@
-/turf/closed/wall/mineral/titanium/custom //For spicy custom shuttles
- name = "whoops!"
- desc = "Scream at Dahl please!"
- icon = 'hyperstation/icons/turf/walls/customshuttles.dmi'
- icon_state = "amogus"
- explosion_block = 10
- smooth = SMOOTH_FALSE
- canSmoothWith = null
-
-/turf/closed/wall/mineral/titanium/custom/window
- opacity = FALSE
-
-/turf/closed/wall/mineral/titanium/custom/AfterChange(flags, oldType)
- . = ..()
- // Manually add space underlay, in a way similar to turf_z_transparency,
- // but we actually show the old content of the same z-level, as desired for shuttles
-
- var/turf/underturf_path
-
- // Grab previous turf icon
- if(!ispath(oldType, /turf/closed/wall/mineral/titanium/custom))
- underturf_path = oldType
- else
- // Else use whatever SSmapping tells us, like transparent open tiles do
- underturf_path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
-
- var/mutable_appearance/underlay_appearance = mutable_appearance(
- initial(underturf_path.icon),
- initial(underturf_path.icon_state),
- layer = TURF_LAYER - 0.02, plane = initial(underturf_path.plane))
- underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
- underlays += underlay_appearance
-
-/turf/closed/wall/mineral/titanium/custom/ferry
- name = "\improper ferry wall"
- desc = "A low tech hull for Layenia flight."
- icon_state = "ferry"
-
-/turf/closed/wall/mineral/titanium/custom/window/ferry
- name = "\improper ferry wall"
- desc = "A low tech hull for Layenia flight."
- icon_state = "ferry"
-
-/turf/closed/wall/mineral/titanium/custom/arrivals
- name = "\improper shuttle wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/customarrivals.dmi'
- icon_state = "amogus"
-
-/turf/closed/wall/mineral/titanium/custom/window/arrivals
- name = "\improper shuttle wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/customarrivals.dmi'
- icon_state = "amogus"
-
-/turf/closed/wall/mineral/titanium/custom/pod
- name = "\improper pod wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/custompod.dmi'
- icon_state = "amogus"
-
-/turf/closed/wall/mineral/titanium/custom/window/pod
- name = "\improper pod wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/custompod.dmi'
- icon_state = "amogus"
-
-/turf/closed/wall/mineral/titanium/custom/departures
- name = "\improper pod wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/customdepartures.dmi'
- icon_state = "amogus"
-
-/turf/closed/wall/mineral/titanium/custom/window/departures
- name = "\improper pod wall"
- desc = "A low tech hull for Layenia and space-flight"
- icon = 'hyperstation/icons/turf/walls/customdepartures.dmi'
- icon_state = "amogus"
diff --git a/hyperstation/code/modules/arousal/arousalhud.dm b/hyperstation/code/modules/arousal/arousalhud.dm
index 509438813..318edefd0 100644
--- a/hyperstation/code/modules/arousal/arousalhud.dm
+++ b/hyperstation/code/modules/arousal/arousalhud.dm
@@ -11,7 +11,15 @@
for(var/obj/item/organ/genital/G in U.internal_organs)
if(!G.nochange)
if(!G.dontlist)
- dat += "[G.mode == "hidden" ? "[G.name] (Hidden)" : (G.mode == "clothes" ? "[G.name] (Hidden by Clothes)" : (G.mode == "visable" ? "[G.name] (Visable)" : "[G.name] (Visable)"))]
"
+ var/genital_visibility = "[G.name] (Visible)"
+ switch(G.mode)
+ if(GENITALS_HIDDEN)
+ genital_visibility = "[G.name] (Hidden)"
+ if(GENITALS_CLOTHES)
+ genital_visibility = "[G.name] (Hidden by Clothes)"
+ if(GENITALS_VISIBLE)
+ genital_visibility = "[G.name] (Visible)"
+ dat += "[genital_visibility]
"
dat += {"
Contexual Options
"}
var/obj/item/organ/genital/penis/P = user.getorganslot("penis")
@@ -45,20 +53,17 @@
if(Belly.inflatable)
dat += "Deflate belly"
dat += "(Shrink your belly down a size)
"
-
-
- if(user.pulling)
+
+ if(user.pulling && !isnoncarbon(user.pulling)) // do not fuck animals
dat += "Climax over [user.pulling]" //you can cum on objects if you really want...
dat += "(Orgasm over a person or object.)
"
- if(isliving(user.pulling))
- if(iscarbon(user.pulling))
- dat += "Climax with [user.pulling]"
- dat += {"(Orgasm with another person.)
"}
-
- var/mob/living/carbon/human/H = user.pulling
- if(H.breedable && P && H)
- dat += "Impregnate [U.pulling] ([clamp(U.impregchance,0,100)]%)"
- dat += "(Climax inside another person, and attempt to knock them up.)
"
+ if(iscarbon(user.pulling))
+ dat += "Climax with [user.pulling]"
+ dat += {"(Orgasm with another person.)
"}
+ var/mob/living/carbon/human/H = user.pulling
+ if(H && H.breedable && P)
+ dat += "Impregnate [U.pulling] ([clamp(U.impregchance,0,100)]%)"
+ dat += "(Climax inside another person, and attempt to knock them up.)
"
else
dat += "Climax over"
dat += "(Requires a partner)
"
@@ -81,11 +86,9 @@
dat += "Old Menu"
dat += "Toggle Undergarments "
dat += "
"
-
var/datum/browser/popup = new(user, "arousal", "Arousal Panel")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state), 500,600)
-
popup.open()
@@ -140,7 +143,7 @@
T.toggle_visibility(picked_visibility)
if(href_list["masturbate"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.solomasturbate()
return
else
@@ -148,7 +151,7 @@
return
if(href_list["container"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.cumcontainer()
return
else
@@ -156,7 +159,7 @@
return
if(href_list["clothesplosion"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //Requires 33% arousal.
+ if (H.isPercentAroused(33)) //Requires 33% arousal.
H.clothesplosion()
return
else
@@ -164,7 +167,7 @@
return
if(href_list["climaxself"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.climaxself()
return
else
@@ -172,7 +175,7 @@
return
if(href_list["climax"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.climaxalone(FALSE)
return
else
@@ -180,7 +183,7 @@
return
if(href_list["climaxover"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.climaxover(usr.pulling)
return
else
@@ -188,7 +191,7 @@
return
if(href_list["climaxwith"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.climaxwith(usr.pulling)
return
else
@@ -196,7 +199,7 @@
return
if(href_list["impreg"])
- if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
+ if (H.isPercentAroused(33)) //requires 33% arousal.
H.impregwith(usr.pulling)
return
else
@@ -331,7 +334,7 @@ obj/screen/arousal/proc/kiss()
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
- picked_organ = pick_masturbate_genitals()
+ picked_organ = pick_climax_genitals(masturbation=TRUE, title="Masturbation")
if(picked_organ)
src << browse(null, "window=arousal") //closes the window
mob_masturbate(picked_organ)
@@ -365,55 +368,31 @@ obj/screen/arousal/proc/kiss()
to_chat(src, "You cannot climax without choosing genitals.")
return
-/mob/living/carbon/human/proc/climaxwith(mob/living/T)
-
- var/mob/living/carbon/human/L = pick_partner()
+/mob/living/carbon/human/proc/climaxwith(mob/living/carbon/human/partner)
+ if(!partner)
+ to_chat(src, "You cannot do this alone.")
+ return
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals()
- if(picked_organ)
- var/mob/living/partner = L
- if(partner)
- src << browse(null, "window=arousal") //alls fine, we can close the window now.
- var/obj/item/organ/genital/penis/P = picked_organ
- var/spillage = "No" //default to no, just incase player has items on to prevent climax
- if(!P.condom == 1&&!P.sounding == 1) //you cant climax with a condom on or sounding in.
- spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
- if(spillage == "Yes")
- mob_climax_partner(picked_organ, partner, TRUE, FALSE, FALSE)
- else
- mob_climax_partner(picked_organ, partner, FALSE, FALSE, FALSE)
- else
- to_chat(src, "You cannot do this alone.")
- return
- else //They either lack organs that can masturbate, or they didn't pick one.
+ if(!picked_organ)
to_chat(src, "You cannot climax without choosing genitals.")
return
+ src << browse(null, "window=arousal") // close arousal window
+ mob_climax_inside_spillage(picked_organ, partner, impreg=FALSE)
-
-/mob/living/carbon/human/proc/climaxover(mob/living/T)
-
- var/mob/living/carbon/human/L = T
+/mob/living/carbon/human/proc/climaxover(atom/partner)
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals()
- if(picked_organ)
- src << browse(null, "window=arousal") //alls fine, we can close the window now.
- var/mob/living/partner = L
- if(partner)
- var/obj/item/organ/genital/penis/P = picked_organ
- if(P.condom == 1)
- to_chat(src, "You cannot do this action with a condom on.")
- return
- if(P.sounding == 1)
- to_chat(src, "You cannot do this action with a sounding in.")
- return
- mob_climax_partner(picked_organ, partner, FALSE, FALSE, TRUE)
- else
- to_chat(src, "You cannot do this alone.")
- return
- else //They either lack organs that can masturbate, or they didn't pick one.
+ if(!picked_organ)
to_chat(src, "You cannot climax without choosing genitals.")
return
+ src << browse(null, "window=arousal") //alls fine, we can close the window now.
+ if(!partner || isnoncarbon(partner))
+ to_chat(src, "You cannot do this alone.")
+ return
+ mob_climax_cover(picked_organ, partner)
+
/mob/living/carbon/human/proc/clothesplosion()
if(usr.restrained(TRUE))
@@ -428,39 +407,29 @@ obj/screen/arousal/proc/kiss()
H.visible_message("[H] explodes out of their clothes!'")
-
-/mob/living/carbon/human/proc/impregwith(mob/living/T)
-
- var/mob/living/carbon/human/L = pick_partner()
- var/obj/item/organ/genital/picked_organ
- picked_organ = src.getorganslot("penis") //Impregnation must be done with a penis.
- if(picked_organ)
- var/mob/living/partner = L
- if(partner)
- if(!partner.breedable)//check if impregable.
- to_chat(src, "Your partner cannot be impregnated.")//some fuckary happening, you shouldnt even get to this point tbh.
- return
- var/obj/item/organ/genital/penis/P = picked_organ
- //you cant impreg with a condom on or sounding in.
- if(P.condom == 1)
- to_chat(src, "You cannot do this action with a condom on.")
- return
- if(P.sounding == 1)
- to_chat(src, "You cannot do this action with a sounding in.")
- return
- src << browse(null, "window=arousal") //alls fine, we can close the window now.
- //Keeping this for messy fun
- var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
- if(spillage == "Yes")
- mob_climax_partner(picked_organ, partner, TRUE, TRUE, FALSE)
- else
- mob_climax_partner(picked_organ, partner, FALSE, TRUE, FALSE)
- else
- to_chat(src, "You cannot do this alone.")
- return
- else //no penis :(
- to_chat(src, "You cannot impregnate without a penis.")
+/mob/living/carbon/human/proc/impregwith(mob/living/carbon/T)
+ var/mob/living/carbon/human/partner = pick_partner()
+ var/obj/item/organ/genital/penis/picked_organ = src.getorganslot("penis")
+ // wow that is a lot of conditionals huh
+ if(!picked_organ) // no penis :(
+ to_chat(src, "You cannot impregnate someone without a penis.")
return
+ if(!partner)
+ to_chat(src, "You cannot do this alone.")
+ return
+ if(!partner.breedable) //check if impregable.
+ to_chat(src, "Your partner cannot be impregnated.")
+ //some fuckery happening, you shouldnt even get to this point tbh.
+ return
+ if(picked_organ.condom)
+ to_chat(src, "You cannot impregnate someone with a condom on.")
+ return
+ if(picked_organ.sounding)
+ to_chat(src, "You cannot impregnate someone with a sounding rod in.")
+ return
+ src << browse(null, "window=arousal") //alls fine, we can close the window now.
+ mob_climax_inside_spillage(picked_organ, partner, impreg=TRUE)
+
/mob/living/carbon/human/proc/cumcontainer(mob/living/T)
//We'll need hands and no restraints.
@@ -500,6 +469,11 @@ obj/screen/arousal/proc/kiss()
cum_splatter_icon.Blend(icon('hyperstation/icons/effects/cumoverlay.dmi', "cum_obj"), ICON_MULTIPLY)
add_overlay(cum_splatter_icon)
+/mob/living/carbon/add_cum_overlay(type="normal")
+ var/mutable_appearance/cumoverlay = mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi')
+ cumoverlay.icon_state = "cum_[type]"
+ add_overlay(cumoverlay)
+
/atom/proc/wash_cum()
cut_overlay(mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi', "cum_normal"))
cut_overlay(mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi', "cum_large"))
@@ -523,7 +497,7 @@ obj/screen/arousal/proc/kiss()
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
- picked_organ = pick_masturbate_genitals()
+ picked_organ = pick_climax_genitals(masturbation=TRUE, title="Masturbation")
if(picked_organ)
src << browse(null, "window=arousal") //closes the window
mob_masturbate(picked_organ, cover = TRUE)
diff --git a/hyperstation/code/modules/arousal/organs/genitals.dm b/hyperstation/code/modules/arousal/organs/genitals.dm
new file mode 100644
index 000000000..9da552021
--- /dev/null
+++ b/hyperstation/code/modules/arousal/organs/genitals.dm
@@ -0,0 +1,6 @@
+/obj/item/organ/genital/proc/get_fluid_source()
+ if(producing)
+ return src.reagents
+ if(linked_organ && linked_organ.producing)
+ return linked_organ.reagents
+ return null
\ No newline at end of file
diff --git a/hyperstation/code/modules/cargo/packs/misc.dm b/hyperstation/code/modules/cargo/packs/misc.dm
index d1b88903f..21eb315b2 100644
--- a/hyperstation/code/modules/cargo/packs/misc.dm
+++ b/hyperstation/code/modules/cargo/packs/misc.dm
@@ -5,3 +5,31 @@
contains = list(/obj/item/polepack/,
/obj/item/wrench/)
crate_name = "stripper pole crate"
+
+/datum/supply_pack/organic/donkpockets
+ name = "Donkpocket Shipment"
+ desc = "We at Donk corp provide a wide five selection of holovid ready dinner pockets for all your dietary needs from extra-cheese to vegan to even mothpeople. Product of Donk co."
+ cost = 1500
+ contains = list()
+ crate_name = "Donk Crate"
+ crate_type = /obj/structure/closet/crate/freezer
+ var/num_contained = 5
+ //Put the types you want to contain inside this list below.
+ var/can_contain = list( /obj/item/storage/box/donkpockets,
+ /obj/item/storage/box/donkpockets/donkpockettaco,
+ /obj/item/storage/box/donkpockets/donkpocketplasma,
+ /obj/item/storage/box/donkpockets/donkpocketbreakfast,
+ /obj/item/storage/box/donkpockets/donkpocketmoth,
+ /obj/item/storage/box/donkpockets/donkpocketvegan,
+ /obj/item/storage/box/donkpockets/donkpocketspicy,
+ /obj/item/storage/box/donkpockets/donkpocketteriyaki,
+ /obj/item/storage/box/donkpockets/donkpocketpizza,
+ /obj/item/storage/box/donkpockets/donkpocketberry,
+ /obj/item/storage/box/donkpockets/donkpockethonk
+ )
+
+/datum/supply_pack/organic/donkpockets/fill(obj/structure/closet/crate/C)
+ contains = list()
+ for(var/i = 0; i < num_contained; i++)
+ contains += pick(can_contain)
+ . = ..()
\ No newline at end of file
diff --git a/hyperstation/code/modules/client/client_defines.dm b/hyperstation/code/modules/client/client_defines.dm
deleted file mode 100644
index 705945fac..000000000
--- a/hyperstation/code/modules/client/client_defines.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Additional client defines. I needed somewhere to put these so here it is!
- */
-/client
- //////////////////////////////////////
- // Things that require the database //
- //////////////////////////////////////
- var/list/department_hours = list() // Track hours of leave accrued for each department
- var/list/play_hours = list() // Tracks total playtime hours for each department
diff --git a/hyperstation/code/modules/client/hyper_pref_savefile.dm b/hyperstation/code/modules/client/hyper_pref_savefile.dm
new file mode 100644
index 000000000..a0a71216b
--- /dev/null
+++ b/hyperstation/code/modules/client/hyper_pref_savefile.dm
@@ -0,0 +1,36 @@
+/datum/preferences/proc/hyper_character_pref_load(savefile/S)
+ S["feature_cosmetic_head"] >> features["cosmetic_head"]
+ S["feature_cosmetic_chest"] >> features["cosmetic_chest"]
+ S["feature_cosmetic_l_arm"] >> features["cosmetic_l_arm"]
+ S["feature_cosmetic_r_arm"] >> features["cosmetic_r_arm"]
+ S["feature_cosmetic_l_leg"] >> features["cosmetic_l_leg"]
+ S["feature_cosmetic_r_leg"] >> features["cosmetic_r_leg"]
+ S["cosmetic_markings"] >> features["cosmetic_markings"]
+ var/cosmetic_head = sanitize_inlist(features["cosmetic_head"], GLOB.cosmetic_heads, "default")
+ var/cosmetic_chest = sanitize_inlist(features["cosmetic_chest"], GLOB.cosmetic_chests, "default")
+ var/cosmetic_l_arm = sanitize_inlist(features["cosmetic_l_arm"], GLOB.cosmetic_arms, "default")
+ var/cosmetic_r_arm = sanitize_inlist(features["cosmetic_r_arm"], GLOB.cosmetic_arms, "default")
+ var/cosmetic_l_leg = sanitize_inlist(features["cosmetic_l_leg"], GLOB.cosmetic_legs, "default")
+ var/cosmetic_r_leg = sanitize_inlist(features["cosmetic_r_leg"], GLOB.cosmetic_legs, "default")
+ features["cosmetic_head"] = GLOB.cosmetic_heads[cosmetic_head]
+ features["cosmetic_chest"] = GLOB.cosmetic_chests[cosmetic_chest]
+ features["cosmetic_l_arm"] = GLOB.cosmetic_arms[cosmetic_l_arm]
+ features["cosmetic_r_arm"] = GLOB.cosmetic_arms[cosmetic_r_arm]
+ features["cosmetic_l_leg"] = GLOB.cosmetic_legs[cosmetic_l_leg]
+ features["cosmetic_r_leg"] = GLOB.cosmetic_legs[cosmetic_r_leg]
+
+
+/datum/preferences/proc/hyper_character_pref_save(savefile/S)
+ var/datum/cosmetic_part/head = features["cosmetic_head"]
+ var/datum/cosmetic_part/chest = features["cosmetic_chest"]
+ var/datum/cosmetic_part/l_arm = features["cosmetic_l_arm"]
+ var/datum/cosmetic_part/r_arm = features["cosmetic_r_arm"]
+ var/datum/cosmetic_part/l_leg = features["cosmetic_l_leg"]
+ var/datum/cosmetic_part/r_leg = features["cosmetic_r_leg"]
+ WRITE_FILE(S["feature_cosmetic_head"], head.id)
+ WRITE_FILE(S["feature_cosmetic_chest"], chest.id)
+ WRITE_FILE(S["feature_cosmetic_l_arm"], l_arm.id)
+ WRITE_FILE(S["feature_cosmetic_r_arm"], r_arm.id)
+ WRITE_FILE(S["feature_cosmetic_l_leg"], l_leg.id)
+ WRITE_FILE(S["feature_cosmetic_r_leg"], r_leg.id)
+ WRITE_FILE(S["cosmetic_markings"], features["cosmetic_markings"])
\ No newline at end of file
diff --git a/hyperstation/code/modules/clothing/gloves.dm b/hyperstation/code/modules/clothing/gloves.dm
index 107126506..c3ecb21fe 100644
--- a/hyperstation/code/modules/clothing/gloves.dm
+++ b/hyperstation/code/modules/clothing/gloves.dm
@@ -10,4 +10,4 @@
strip_delay = 40
equip_delay_other = 20
cold_protection = HANDS
- min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
+ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
\ No newline at end of file
diff --git a/hyperstation/code/modules/clothing/suits/misc.dm b/hyperstation/code/modules/clothing/suits/misc.dm
index 31ef1643f..0793aaa26 100644
--- a/hyperstation/code/modules/clothing/suits/misc.dm
+++ b/hyperstation/code/modules/clothing/suits/misc.dm
@@ -21,4 +21,43 @@
name = "\improper Hellraider's Vest"
desc = "An open leather vest with battlescarred metal shoulderpads, discovered in a dimensional anomaly. Smells of gunpowder and plasma."
icon_state = "guncaster_alt"
- item_state = "guncaster_alt"
\ No newline at end of file
+ item_state = "guncaster_alt"
+
+/*
+ * Posshim's Corpus atire
+ */
+ //Making this a subset of wintercoats/winterhoods since poss intends it to have wintercoat stats --Archie
+
+/obj/item/clothing/suit/hooded/wintercoat/corpus
+ name = "Standard Voidsuit"
+ desc = "Standard issue voidsuit in the name of Grofit!"
+ icon_state = "corpus"
+ item_state = "armor"
+ body_parts_covered = CHEST|GROIN|LEGS|ARMS|FEET|HANDS
+ hoodtype = /obj/item/clothing/head/hooded/winterhood/corpus
+ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT //"Hide shoes" but digi shoes dont get hidden, too bad!
+ mutantrace_variation = NO_MUTANTRACE_VARIATION //There is no need for a digi variant, it's a costume
+
+/obj/item/clothing/suit/hooded/wintercoat/corpus/sec
+ name = "Enforcer Voidsuit"
+ desc = "Delux issue grofit voidsuit. Let the middle class know You're in charge."
+ icon_state = "corpuss"
+ hoodtype = /obj/item/clothing/head/hooded/winterhood/corpus/sec //Enjoy this nice red outfit Kinaris! There is NO NEED for a pink one! xoxo -VivI Fanteriso
+
+/obj/item/clothing/suit/hooded/wintercoat/corpus/command
+ name = "Commander Voidsuit"
+ desc = "Premium issue correctional worker attire. Grease the gears of production."
+ icon_state = "corpusc"
+ hoodtype = /obj/item/clothing/head/hooded/winterhood/corpus/command
+
+/obj/item/clothing/head/hooded/winterhood/corpus
+ name = "Voidsuit helmet"
+ desc = "galvanized reinforced helm to protect against the elements"
+ icon_state = "corpus"
+ flags_inv = HIDEHAIR|HIDEEARS|HIDEFACIALHAIR|HIDEFACE|HIDEMASK|HIDESNOUT|HIDENECK //hide your ugly face with this one simple trick!
+
+/obj/item/clothing/head/hooded/winterhood/corpus/sec
+ icon_state = "corpuss"
+
+/obj/item/clothing/head/hooded/winterhood/corpus/command
+ icon_state = "corpusc"
\ No newline at end of file
diff --git a/hyperstation/code/modules/jobs/job_types/_job.dm b/hyperstation/code/modules/jobs/job_types/_job.dm
deleted file mode 100644
index 9051523de..000000000
--- a/hyperstation/code/modules/jobs/job_types/_job.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/datum/job
- var/timeoff_factor = 3
- var/pto_type
diff --git a/hyperstation/code/modules/jobs/job_types/civilian.dm b/hyperstation/code/modules/jobs/job_types/civilian.dm
deleted file mode 100644
index 9ed93fdb2..000000000
--- a/hyperstation/code/modules/jobs/job_types/civilian.dm
+++ /dev/null
@@ -1,52 +0,0 @@
-/datum/job/barista
- title = "Barista"
- flag = BARISTA
- department_head = list("Head of Personnel")
- department_flag = CIVILIAN
- faction = "Station"
- total_positions = 1
- spawn_positions = 1
- supervisors = "the head of personnel"
- selection_color = "#bbe291"
-
- outfit = /datum/outfit/job/barista
-
- access = list(ACCESS_HYDROPONICS, ACCESS_BARISTA, ACCESS_KITCHEN, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_BARISTA, ACCESS_MINERAL_STOREROOM)
-
-/datum/outfit/job/barista
- name = "Barista"
- jobtype = /datum/job/barista
-
- belt = /obj/item/pda/bar
- ears = /obj/item/radio/headset/headset_srv
- uniform = /obj/item/clothing/under/lawyer/blacksuit
- suit = /obj/item/clothing/suit/toggle/lawyer/black
- backpack_contents = list(/obj/item/book/granter/action/drink_fling=1, /obj/item/clothing/accessory/waistcoat)
- shoes = /obj/item/clothing/shoes/laceup
-
-/datum/job/barber
- title = "Barber"
- flag = BARBER
- department_head = list("Head of Personnel")
- department_flag = CIVILIAN
- faction = "Station"
- total_positions = 2
- spawn_positions = 1
- supervisors = "the head of personnel"
- selection_color = "#bbe291"
-
- outfit = /datum/outfit/job/barber
-
- access = list(ACCESS_BARBER)
- minimal_access = list(ACCESS_BARBER)
-
-/datum/outfit/job/barber
- name = "Barber"
- jobtype = /datum/job/barber
-
- glasses = /obj/item/clothing/glasses/sunglasses
- ears = /obj/item/radio/headset/headset_srv
- belt = /obj/item/pda
- uniform = /obj/item/clothing/under/barber
- shoes = /obj/item/clothing/shoes/laceup
diff --git a/hyperstation/code/modules/jobs/job_types/job_alt_titles.dm b/hyperstation/code/modules/jobs/job_types/job_alt_titles.dm
deleted file mode 100644
index 0f20b5e46..000000000
--- a/hyperstation/code/modules/jobs/job_types/job_alt_titles.dm
+++ /dev/null
@@ -1,8 +0,0 @@
-/datum/job/lambent
- alt_titles = list("Kinaris Protectorate", "Hardshield", "Asset Specialist", "Luminal")
-
-/datum/job/barber
- alt_titles = list("Cosmetologist", "Beautician", "Hairdresser", "Hair Stylist")
-
-/datum/job/barista
- alt_titles = list("Cafe Attendant", "Cafe Server")
diff --git a/hyperstation/code/modules/jobs/job_types/security.dm b/hyperstation/code/modules/jobs/job_types/security.dm
deleted file mode 100644
index 0360b5423..000000000
--- a/hyperstation/code/modules/jobs/job_types/security.dm
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-Lambent
-*/
-/datum/job/lambent
- title = "Lambent"
- flag = LAMBENT
- department_head = list("CentCom")
- department_flag = ENGSEC
- faction = "Station"
- total_positions = 1
- spawn_positions = 1
- supervisors = "Central Command and Kinaris officials"
- selection_color = "#ffedcc"
- req_admin_notify = 1
- minimal_player_age = 30
- exp_requirements = 9000
- exp_type = EXP_TYPE_COMMAND
- exp_type_department = EXP_TYPE_COMMAND
- whitelist_type = "important"
- custom_spawn_text = "You are a Kinaris Lambent; a person hired directly by Kinaris who has a high interest in asset security and the protection of the station. Unlike the station, your gear is official Kinaris items, not replicated Milky-Way Engrams. As such, you should keep them safe due to the power they hold. You answer directly to Central Command and Kinaris, and security matters should not involve you for the most part, unless staffing is low or there is a problem with securing assets. Thankfully, Layenia Station is one of Kinaris's most low-tech stations with hardly anything important to secure; not even the items in the vault are noteworthy due to the falsified, low-tech Engram they're under. Just ensure peace is kept and the station is functioning in a calm manner."
-
- outfit = /datum/outfit/job/lambent
-
- access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT,
- ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
- ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
- ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT,
- ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
- ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
- ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
-
- mind_traits = list(TRAIT_CAPTAIN_METABOLISM)
-
- blacklisted_quirks = list(/datum/quirk/brainproblems, /datum/quirk/insanity, /datum/quirk/nonviolent)
-
-/datum/outfit/job/lambent
- name = "Lambent"
- jobtype = /datum/job/lambent
-
- id = /obj/item/card/id/silver
- belt = /obj/item/pda/captain
- glasses = /obj/item/clothing/glasses/hud/toggle/zao
- ears = /obj/item/radio/headset/heads/captain/alt
- gloves = /obj/item/clothing/gloves/lambent
- uniform = /obj/item/clothing/under/rank/lambent
- suit = /obj/item/clothing/suit/lambent
- shoes = /obj/item/clothing/shoes/lambent
- backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1)
-
- backpack = /obj/item/storage/backpack/lambent
- satchel = /obj/item/storage/backpack/satchel/lambent
- duffelbag = /obj/item/storage/backpack/duffelbag/lambent
- box = /obj/item/storage/box/security
-
- implants = list(/obj/item/implant/mindshield)
diff --git a/hyperstation/code/modules/mob/dead/new_player/cosmetic_parts.dm b/hyperstation/code/modules/mob/dead/new_player/cosmetic_parts.dm
new file mode 100644
index 000000000..a08db8726
--- /dev/null
+++ b/hyperstation/code/modules/mob/dead/new_player/cosmetic_parts.dm
@@ -0,0 +1,154 @@
+/*
+COSMETIC PARTS
+
+this system allows you to change the _base_ appearance of a limb independent
+of species or markings. this, for example, allows us to create "hybrids" like a
+mammal with avian legs.
+
+keep in mind that this does not change the species of a leg! in the above example,
+the mammal's bird-legs are still mammal legs. this matters in some places, like
+body part transplants; mis-matched species will cause extra damage if the surgery
+fails and the part is rejected. so you can't attach mammal-bird legs to avians
+safely.
+*/
+
+/datum/cosmetic_part
+ /** A unique string that is used to identify this part for save files. Allows name changes without breaking saves */
+ var/id
+ /** The name of the cosmetic part. This shows up in the preferences dropdown. */
+ var/name
+ var/icon = 'hyperstation/icons/mob/char_parts.dmi'
+ var/icon_state
+ /** How colors are determined for this part. MUTCOLORS for base color, MATRIXED to allow multiple channels. */
+ var/color_src = MUTCOLORS
+ /** Whether or not this cosmetic part has an alternate form for digitigrade legs. */
+ var/support_digitigrade = TRUE
+ /** Species IDs that support this cosmetic part. Bypassed with "show mismatched markings" option. */
+ var/list/supported_species
+
+/datum/cosmetic_part/head
+/datum/cosmetic_part/chest
+/datum/cosmetic_part/arms
+/datum/cosmetic_part/legs
+
+// HEADS
+// =========================================
+
+/datum/cosmetic_part/head/default
+ id = "default"
+ name = "default"
+ icon = null
+
+/datum/cosmetic_part/head/ipc_round
+ id = "ipc_round"
+ name = "round ipc head"
+ icon_state = "ipc_round"
+ supported_species = list("ipc")
+
+
+// CHESTS
+// =========================================
+
+/datum/cosmetic_part/chest/default
+ id = "default"
+ name = "default"
+ icon = null
+
+/datum/cosmetic_part/chest/ipc_sleek
+ id = "ipc_sleek"
+ name = "sleek ipc chest"
+ icon_state = "ipc_sleek"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+
+/datum/cosmetic_part/chest/ipc_jointed
+ id = "ipc_jointed"
+ name = "jointed ipc chest"
+ icon_state = "ipc_jointed"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+
+
+// ARMS
+// =========================================
+
+/datum/cosmetic_part/arms/default
+ id = "default"
+ name = "default"
+ icon = null
+
+/datum/cosmetic_part/arms/avian_alt
+ id = "avian_alt"
+ name = "avian claws"
+ icon_state = "avian_alt"
+ supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
+
+/datum/cosmetic_part/arms/insect
+ id = "insect"
+ name = "insect arms"
+ icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
+ icon_state = "insect"
+ supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
+
+/datum/cosmetic_part/arms/ipc_sleek
+ id = "ipc_sleek"
+ name = "sleek ipc arms"
+ icon_state = "ipc_sleek"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+
+/datum/cosmetic_part/arms/ipc_jointed
+ id = "ipc_jointed"
+ name = "jointed ipc arms"
+ icon_state = "ipc_jointed"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+
+
+// LEGS
+// =========================================
+
+/datum/cosmetic_part/legs/default
+ id = "default"
+ name = "default"
+ icon = null
+
+/datum/cosmetic_part/legs/avian
+ id = "avian"
+ name = "avian legs"
+ icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
+ icon_state = "avian"
+ supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
+ support_digitigrade = FALSE
+
+/datum/cosmetic_part/legs/mammal
+ id = "mammal"
+ name = "mammal legs"
+ icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
+ icon_state = "mammal"
+ supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
+ support_digitigrade = TRUE
+
+/datum/cosmetic_part/legs/insect
+ id = "insect"
+ name = "insect legs"
+ icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
+ icon_state = "insect"
+ supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
+ support_digitigrade = TRUE
+
+/datum/cosmetic_part/legs/ipc_sleek
+ id = "ipc_sleek"
+ name = "sleek ipc legs"
+ icon_state = "ipc_sleek"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+ support_digitigrade = FALSE
+
+/datum/cosmetic_part/legs/ipc_jointed
+ id = "ipc_jointed"
+ name = "jointed ipc legs"
+ icon_state = "ipc_jointed"
+ supported_species = list("ipc")
+ color_src = MATRIXED
+ support_digitigrade = FALSE
\ No newline at end of file
diff --git a/hyperstation/code/modules/mob/dead/new_player/sprite_accessories.dm b/hyperstation/code/modules/mob/dead/new_player/sprite_accessories.dm
index f76d2ddf0..34dc50426 100644
--- a/hyperstation/code/modules/mob/dead/new_player/sprite_accessories.dm
+++ b/hyperstation/code/modules/mob/dead/new_player/sprite_accessories.dm
@@ -87,6 +87,11 @@ SNOUTS
icon_state = "feasterndnw"
icon = 'hyperstation/icons/mob/char_snouts.dmi'
+/datum/sprite_accessory/mam_snouts/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_snouts.dmi'
+
/datum/sprite_accessory/mam_snouts/fchemlight
name = "RadDog (Top) (Hyper)"
icon_state = "fchemlight"
@@ -143,6 +148,11 @@ EARS
icon_state = "easternd"
icon = 'hyperstation/icons/mob/char_ears.dmi'
+/datum/sprite_accessory/mam_ears/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_ears.dmi'
+
/datum/sprite_accessory/mam_ears/chemlight
name = "RadDog (Hyper)"
icon_state = "chemlight"
@@ -185,6 +195,13 @@ WINGS
icon_state = "insect"
icon = 'hyperstation/icons/mob/char_wings.dmi'
+/datum/sprite_accessory/deco_wings/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_wings.dmi'
+ //recommended_species = list("synthliz") need to give synths a deco wing slot
+ color_src = MATRIXED
+
/datum/sprite_accessory/deco_wings/minibat // sarcoph @ hyperstation, march 2022
name = "Mini Bat (Hyper)"
icon_state = "minibat"
@@ -324,6 +341,18 @@ TAILS + ANIMATED TAILS
icon_state = "easternd"
icon = 'hyperstation/icons/mob/char_tails.dmi'
+/datum/sprite_accessory/mam_tails/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_tails.dmi'
+ recommended_species = list("synthliz")
+
+/datum/sprite_accessory/mam_tails_animated/knshuttle
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_tails.dmi'
+ recommended_species = list("synthliz")
+
/datum/sprite_accessory/mam_tails/chemlight
name = "RadDog (Hyper)"
icon_state = "chemlight"
@@ -398,6 +427,11 @@ from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
icon_state = "easternd"
icon = 'hyperstation/icons/mob/char_markings.dmi'
+/datum/sprite_accessory/mam_body_markings/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
+ name = "Kinaris - Shuttle (Hyper)"
+ icon_state = "knshuttle"
+ icon = 'hyperstation/icons/mob/char_markings.dmi'
+
//doged was here
/datum/sprite_accessory/mam_body_markings/chemlight
name = "RadDog (Hyper)"
@@ -441,6 +475,92 @@ from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
taur_mode = PAW_TAURIC
ckeys_allowed = list("chemlight")
+
+/*
+IPCS
+==========================================================
+*/
+
+/*
+from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
+
+/datum/sprite_accessory/antenna
+ icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
+ color_src = MUTCOLORS3
+ recommended_species = list("ipc")
+
+/datum/sprite_accessory/screen
+ icon = 'modular_citadel/icons/mob/ipc_screens.dmi'
+ color_src = null
+*/
+
+/datum/sprite_accessory/antenna/idog_down
+ name = "Dog, down (Hyper)"
+ icon_state = "idog_down"
+ color_src = MATRIXED
+
+/datum/sprite_accessory/antenna/idog_up
+ name = "Dog, up (Hyper)"
+ icon_state = "idog_up"
+ color_src = MATRIXED
+
+/datum/sprite_accessory/antenna/headset
+ name = "Headphones (Hyper)"
+ icon_state = "headset"
+ color_src = MATRIXED
+
+/datum/sprite_accessory/antenna/aquatic
+ name = "Fins (Hyper)"
+ icon_state = "aquatic"
+ color_src = MATRIXED
+
+/datum/sprite_accessory/screen/ghost
+ name = "Ghost (Hyper)"
+ icon_state = "ghost"
+
+/datum/sprite_accessory/screen/heartbeat
+ name = "Heartbeat (Hyper)"
+ icon_state = "heartbeat"
+
+/datum/sprite_accessory/screen/ocean
+ name = "Ocean (Hyper)"
+ icon_state = "ocean"
+
+/datum/sprite_accessory/antenna/catears
+ name = "Pointy Ears (Hyper)"
+ icon_state = "catears"
+ color_src = MATRIXED
+
+/datum/sprite_accessory/screen/valley
+ name = "Valley (Hyper)"
+ icon_state = "valley"
+
+/datum/sprite_accessory/screen/visor
+ name = "Black Visor (Hyper)"
+ icon = 'hyperstation/icons/mob/ipc_screen_visor.dmi'
+ icon_state = "visor_black"
+
+/datum/sprite_accessory/screen/visor/blue
+ name = "Blue Visor (Hyper)"
+ icon_state = "visor_blue"
+
+/datum/sprite_accessory/screen/visor/green
+ name = "Green Visor (Hyper)"
+ icon_state = "visor_green"
+
+/datum/sprite_accessory/screen/visor/red
+ name = "Red Visor (Hyper)"
+ icon_state = "visor_red"
+
+/datum/sprite_accessory/screen/visor/white
+ name = "White Visor (Hyper)"
+ icon_state = "visor_white"
+
+/datum/sprite_accessory/screen/visor/yellow
+ name = "Yellow Visor (Hyper)"
+ icon_state = "visor_yellow"
+
+
/*
HAIRSTYLES
==========================================================
@@ -480,4 +600,4 @@ from code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm:
/datum/sprite_accessory/hair/emoh
name = "Emo (Hyper)"
- icon_state = "hair_emoh"
\ No newline at end of file
+ icon_state = "hair_emoh"
diff --git a/hyperstation/code/modules/mob/living/carbon/carbon.dm b/hyperstation/code/modules/mob/living/carbon/carbon.dm
index ec2f69c1d..3af2e9447 100644
--- a/hyperstation/code/modules/mob/living/carbon/carbon.dm
+++ b/hyperstation/code/modules/mob/living/carbon/carbon.dm
@@ -13,6 +13,11 @@
/mob/living/carbon/handle_status_effects()
..()
handle_pain()
+
+/mob/living/carbon/has_mouth()
+ var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD)
+ if(head && head.mouth)
+ return TRUE
/mob/living/carbon/proc/handle_pain()
var/pain_amount = 0
diff --git a/hyperstation/code/modules/mob/living/carbon/human/cosmetic_part_handler.dm b/hyperstation/code/modules/mob/living/carbon/human/cosmetic_part_handler.dm
new file mode 100644
index 000000000..25b93526f
--- /dev/null
+++ b/hyperstation/code/modules/mob/living/carbon/human/cosmetic_part_handler.dm
@@ -0,0 +1,17 @@
+/obj/item/bodypart/proc/apply_cosmetic(datum/cosmetic_part/part)
+ if(!is_organic_limb() || animal_origin || !part)
+ return
+ cosmetic_icon = part
+
+
+/mob/living/carbon/human/proc/handle_cosmetic_parts()
+ var/features = dna.features
+ var/list/body_zones = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ for(var/zone in body_zones)
+ var/datum/cosmetic_part/cosmetic_pref = features["cosmetic_" + zone]
+ if(!istype(cosmetic_pref, /datum/cosmetic_part))
+ continue
+ var/datum/cosmetic_part/part = cosmetic_pref
+ var/obj/item/bodypart/body_part = get_bodypart(zone)
+ if(body_part && part)
+ body_part.apply_cosmetic(part)
\ No newline at end of file
diff --git a/hyperstation/code/modules/mob/living/carbon/human/species_types/ipc.dm b/hyperstation/code/modules/mob/living/carbon/human/species_types/ipc.dm
new file mode 100644
index 000000000..b3e22f9ef
--- /dev/null
+++ b/hyperstation/code/modules/mob/living/carbon/human/species_types/ipc.dm
@@ -0,0 +1,58 @@
+// APC powercord: oracle port
+
+/obj/item/apc_powercord
+ name = "power cord"
+ desc = "An internal power cord hooked up to a battery. Useful if you run on electricity. Not so much otherwise."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "wire1"
+
+
+/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
+ return ..()
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/stomach/cell/battery = H.getorganslot(ORGAN_SLOT_STOMACH)
+ if(!battery)
+ to_chat(H, "You try to siphon energy from \the [target], but your power cell is gone!")
+ return
+
+ if(istype(H) && H.nutrition >= NUTRITION_LEVEL_ALMOST_FULL)
+ to_chat(user, "You are already fully charged!")
+ return
+
+ if(istype(target, /obj/machinery/power/apc))
+ var/obj/machinery/power/apc/A = target
+ if(A.cell && A.cell.charge > A.cell.maxcharge*0.25)
+ powerdraw_loop(A, H)
+ return
+ else
+ to_chat(user, "There is not enough charge to draw from that APC.")
+ return
+
+
+/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
+ H.visible_message("[H] inserts a power connector into the [A].", "You begin to draw power from the [A].")
+ while(do_after(H, 10, target = A))
+ if(!istype(A))
+ return
+ if(loc != H)
+ to_chat(H, "You must keep your connector out while charging!")
+ break
+ if(A.cell.charge == 0)
+ to_chat(H, "The [A] doesn't have enough charge to spare.")
+ break
+ A.charging = 1
+ if(A.cell.charge >= 500)
+ H.nutrition += 50
+ A.cell.charge -= 250
+ to_chat(H, "You siphon off some of the stored charge for your own use.")
+ else
+ H.nutrition += A.cell.charge/10
+ A.cell.charge = 0
+ to_chat(H, "You siphon off as much as the [A] can spare.")
+ break
+ if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
+ to_chat(H, "You are now fully charged.")
+ break
+ H.visible_message("[H] unplugs from the [A].", "You unplug from the [A].")
\ No newline at end of file
diff --git a/hyperstation/code/modules/mob/living/silicon/robot/examine_vr.dm b/hyperstation/code/modules/mob/living/silicon/robot/examine_vr.dm
new file mode 100644
index 000000000..f3b04a440
--- /dev/null
+++ b/hyperstation/code/modules/mob/living/silicon/robot/examine_vr.dm
@@ -0,0 +1,8 @@
+/mob/living/silicon/robot/proc/examine_bellies_borg()
+
+ var/message = ""
+ for(var/belly in vore_organs)
+ var/obj/belly/B = belly
+ message += B.get_examine_msg()
+
+ return message
diff --git a/hyperstation/code/modules/mob/living/silicon/robot/robot.dm b/hyperstation/code/modules/mob/living/silicon/robot/robot.dm
index 4752f0c95..20c7e7679 100644
--- a/hyperstation/code/modules/mob/living/silicon/robot/robot.dm
+++ b/hyperstation/code/modules/mob/living/silicon/robot/robot.dm
@@ -1,3 +1,3 @@
//This file is empty right now, but leaves room for people to put shit here in the future for those who are lazy
/mob/living/silicon/robot
- var/datum/action/cyborg_small_sprite/small_sprite_action //This gets replaced every time the cyborg changes modules --Cyanosis
\ No newline at end of file
+ var/datum/action/cyborg_small_sprite/small_sprite_action //This gets replaced every time the cyborg changes modules --Cyanosis
diff --git a/hyperstation/code/modules/mob/living/silicon/robot/robot_modules.dm b/hyperstation/code/modules/mob/living/silicon/robot/robot_modules.dm
index dbef0ad93..d42f3dbeb 100644
--- a/hyperstation/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/hyperstation/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -1,11 +1,60 @@
//This file is empty right now, but leaves room for people to put shit here in the future for those who are lazy
+/obj/item/robot_module
+ var/list/added_channels = list() //Borg radio stuffs
+
+//service
+/obj/item/robot_module/butler
+ added_channels = list(RADIO_CHANNEL_SERVICE = 1)
+
+/obj/item/robot_module/clown
+ added_channels = list(RADIO_CHANNEL_SERVICE = 1)
+
+/obj/item/robot_module/janitor
+ added_channels = list(RADIO_CHANNEL_SERVICE = 1)
+
+//engineering
+/obj/item/robot_module/engineering
+ added_channels = list(RADIO_CHANNEL_ENGINEERING = 1)
+
+//medical
+/obj/item/robot_module/medical
+ added_channels = list(RADIO_CHANNEL_MEDICAL = 1)
+
+//security
+/obj/item/robot_module/peacekeeper
+ added_channels = list(RADIO_CHANNEL_SECURITY = 1)
+
+/obj/item/robot_module/security
+ added_channels = list(RADIO_CHANNEL_SECURITY = 1)
+
+//supply
+/obj/item/robot_module/miner
+ added_channels = list(RADIO_CHANNEL_SUPPLY = 1) // Probably already handled by other code when spawned with pre-set module, but whatever.
+
+//dogborgs
+/obj/item/robot_module/k9
+ added_channels = list(RADIO_CHANNEL_SECURITY = 1)
+
+/obj/item/robot_module/medihound
+ added_channels = list(RADIO_CHANNEL_MEDICAL = 1)
+
+/obj/item/robot_module/scrubpup
+ added_channels = list(RADIO_CHANNEL_SERVICE = 1)
+
+/obj/item/robot_module/borgi
+ added_channels = list(RADIO_CHANNEL_SERVICE = 1)
+
+/obj/item/robot_module/orepup
+ added_channels = list(RADIO_CHANNEL_SUPPLY = 1)
+
+
//This proc gets called whenever a new robot module is being applied --Cyanosis
/obj/item/robot_module/proc/handle_sprite_action(mob/living/silicon/robot/R, is_huge = FALSE)
ASSERT(istype(R))
if(R.small_sprite_action)
QDEL_NULL(R.small_sprite_action)
- if(!is_huge) //only from the expander upgrade. The borg won't have an action if they don't have the expander upgrade
+ if(!is_huge) //only from the expander upgrade. The borg won't have an action if they don't have the expander upgrade
return
for(var/P in typesof(/datum/action/cyborg_small_sprite))
var/datum/action/cyborg_small_sprite/action = P
diff --git a/hyperstation/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/hyperstation/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 3d12f301b..f5c7df2e2 100644
--- a/hyperstation/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/hyperstation/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -241,6 +241,6 @@
/mob/living/simple_animal/chicken/examine()
. = ..()
- . += "this one is [gender]."
+ . += "This one is [gender]."
if(happiness<20)
. += "It looks stressed."
diff --git a/hyperstation/code/modules/mob/mob_helpers.dm b/hyperstation/code/modules/mob/mob_helpers.dm
index 00f9c8631..0a47f7b0a 100644
--- a/hyperstation/code/modules/mob/mob_helpers.dm
+++ b/hyperstation/code/modules/mob/mob_helpers.dm
@@ -27,3 +27,7 @@ mob/proc/checkloadappearance()
else
to_chat(H, "You either took too long or chose not to change. Alrighty. Remember, you have 90 seconds from spawn to get to a mirror and still do it if you wish.")
return
+
+// oracle port
+/mob/proc/has_mouth()
+ return FALSE
\ No newline at end of file
diff --git a/hyperstation/code/modules/power/lighting.dm b/hyperstation/code/modules/power/lighting.dm
deleted file mode 100644
index 9c98912a5..000000000
--- a/hyperstation/code/modules/power/lighting.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-/obj/item/wallframe/light_fixture/fairy
- name = "fairy lights frame"
- icon_state = "fairy-construct-item"
- result_path = /obj/structure/light_construct/fairy
- materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)
-
-/obj/structure/light_construct/fairy
- name = "fairy lights frame"
- icon_state = "fairy-construct-stage1"
- fixture_type = "fairy"
- sheets_refunded = 1
-
-/obj/machinery/light/fairy
- icon_state = "fairy"
- base_state = "fairy"
- fitting = "fairy"
- brightness = 3
- desc = "Small fairy lights."
- //light_type = /obj/item/light/fairy
-
-/obj/machinery/light/fairy/broken
- status = LIGHT_BROKEN
- icon_state = "fairy-broken"
-
-/obj/machinery/light/fairy/built
- icon_state = "bulb-empty"
-
-/obj/machinery/light/fairy/built/Initialize()
- . = ..()
- status = LIGHT_EMPTY
- update(0)
diff --git a/hyperstation/code/modules/research/designs/medical_designs.dm b/hyperstation/code/modules/research/designs/medical_designs.dm
new file mode 100644
index 000000000..825bcd2a2
--- /dev/null
+++ b/hyperstation/code/modules/research/designs/medical_designs.dm
@@ -0,0 +1,69 @@
+/datum/design/ipc_liver
+ name = "IPC Reagent Processor"
+ id = "ipc_liver"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
+ build_path = /obj/item/organ/liver/ipc
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+/datum/design/ipc_eyes
+ name = "IPC Eyes"
+ id = "ipc_eyes"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 1000, MAT_GLASS = 2000)
+ build_path = /obj/item/organ/eyes/ipc
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+/datum/design/ipc_tongue
+ name = "Positronic Voicebox"
+ id = "ipc_tongue"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
+ build_path = /obj/item/organ/tongue/robot/ipc
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+/datum/design/ipc_stomach
+ name = "Micro-cell"
+ id = "ipc_stomach"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000, MAT_PLASMA = 200)
+ build_path = /obj/item/organ/stomach/cell
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+/datum/design/synthliz_stomach
+ name = "Synthetic Lizardperson Stomach"
+ id = "synthliz_stomach"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
+ build_path = /obj/item/organ/stomach/synthliz
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+/datum/design/power_cord
+ name = "IPC Power Cord"
+ id = "power_cord"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
+ build_path = /obj/item/organ/cyberimp/arm/power_cord
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ construction_time = 100
+
+
+/datum/techweb_node/ipc_organs
+ id = "ipc_organs"
+ display_name = "IPC Parts"
+ description = "We have the technology to replace him."
+ prereq_ids = list("cyber_organs","robotics")
+ design_ids = list("ipc_liver", "ipc_eyes", "ipc_tongue", "ipc_stomach", "synthliz_stomach", "power_cord")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
+ export_price = 5000
diff --git a/hyperstation/code/modules/salon/barber.dm b/hyperstation/code/modules/salon/barber.dm
deleted file mode 100644
index fe5163150..000000000
--- a/hyperstation/code/modules/salon/barber.dm
+++ /dev/null
@@ -1,541 +0,0 @@
-//Proper modularity to come at a later date
-/obj/structure/chair/barber_chair
- name = "barbers chair"
- desc = "You sit in this, and your hair shall be cut."
- icon = 'icons/obj/chairs.dmi'
- icon_state = "barber_chair"
-
-/obj/structure/closet/secure_closet/barber
- name = "Barber's locker"
- icon_state = "barber"
- icon = 'icons/obj/closet.dmi'
- req_access = list(ACCESS_BARBER)
-
-/obj/structure/closet/secure_closet/barber/PopulateContents()
- new /obj/item/clothing/mask/surgical(src) // These three are here, so the barber can pick and choose what he's painting.
- new /obj/item/clothing/under/rank/medical/blue(src)
- new /obj/item/clothing/suit/apron/surgical(src)
- new /obj/item/clothing/accessory/waistcoat(src)
- //new /obj/item/clothing/under/rank/civilian/lawyer/purpsuit(src)
- new /obj/item/clothing/suit/toggle/lawyer/purple(src)
- new /obj/item/razor(src)
- //new /obj/item/straight_razor(src)
- new /obj/item/hairbrush/comb(src)
- new /obj/item/scissors(src)
- new /obj/item/fur_dyer(src)
- new /obj/item/dyespray(src)
- new /obj/item/storage/box/lipsticks(src)
- new /obj/item/reagent_containers/spray/quantum_hair_dye(src)
- new /obj/item/reagent_containers/spray/barbers_aid(src)
- new /obj/item/reagent_containers/spray/cleaner(src)
- new /obj/item/reagent_containers/rag(src)
- new /obj/item/storage/firstaid/regular(src)
-
-/obj/machinery/vending/barbervend
- name = "Fab-O-Vend"
- desc = "It would seem it vends dyes, and other stuff to make you pretty."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "barbervend"
- product_slogans = "Spread the colour, like butter, onto toast... Onto their hair.; Sometimes, I dream about dyes...; Paint 'em up and call me Mr. Painter.; Look brother, I'm a vendomat, I solve practical problems."
- product_ads = "Cut 'em all!; To sheds!; Hair be gone!; Prettify!; Beautify!"
- vend_reply = "Come again!; Buy another!; Dont you love your new look?"
- req_access = list(ACCESS_BARBER)
- refill_canister = /obj/item/vending_refill/barbervend
- products = list(
- /obj/item/reagent_containers/spray/quantum_hair_dye = 3,
- // /obj/item/reagent_containers/spray/baldium = 3,
- /obj/item/reagent_containers/spray/barbers_aid = 3,
- /obj/item/dyespray = 5,
- /obj/item/hairbrush = 3,
- /obj/item/hairbrush/comb = 3,
- /obj/item/fur_dyer = 1,
- )
- premium = list(
- /obj/item/scissors = 3,
- /obj/item/reagent_containers/spray/super_barbers_aid = 3,
- /obj/item/storage/box/lipsticks = 3,
- /obj/item/lipstick/quantum = 1,
- /obj/item/razor = 1,
- // /obj/item/storage/box/perfume = 1,
- )
- refill_canister = /obj/item/vending_refill/barbervend
-
-/obj/item/vending_refill/barbervend
- machine_name = "barber vend resupply"
- icon_state = "refill_snack" //generic item refill because there isnt one sprited yet.
-
-/obj/effect/landmark/start/barber
- name = "Barber"
- icon_state = "Barber"
- //icon = 'modular_skyrat/master_files/icons/mob/landmarks.dmi'
-
-//Brush
-/obj/item/hairbrush
- name = "hairbrush"
- desc = "A small, circular brush with an ergonomic grip for efficient brush application."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "brush"
- //Put lefthand and righthand files here
- w_class = WEIGHT_CLASS_TINY
- var/brush_speed = 3 SECONDS
-
-/obj/item/hairbrush/comb
- name = "comb"
- desc = "A rather simple tool, used to straighten out hair and knots in it."
- icon_state = "blackcomb"
-
-/obj/item/hairbrush/attack(mob/target, mob/user)
- if(target.stat == DEAD)
- to_chat(usr, "There isn't much point in brushing someone who can't appreciate it!")
- return
- brush(target, user)
- return COMPONENT_CANCEL_ATTACK_CHAIN
-
-//Brushes someone
-/obj/item/hairbrush/proc/brush(mob/living/target, mob/user)
- if(ishuman(target))
- var/mob/living/carbon/human/human_target = target
- var/obj/item/bodypart/head = human_target.get_bodypart(BODY_ZONE_HEAD)
-
- //Don't brush if you can't reach their head or cancel the action
- if(!head) //No head? No bitches?
- to_chat(usr, "[human_target] has no head!")
- return
- if(human_target.is_mouth_covered(head_only = 1))
- to_chat(usr, "You can't brush [human_target]'s hair while [human_target.p_their()] head is covered!")
- return
- if(!do_after(user, brush_speed, human_target))
- return
-
- // Do 1 brute to their head if they're bald. Should've been more careful.
- if(human_target.hair_style == "Bald" || human_target.hair_style == "Skinhead" && is_species(human_target, /datum/species/human)) //It can be assumed most anthros have hair on them!
- human_target.visible_message("[usr] scrapes the bristles uncomfortably over [human_target]'s scalp.","You scrape the bristles uncomfortably over [human_target]'s scalp.")
- playsound(target, 'hyperstation/sound/misc/bonk.ogg', 100, 1) //Until I fix it
- return
-
- //Brush their hair
- if(human_target == user)
- human_target.visible_message("[usr] brushes [usr.p_their()] hair!","You brush your hair.")
- //SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "brushed", /datum/mood/brushed/self)
- else
- user.visible_message("[usr] brushes [human_target]'s hair!","You brush [human_target]'s hair.")
- //SEND_SIGNAL(human_target, COMISG_ADD_MOOD_EVENT, "brushed", /datum/mood_event/brushed, user)
-
-
-
-//fur dyer
-#define COLOR_MODE_SPECIFIC "Specific Marking"
-#define COLOR_MODE_GENERAL "General Color"
-
-/obj/item/fur_dyer
- name = "electric fur dyer"
- desc = "Dye that is capable of recoloring fur in a mostly permanent way."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "fur_sprayer"
- w_class = WEIGHT_CLASS_TINY
-
- var/mode = COLOR_MODE_GENERAL
-/*
-/obj/item/fur_dyer/Initialize(mapload)
- . = ..()
- AddComponent(/datum/component/cell)
-*/
-/obj/item/fur_dyer/attack_self(mob/user, modifiers)
- . = ..()
- if(mode == COLOR_MODE_SPECIFIC)
- mode = COLOR_MODE_GENERAL
- else
- mode = COLOR_MODE_SPECIFIC
-
- to_chat(user, "Set to [mode]!")
-
-/obj/item/fur_dyer/attack(mob/living/M, mob/living/user, params)
- if(!ishuman(M))
- return ..()
-
- var/mob/living/carbon/human/target_human = M
-
- switch(mode)
- if(COLOR_MODE_SPECIFIC)
- to_chat(user, "The device resonates ominously, and stops. It seems to be interfered by an Engram.")
- //dye_marking(target_human, user)
- if(COLOR_MODE_GENERAL)
- dye_general(target_human, user)
-
-/obj/item/fur_dyer/proc/dye_general(mob/living/carbon/human/target_human, mob/living/user)
- var/selected_mutant_color = tgalert(user, "Please select which mutant color you'd like to change", "Select Color", "One", "Two", "Three")
-
- if(!selected_mutant_color)
- return
-
- var/selected_color = input(
- user,
- "Select marking color",
- null,
- "#FFFFFF"
- ) as color | null
-
- if(!selected_color)
- return
-
- selected_color = sanitize_hexcolor(selected_color)
-
- visible_message("[user] starts to masterfully paint [target_human]!")
-
- if(do_after(user, 20 SECONDS, target_human))
- switch(selected_mutant_color)
- if("One")
- target_human.dna.features["mcolor"] = selected_color
- if("Two")
- target_human.dna.features["mcolor2"] = selected_color
- if("Three")
- target_human.dna.features["mcolor3"] = selected_color
-
- target_human.regenerate_icons()
- //use power
-
- visible_message("[user] finishes painting [target_human]!")
-
- playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE)
-
-
-/* We don't have markings that can be colored separately yet, so this is not needed
-/obj/item/fur_dyer/proc/dye_marking(mob/living/carbon/human/target_human, mob/living/user)
-
- var/list/list/current_markings = target_human.dna.body_markings.Copy()
-
- if(!current_markings.len)
- to_chat(user, "[target_human] has no markings!")
- return
-
- //power stuff here
-
- /var/selected_marking_area = user.zone_selected
-
- if(!current_markings[selected_marking_area])
- to_chat(user, "[target_human] has no bodymarkings on this limb!")
- return
-
- var/selected_marking_id = input(user, "Please select which marking you'd like to color!", "Select marking", current_markings[selected_marking_area])
-
- if(!selected_marking_id)
- return
-
- var/selected_color = input(
- user,
- "Select marking color",
- null,
- "#FFFFFF"
- ) as color | null
-
- if(!selected_color)
- return
-
- selected_color = sanitize_hexcolor(selected_color)
-
- visible_message("[user] starts to masterfully paint [target_human]!")
-
- if(do_after(user, 20 SECONDS, target_human))
- current_markings[selected_marking_area][selected_marking_id] = selected_color
-
- target_human.dna.body_markings = current_markings.Copy()
-
- target_human.regenerate_icons()
-
- //item_use_power(power_use_amount, user)
-
- visible_message("[user] finishes painting [target_human]!")
-
- playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE)
-*/
-
-/obj/machinery/dryer
- name = "hand dryer"
- desc = "The Breath Of Lizards-3000, an experimental dryer."
- icon = 'hyperstation/icons/obj/dryer.dmi'
- icon_state = "dryer"
- density = FALSE
- anchored = TRUE
- var/busy = FALSE
-
-/obj/machinery/dryer/attack_hand(mob/user)
- if(iscyborg(user) || isAI(user))
- return
-
- if(!can_interact(user))
- return
-
- if(busy)
- to_chat(user, "Someone is already drying here.")
- return
-
- to_chat(user, "You start drying your hands.")
- playsound(src, 'hyperstation/sound/salon/drying.ogg', 50)
- add_fingerprint(user)
- busy = TRUE
- if(do_after(user, 4 SECONDS, src))
- busy = FALSE
- user.visible_message("[user] dried their hands using \the [src].")
- else
- busy = FALSE
-
-/obj/item/reagent_containers/dropper/precision
- name = "pipette"
- desc = "A high precision pippette. Holds 1 unit."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "pipette1"
- amount_per_transfer_from_this = 1
- possible_transfer_amounts = list(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1)
- volume = 1
- w_class = WEIGHT_CLASS_TINY
-
-/obj/item/storage/box/lipsticks
- name = "lipstick box"
-
-/obj/item/storage/box/lipsticks/PopulateContents()
- ..()
- new /obj/item/lipstick(src)
- new /obj/item/lipstick/purple(src)
- new /obj/item/lipstick/jade(src)
- new /obj/item/lipstick/black(src)
-
-/obj/item/lipstick/quantum
- name = "quantum lipstick"
-
-/obj/item/lipstick/quantum/attack(mob/attacked_mob, mob/user)
- if(!open || !ismob(attacked_mob))
- return
-
- if(!ishuman(attacked_mob))
- to_chat(user, "Where are the lips on that?")
- return
-
- var/new_color = input(
- user,
- "Select lipstick color",
- null,
- "#FFFFFF"
- ) as color | null
-
- var/mob/living/carbon/human/target = attacked_mob
- if(target.is_mouth_covered())
- to_chat(user, "Remove [ target == user ? "your" : "[target.p_their()]" ] mask!")
- return
- if(target.lip_style) //if they already have lipstick on
- to_chat(user, "You need to wipe off the old lipstick first!")
- return
-
- if(target == user)
- visible_message("[user] does [user.p_their()] lips with \the [src].","You take a moment to apply \the [src]. Perfect!")
- target.lip_style = "lipstick"
- target.lip_color = new_color
- target.update_body()
- return
-
- visible_message("[user] begins to do [target]'s lips with \the [src].","You begin to apply \the [src] on [target]'s lips...")
- if(!do_after(user, 2 SECONDS, target = target))
- return
- visible_message("[user] does [target]'s lips with \the [src].","You apply \the [src] on [target]'s lips.")
- target.lip_style = "lipstick"
- target.lip_color = new_color
- target.update_body()
-
-/obj/effect/decal/cleanable/hair
- name = "hair cuttings"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "cut_hair"
-
-/obj/item/razor
- name = "electric razor"
- desc = "The latest and greatest power razor born from the science of shaving."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "razor"
- flags_1 = CONDUCT_1
- w_class = WEIGHT_CLASS_TINY
- // How long do we take to shave someone's (facial) hair?
- var/shaving_time = 10 SECONDS
-
-/obj/item/razor/proc/shave(mob/living/carbon/human/target_human, location = BODY_ZONE_PRECISE_MOUTH)
- if(location == BODY_ZONE_PRECISE_MOUTH)
- target_human.facial_hair_style = "Shaved"
- else
- target_human.hair_style = "Bald"
-
- target_human.update_hair()
- playsound(loc, 'sound/items/unsheath.ogg', 20, TRUE)
-
-/obj/item/razor/attack(mob/attacked_mob, mob/living/user)
- if(ishuman(attacked_mob))
- var/mob/living/carbon/human/target_human = attacked_mob
- var/location = user.zone_selected
- if(!(location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)))
- to_chat(user, "You stop, look down at what you're currently holding and ponder to yourself, \"This is probably to be used on their hair or their facial hair.\"")
- return
- if((location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)) && !target_human.get_bodypart(BODY_ZONE_HEAD))
- to_chat(user, "[target_human] doesn't have a head!")
- return
-
- if(location == BODY_ZONE_PRECISE_MOUTH)
- if(!(FACEHAIR in target_human.dna.species.species_traits))
- to_chat(user, "There is no facial hair to shave!")
- return
- if(!get_location_accessible(target_human, location))
- to_chat(user, "The mask is in the way!")
- return
- if(target_human.facial_hair_style == "Shaved")
- to_chat(user, "Already clean-shaven!")
- return
-
- var/self_shaving = target_human == user // Shaving yourself?
- visible_message("[user] starts to shave [self_shaving ? user.p_their() : "[target_human]'s"] hair with [src].","You take a moment to shave [self_shaving ? "your" : "[target_human]'s" ] hair with [src]...")
- if(do_after(user, shaving_time, target = target_human))
- visible_message("[user] shaves [self_shaving ? user.p_their() : "[target_human]'s"] hair clean with [src].","You finish shaving [self_shaving ? "your" : " [target_human]'s"] hair with [src]. Fast and clean!")
- shave(target_human, location)
-
- else if(location == BODY_ZONE_HEAD)
- if(!(HAIR in target_human.dna.species.species_traits))
- to_chat(user, "There is no hair to shave!")
- return
- if(!get_location_accessible(target_human, location))
- to_chat(user, "Their headgear is in the way!")
- return
- if(target_human.hair_style == "Bald" || target_human.hair_style == "Balding Hair" || target_human.hair_style == "Skinhead")
- to_chat(user, "There is not enough hair left to shave!")
- return
-
- var/self_shaving = target_human == user // Shaving yourself?
- visible_message("[user] starts to shave [self_shaving ? user.p_their() : "[target_human]'s"] hair with [src].","You take a moment to shave [self_shaving ? "your" : "[target_human]'s" ] hair with [src]...")
- if(do_after(user, shaving_time, target = target_human))
- visible_message("[user] shaves [self_shaving ? user.p_their() : "[target_human]'s"] hair clean with [src].","You finish shaving [self_shaving ? "your" : " [target_human]'s"] hair with [src]. Fast and clean!")
- shave(target_human, location)
- else
- ..()
- else
- ..()
-
-/obj/structure/sign/barber
- name = "barbershop sign"
- desc = "A glowing red-blue-white stripe you won't mistake for any other!"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "barber"
- buildable_sign = FALSE // Don't want them removed, they look too jank.
-
-/obj/item/scissors
- name = "barber's scissors"
- desc = "Some say a barbers best tool is his electric razor, that is not the case. These are used to cut hair in a professional way!"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "scissors"
- w_class = WEIGHT_CLASS_TINY
- sharpness = TRUE
- // How long does it take to change someone's hairstyle?
- var/haircut_duration = 1 MINUTES
- // How long does it take to change someone's facial hair style?
- var/facial_haircut_duration = 20 SECONDS
-
-/obj/item/scissors/attack(mob/living/attacked_mob, mob/living/user, params)
- if(!ishuman(attacked_mob))
- return
-
- var/mob/living/carbon/human/target_human = attacked_mob
-
- var/location = user.zone_selected
- if(!(location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)))
- to_chat(user, "You stop, look down at what you're currently holding and ponder to yourself, \"This is probably to be used on their hair or their facial hair.\"")
- return
-
- if(target_human.hair_style == "Bald" && target_human.facial_hair_style == "Shaved")
- to_chat(user, "What hair? They have none!")
- return
-
- if(user.zone_selected != BODY_ZONE_HEAD)
- return ..()
-
- var/selected_part = tgalert(user, "Please select which part of [target_human] you would like to sculpt!", "It's sculpting time!", "Hair", "Facial Hair", "Cancel")
-
- if(!selected_part || selected_part == "Cancel")
- return
-
- if(selected_part == "Hair")
- if(!target_human.hair_style == "Bald" && target_human.head)
- to_chat(user, "There is no hair to cut!")
- return
-
- var/hair_id = input(user, "Please select what hairstyle you'd like to sculpt!", "Select masterpiece") as null|anything in GLOB.hair_styles_list //dear god help me please
- if(!hair_id)
- return
-
- if(hair_id == "Bald")
- to_chat(target_human, "[user] seems to be cutting all your hair off!")
-
- to_chat(user, "You begin to masterfully sculpt [target_human]'s hair!")
-
- playsound(target_human, 'hyperstation/sound/salon/haircut.ogg', 100)
-
- if(do_after(user, haircut_duration, target_human))
- target_human.hair_style = hair_id
- target_human.update_hair()
- visible_message("[user] successfully cuts [target_human]'s hair!","You successfully cut [target_human]'s hair!")
- new /obj/effect/decal/cleanable/hair(get_turf(src))
- else
- if(!target_human.facial_hair_style == "Shaved" && target_human.wear_mask)
- to_chat(user, "There is no hair to cut!")
- return
-
- var/facial_hair_id = input(user, "Please select what facial hairstyle you'd like to sculpt!", "Select masterpiece") as null|anything in GLOB.facial_hair_styles_list
- if(!facial_hair_id)
- return
-
- if(facial_hair_id == "Shaved")
- to_chat(target_human, "[user] seems to be cutting all your facial hair off!")
-
- to_chat(user, "You begin to masterfully sculpt [target_human]'s facial hair!")
-
- playsound(target_human, 'hyperstation/sound/salon/haircut.ogg', 100)
-
- if(do_after(user, facial_haircut_duration, target_human))
- target_human.facial_hair_style = facial_hair_id
- target_human.update_hair()
- visible_message("[user] successfully cuts [target_human]'s facial hair!","You successfully cut [target_human]'s facial hair!")
- new /obj/effect/decal/cleanable/hair(get_turf(src))
-
-
-//reagents
-/obj/item/reagent_containers/spray/quantum_hair_dye
- name = "quantum hair dye"
- desc = "Changes hair colour RANDOMLY! Don't forget to read the label!"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "hairspraywhite"
- amount_per_transfer_from_this = 1
- possible_transfer_amounts = list(5,10)
- list_reagents = list(/datum/reagent/hair_dye = 30)
- volume = 50
-/*
-/obj/item/reagent_containers/spray/baldium
- name = "baldium spray"
- desc = "Causes baldness, exessive use may cause customer disatisfaction."
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "hairremoval"
- amount_per_transfer_from_this = 1
- possible_transfer_amounts = list(5,10)
- list_reagents = list(/datum/reagent/baldium = 30)
- volume = 50
-*/
-/obj/item/reagent_containers/spray/barbers_aid
- name = "barber's aid"
- desc = "Causes rapid hair and facial hair growth!"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "hairaccelerator"
- amount_per_transfer_from_this = 1
- possible_transfer_amounts = list(5,10)
- list_reagents = list(/datum/reagent/barbers_aid = 50)
- volume = 50
-
-/obj/item/reagent_containers/spray/super_barbers_aid
- name = "super barber's aid"
- desc = "Causes SUPER rapid hair and facial hair growth!"
- icon = 'hyperstation/icons/obj/barber.dmi'
- icon_state = "hairaccelerator"
- amount_per_transfer_from_this = 1
- possible_transfer_amounts = list(5,10)
- list_reagents = list(/datum/reagent/concentrated_barbers_aid = 30)
- volume = 50
diff --git a/hyperstation/code/modules/surgery/organs/augments_arms.dm b/hyperstation/code/modules/surgery/organs/augments_arms.dm
index 8430fcac5..933b584eb 100644
--- a/hyperstation/code/modules/surgery/organs/augments_arms.dm
+++ b/hyperstation/code/modules/surgery/organs/augments_arms.dm
@@ -23,3 +23,11 @@
w_class = WEIGHT_CLASS_BULKY
sharpness = IS_SHARP_ACCURATE
attack_verb = list("slashed", "cut")
+
+
+// oracle port
+/obj/item/organ/cyberimp/arm/power_cord
+ name = "power cord implant"
+ desc = "An internal power cord hooked up to a battery. Useful if you run on volts."
+ contents = newlist(/obj/item/apc_powercord)
+ zone = "l_arm"
\ No newline at end of file
diff --git a/hyperstation/code/modules/vending/teavendomatic.dm b/hyperstation/code/modules/vending/teavendomatic.dm
deleted file mode 100644
index ba71bde81..000000000
--- a/hyperstation/code/modules/vending/teavendomatic.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/obj/machinery/vending/teavendomatic
- name = "\improper Tea Vend-O-Matic"
- desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one, this one is branded for tea and non-alcoholic beverages... Mostly."
- icon_state = "boozeomat"
- icon_deny = "boozeomat-deny"
- products = list(
- /obj/item/reagent_containers/food/drinks/mug/tea = 30,
- /obj/item/reagent_containers/food/drinks/bottle/wine = 5,
- /obj/item/reagent_containers/food/drinks/bottle/cognac = 5,
- /obj/item/reagent_containers/food/drinks/bottle/grappa = 5,
- /obj/item/reagent_containers/food/drinks/bottle/sake = 5,
- /obj/item/reagent_containers/food/drinks/bottle/orangejuice = 8,
- /obj/item/reagent_containers/food/drinks/bottle/tomatojuice = 8,
- /obj/item/reagent_containers/food/drinks/bottle/limejuice = 8,
- /obj/item/reagent_containers/food/drinks/bottle/grenadine = 4,
- /obj/item/reagent_containers/food/drinks/bottle/cream = 8,
- /obj/item/reagent_containers/food/drinks/soda_cans/tonic = 8,
- /obj/item/reagent_containers/food/drinks/soda_cans/cola = 8,
- /obj/item/reagent_containers/food/drinks/soda_cans/sodawater = 15,
- /obj/item/reagent_containers/food/drinks/drinkingglass = 30,
- /obj/item/reagent_containers/food/drinks/ice = 10,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12,
- /obj/item/reagent_containers/food/drinks/flask = 3)
- contraband = list(/obj/item/reagent_containers/food/drinks/mug/tea = 12,)
- premium = list(/obj/item/reagent_containers/glass/bottle/ethanol = 4,
- /obj/item/reagent_containers/food/drinks/bottle/champagne = 5,
- /obj/item/reagent_containers/food/drinks/bottle/trappist = 5)
- product_slogans = "Keep a clear head and drink on.;It is a quite fine day to sit down and have a drink.;Remember to drink responsibly.;Products are assured to be GMO free."
- product_ads = "Stay Radiant.;Remember to balance your intake.;Radiikist brands are not permitted in sectors 34-A through 59-B.;Keep a level head.;Refreshments are to be taken in modicum.;Let the day's stress melt away.;Please, enjoy.;In-service since the sixth Era."
- req_access = list(ACCESS_BAR)
- //refill_canister = /obj/item/vending_refill/teavendomatic
- free = TRUE
diff --git a/hyperstation/code/obj/Kitchen compliances/reagentblender.dm b/hyperstation/code/obj/Kitchen compliances/reagentblender.dm
deleted file mode 100644
index 5837e7063..000000000
--- a/hyperstation/code/obj/Kitchen compliances/reagentblender.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/machinery/reagentgrinder/reagentblender
- name = "Stand mixer"
- desc = "a stationary electric mixer for heavy-duty mixing various foods and other reagents."
- icon = 'hyperstation/icons/obj/machinery/reagentblender.dmi'
- icon_state = "mixer1"
-
-/obj/machinery/reagentgrinder/reagentblender/update_icon()
- if(beaker)
- icon_state = "mixer1"
- else
- icon_state = "mixer0"
\ No newline at end of file
diff --git a/hyperstation/code/obj/Lambent/gloves.dm b/hyperstation/code/obj/Lambent/gloves.dm
deleted file mode 100644
index 8cbb2df61..000000000
--- a/hyperstation/code/obj/Lambent/gloves.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-/obj/item/clothing/gloves/lambent
- name = "Lambent's sleeves"
- desc = "An elegant sleeve worn from the shoulder down. Despite missing anything on the palm and fingers, it seems to cast small hardlight protections over the hands, like a glove."
- icon_state = "lambent"
- item_state = "lambent"
- icon = 'hyperstation/icons/obj/clothing/gloves.dmi'
- alternate_worn_icon = 'hyperstation/icons/mobs/gloves.dmi'
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
- resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
- transfer_prints = FALSE
- strip_delay = 40
- body_parts_covered = ARMS|HANDS
- cold_protection = ARMS|HANDS
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- siemens_coefficient = 0
- permeability_coefficient = 0.05
diff --git a/hyperstation/code/obj/Lambent/shoes.dm b/hyperstation/code/obj/Lambent/shoes.dm
deleted file mode 100644
index aff7e1271..000000000
--- a/hyperstation/code/obj/Lambent/shoes.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/obj/item/clothing/shoes/lambent
- name = "Lambent's heels"
- desc = "A sleek pair of leggings with high heels, gilded in golden strips. It seems to have an autobalancing matrix installed."
- icon_state = "lambent"
- item_state = "lambent"
- icon = 'hyperstation/icons/obj/clothing/shoes.dmi'
- alternate_worn_icon = 'hyperstation/icons/mobs/feet.dmi'
- body_parts_covered = LEGS|FEET
- cold_protection = LEGS|FEET
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- strip_delay = 70
- resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
- clothing_flags = NOSLIP
diff --git a/hyperstation/code/obj/Lambent/suit.dm b/hyperstation/code/obj/Lambent/suit.dm
deleted file mode 100644
index c9c990bcf..000000000
--- a/hyperstation/code/obj/Lambent/suit.dm
+++ /dev/null
@@ -1,13 +0,0 @@
-/obj/item/clothing/suit/lambent
- name = "Lambent's coat"
- desc = "A regal-esque coat outfitted with inert nanites, waiting to be activated at a moment's notice."
- icon = 'hyperstation/icons/obj/clothing/suits.dmi'
- //alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
- icon_state = "lambent"
- item_state = "lambent"
- body_parts_covered = CHEST|LEGS
- cold_protection = CHEST|GROIN|LEGS|ARMS
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- strip_delay = 70
- resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
diff --git a/hyperstation/code/obj/Lambent/uniform.dm b/hyperstation/code/obj/Lambent/uniform.dm
deleted file mode 100644
index 8fcd48a2b..000000000
--- a/hyperstation/code/obj/Lambent/uniform.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/obj/item/clothing/under/rank/lambent
- name = "Lambent's outfitting"
- desc = "A Hyperwoven outfitting meant for a Kinaris Lambent. It's gilded colors and ultratech weaving speak highly about status."
- icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
- //alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
- icon_state = "lambent"
- item_state = "lambent"
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
- resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
- strip_delay = 50
- sensor_mode = SENSOR_COORDS
- random_sensor = FALSE
-
-//We'll add more alternative outfits here later. For now this'll be how it is!
diff --git a/hyperstation/code/obj/clothes.dm b/hyperstation/code/obj/clothes.dm
deleted file mode 100644
index da96e29ad..000000000
--- a/hyperstation/code/obj/clothes.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/obj/item/clothing/under/barber
- name = "barber's uniform"
- desc = "A fancy pink shirt paired with light-catching white pants. Yet to be blood- and puke-stained."
- icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
- //alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
- icon_state = "barber"
- item_state = "barber"
diff --git a/hyperstation/code/obj/condom.dm b/hyperstation/code/obj/condom.dm
index 727ff4739..2c3122fe2 100644
--- a/hyperstation/code/obj/condom.dm
+++ b/hyperstation/code/obj/condom.dm
@@ -115,7 +115,6 @@ obj/item/condom/update_icon()
return
if(!P.condom)
return
-
var/obj/item/condom/filled/C = new
P.linked_organ.reagents.trans_to(C, P.linked_organ.reagents.total_volume)
C.loc = loc
diff --git a/hyperstation/code/obj/farming/farming.dm b/hyperstation/code/obj/farming/farming.dm
index 8c203d78d..ad4671774 100644
--- a/hyperstation/code/obj/farming/farming.dm
+++ b/hyperstation/code/obj/farming/farming.dm
@@ -1,5 +1,5 @@
-/obj/item/reagent_containers/food/snacks/grown/wheat/
- var stacktype = /obj/item/stack/tile/hay
+/obj/item/reagent_containers/food/snacks/grown/wheat
+ var/stacktype = /obj/item/stack/tile/hay
var/tile_coefficient = 0.02 // same as grass
/obj/item/reagent_containers/food/snacks/grown/wheat/attack_self(mob/user)
diff --git a/hyperstation/code/obj/fleshlight.dm b/hyperstation/code/obj/fleshlight.dm
index 125c7ec34..421cfb8f6 100644
--- a/hyperstation/code/obj/fleshlight.dm
+++ b/hyperstation/code/obj/fleshlight.dm
@@ -45,11 +45,9 @@
inuse = 1
if(!(C == user)) //if we are targeting someone else.
C.visible_message("[user] is trying to use [src] on [C]'s penis.", "[user] is trying to use [src] on your penis.")
-
if(!do_mob(user, C, 3 SECONDS)) //3 second delay
inuse = 0
return
-
//checked if not used on yourself, if not, carry on.
playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound
inuse = 0
@@ -57,27 +55,22 @@
C.visible_message("[user] pumps [src] on [C]'s penis.", "[user] pumps [src] up and down on your penis.")
else
user.visible_message("[user] pumps [src] on their penis.", "You pump the fleshlight on your penis.")
-
if(prob(30)) //30% chance to make them moan.
C.emote("moan")
-
C.do_jitter_animation()
C.adjustArousalLoss(20) //make the target more aroused.
- if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
- C.mob_climax(forced_climax=TRUE) //make them cum if they are over the edge.
-
+ if(C.can_orgasm() && ishuman(C))
+ var/mob/living/carbon/human/user_human = C
+ user_human.mob_climax_outside(P, mb_time=0) // instant, because we already did a warmup
return
-
else
to_chat(user, "You don't see anywhere to use this on.")
-
inuse = 0
..()
//Hyperstation 13 portal fleshlight
//kinky!
-
/obj/item/portallight
name = "portal fleshlight"
desc = "A silver love(TM) fleshlight, used to stimulate someones penis, with bluespace tech that allows lovers to hump at a distance."
@@ -95,7 +88,6 @@
var/paired = 0
var/obj/item/portalunderwear
var/useable = FALSE
- var/option = ""
/obj/item/portallight/examine(mob/user)
. = ..()
@@ -104,136 +96,109 @@
else
. += "The device is paired, and awaiting input. "
-/obj/item/portallight/attack(mob/living/carbon/C, mob/living/user) //use portallight! nearly the same as the fleshlight apart from you have a buddy!
- var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
-
+/obj/item/portallight/attack(mob/living/carbon/user, mob/living/holder)
if(inuse) //just to stop stacking and causing people to cum instantly
return
- if(!useable)
- to_chat(user, "It seems the device has failed or your partner is not wearing their device.")
-
- if(C == user)//if your using it on yourself, more options! otherwise, just fuck.
+ if(!UpdateUsability())
+ to_chat(holder, "\The [src] appears to be currently unusable.")
+ return
+ var/option = "Fuck"
+ if(user == holder)
option = input(usr, "Choose action", "Portal Fleshlight", "Fuck") in list("Fuck", "Lick", "Touch")
- else
- option = "Fuck"
-
- var/obj/item/organ/genital/G
- if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime error.
- G = portalunderwear.loc
- if(!G)
+ var/obj/item/organ/genital/target_genital = portalunderwear.loc
+ var/mob/living/carbon/human/target = target_genital.owner
+ var/obj/item/organ/genital/penis/P = user.getorganslot("penis")
+ if(option == "Fuck" && !P.is_exposed())
+ to_chat(holder, "You don't see anywhere to use this on.")
return
- var/mob/living/carbon/human/M = G.owner
-
- if(option == "Fuck"&&!P.is_exposed()) //we are trying to fuck with no penis!
- to_chat(user, "You don't see anywhere to use this on.")
- return
- else //other options dont need checks
- inuse = 1
- if(!(C == user)) //if we are targeting someone else.
- C.visible_message("[user] is trying to use [src] on [C]'s penis.", "[user] is trying to use [src] on your penis.")
-
- if(!do_mob(user, C, 3 SECONDS)) //3 second delay
- inuse = 0
- return
-
- //checked if not used on yourself, if not, carry on.
- if(option == "Fuck")
- playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound for fuck.
-
- inuse = 0
- if(!(C == user))
- C.visible_message("[user] pumps [src] on [C]'s penis.", "[user] pumps [src] up and down on your penis.")
- else
- if(option == "Fuck")
- user.visible_message("[user] pumps [src] on their penis.", "You pump the fleshlight on your penis.")
- if(option == "Lick")
- user.visible_message("[user] licks into [src].", "You lick into [src].")
- if(option == "Touch")
- user.visible_message("[user] touches softly against [src].", "You touch softly on [src].")
-
-
- if(prob(30)) //30% chance to make your partner moan.
- M.emote("moan")
-
- if(option == "Fuck")// normal fuck
- to_chat(M, "You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [G.name].")//message your partner, and kinky!
- if(prob(30)) //30% chance to make them moan.
- C.emote("moan")
- if(prob(30)) //30% chance to make your partner moan.
- M.emote("moan")
- C.adjustArousalLoss(20)
- M.adjustArousalLoss(20)
- M.do_jitter_animation() //make your partner shake too!
-
- if (M.getArousalLoss() >= 100 && ishuman(M) && prob(5))//Why not have a probability to cum when someone's getting nailed with max arousal?~
- if(G.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
- M.mob_climax_outside(G, spillage = TRUE)
- else
- M.mob_climax_outside(G, spillage = FALSE)
-
- if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
- var/mob/living/carbon/human/O = C
-
- if( (P.condom == 1) || (P.sounding == 1)) //If coundomed and/or sounded, do not fire impreg chance
- O.mob_climax_partner(P, M, FALSE, FALSE, FALSE, TRUE)
- else //Else, fire impreg chance
- if(G.name == "vagina") //no more spontaneous impregnations through the butt!
- O.mob_climax_partner(P, M, FALSE, TRUE, FALSE, TRUE)
- else
- O.mob_climax_partner(P, M, FALSE, FALSE, FALSE, TRUE)
-
- if(option == "Lick")
- to_chat(M, "You feel a tongue lick you through the portal against your [G.name].")
- M.adjustArousalLoss(10)
- if(option == "Touch")
- to_chat(M, "You feel someone touching your [G.name] through the portal.")
- M.adjustArousalLoss(5)
-
+ /*
+ WARMUP START - prevents spam/instant climax
+ */
+ inuse = TRUE
+ if(user != holder)
+ user.visible_message("[holder] is trying to use [src] on [user]'s penis.",\
+ "[holder] is trying to use [src] on your penis.")
+ if(!do_mob(holder, user, 3 SECONDS))
+ inuse = FALSE
return
+ inuse = FALSE
+ /*
+ WARMUP END - proceed with the action
+ */
+ switch(option)
+ if("Fuck")
+ playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1)
+ if(user == holder)
+ holder.visible_message("[holder] pumps [src] on their penis.",
+ "You pump the fleshlight on your penis.")
+ else
+ user.visible_message("[holder] pumps [src] on [user]'s penis.",\
+ "[holder] pumps [src] up and down on your penis.")
+ to_chat(target, "You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [target_genital.name].")
+ if(prob(30))
+ user.emote("moan")
+ user.adjustArousalLoss(20)
+ target.adjustArousalLoss(20)
+ target.do_jitter_animation()
+ if(target.can_orgasm() && prob(5))
+ target.mob_climax_outside(target_genital, spillage=target_genital.is_exposed())
+ if(user.can_orgasm())
+ var/mob/living/carbon/human/O = user
+ var/impreg_chance = target_genital.name == "vagina" && !P.condom && !P.sounding
+ if(O.mob_climax_in_partner(P, target, spillage=FALSE, remote=TRUE) && impreg_chance)
+ target.impregnate(by=O)
+ if("Lick")
+ holder.visible_message("[holder] licks into [src].",\
+ "You lick into [src].")
+ to_chat(target, "You feel a tongue lick you through the portal against your [target_genital.name].")
+ target.adjustArousalLoss(10)
+ if("Touch")
+ holder.visible_message("[holder] touches softly against [src].",\
+ "You touch softly on [src].")
+ to_chat(target, "You feel someone touching your [target_genital.name] through the portal.")
+ target.adjustArousalLoss(5)
+ if(prob(30))
+ target.emote("moan")
..()
/obj/item/portallight/proc/updatesleeve()
//get their looks and vagina colour!
- cut_overlays()//remove current overlays
-
- var/obj/item/organ/genital/G
- if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime.
- G = portalunderwear.loc
- if(!G)
- useable = FALSE
+ cut_overlays()
+ if(!UpdateUsability())
return
+ var/obj/item/organ/genital/G = portalunderwear.loc
+ var/mob/living/carbon/human/H = G.owner // H is verified by UpdateUsability()
+ var/sleeve_species = "normal"
+ switch(H.dna.species.name)
+ if("Lizardperson")
+ sleeve_species = "lizard"
+ if("Slimeperson")
+ sleeve_species = "slime"
+ if("Avian")
+ sleeve_species = "avian"
+ sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_[sleeve_species]")
+ sleeve.color = "#" + H.dna.features["mcolor"]
+ add_overlay(sleeve)
+ if(G.name == "vagina")
+ organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
+ organ.color = portalunderwear.loc.color
+ if(G.name == "anus")
+ organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus")
+ organ.color = "#" + H.dna.features["mcolor"]
+ add_overlay(organ)
- var/mob/living/carbon/human/H = G.owner
+/obj/item/portallight/proc/UpdateUsability()
+ var/useable = FALSE
+ if(portalunderwear && istype(portalunderwear.loc, /obj/item/organ/genital))
+ var/obj/item/organ/genital/loc_genitals = portalunderwear.loc
+ if(loc_genitals.owner && ishuman(loc_genitals.owner))
+ useable = TRUE
+ src.useable = useable
+ return useable
- if(H) //if the portal panties are on someone.
- sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_normal")
- if(H.dna.species.name == "Lizardperson") // lizard nerd
- sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_lizard")
-
- if(H.dna.species.name == "Slimeperson") // slime nerd
- sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_slime")
-
- if(H.dna.species.name == "Avian") // bird nerd
- sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_avian")
-
- sleeve.color = "#" + H.dna.features["mcolor"]
- add_overlay(sleeve)
-
- if(G.name == "vagina")
- organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
- organ.color = portalunderwear.loc.color
- if(G.name == "anus")
- organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus")
- organ.color = "#" + H.dna.features["mcolor"]
-
- useable = TRUE
- add_overlay(organ)
- else
- useable = FALSE
//Hyperstation 13 portal underwear
//can be attached to vagina or anus, just like the vibrator, still requires pairing with the portallight
-
/obj/item/portalpanties
name = "portal panties"
desc = "A silver love(TM) pair of portal underwear, with bluespace tech allows lovers to hump at a distance. Needs to be paired with a portal fleshlight before use."
@@ -252,7 +217,6 @@
else
. += "The device is paired, and awaiting attachment. "
-
/obj/item/portalpanties/attackby(obj/item/I, mob/living/user) //pairing
if(istype(I, /obj/item/portallight))
var/obj/item/portallight/P = I
@@ -268,11 +232,9 @@
..() //just allows people to hit it with other objects, if they so wished.
/obj/item/portalpanties/attack(mob/living/carbon/C, mob/living/user)
-
if(!portallight) //we arent paired yet! noobie trap, let them know.
to_chat(user, "[src] can only be attached once paired with a portal fleshlight.")
return
-
var/obj/item/organ/genital/picked_organ
var/mob/living/carbon/human/S = user
var/mob/living/carbon/human/T = C
@@ -282,21 +244,17 @@
"[user] is trying to put [src] on you!")
if(!do_mob(user, C, 3 SECONDS))//warn them and have a delay of 5 seconds to apply.
return
-
if((picked_organ.name == "vagina")||(picked_organ.name == "anus")) //only fits on a vagina or anus
-
src.shapetype = picked_organ.name
if(!picked_organ.equipment)
to_chat(user, "You wrap [src] around [T]'s [picked_organ.name].")
else
to_chat(user, "They already have [picked_organ.equipment.name] there.")
return
-
if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
return
src.attached = TRUE
picked_organ.equipment = src
-
var/obj/item/portallight/P = portallight
//now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
if(P) //just to make sure
@@ -312,6 +270,7 @@
var/obj/item/portallight/P = portallight
P.updatesleeve()
+
/obj/item/storage/box/portallight
name = "Portal Fleshlight and Underwear"
icon = 'hyperstation/icons/obj/fleshlight.dmi'
diff --git a/hyperstation/code/obj/items/lorebooks.dm b/hyperstation/code/obj/items/lorebooks.dm
index 07fc09ee1..700089f55 100644
--- a/hyperstation/code/obj/items/lorebooks.dm
+++ b/hyperstation/code/obj/items/lorebooks.dm
@@ -156,7 +156,7 @@
Chapter 4
About Layenia Station
- After reading this far in, it may become apparent that Layenia does not reflect the values of Kinaris in many ways. From the technological progress to the surroundings, it may seem like Layenia Station is far behind its time. And that’s an entirely correct notion, all thanks to the standards of Kinaris Uplifting.
+ After reading this far in, it may become apparent that Layenia does not reflect the values of Kinaris in many ways. From the technological progress to the surroundings, it may seem like Layenia Station is far behind its time. And that’s an entirely correct notion, all thanks to the standards of Kinaris Uplifting.
As it stands right now, Layenia Station uses a fabricated Engram to replicate that of its former employers and owners. The star was previously given to humanity prior to the first attempt at Uplifting, but it was taken back shortly after things went south, and given open borders to the Milky Way. The Engram in particular mimics a lot of Nanotrasen-esque technology, which makes Layenia Station one of the most low-tech Kinaris stations to exist out there to date!
@@ -166,7 +166,7 @@
-
+