Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into modular_cit_cleaning
This commit is contained in:
@@ -57,9 +57,3 @@
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
color = "#[owner.dna.features["breasts_color"]]"
|
||||
|
||||
/obj/item/organ/genital/breasts/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_chest_exposed()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/obj/item/organ/genital/linked_organ
|
||||
var/through_clothes = FALSE
|
||||
var/internal = FALSE
|
||||
var/hidden = FALSE
|
||||
|
||||
/obj/item/organ/genital/Initialize()
|
||||
. = ..()
|
||||
@@ -47,18 +48,39 @@
|
||||
/obj/item/organ/genital/proc/is_exposed()
|
||||
if(!owner)
|
||||
return FALSE
|
||||
if(hidden)
|
||||
return FALSE
|
||||
if(internal)
|
||||
return FALSE
|
||||
if(through_clothes)
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/genital/proc/toggle_through_clothes()
|
||||
if(through_clothes)
|
||||
through_clothes = FALSE
|
||||
owner.exposed_genitals -= src
|
||||
else
|
||||
through_clothes = TRUE
|
||||
owner.exposed_genitals += src
|
||||
switch(zone) //update as more genitals are added
|
||||
if("chest")
|
||||
return owner.is_chest_exposed()
|
||||
if("groin")
|
||||
return owner.is_groin_exposed()
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/organ/genital/proc/toggle_visibility(visibility)
|
||||
switch(visibility)
|
||||
if("Always visible")
|
||||
through_clothes = TRUE
|
||||
hidden = FALSE
|
||||
if(!(src in owner.exposed_genitals))
|
||||
owner.exposed_genitals += src
|
||||
if("Hidden by clothes")
|
||||
through_clothes = FALSE
|
||||
hidden = FALSE
|
||||
if(src in owner.exposed_genitals)
|
||||
owner.exposed_genitals -= src
|
||||
if("Always hidden")
|
||||
through_clothes = FALSE
|
||||
hidden = TRUE
|
||||
if(src in owner.exposed_genitals)
|
||||
owner.exposed_genitals -= src
|
||||
|
||||
if(ishuman(owner)) //recast to use update genitals proc
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.update_genitals()
|
||||
@@ -78,9 +100,10 @@
|
||||
return
|
||||
//Full list of exposable genitals created
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = input(src, "Expose/Hide genitals", "Choose which genitalia to expose/hide", null) in genital_list
|
||||
picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
|
||||
if(picked_organ)
|
||||
picked_organ.toggle_through_clothes()
|
||||
var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
picked_organ.toggle_visibility(picked_visibility)
|
||||
return
|
||||
|
||||
|
||||
@@ -251,6 +274,8 @@
|
||||
return
|
||||
if(NOGENITALS in species_traits)//golems and such
|
||||
return
|
||||
if(H.has_trait(TRAIT_HUSK))
|
||||
return
|
||||
|
||||
var/list/genitals_to_add = list()
|
||||
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER)
|
||||
@@ -260,8 +285,6 @@
|
||||
for(var/L in relevant_layers) //Less hardcode
|
||||
H.remove_overlay(L)
|
||||
|
||||
if(H.has_trait(TRAIT_HUSK))
|
||||
return
|
||||
//start scanning for genitals
|
||||
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
|
||||
for(var/obj/item/organ/O in H.internal_organs)
|
||||
|
||||
@@ -58,9 +58,3 @@
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/penis/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_groin_exposed()
|
||||
|
||||
@@ -64,9 +64,3 @@
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/vagina/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_groin_exposed()
|
||||
|
||||
@@ -326,3 +326,9 @@ datum/gear/darksabresheath
|
||||
category = SLOT_IN_BACKPACK
|
||||
path = /obj/item/toy/gun/m41
|
||||
ckeywhitelist = list("thalverscholen")
|
||||
|
||||
/datum/gear/Divine_robes
|
||||
name = "Divine robes"
|
||||
category = SLOT_W_UNIFORM
|
||||
path = /obj/item/clothing/under/lunasune
|
||||
ckeywhitelist = list("invader4352")
|
||||
@@ -42,9 +42,9 @@
|
||||
"mam_ears" = "None",
|
||||
"mam_tail" = "None",
|
||||
"mam_tail_animated" = "None",
|
||||
"xenodorsal" = "None",
|
||||
"xenohead" = "None",
|
||||
"xenotail" = "None",
|
||||
"xenodorsal" = "Standard",
|
||||
"xenohead" = "Standard",
|
||||
"xenotail" = "Xenomorph Tail",
|
||||
"taur" = "None",
|
||||
"exhibitionist" = FALSE,
|
||||
"genitals_use_skintone" = FALSE,
|
||||
@@ -99,563 +99,6 @@
|
||||
..()
|
||||
LAZYINITLIST(chosen_gear)
|
||||
|
||||
/datum/preferences/proc/citadel_dat_replace(current_tab)
|
||||
var/mob/user
|
||||
//This proc is for menus other than game pref and char pref
|
||||
. = "<center>"
|
||||
. += "<a href='?_src_=prefs;preference=tab;tab=0' [current_tab == 0 ? "class='linkOn'" : ""]>Character Settings</a>"
|
||||
. += "<a href='?_src_=prefs;preference=tab;tab=2' [current_tab == 2 ? "class='linkOn'" : ""]>Character Appearance</a>"
|
||||
. += "<a href='?_src_=prefs;preference=tab;tab=3' [current_tab == 3 ? "class='linkOn'" : ""]>Loadout</a>"
|
||||
. += "<a href='?_src_=prefs;preference=tab;tab=1' [current_tab == 1 ? "class='linkOn'" : ""]>Game Preferences</a>"
|
||||
|
||||
if(!path)
|
||||
. += "<div class='notice'>Please create an account to save your preferences</div>"
|
||||
|
||||
. += "</center>"
|
||||
|
||||
. += "<HR>"
|
||||
|
||||
//Character Appearance
|
||||
if(current_tab == 2)
|
||||
update_preview_icon(nude=TRUE)
|
||||
user << browse_rsc(preview_icon, "previewicon.png")
|
||||
. += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
. += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
|
||||
. += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Flavor Text</b></a><br>"
|
||||
if(lentext(features["flavor_text"]) <= 40)
|
||||
if(!lentext(features["flavor_text"]))
|
||||
. += "\[...\]"
|
||||
else
|
||||
. += "[features["flavor_text"]]"
|
||||
else
|
||||
. += "[TextPreview(features["flavor_text"])]...<BR>"
|
||||
. += "<h2>Body</h2>"
|
||||
. += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : "Female"]</a><BR>"
|
||||
. += "<b>Species:</b><a href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
|
||||
. += "<a href='?_src_=prefs;preference=all;task=random'>Random Body</A><BR>"
|
||||
. += "<a href='?_src_=prefs;preference=all'>Always Random Body: [be_random_body ? "Yes" : "No"]</A><BR>"
|
||||
if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
|
||||
. += "<b>Primary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor"]];'> </span> <a href='?_src_=prefs;preference=mutant_color;task=input'>Change</a><BR>"
|
||||
. += "<b>Secondary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor2"]];'> </span> <a href='?_src_=prefs;preference=mutant_color2;task=input'>Change</a><BR>"
|
||||
. += "<b>Tertiary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'> </span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
|
||||
if(pref_species.use_skintones)
|
||||
. += "<b>Skin Tone: </b><a href='?_src_=prefs;preference=s_tone;task=input'>[skin_tone]</a><BR>"
|
||||
. += "<b>Genitals Use Skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Enabled" : "Disabled"]</a><BR>"
|
||||
|
||||
if(HAIR in pref_species.species_traits)
|
||||
. += "<b>Hair Style: </b><a href='?_src_=prefs;preference=hair_style;task=input'>[hair_style]</a><BR>"
|
||||
. += "<b>Hair Color: </b><span style='border:1px solid #161616; background-color: #[hair_color];'> </span> <a href='?_src_=prefs;preference=hair;task=input'>Change</a><BR>"
|
||||
. += "<b>Facial Hair Style: </b><a href='?_src_=prefs;preference=facial_hair_style;task=input'>[facial_hair_style]</a><BR>"
|
||||
. += "<b>Facial Hair Color: </b><span style='border: 1px solid #161616; background-color: #[facial_hair_color];'> </span> <a href='?_src_=prefs;preference=facial;task=input'>Change</a><BR>"
|
||||
if(EYECOLOR in pref_species.species_traits)
|
||||
. += "<b>Eye Color: </b><span style='border: 1px solid #161616; background-color: #[eye_color];'> </span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a><BR>"
|
||||
if("tail_lizard" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Tail: </b><a href='?_src_=prefs;preference=tail_lizard;task=input'>[features["tail_lizard"]]</a><BR>"
|
||||
else if("mam_tail" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Tail: </b><a href='?_src_=prefs;preference=mam_tail;task=input'>[features["mam_tail"]]</a><BR>"
|
||||
else if("tail_human" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Tail: </b><a href='?_src_=prefs;preference=tail_human;task=input'>[features["tail_human"]]</a><BR>"
|
||||
if("snout" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Snout: </b><a href='?_src_=prefs;preference=snout;task=input'>[features["snout"]]</a><BR>"
|
||||
if("horns" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Horns: </b><a href='?_src_=prefs;preference=horns;task=input'>[features["horns"]]</a><BR>"
|
||||
if("frills" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Frills: </b><a href='?_src_=prefs;preference=frills;task=input'>[features["frills"]]</a><BR>"
|
||||
if("spines" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Spines: </b><a href='?_src_=prefs;preference=spines;task=input'>[features["spines"]]</a><BR>"
|
||||
if("body_markings" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Body Markings: </b><a href='?_src_=prefs;preference=body_markings;task=input'>[features["body_markings"]]</a><BR>"
|
||||
else if("mam_body_markings" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Body Markings: </b><a href='?_src_=prefs;preference=mam_body_markings;task=input'>[features["mam_body_markings"]]</a><BR>"
|
||||
if("mam_ears" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Ears: </b><a href='?_src_=prefs;preference=mam_ears;task=input'>[features["mam_ears"]]</a><BR>"
|
||||
else if("ears" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Ears: </b><a href='?_src_=prefs;preference=ears;task=input'>[features["ears"]]</a><BR>"
|
||||
if("legs" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Legs: </b><a href='?_src_=prefs;preference=legs;task=input'>[features["legs"]]</a><BR>"
|
||||
if("moth_wings" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Moth wings</b><a href='?_src_=prefs;preference=moth_wings;task=input'>[features["moth_wings"]]</a><BR>"
|
||||
if("taur" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Taur: </b><a href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a><BR>"
|
||||
if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1)
|
||||
. += "<b>Wings: </b><a href='?_src_=prefs;preference=wings;task=input'>[features["wings"]]</a><BR>"
|
||||
if("xenohead" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Caste: </b><a href='?_src_=prefs;preference=xenohead;task=input'>[features["xenohead"]]</a><BR>"
|
||||
if("xenotail" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Tail: </b><a href='?_src_=prefs;preference=xenotail;task=input'>[features["xenotail"]]</a><BR>"
|
||||
if("xenodorsal" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Dorsal Tubes: </b><a href='?_src_=prefs;preference=xenodorsal;task=input'>[features["xenodorsal"]]</a><BR>"
|
||||
if("ipc_screen" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Screen:</b><a href='?_src_=prefs;preference=ipc_screen;task=input'>[features["ipc_screen"]]</a><BR>"
|
||||
if("ipc_antenna" in pref_species.mutant_bodyparts)
|
||||
. += "<b>Antenna:</b><a href='?_src_=prefs;preference=ipc_antenna;task=input'>[features["ipc_antenna"]]</a><BR>"
|
||||
|
||||
. += "</td><td width='300px' height='300px' valign='top'>"
|
||||
|
||||
. += "<h2>Clothing & Equipment</h2>"
|
||||
|
||||
. += "<b>Underwear:</b><a href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a><br>"
|
||||
. += "<b>Undershirt:</b><a href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a><br>"
|
||||
. += "<b>Socks:</b><a href ='?_src_=prefs;preference=socks;task=input'>[socks]</a><br>"
|
||||
. += "<b>Backpack:</b><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><br>"
|
||||
. += "<b>Uplink Location:</b><a href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a><br>"
|
||||
|
||||
. += "<h2>Genitals</h2>"
|
||||
if(NOGENITALS in pref_species.species_traits)
|
||||
. += "<b>Your species ([pref_species.name]) does not support genitals!</b><br>"
|
||||
else
|
||||
. += "<b>Has Penis:</b><a href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
if(features["has_cock"] == TRUE)
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
. += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
||||
else
|
||||
. += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'> </span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><BR>"
|
||||
. += "<b>Penis Shape:</b> <a href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a><BR>"
|
||||
. += "<b>Penis Length:</b> <a href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a><BR>"
|
||||
. += "<b>Has Testicles:</b><a href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
if(features["has_balls"] == TRUE)
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
. += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
||||
else
|
||||
. += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'> </span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><BR>"
|
||||
. += "<b>Has Vagina:</b><a href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
if(features["has_vag"])
|
||||
. += "<b>Vagina Type:</b> <a href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a><BR>"
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
. += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
||||
else
|
||||
. += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'> </span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><BR>"
|
||||
. += "<b>Has Womb:</b><a href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
. += "<b>Has Breasts:</b><a href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
if(features["has_breasts"])
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
. += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
||||
else
|
||||
. += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'> </span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><BR>"
|
||||
. += "<b>Cup Size:</b><a href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a><br>"
|
||||
. += "<b>Breast Shape:</b><a href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a><br>"
|
||||
/*
|
||||
. += "<h3>Ovipositor</h3>"
|
||||
. += "<b>Has Ovipositor:</b><a href='?_src_=prefs;preference=has_ovi'>[features["has_ovi"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_ovi"])
|
||||
. += "<b>Ovi Color:</b><span style='border: 1px solid #161616; background-color: #[features["ovi_color"]];'> </span> <a href='?_src_=prefs;preference=ovi_color;task=input'>Change</a>"
|
||||
. += "<h3>Eggsack</h3>"
|
||||
. += "<b>Has Eggsack:</b><a href='?_src_=prefs;preference=has_eggsack'>[features["has_eggsack"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
if(features["has_eggsack"] == TRUE)
|
||||
. += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[features["eggsack_color"]];'> </span> <a href='?_src_=prefs;preference=eggsack_color;task=input'>Change</a>"
|
||||
. += "<b>Egg Color:</b><span style='border: 1px solid #161616; background-color: #[features["eggsack_egg_color"]];'> </span> <a href='?_src_=prefs;preference=egg_color;task=input'>Change</a>"
|
||||
. += "<b>Egg Size:</b><a href='?_src_=prefs;preference=egg_size;task=input'>[features["eggsack_egg_size"]]\" Diameter</a>"
|
||||
. += "</td>"
|
||||
*/
|
||||
. += "</td></tr></table>"
|
||||
|
||||
/datum/preferences/proc/process_citadel_link(mob/user, list/href_list)
|
||||
if("input")
|
||||
switch(href_list["preference"])
|
||||
if("flavor_text")
|
||||
var/msg = stripped_multiline_input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) as null|message
|
||||
if(!isnull(msg))
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN*2)
|
||||
features["flavor_text"] = msg
|
||||
|
||||
if("hair")
|
||||
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
||||
if(new_hair)
|
||||
hair_color = sanitize_hexcolor(new_hair)
|
||||
|
||||
if("hair_style")
|
||||
var/new_hair_style
|
||||
if(gender == MALE)
|
||||
new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_male_list
|
||||
else
|
||||
new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_female_list
|
||||
if(new_hair_style)
|
||||
hair_style = new_hair_style
|
||||
|
||||
if("next_hair_style")
|
||||
if (gender == MALE)
|
||||
hair_style = next_list_item(hair_style, GLOB.hair_styles_male_list)
|
||||
else
|
||||
hair_style = next_list_item(hair_style, GLOB.hair_styles_female_list)
|
||||
|
||||
if("previous_hair_style")
|
||||
if (gender == MALE)
|
||||
hair_style = previous_list_item(hair_style, GLOB.hair_styles_male_list)
|
||||
else
|
||||
hair_style = previous_list_item(hair_style, GLOB.hair_styles_female_list)
|
||||
|
||||
if("facial")
|
||||
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null
|
||||
if(new_facial)
|
||||
facial_hair_color = sanitize_hexcolor(new_facial)
|
||||
if("facial_hair_style")
|
||||
var/new_facial_hair_style
|
||||
if(gender == MALE)
|
||||
new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_male_list
|
||||
else
|
||||
new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_female_list
|
||||
if(new_facial_hair_style)
|
||||
facial_hair_style = new_facial_hair_style
|
||||
|
||||
if("next_facehair_style")
|
||||
if (gender == MALE)
|
||||
facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list)
|
||||
else
|
||||
facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list)
|
||||
if("previous_facehair_style")
|
||||
if (gender == MALE)
|
||||
facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list)
|
||||
else
|
||||
facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list)
|
||||
|
||||
if("underwear")
|
||||
var/new_underwear
|
||||
if(gender == MALE)
|
||||
new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m
|
||||
else
|
||||
new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f
|
||||
if(new_underwear)
|
||||
underwear = new_underwear
|
||||
|
||||
if("undershirt")
|
||||
var/new_undershirt
|
||||
if(gender == MALE)
|
||||
new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m
|
||||
else
|
||||
new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f
|
||||
if(new_undershirt)
|
||||
undershirt = new_undershirt
|
||||
|
||||
if("socks")
|
||||
var/new_socks
|
||||
new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list
|
||||
if(new_socks)
|
||||
socks = new_socks
|
||||
|
||||
if("eyes")
|
||||
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null
|
||||
if(new_eyes)
|
||||
eye_color = sanitize_hexcolor(new_eyes)
|
||||
|
||||
if("species")
|
||||
var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_races
|
||||
if(result)
|
||||
var/newtype = GLOB.species_list[result]
|
||||
pref_species = new newtype()
|
||||
//Now that we changed our species, we must verify that the mutant colour is still allowed.
|
||||
var/temp_hsv = RGBtoHSV(features["mcolor"])
|
||||
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor"] = pref_species.default_color
|
||||
if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor2"] = pref_species.default_color
|
||||
if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor3"] = pref_species.default_color
|
||||
|
||||
if("mutant_color")
|
||||
var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null
|
||||
if(new_mutantcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("mutant_color2")
|
||||
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null
|
||||
if(new_mutantcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor2"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("mutant_color3")
|
||||
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null
|
||||
if(new_mutantcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor3"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("ipc_screen")
|
||||
var/new_ipc_screen
|
||||
new_ipc_screen = input(user, "Choose your character's screen:", "Character Preference") as null|anything in GLOB.ipc_screens_list
|
||||
if(new_ipc_screen)
|
||||
features["ipc_screen"] = new_ipc_screen
|
||||
|
||||
if("ipc_antenna")
|
||||
var/new_ipc_antenna
|
||||
new_ipc_antenna = input(user, "Choose your character's antenna:", "Character Preference") as null|anything in GLOB.ipc_antennas_list
|
||||
if(new_ipc_antenna)
|
||||
features["ipc_antenna"] = new_ipc_antenna
|
||||
|
||||
if("tail_lizard")
|
||||
var/new_tail
|
||||
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_lizard
|
||||
if(new_tail)
|
||||
features["tail_lizard"] = new_tail
|
||||
if(new_tail != "None")
|
||||
features["taur"] = "None"
|
||||
|
||||
if("tail_human")
|
||||
var/list/snowflake_tails_list = list("Normal" = null)
|
||||
for(var/path in GLOB.tails_list_human)
|
||||
var/datum/sprite_accessory/tails/human/instance = GLOB.tails_list_human[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_tails_list[S.name] = path
|
||||
var/new_tail
|
||||
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
|
||||
if(new_tail)
|
||||
features["tail_human"] = new_tail
|
||||
if(new_tail != "None")
|
||||
features["taur"] = "None"
|
||||
|
||||
if("mam_tail")
|
||||
var/list/snowflake_tails_list = list("Normal" = null)
|
||||
for(var/path in GLOB.mam_tails_list)
|
||||
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_tails_list[S.name] = path
|
||||
var/new_tail
|
||||
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
|
||||
if(new_tail)
|
||||
features["mam_tail"] = new_tail
|
||||
if(new_tail != "None")
|
||||
features["taur"] = "None"
|
||||
|
||||
if("snout")
|
||||
var/new_snout
|
||||
new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.snouts_list
|
||||
if(new_snout)
|
||||
features["snout"] = new_snout
|
||||
|
||||
if("horns")
|
||||
var/new_horns
|
||||
new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list
|
||||
if(new_horns)
|
||||
features["horns"] = new_horns
|
||||
|
||||
if("ears")
|
||||
var/new_ears
|
||||
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list
|
||||
if(new_ears)
|
||||
features["ears"] = new_ears
|
||||
|
||||
if("wings")
|
||||
var/new_wings
|
||||
new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list
|
||||
if(new_wings)
|
||||
features["wings"] = new_wings
|
||||
|
||||
if("frills")
|
||||
var/new_frills
|
||||
new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list
|
||||
if(new_frills)
|
||||
features["frills"] = new_frills
|
||||
|
||||
if("spines")
|
||||
var/new_spines
|
||||
new_spines = input(user, "Choose your character's spines:", "Character Preference") as null|anything in GLOB.spines_list
|
||||
if(new_spines)
|
||||
features["spines"] = new_spines
|
||||
|
||||
if("body_markings")
|
||||
var/new_body_markings
|
||||
new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list
|
||||
if(new_body_markings)
|
||||
features["body_markings"] = new_body_markings
|
||||
|
||||
if("legs")
|
||||
var/new_legs
|
||||
new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list
|
||||
if(new_legs)
|
||||
features["legs"] = new_legs
|
||||
|
||||
if("moth_wings")
|
||||
var/new_moth_wings
|
||||
new_moth_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.moth_wings_list
|
||||
if(new_moth_wings)
|
||||
features["moth_wings"] = new_moth_wings
|
||||
|
||||
if("s_tone")
|
||||
var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones
|
||||
if(new_s_tone)
|
||||
skin_tone = new_s_tone
|
||||
|
||||
if("taur")
|
||||
var/list/snowflake_taur_list = list("Normal" = null)
|
||||
for(var/path in GLOB.taur_list)
|
||||
var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_taur_list[S.name] = path
|
||||
var/new_taur
|
||||
new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in snowflake_taur_list
|
||||
if(new_taur)
|
||||
features["taur"] = new_taur
|
||||
if(new_taur != "None")
|
||||
features["mam_tail"] = "None"
|
||||
features["xenotail"] = "None"
|
||||
|
||||
if("ears")
|
||||
var/list/snowflake_ears_list = list("Normal" = null)
|
||||
for(var/path in GLOB.ears_list)
|
||||
var/datum/sprite_accessory/ears/instance = GLOB.ears_list[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_ears_list[S.name] = path
|
||||
var/new_ears
|
||||
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
|
||||
if(new_ears)
|
||||
features["ears"] = new_ears
|
||||
|
||||
if("mam_ears")
|
||||
var/list/snowflake_ears_list = list("Normal" = null)
|
||||
for(var/path in GLOB.mam_ears_list)
|
||||
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_ears_list[S.name] = path
|
||||
var/new_ears
|
||||
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
|
||||
if(new_ears)
|
||||
features["mam_ears"] = new_ears
|
||||
|
||||
if("mam_body_markings")
|
||||
var/list/snowflake_markings_list = list("Normal" = null)
|
||||
for(var/path in GLOB.mam_body_markings_list)
|
||||
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path]
|
||||
if(istype(instance, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/S = instance
|
||||
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
||||
snowflake_markings_list[S.name] = path
|
||||
var/new_mam_body_markings
|
||||
new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in snowflake_markings_list
|
||||
if(new_mam_body_markings)
|
||||
features["mam_body_markings"] = new_mam_body_markings
|
||||
|
||||
//Xeno Bodyparts
|
||||
if("xenohead")//Head or caste type
|
||||
var/new_head
|
||||
new_head = input(user, "Choose your character's caste:", "Character Preference") as null|anything in GLOB.xeno_head_list
|
||||
if(new_head)
|
||||
features["xenohead"] = new_head
|
||||
|
||||
if("xenotail")//Currently one one type, more maybe later if someone sprites them. Might include animated variants in the future.
|
||||
var/new_tail
|
||||
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.xeno_tail_list
|
||||
if(new_tail)
|
||||
features["xenotail"] = new_tail
|
||||
|
||||
if("xenodorsal")
|
||||
var/new_dors
|
||||
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
|
||||
//Genital code
|
||||
if("cock_color")
|
||||
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
|
||||
if(new_cockcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_cockcolor)
|
||||
if(new_cockcolor == "#000000")
|
||||
features["cock_color"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["cock_color"] = sanitize_hexcolor(new_cockcolor)
|
||||
else
|
||||
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
if("cock_length")
|
||||
var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null
|
||||
if(new_length)
|
||||
features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
|
||||
|
||||
if("cock_shape")
|
||||
var/new_shape
|
||||
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list
|
||||
if(new_shape)
|
||||
features["cock_shape"] = new_shape
|
||||
|
||||
if("balls_color")
|
||||
var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null
|
||||
if(new_ballscolor)
|
||||
var/temp_hsv = RGBtoHSV(new_ballscolor)
|
||||
if(new_ballscolor == "#000000")
|
||||
features["balls_color"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["balls_color"] = sanitize_hexcolor(new_ballscolor)
|
||||
else
|
||||
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
if("egg_size")
|
||||
var/new_size
|
||||
var/list/egg_sizes = list(1,2,3)
|
||||
new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes
|
||||
if(new_size)
|
||||
features["eggsack_egg_size"] = new_size
|
||||
|
||||
if("egg_color")
|
||||
var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null
|
||||
if(new_egg_color)
|
||||
var/temp_hsv = RGBtoHSV(new_egg_color)
|
||||
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color)
|
||||
else
|
||||
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
if("breasts_size")
|
||||
var/new_size
|
||||
new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list
|
||||
if(new_size)
|
||||
features["breasts_size"] = new_size
|
||||
|
||||
if("breasts_shape")
|
||||
var/new_shape
|
||||
new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list
|
||||
if(new_shape)
|
||||
features["breasts_shape"] = new_shape
|
||||
|
||||
if("breasts_color")
|
||||
var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null
|
||||
if(new_breasts_color)
|
||||
var/temp_hsv = RGBtoHSV(new_breasts_color)
|
||||
if(new_breasts_color == "#000000")
|
||||
features["breasts_color"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["breasts_color"] = sanitize_hexcolor(new_breasts_color)
|
||||
else
|
||||
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
if("vag_shape")
|
||||
var/new_shape
|
||||
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
|
||||
if(new_shape)
|
||||
features["vag_shape"] = new_shape
|
||||
|
||||
if("vag_color")
|
||||
var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null
|
||||
if(new_vagcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_vagcolor)
|
||||
if(new_vagcolor == "#000000")
|
||||
features["vag_color"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["vag_color"] = sanitize_hexcolor(new_vagcolor)
|
||||
else
|
||||
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
/datum/preferences/proc/is_loadout_slot_available(slot)
|
||||
var/list/L
|
||||
LAZYINITLIST(L)
|
||||
|
||||
@@ -240,7 +240,6 @@
|
||||
icon_state = "fedcapofficer"
|
||||
icon_override = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
|
||||
item_state = "fedcapofficer_mob"
|
||||
armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 10, "rad" = 10, "fire" = 0, "acid" = 0)
|
||||
|
||||
//Variants
|
||||
/obj/item/clothing/head/caphat/formal/fedcover/medsci
|
||||
|
||||
@@ -397,3 +397,11 @@
|
||||
desc = "Comfy Lucky Jackboots with the word Luck on them."
|
||||
item_state = "luckyjack"
|
||||
icon_state = "luckyjack"
|
||||
|
||||
/obj/item/clothing/under/lunasune
|
||||
name = "Divine Robes"
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
icon_override = 'icons/mob/custom_w.dmi'
|
||||
desc = "Heavenly robes of the kitsune Luna Pumpkin,you can feel radiance coming from them."
|
||||
item_state = "Divine_robes"
|
||||
icon_state = "Divine_robes"
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/datum/map_template/ruin/lavaland/alien_nest
|
||||
name = "Alien Nest"
|
||||
id = "alien-nest"
|
||||
description = "Not even Necropolis is safe from alien infestation. The competition for hosts has locked the legion and aliens in an endless conflict that can only be resolved by a PKA."
|
||||
suffix = "lavaland_surface_alien_nest.dmm"
|
||||
cost = 20
|
||||
|
||||
//Aliens for the alien nest space ruin.
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/drone
|
||||
mob_type = /mob/living/carbon/alien/humanoid/drone
|
||||
death = TRUE
|
||||
name = "alien drone"
|
||||
mob_name = "alien drone"
|
||||
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/queen
|
||||
mob_type = /mob/living/carbon/alien/humanoid/royal/queen
|
||||
death = TRUE
|
||||
name = "alien queen"
|
||||
mob_name = "alien queen"
|
||||
|
||||
/obj/item/reagent_containers/syringe/alien
|
||||
name = "Hive's Blessing"
|
||||
desc = "A syringe filled with a strange viscous liquid. It might be best to leave it alone."
|
||||
amount_per_transfer_from_this = 1
|
||||
volume = 1
|
||||
list_reagents = list("xenomicrobes" = 1)
|
||||
@@ -426,6 +426,7 @@
|
||||
|
||||
/datum/sprite_accessory/mam_tails
|
||||
icon = 'modular_citadel/icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/none
|
||||
name = "None"
|
||||
|
||||
@@ -1430,3 +1431,224 @@ datum/sprite_accessory/mam_tails/tentacle
|
||||
extra = FALSE
|
||||
extra2 = FALSE
|
||||
ckeys_allowed = list("poojawa")
|
||||
|
||||
|
||||
//Lunasune
|
||||
/datum/sprite_accessory/mam_ears/lunasune
|
||||
name = "lunasune"
|
||||
icon_state = "lunasune"
|
||||
hasinner = 1
|
||||
extra = TRUE
|
||||
extra_color_src = MUTCOLORS2
|
||||
ckeys_allowed = list("invader4352")
|
||||
|
||||
/datum/sprite_accessory/mam_tails/lunasune
|
||||
name = "lunasune"
|
||||
icon_state = "lunasune"
|
||||
extra = TRUE
|
||||
ckeys_allowed = list("invader4352")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/lunasune
|
||||
name = "lunasune"
|
||||
icon_state = "lunasune"
|
||||
extra = TRUE
|
||||
|
||||
/*************** VIRGO PORTED HAIRS ****************************/
|
||||
#define VHAIR(_name, new_state) /datum/sprite_accessory/hair/##new_state/icon_state=#new_state;/datum/sprite_accessory/hair/##new_state/name = "Virgo - " + #_name
|
||||
//VIRGO PORTED HAIRS
|
||||
VHAIR(Short Hair Rosa, hair_rosa_s)
|
||||
VHAIR(Short Hair 80s, hair_80s_s)
|
||||
VHAIR(Long Bedhead, hair_long_bedhead_s)
|
||||
VHAIR(Dave, hair_dave_s)
|
||||
VHAIR(Country, hair_country_s)
|
||||
VHAIR(Shy, hair_shy_s)
|
||||
VHAIR(Unshaven Mohawk, hair_unshaven_mohawk_s)
|
||||
VHAIR(Manbun, hair_manbun_s)
|
||||
VHAIR(Longer Bedhead, hair_longer_bedhead_s)
|
||||
VHAIR(Ponytail, hair_ponytail_s)
|
||||
VHAIR(Ziegler, hair_ziegler_s)
|
||||
VHAIR(Emo Fringe, hair_emofringe_s)
|
||||
VHAIR(Very Short Over Eye Alt, hair_veryshortovereyealternate_s)
|
||||
VHAIR(Shorthime, hair_shorthime_s)
|
||||
VHAIR(High Tight, hair_hightight_s)
|
||||
VHAIR(Thinning Front, hair_thinningfront_s)
|
||||
VHAIR(Big Afro, hair_bigafro_s)
|
||||
VHAIR(Afro, hair_afro_s)
|
||||
VHAIR(High Braid, hair_hbraid_s)
|
||||
VHAIR(Braid, hair_braid_s)
|
||||
VHAIR(Sargeant, hair_sargeant_s)
|
||||
VHAIR(Gelled, hair_gelled_s)
|
||||
VHAIR(Kagami, hair_kagami_s)
|
||||
VHAIR(ShortTail, hair_stail_s)
|
||||
VHAIR(Gentle, hair_gentle_s)
|
||||
VHAIR(Grande, hair_grande_s)
|
||||
VHAIR(Bobcurl, hair_bobcurl_s)
|
||||
VHAIR(Pompadeur, hair_pompadour_s)
|
||||
VHAIR(Plait, hair_plait_s)
|
||||
VHAIR(Long, hair_long_s)
|
||||
VHAIR(Rattail, hair_rattail_s)
|
||||
VHAIR(Tajspiky, hair_tajspiky_s)
|
||||
VHAIR(Messy, hair_messy_s)
|
||||
VHAIR(Bangs, hair_bangs_s)
|
||||
VHAIR(TBraid, hair_tbraid_s)
|
||||
VHAIR(Toriyama2, hair_toriyama2_s)
|
||||
VHAIR(CIA, hair_cia_s)
|
||||
VHAIR(Mulder, hair_mulder_s)
|
||||
VHAIR(Scully, hair_scully_s)
|
||||
VHAIR(Nitori, hair_nitori_s)
|
||||
VHAIR(Joestar, hair_joestar_s)
|
||||
VHAIR(Ponytail4, hair_ponytail4_s)
|
||||
VHAIR(Ponytail5, hair_ponytail5_s)
|
||||
VHAIR(Beehive2, hair_beehive2_s)
|
||||
VHAIR(Short Braid, hair_shortbraid_s)
|
||||
VHAIR(Reverse Mohawk, hair_reversemohawk_s)
|
||||
VHAIR(SHort Bangs, hair_shortbangs_s)
|
||||
VHAIR(Half Shaved, hair_halfshaved_s)
|
||||
VHAIR(Longer Alt 2, hair_longeralt2_s)
|
||||
VHAIR(Bun, hair_bun_s)
|
||||
VHAIR(Curly, hair_curly_s)
|
||||
VHAIR(Victory, hair_victory_s)
|
||||
VHAIR(Ponytail6, hair_ponytail6_s)
|
||||
VHAIR(Undercut3, hair_undercut3_s)
|
||||
VHAIR(Bobcut Alt, hair_bobcultalt_s)
|
||||
VHAIR(Fingerwave, hair_fingerwave_s)
|
||||
VHAIR(Oxton, hair_oxton_s)
|
||||
VHAIR(Poofy2, hair_poofy2_s)
|
||||
VHAIR(Fringe Tail, hair_fringetail_s)
|
||||
VHAIR(Bun3, hair_bun3_s)
|
||||
VHAIR(Wisp, hair_wisp_s)
|
||||
VHAIR(Undercut2, hair_undercut2_s)
|
||||
VHAIR(TBob, hair_tbob_s)
|
||||
VHAIR(Spiky Ponytail, hair_spikyponytail_s)
|
||||
VHAIR(Rowbun, hair_rowbun_s)
|
||||
VHAIR(Rowdualtail, hair_rowdualtail_s)
|
||||
VHAIR(Rowbraid, hair_rowbraid_s)
|
||||
VHAIR(Shaved Mohawk, hair_shavedmohawk_s)
|
||||
VHAIR(Topknot, hair_topknot_s)
|
||||
VHAIR(Ronin, hair_ronin_s)
|
||||
VHAIR(Bowlcut2, hair_bowlcut2_s)
|
||||
VHAIR(Thinning Rear, hair_thinningrear_s)
|
||||
VHAIR(Thinning, hair_thinning_s)
|
||||
VHAIR(Jade, hair_jade_s)
|
||||
VHAIR(Bedhead, hair_bedhead_s)
|
||||
VHAIR(Dreadlocks, hair_dreads_s)
|
||||
VHAIR(Very Long, hair_vlong_s)
|
||||
VHAIR(Jensen, hair_jensen_s)
|
||||
VHAIR(Halfbang, hair_halfbang_s)
|
||||
VHAIR(Kusangi, hair_kusangi_s)
|
||||
VHAIR(Ponytail, hair_ponytail_s)
|
||||
VHAIR(Ponytail3, hair_ponytail3_s)
|
||||
VHAIR(Halfbang Alt, hair_halfbang_alt_s)
|
||||
VHAIR(Bedhead V2, hair_bedheadv2_s)
|
||||
VHAIR(Long Fringe, hair_longfringe_s)
|
||||
VHAIR(Flair, hair_flair_s)
|
||||
VHAIR(Bedhead V3, hair_bedheadv3_s)
|
||||
VHAIR(Himecut, hair_himecut_s)
|
||||
VHAIR(Curls, hair_curls_s)
|
||||
VHAIR(Very Long Fringe, hair_vlongfringe_s)
|
||||
VHAIR(Longest, hair_longest_s)
|
||||
VHAIR(Father, hair_father_s)
|
||||
VHAIR(Emo Long, hair_emolong_s)
|
||||
VHAIR(Short Hair 3, hair_shorthair3_s)
|
||||
VHAIR(Double Bun, hair_doublebun_s)
|
||||
VHAIR(Sleeze, hair_sleeze_s)
|
||||
VHAIR(Twintail, hair_twintail_s)
|
||||
VHAIR(Emo 2, hair_emo2_s)
|
||||
VHAIR(Low Fade, hair_lowfade_s)
|
||||
VHAIR(Med Fade, hair_medfade_s)
|
||||
VHAIR(High Fade, hair_highfade_s)
|
||||
VHAIR(Bald Fade, hair_baldfade_s)
|
||||
VHAIR(No Fade, hair_nofade_s)
|
||||
VHAIR(Trim Flat, hair_trimflat_s)
|
||||
VHAIR(Shaved, hair_shaved_s)
|
||||
VHAIR(Trimmed, hair_trimmed_s)
|
||||
VHAIR(Tight Bun, hair_tightbun_s)
|
||||
VHAIR(Short Hair 4, hair_d_s)
|
||||
VHAIR(Short Hair 5, hair_e_s)
|
||||
VHAIR(Short Hair 6, hair_f_s)
|
||||
VHAIR(Skinhead, hair_skinhead_s)
|
||||
VHAIR(Afro2, hair_afro2_s)
|
||||
VHAIR(Bobcut, hair_bobcut_s)
|
||||
VHAIR(Emo, hair_emo_s)
|
||||
VHAIR(Long Over Eye, hair_longovereye_s)
|
||||
VHAIR(Feather, hair_feather_s)
|
||||
VHAIR(Hitop, hair_hitop_s)
|
||||
VHAIR(Short Over Eye, hair_shortoverye_s)
|
||||
VHAIR(Straight, hair_straight_s)
|
||||
VHAIR(Buzzcut, hair_buzzcut_s)
|
||||
VHAIR(Combover, hair_combover_s)
|
||||
VHAIR(Crewcut, hair_crewcut_s)
|
||||
VHAIR(Devillock, hair_devilock_s)
|
||||
VHAIR(Clean, hair_clean_s)
|
||||
VHAIR(Shaggy, hair_shaggy_s)
|
||||
VHAIR(Updo, hair_updo_s)
|
||||
VHAIR(Mohawk, hair_mohawk_s)
|
||||
VHAIR(Odango, hair_odango_s)
|
||||
VHAIR(Ombre, hair_ombre_s)
|
||||
VHAIR(Parted, hair_parted_s)
|
||||
VHAIR(Quiff, hair_quiff_s)
|
||||
VHAIR(Volaju, hair_volaju_s)
|
||||
VHAIR(Bun2, hair_bun2_s)
|
||||
VHAIR(Rows1, hair_rows1_s)
|
||||
VHAIR(Rows2, hair_rows2_s)
|
||||
VHAIR(Dandy Pompadour, hair_dandypompadour_s)
|
||||
VHAIR(Poofy, hair_poofy_s)
|
||||
VHAIR(Toriyama, hair_toriyama_s)
|
||||
VHAIR(Drillruru, hair_drillruru_s)
|
||||
VHAIR(Bowlcut, hair_bowlcut_s)
|
||||
VHAIR(Coffee House, hair_coffeehouse_s)
|
||||
VHAIR(Family Man, hair_thefamilyman_s)
|
||||
VHAIR(Shaved Part, hair_shavedpart_s)
|
||||
VHAIR(Modern, hair_modern_s)
|
||||
VHAIR(One Shoulder, hair_oneshoulder_s)
|
||||
VHAIR(Very Short Over Eye, hair_veryshortovereye_s)
|
||||
VHAIR(Unkept, hair_unkept_s)
|
||||
VHAIR(Wife, hair_wife_s)
|
||||
VHAIR(Nia, hair_nia_s)
|
||||
VHAIR(Undercut, hair_undercut_s)
|
||||
VHAIR(Bobcut Alt, hair_bobcutalt_s)
|
||||
VHAIR(Short Hair 4 alt, hair_shorthair4_s)
|
||||
VHAIR(Tressshoulder, hair_tressshoulder_s)
|
||||
//END
|
||||
#undef VHAIR
|
||||
|
||||
#define VFACE(_name, new_state) /datum/sprite_accessory/facial_hair/##new_state/icon_state=#new_state;;/datum/sprite_accessory/facial_hair/##new_state/name="Virgo" + #_name
|
||||
VFACE(Watson, facial_watson_s)
|
||||
VFACE(Chaplin, facial_chaplin_s)
|
||||
VFACE(Fullbeard, facial_fullbeard_s)
|
||||
VFACE(Vandyke, facial_vandyke_s)
|
||||
VFACE(Elvis, facial_elvis_s)
|
||||
VFACE(Abe, facial_abe_s)
|
||||
VFACE(Chin, facial_chin_s)
|
||||
VFACE(GT, facial_gt_s)
|
||||
VFACE(Hip, facial_hip_s)
|
||||
VFACE(Hogan, facial_hogan_s)
|
||||
VFACE(Selleck, facial_selleck_s)
|
||||
VFACE(Neckbeard, facial_neckbeard_s)
|
||||
VFACE(Longbeard, facial_longbeard_s)
|
||||
VFACE(Dwarf, facial_dwarf_s)
|
||||
VFACE(Sideburn, facial_sideburn_s)
|
||||
VFACE(Mutton, facial_mutton_s)
|
||||
VFACE(Moustache, facial_moustache_s)
|
||||
VFACE(Pencilstache, facial_pencilstache_s)
|
||||
VFACE(Goatee, facial_goatee_s)
|
||||
VFACE(Smallstache, facial_smallstache_s)
|
||||
VFACE(Volaju, facial_volaju_s)
|
||||
VFACE(3 O\'clock, facial_3oclock_s)
|
||||
VFACE(5 O\'clock, facial_5oclock_s)
|
||||
VFACE(7 O\'clock, facial_7oclock_s)
|
||||
VFACE(5 O\'clock Moustache, facial_5oclockmoustache_s)
|
||||
VFACE(7 O\'clock, facial_7oclockmoustache_s)
|
||||
VFACE(Walrus, facial_walrus_s)
|
||||
VFACE(Muttonmus, facial_muttonmus_s)
|
||||
VFACE(Wise, facial_wise_s)
|
||||
VFACE(Martial Artist, facial_martialartist_s)
|
||||
VFACE(Dorsalfnil, facial_dorsalfnil_s)
|
||||
VFACE(Hornadorns, facial_hornadorns_s)
|
||||
VFACE(Spike, facial_spike_s)
|
||||
VFACE(Chinhorns, facial_chinhorns_s)
|
||||
VFACE(Cropped Fullbeard, facial_croppedfullbeard_s)
|
||||
VFACE(Chinless Beard, facial_chinlessbeard_s)
|
||||
VFACE(Moonshiner, facial_moonshiner_s)
|
||||
VFACE(Tribearder, facial_tribearder_s)
|
||||
#undef VFACE
|
||||
@@ -0,0 +1,42 @@
|
||||
/mob/living/carbon/human/species/mammal
|
||||
race = /datum/species/mammal
|
||||
|
||||
/mob/living/carbon/human/species/avian
|
||||
race = /datum/species/avian
|
||||
|
||||
/mob/living/carbon/human/species/aquatic
|
||||
race = /datum/species/aquatic
|
||||
|
||||
/mob/living/carbon/human/species/insect
|
||||
race = /datum/species/insect
|
||||
|
||||
/mob/living/carbon/human/species/xeno
|
||||
race = /datum/species/xeno
|
||||
|
||||
/mob/living/carbon/human/resist()
|
||||
. = ..()
|
||||
if(wear_suit && wear_suit.breakouttime)//added in human cuff breakout proc
|
||||
return
|
||||
if(.)
|
||||
if(canmove && !on_fire)
|
||||
for(var/obj/item/bodypart/L in bodyparts)
|
||||
if(istype(L) && L.embedded_objects.len)
|
||||
for(var/obj/item/I in L.embedded_objects)
|
||||
if(istype(I) && I.w_class >= WEIGHT_CLASS_NORMAL) //minimum weight class to insta-ripout via resist
|
||||
remove_embedded_unsafe(L, I, src, 1.5) //forcefully call the remove embedded unsafe proc but with extra pain multiplier. if you want to remove it less painfully, examine and remove it carefully.
|
||||
return FALSE //Hands are occupied
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/remove_embedded_unsafe(obj/item/bodypart/L, obj/item/I, mob/user, painmul = 1)
|
||||
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
|
||||
return
|
||||
L.embedded_objects -= I
|
||||
L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class*painmul)//It hurts to rip it out, get surgery you dingus. And if you're ripping it out quickly via resist, it's gonna hurt even more
|
||||
I.forceMove(get_turf(src))
|
||||
user.put_in_hands(I)
|
||||
user.emote("scream")
|
||||
user.visible_message("[user] rips [I] out of [user.p_their()] [L.name]!","<span class='notice'>You remove [I] from your [L.name].</span>")
|
||||
if(!has_embedded_objects())
|
||||
clear_alert("embeddedobject")
|
||||
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "embedded")
|
||||
return
|
||||
@@ -9,7 +9,7 @@
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
|
||||
add_logs(M, H, "attempted to touch")
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return TRUE
|
||||
switch(M.a_intent)
|
||||
@@ -49,7 +49,7 @@
|
||||
"<span class='userdanger'>[user] has pushed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.apply_effect(40, EFFECT_KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
add_logs(user, target, "disarmed", " pushing them to the ground")
|
||||
log_combat(user, target, "disarmed", " pushing them to the ground")
|
||||
return
|
||||
|
||||
playsound(target, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
|
||||
+118
-15
@@ -5,7 +5,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "snout", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "body_markings" = "husky", "mam_tail" = "husky", "mam_ears" = "husky", "mam_body_markings" = "husky", "taur" = "None")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "snout" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
@@ -13,9 +13,34 @@
|
||||
liked_food = MEAT | FRIED
|
||||
disliked_food = TOXIC
|
||||
|
||||
//Curiosity killed the cat's wagging tail.
|
||||
/datum/species/mammal/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/mammal/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/mammal/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/mammal/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/mammal/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/mammal/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
|
||||
/datum/species/mammal/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
@@ -27,6 +52,7 @@
|
||||
/datum/species/mammal/on_species_loss(mob/living/carbon/human/C)
|
||||
C.draw_citadel_parts(TRUE)
|
||||
. = ..()
|
||||
|
||||
//AVIAN//
|
||||
/datum/species/avian
|
||||
name = "Avian"
|
||||
@@ -36,7 +62,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings", "taur")
|
||||
default_features = list("snout" = "Sharp", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "snout" = "Beak", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk", "mam_tail" = "Hawk")
|
||||
attack_verb = "peck"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
@@ -45,7 +71,30 @@
|
||||
|
||||
/datum/species/avian/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/avian/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/avian/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/avian/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/avian/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/avian/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/avian/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
@@ -66,7 +115,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark", "mam_body_markings" = "None", "mam_ears" = "None")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "Shark", "mam_body_markings" = "Shark", "mam_ears" = "None", "snout" = "Round")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
@@ -76,7 +125,30 @@
|
||||
|
||||
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/aquatic/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/aquatic/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/aquatic/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/aquatic/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/aquatic/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/aquatic/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
@@ -97,7 +169,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "taur", "moth_wings")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "moth", "mam_tail" = "None", "mam_ears" = "None", "moth_wings" = "None")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "Moth", "mam_tail" = "None", "mam_ears" = "None", "moth_wings" = "Plain", "snout" = "None")
|
||||
attack_verb = "flutter" //wat?
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
@@ -106,7 +178,30 @@
|
||||
|
||||
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/insect/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/insect/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/insect/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/insect/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/insect/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/insect/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
@@ -122,14 +217,14 @@
|
||||
//Alien//
|
||||
/datum/species/xeno
|
||||
// A cloning mistake, crossing human and xenomorph DNA
|
||||
name = "xeno"
|
||||
name = "Xeno Hybrid"
|
||||
id = "xeno"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "legs", "taur","mam_body_markings")
|
||||
default_features = list("xenotail"="xeno","xenohead"="standard","xenodorsal"="standard","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None","mam_body_markings" = "xeno")
|
||||
mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "taur", "mam_body_markings")
|
||||
default_features = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None","mam_body_markings" = "Xeno")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
@@ -139,12 +234,20 @@
|
||||
damage_overlay_type = "xeno"
|
||||
liked_food = MEAT
|
||||
|
||||
/datum/species/xeno/on_species_gain(mob/living/carbon/human/C)
|
||||
/datum/species/xeno/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
|
||||
C.draw_citadel_parts()
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Digitigrade Legs")
|
||||
species_traits += DIGITIGRADE
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(FALSE)
|
||||
. = ..()
|
||||
|
||||
/datum/species/xeno/on_species_loss(mob/living/carbon/human/C)
|
||||
/datum/species/xeno/on_species_loss(mob/living/carbon/human/C, datum/species/new_species)
|
||||
C.draw_citadel_parts(TRUE)
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Normal Legs")
|
||||
species_traits -= DIGITIGRADE
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(TRUE)
|
||||
. = ..()
|
||||
|
||||
//Praise the Omnissiah, A challange worthy of my skills - HS
|
||||
@@ -157,4 +260,4 @@
|
||||
no_vore = TRUE
|
||||
|
||||
/mob/living/carbon/human/vore
|
||||
devourable = TRUE
|
||||
devourable = TRUE
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
organ.forceMove(get_turf(H))
|
||||
qdel(organ)
|
||||
H.update_body()
|
||||
|
||||
|
||||
else if (select_alteration == "Ears")
|
||||
var/list/snowflake_ears_list = list("Normal" = null)
|
||||
for(var/path in GLOB.mam_ears_list)
|
||||
@@ -108,7 +108,7 @@
|
||||
if(new_ears)
|
||||
H.dna.features["mam_ears"] = new_ears
|
||||
H.update_body()
|
||||
|
||||
|
||||
else if (select_alteration == "Tail")
|
||||
var/list/snowflake_tails_list = list("Normal" = null)
|
||||
for(var/path in GLOB.mam_tails_list)
|
||||
@@ -124,7 +124,7 @@
|
||||
if(new_tail != "None")
|
||||
H.dna.features["taur"] = "None"
|
||||
H.update_body()
|
||||
|
||||
|
||||
else if (select_alteration == "Taur body")
|
||||
var/list/snowflake_taur_list = list("Normal" = null)
|
||||
for(var/path in GLOB.taur_list)
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(makesfootstepsounds)
|
||||
CitFootstep(newloc)
|
||||
pseudo_z_axis = newloc.get_fake_z()
|
||||
pixel_z = pseudo_z_axis
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
|
||||
..()
|
||||
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
|
||||
log_combat(user, A, "bit")
|
||||
|
||||
/obj/item/dogborg/jaws/small/attack_self(mob/user)
|
||||
var/mob/living/silicon/robot.R = user
|
||||
@@ -74,8 +75,8 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_inv_handcuffed(0)
|
||||
to_chat(user,"<span class='notice'>You handcuff [C].</span>")
|
||||
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
|
||||
add_logs(user, C, "handcuffed")
|
||||
playsound(loc, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE)
|
||||
log_combat(user, C, "handcuffed")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>You fail to handcuff [C]!</span>")
|
||||
|
||||
@@ -90,7 +91,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
flags_1 = CONDUCT_1
|
||||
force = 0
|
||||
throwforce = 0
|
||||
attack_verb = list("nuzzled", "nosed", "booped")
|
||||
attack_verb = list("nuzzles", "pushes", "boops")
|
||||
w_class = 1
|
||||
|
||||
/obj/item/analyzer/nose/attack_self(mob/user)
|
||||
@@ -151,8 +152,12 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens
|
||||
. = ..()
|
||||
|
||||
//Delivery
|
||||
/obj/item/analyzer/nose/afterattack(atom/target, mob/user)
|
||||
. = ..()
|
||||
do_attack_animation(target, null, src)
|
||||
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
|
||||
|
||||
//Delivery
|
||||
/obj/item/storage/bag/borgdelivery
|
||||
name = "fetching storage"
|
||||
desc = "Fetch the thing!"
|
||||
@@ -176,6 +181,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
icon_state = "synthtongue"
|
||||
hitsound = 'sound/effects/attackblob.ogg'
|
||||
cleanspeed = 80
|
||||
var/status = 0
|
||||
|
||||
/obj/item/soap/tongue/scrubpup
|
||||
cleanspeed = 25 //slightly faster than a mop.
|
||||
@@ -192,18 +198,22 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
|
||||
/obj/item/soap/tongue/attack_self(mob/user)
|
||||
var/mob/living/silicon/robot.R = user
|
||||
if(R.emagged)
|
||||
name = "hacked tongue of doom"
|
||||
desc = "Your tongue has been upgraded successfully. Congratulations."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "syndietongue"
|
||||
cleanspeed = 10 //(nerf'd)tator soap stat
|
||||
else
|
||||
name = "synthetic tongue"
|
||||
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "synthtongue"
|
||||
cleanspeed = initial(cleanspeed)
|
||||
if(R.cell && R.cell.charge > 100)
|
||||
if(R.emagged && status == 0)
|
||||
status = !status
|
||||
name = "energized tongue"
|
||||
desc = "Your tongue is energized for dangerously maximum efficency."
|
||||
icon_state = "syndietongue"
|
||||
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
|
||||
cleanspeed = 10 //(nerf'd)tator soap stat
|
||||
else
|
||||
status = 0
|
||||
name = "synthetic tongue"
|
||||
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
|
||||
icon_state = "synthtongue"
|
||||
cleanspeed = initial(cleanspeed)
|
||||
if(R.emagged)
|
||||
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
|
||||
@@ -223,77 +233,74 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
else if(isobj(target)) //hoo boy. danger zone man
|
||||
if(istype(target,/obj/item/trash))
|
||||
R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
|
||||
if(do_after(R, src.cleanspeed, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(target)
|
||||
R.cell.give(250)
|
||||
if(!do_after(R, src.cleanspeed, target = target))
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(target)
|
||||
R.cell.give(250)
|
||||
return
|
||||
if(istype(target,/obj/item/stock_parts/cell))
|
||||
R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
|
||||
if(do_after(R, 50, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
var/obj/item/stock_parts/cell.C = target
|
||||
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
|
||||
qdel(target)
|
||||
if(!do_after(R, 50, target = target))
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
var/obj/item/stock_parts/cell.C = target
|
||||
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
|
||||
qdel(target)
|
||||
return
|
||||
var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
|
||||
if(!I.anchored && R.emagged)
|
||||
R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
|
||||
if(do_after(R, 100, target = I)) //Nerf dat time yo
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. Even emags don't make you magically eat things at range.
|
||||
return //If they moved away, you can't eat them.
|
||||
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(I)
|
||||
R.cell.give(500)
|
||||
if(!do_after(R, 100, target = I)) //Nerf dat time yo
|
||||
return //If they moved away, you can't eat them.
|
||||
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(I)
|
||||
R.cell.give(500)
|
||||
return
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
if(do_after(R, src.cleanspeed, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't clean them.
|
||||
to_chat(R,"<span class='notice'>You clean \the [target.name].</span>")
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
|
||||
else if(ishuman(target))
|
||||
if(R.emagged)
|
||||
var/mob/living/L = target
|
||||
if(R.cell.charge <= 666)
|
||||
var/mob/living/L = target
|
||||
if(status == 0 && check_zone(R.zone_selected) == "head")
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
if(istype(L) && L.fire_stacks > 0)
|
||||
L.adjust_fire_stacks(-10)
|
||||
return
|
||||
else if(status == 0)
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
if(istype(L) && L.fire_stacks > 0)
|
||||
L.adjust_fire_stacks(-10)
|
||||
return
|
||||
else
|
||||
if(R.cell.charge <= 800)
|
||||
to_chat(R, "Insufficent Power!")
|
||||
return
|
||||
L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
|
||||
L.Knockdown(80)
|
||||
L.apply_effect(EFFECT_STUTTER, 4)
|
||||
L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \
|
||||
"<span class='userdanger'>[R] has shocked you with its tongue! You can feel the betrayal.</span>")
|
||||
"<span class='userdanger'>[R] has shocked you with its tongue!</span>")
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
R.cell.use(666)
|
||||
else
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [target]'s face!</span>", "<span class='notice'>You affectionally lick \the [target]'s face!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
var/mob/living/L = target
|
||||
if(istype(L) && L.fire_stacks > 0)
|
||||
L.adjust_fire_stacks(-10)
|
||||
return
|
||||
log_combat(R, L, "tongue stunned")
|
||||
|
||||
else if(istype(target, /obj/structure/window))
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
if(do_after(R, src.cleanspeed, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't clean them.
|
||||
to_chat(R, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
target.color = initial(target.color)
|
||||
if(do_after(user, src.cleanspeed, target = target))
|
||||
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
target.set_opacity(initial(target.opacity))
|
||||
else
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
if(do_after(R, src.cleanspeed, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't clean them.
|
||||
to_chat(R, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
if(do_after(user, src.cleanspeed, target = target))
|
||||
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
target.wash_cream()
|
||||
return
|
||||
|
||||
|
||||
@@ -385,6 +392,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
log_combat(src, L, "borg pounced")
|
||||
else
|
||||
Knockdown(45, 1, 1)
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
cyborg_pixel_offset = -16
|
||||
|
||||
/obj/item/robot_module/scrubpup
|
||||
name = "Janitor"
|
||||
name = "Scrub Pup"
|
||||
basic_modules = list(
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/analyzer/nose,
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
return
|
||||
|
||||
var/contained = vial.reagents.log_list()
|
||||
add_logs(user, L, "attemped to inject", src, addition="which had [contained]")
|
||||
log_combat(user, L, "attemped to inject", src, addition="which had [contained]")
|
||||
//Always log attemped injections for admins
|
||||
if(vial != null)
|
||||
switch(mode)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
// var/shrink_grow_size = 1 // This horribly named variable determines the minimum/maximum size it will shrink/grow prey to.
|
||||
var/silent = FALSE
|
||||
|
||||
var/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
|
||||
var/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
|
||||
var/transferchance = 0 // % Chance of prey being transferred to transfer location when resisting
|
||||
var/autotransferchance = 0 // % Chance of prey being autotransferred to transfer location
|
||||
var/autotransferwait = 10 // Time between trying to transfer.
|
||||
@@ -183,18 +183,24 @@
|
||||
var/atom/movable/AM = thing
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
var/mob/living/OW = owner
|
||||
if(L.absorbed && !include_absorbed)
|
||||
continue
|
||||
L.absorbed = FALSE
|
||||
L.stop_sound_channel(CHANNEL_PREYLOOP)
|
||||
L.cure_blind("belly_[REF(src)]")
|
||||
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
|
||||
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
|
||||
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
|
||||
AM.forceMove(destination) // Move the belly contents into the same location as belly's owner.
|
||||
count++
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
|
||||
playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
if(!silent)
|
||||
owner.visible_message("<font color='green'><b>[owner] expels everything from their [lowertext(name)]!</b></font>")
|
||||
items_preserved.Cut()
|
||||
owner.visible_message("<font color='green'><b>[owner] expels everything from their [lowertext(name)]!</b></font>")
|
||||
owner.update_icons()
|
||||
|
||||
return count
|
||||
@@ -218,6 +224,11 @@
|
||||
var/mob/living/OW = owner
|
||||
ML.stop_sound_channel(CHANNEL_PREYLOOP)
|
||||
ML.cure_blind("belly_[REF(src)]")
|
||||
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
|
||||
SEND_SIGNAL(ML, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
|
||||
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
|
||||
SEND_SIGNAL(ML, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
|
||||
|
||||
if(ML.absorbed)
|
||||
ML.absorbed = FALSE
|
||||
if(ishuman(M) && ishuman(OW))
|
||||
@@ -228,8 +239,8 @@
|
||||
if(P.absorbed)
|
||||
absorbed_count++
|
||||
Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
|
||||
|
||||
owner.visible_message("<font color='green'><b>[owner] expels [M] from their [lowertext(name)]!</b></font>")
|
||||
if(!silent)
|
||||
owner.visible_message("<font color='green'><b>[owner] expels [M] from their [lowertext(name)]!</b></font>")
|
||||
owner.update_icons()
|
||||
return TRUE
|
||||
|
||||
@@ -237,50 +248,55 @@
|
||||
// The purpose of this method is to avoid duplicate code, and ensure that all necessary
|
||||
// steps are taken.
|
||||
/obj/belly/proc/nom_mob(var/mob/prey, var/mob/user)
|
||||
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
|
||||
if(owner.stat == DEAD)
|
||||
return
|
||||
if (prey.buckled)
|
||||
prey.buckled.unbuckle_mob(prey,TRUE)
|
||||
|
||||
|
||||
if(!isbelly(prey.loc))
|
||||
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
|
||||
SEND_SIGNAL(prey, COMSIG_ADD_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
|
||||
else
|
||||
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
|
||||
SEND_SIGNAL(prey, COMSIG_CLEAR_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
|
||||
|
||||
prey.forceMove(src)
|
||||
prey.playsound_local(loc,preyloop,70,0, channel = CHANNEL_PREYLOOP)
|
||||
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
|
||||
if(!silent)
|
||||
prey.playsound_local(loc,preyloop,70,0, channel = CHANNEL_PREYLOOP)
|
||||
owner.updateVRPanel()
|
||||
|
||||
for(var/mob/living/M in contents)
|
||||
M.updateVRPanel()
|
||||
M.become_blind("belly_[REF(src)]")
|
||||
|
||||
|
||||
|
||||
// Setup the autotransfer checks if needed
|
||||
if(transferlocation && autotransferchance > 0)
|
||||
if(transferlocation != null && autotransferchance > 0)
|
||||
addtimer(CALLBACK(src, /obj/belly/.proc/check_autotransfer, prey), autotransferwait)
|
||||
|
||||
/obj/belly/proc/check_autotransfer(var/mob/prey)
|
||||
/obj/belly/proc/check_autotransfer(var/mob/prey, var/obj/belly/target)
|
||||
// Some sanity checks
|
||||
if(transferlocation && (autotransferchance > 0) && (prey in contents))
|
||||
if(prob(autotransferchance))
|
||||
// Double check transferlocation isn't insane
|
||||
if(verify_transferlocation())
|
||||
transfer_contents(prey, transferlocation)
|
||||
transfer_contents(prey, transferlocation)
|
||||
else
|
||||
// Didn't transfer, so wait before retrying
|
||||
addtimer(CALLBACK(src, /obj/belly/.proc/check_autotransfer, prey), autotransferwait)
|
||||
|
||||
/obj/belly/proc/verify_transferlocation()
|
||||
for(var/I in owner.vore_organs)
|
||||
var/obj/belly/B = owner.vore_organs[I]
|
||||
if(B == transferlocation)
|
||||
return TRUE
|
||||
|
||||
for(var/I in owner.vore_organs)
|
||||
var/obj/belly/B = owner.vore_organs[I]
|
||||
if(B == transferlocation)
|
||||
transferlocation = B
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Transfers contents from one belly to another
|
||||
/obj/belly/proc/transfer_contents(var/atom/movable/content, var/obj/belly/target, silent = FALSE)
|
||||
if(!(content in src) || !istype(target))
|
||||
return
|
||||
for(var/mob/living/M in contents)
|
||||
M.cure_blind("belly_[REF(src)]")
|
||||
target.nom_mob(content, target.owner)
|
||||
if(!silent)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
|
||||
playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
owner.updateVRPanel()
|
||||
for(var/mob/living/M in contents)
|
||||
M.updateVRPanel()
|
||||
|
||||
// Get the line that should show up in Examine message if the owner of this belly
|
||||
// is examined. By making this a proc, we not only take advantage of polymorphism,
|
||||
@@ -386,20 +402,9 @@
|
||||
if(!M.dropItemToGround(W))
|
||||
qdel(W)
|
||||
|
||||
/* //Reagent transfer //maybe someday
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/Pred = owner
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/Prey = M
|
||||
Prey.bloodstr.del_reagent("numbenzyme")
|
||||
Prey.bloodstr.trans_to_holder(Pred.bloodstr, Prey.bloodstr.total_volume, 0.5, TRUE) // Copy=TRUE because we're deleted anyway
|
||||
Prey.ingested.trans_to_holder(Pred.bloodstr, Prey.ingested.total_volume, 0.5, TRUE) // Therefore don't bother spending cpu
|
||||
Prey.touching.trans_to_holder(Pred.bloodstr, Prey.touching.total_volume, 0.5, TRUE) // On updating the prey's reagents
|
||||
else if(M.reagents)
|
||||
M.reagents.trans_to_holder(Pred.bloodstr, M.reagents.total_volume, 0.5, TRUE) */
|
||||
|
||||
// Delete the digested mob
|
||||
qdel(M)
|
||||
M.stop_sound_channel(CHANNEL_PREYLOOP)
|
||||
//Update owner
|
||||
owner.updateVRPanel()
|
||||
|
||||
@@ -409,19 +414,6 @@
|
||||
to_chat(M,"<span class='notice'>[owner]'s [lowertext(name)] absorbs your body, making you part of them.</span>")
|
||||
to_chat(owner,"<span class='notice'>Your [lowertext(name)] absorbs [M]'s body, making them part of you.</span>")
|
||||
|
||||
// Reagent sharing is neat, but eh. I'll figure it out later
|
||||
/* if(ishuman(M) && ishuman(owner))
|
||||
var/mob/living/carbon/human/Prey = M
|
||||
var/mob/living/carbon/human/Pred = owner
|
||||
//Reagent sharing for absorbed with pred - Copy so both pred and prey have these reagents.
|
||||
Prey.bloodstr.trans_to_holder(Pred.bloodstr, Prey.bloodstr.total_volume, copy = TRUE)
|
||||
Prey.ingested.trans_to_holder(Pred.bloodstr, Prey.ingested.total_volume, copy = TRUE)
|
||||
Prey.touching.trans_to_holder(Pred.bloodstr, Prey.touching.total_volume, copy = TRUE)
|
||||
// TODO - Find a way to make the absorbed prey share the effects with the pred.
|
||||
// Currently this is infeasible because reagent containers are designed to have a single my_atom, and we get
|
||||
// problems when A absorbs B, and then C absorbs A, resulting in B holding onto an invalid reagent container.
|
||||
*/
|
||||
//This is probably already the case, but for sub-prey, it won't be.
|
||||
if(M.loc != src)
|
||||
M.forceMove(src)
|
||||
|
||||
@@ -506,17 +498,17 @@
|
||||
to_chat(R,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
return
|
||||
else //failsafe to make sure people are able to struggle out. friendly ERP should be on help intent.
|
||||
else if(R.a_intent != INTENT_HELP) //failsafe to make sure people are able to struggle out. friendly ERP should be on help intent.
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of [lowertext(name)]. (This will take around [escapetime] seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
if(!do_mob(R,owner,escapetime))
|
||||
return
|
||||
release_specific_contents(R)
|
||||
return
|
||||
|
||||
for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
|
||||
M.show_message(struggle_outer_message, 1) // visible
|
||||
to_chat(R,struggle_user_message)
|
||||
else if (R.a_intent == INTENT_HELP)
|
||||
for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
|
||||
M.show_message(struggle_outer_message, 1) // visible
|
||||
to_chat(R,struggle_user_message)
|
||||
|
||||
if(!silent)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
@@ -572,20 +564,19 @@
|
||||
to_chat(owner,"<span class='warning'>Your prey appears to be unable to make any progress in escaping your [lowertext(name)].</span>")
|
||||
return
|
||||
|
||||
//Transfers contents from one belly to another
|
||||
/obj/belly/proc/transfer_contents(var/atom/movable/content, var/obj/belly/target, silent = FALSE)
|
||||
if(!(content in src) || !istype(target))
|
||||
return
|
||||
for(var/mob/living/M in contents)
|
||||
M.cure_blind("belly_[REF(src)]")
|
||||
target.nom_mob(content, target.owner)
|
||||
if(!silent)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
|
||||
playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
owner.updateVRPanel()
|
||||
for(var/mob/living/M in contents)
|
||||
M.updateVRPanel()
|
||||
/obj/belly/proc/get_mobs_and_objs_in_belly()
|
||||
var/list/see = list()
|
||||
var/list/belly_mobs = list()
|
||||
see["mobs"] = belly_mobs
|
||||
var/list/belly_objs = list()
|
||||
see["objs"] = belly_objs
|
||||
for(var/mob/living/L in loc.contents)
|
||||
belly_mobs |= L
|
||||
for(var/obj/O in loc.contents)
|
||||
belly_objs |= O
|
||||
|
||||
return see
|
||||
|
||||
|
||||
// Belly copies and then returns the copy
|
||||
// Needs to be updated for any var changes AND KEPT IN ORDER OF THE VARS ABOVE AS WELL!
|
||||
|
||||
@@ -21,6 +21,17 @@
|
||||
if(M.digestable || !(digest_mode == DM_DIGEST)) // don't give digesty messages to indigestible people
|
||||
to_chat(M,"<span class='notice'>[pick(EL)]</span>")
|
||||
|
||||
///////////////////// Prey Loop Refresh/hack //////////////////////
|
||||
for(var/mob/living/M in contents)
|
||||
if(isbelly(M.loc))
|
||||
if(world.time > M.next_preyloop)
|
||||
if(!silent)
|
||||
M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
|
||||
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
|
||||
M.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP)
|
||||
M.next_preyloop = world.time + 52 SECONDS
|
||||
|
||||
|
||||
/////////////////////////// Exit Early ////////////////////////////
|
||||
var/list/touchable_items = contents - items_preserved
|
||||
if(!length(touchable_items))
|
||||
@@ -168,7 +179,7 @@
|
||||
//because dragons need snowflake guts
|
||||
if(digest_mode == DM_DRAGON)
|
||||
for (var/mob/living/M in contents)
|
||||
if(prob(25))
|
||||
if(prob(55)) //if you're hearing this, you're a vore ho anyway.
|
||||
M.stop_sound_channel(CHANNEL_DIGEST)
|
||||
for(var/mob/H in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////// Mob Living /////////////////////
|
||||
/mob/living
|
||||
var/digestable = TRUE // Can the mob be digested inside a belly?
|
||||
var/digestable = FALSE // Can the mob be digested inside a belly?
|
||||
var/obj/belly/vore_selected // Default to no vore capability.
|
||||
var/list/vore_organs = list() // List of vore containers inside a mob
|
||||
var/devourable = FALSE // Can the mob be vored at all?
|
||||
@@ -10,6 +10,7 @@
|
||||
var/openpanel = 0 // Is the vore panel open?
|
||||
var/noisy = FALSE // tummies are rumbly?
|
||||
var/absorbed = FALSE //are we absorbed?
|
||||
var/next_preyloop
|
||||
|
||||
//
|
||||
// Hook for generic creation of stuff on new creatures
|
||||
@@ -24,7 +25,7 @@
|
||||
M.verbs += /mob/living/proc/insidePanel
|
||||
|
||||
//Tries to load prefs if a client is present otherwise gives freebie stomach
|
||||
spawn(20 SECONDS) // long delay because the server delays in its startup. just on the safe side.
|
||||
spawn(10 SECONDS) // long delay because the server delays in its startup. just on the safe side.
|
||||
M.init_vore()
|
||||
|
||||
//Return 1 to hook-caller
|
||||
@@ -132,21 +133,24 @@
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
|
||||
testing("[user] attempted to feed [prey] to [pred], via [lowertext(belly.name)] but it went wrong.")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(istype(pred, /mob/living/simple_animal/hostile/megafauna/dragon))
|
||||
if(isliving(prey) && !prey.Adjacent(pred))
|
||||
return FALSE
|
||||
|
||||
// The belly selected at the time of noms
|
||||
var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (at)"
|
||||
var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
/* //Final distance check. Time has passed, menus have come and gone. Can't use do_after adjacent because doesn't behave for held micros
|
||||
var/user_to_pred = get_dist(get_turf(user),get_turf(pred))
|
||||
var/user_to_prey = get_dist(get_turf(user),get_turf(prey)) */
|
||||
|
||||
// Prepare messages
|
||||
if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = text("<span class='warning'>[] starts to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
|
||||
success_msg = text("<span class='warning'>[] manages to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
|
||||
|
||||
if(!prey.Adjacent(user)) // let's doublecheck for sanity's sake.
|
||||
return FALSE
|
||||
|
||||
// Announce that we start the attempt!
|
||||
user.visible_message(attempt_msg)
|
||||
|
||||
@@ -161,8 +165,10 @@
|
||||
belly.nom_mob(prey, user)
|
||||
if (pred == user)
|
||||
message_admins("[key_name(pred)] ate [key_name(prey)].")
|
||||
log_attack("[key_name(pred)] ate [key_name(prey)]")
|
||||
pred.log_message("[key_name(pred)] ate [key_name(prey)].", LOG_ATTACK)
|
||||
prey.log_message("[key_name(prey)] was eaten by [key_name(pred)].", LOG_ATTACK)
|
||||
return TRUE
|
||||
|
||||
//
|
||||
// Master vore proc that actually does vore procedures
|
||||
//
|
||||
@@ -171,18 +177,16 @@
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
|
||||
testing("[user] attempted to feed [prey] to [pred], via [lowertext(belly.name)] but it went wrong.")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if (!prey.devourable)
|
||||
to_chat(user, "This can't be eaten!")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
// The belly selected at the time of noms
|
||||
var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (at)"
|
||||
var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
/* //Final distance check. Time has passed, menus have come and gone. Can't use do_after adjacent because doesn't behave for held micros
|
||||
var/user_to_pred = get_dist(get_turf(user),get_turf(pred))
|
||||
var/user_to_prey = get_dist(get_turf(user),get_turf(prey)) */
|
||||
|
||||
// Prepare messages
|
||||
if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = text("<span class='warning'>[] is attemping to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
|
||||
@@ -193,19 +197,19 @@
|
||||
|
||||
if(!prey.Adjacent(user)) // let's not even bother attempting it yet if they aren't next to us.
|
||||
return FALSE
|
||||
|
||||
|
||||
// Announce that we start the attempt!
|
||||
user.visible_message(attempt_msg)
|
||||
|
||||
// Now give the prey time to escape... return if they did
|
||||
var/swallow_time = delay || ishuman(prey) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
|
||||
|
||||
|
||||
if(!do_mob(src, user, swallow_time))
|
||||
return FALSE // Prey escaped (or user disabled) before timer expired.
|
||||
|
||||
if(!prey.Adjacent(user)) //double check'd just in case they moved during the timer and the do_mob didn't fail for whatever reason
|
||||
return FALSE
|
||||
|
||||
|
||||
// If we got this far, nom successful! Announce it!
|
||||
user.visible_message(success_msg)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(user)))
|
||||
@@ -214,7 +218,6 @@
|
||||
|
||||
// Actually shove prey into the belly.
|
||||
belly.nom_mob(prey, user)
|
||||
// user.update_icons()
|
||||
stop_pulling()
|
||||
|
||||
// Flavor handling
|
||||
@@ -230,10 +233,13 @@
|
||||
prey_braindead = 1
|
||||
if (pred == user)
|
||||
message_admins("[ADMIN_LOOKUPFLW(pred)] ate [ADMIN_LOOKUPFLW(prey)][!prey_braindead ? "" : " (BRAINDEAD)"][prey_stat ? " (DEAD/UNCONSCIOUS)" : ""].")
|
||||
log_attack("[key_name(pred)] ate [key_name(prey)]")
|
||||
pred.log_message("[key_name(pred)] ate [key_name(prey)].", LOG_ATTACK)
|
||||
prey.log_message("[key_name(prey)] was eaten by [key_name(pred)].", LOG_ATTACK)
|
||||
else
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] forced [ADMIN_LOOKUPFLW(pred)] to eat [ADMIN_LOOKUPFLW(prey)].")
|
||||
log_attack("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].")
|
||||
user.log_message("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].", LOG_ATTACK)
|
||||
pred.log_message("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].", LOG_ATTACK)
|
||||
prey.log_message("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].", LOG_ATTACK)
|
||||
return TRUE
|
||||
|
||||
//
|
||||
|
||||
@@ -39,7 +39,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
|
||||
/datum/vore_preferences
|
||||
//Actual preferences
|
||||
var/digestable = TRUE
|
||||
var/digestable = FALSE
|
||||
var/devourable = FALSE
|
||||
// var/allowmobvore = TRUE
|
||||
var/list/belly_prefs = list()
|
||||
@@ -113,7 +113,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
|
||||
//Quick sanitize
|
||||
if(isnull(digestable))
|
||||
digestable = TRUE
|
||||
digestable = FALSE
|
||||
if(isnull(devourable))
|
||||
devourable = FALSE
|
||||
if(isnull(belly_prefs))
|
||||
|
||||
@@ -711,15 +711,5 @@
|
||||
if(user.client.prefs_vr)
|
||||
user.client.prefs_vr.devourable = user.devourable
|
||||
|
||||
if(href_list["togglenoisy"])
|
||||
var/choice = alert(user, "Toggle audible hunger noises. Currently: [user.noisy ? "Enabled" : "Disabled"]", "", "Enable audible hunger", "Cancel", "Disable audible hunger")
|
||||
switch(choice)
|
||||
if("Cancel")
|
||||
return 0
|
||||
if("Enable audible hunger")
|
||||
user.noisy = TRUE
|
||||
if("Disable audible hunger")
|
||||
user.noisy = FALSE
|
||||
|
||||
//Refresh when interacted with, returning 1 makes vore_look.Topic update
|
||||
return 1
|
||||
Reference in New Issue
Block a user