Merge branch 'master' of https://github.com/PolarisSS13/Polaris into Slime_Rework_3

# Conflicts:
#	icons/mob/items/lefthand.dmi
#	icons/mob/items/righthand.dmi
This commit is contained in:
Datraen
2016-05-12 17:24:55 -04:00
265 changed files with 5101 additions and 2994 deletions

View File

@@ -1,12 +1,20 @@
datum/preferences
var/biological_gender = MALE
var/identifying_gender = MALE
datum/preferences/proc/set_biological_gender(var/gender)
biological_gender = gender
identifying_gender = gender
/datum/category_item/player_setup_item/general/basic
name = "Basic"
sort_order = 1
var/list/valid_player_genders = list(MALE, FEMALE, NEUTER, PLURAL)
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
S["real_name"] >> pref.real_name
S["name_is_always_random"] >> pref.be_random_name
S["gender"] >> pref.gender
S["gender"] >> pref.biological_gender
S["id_gender"] >> pref.identifying_gender
S["age"] >> pref.age
S["spawnpoint"] >> pref.spawnpoint
S["OOC_Notes"] >> pref.metadata
@@ -14,7 +22,8 @@
/datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S)
S["real_name"] << pref.real_name
S["name_is_always_random"] << pref.be_random_name
S["gender"] << pref.gender
S["gender"] << pref.biological_gender
S["id_gender"] << pref.identifying_gender
S["age"] << pref.age
S["spawnpoint"] << pref.spawnpoint
S["OOC_Notes"] << pref.metadata
@@ -22,27 +31,32 @@
/datum/category_item/player_setup_item/general/basic/sanitize_character()
if(!pref.species) pref.species = "Human"
var/datum/species/S = all_species[pref.species ? pref.species : "Human"]
pref.age = sanitize_integer(pref.age, S.min_age, S.max_age, initial(pref.age))
pref.gender = sanitize_inlist(pref.gender, valid_player_genders, pick(valid_player_genders))
pref.real_name = sanitize_name(pref.real_name, pref.species)
pref.age = sanitize_integer(pref.age, S.min_age, S.max_age, initial(pref.age))
pref.biological_gender = sanitize_inlist(pref.biological_gender, get_genders(), pick(get_genders()))
pref.identifying_gender = (pref.identifying_gender in all_genders_define_list) ? pref.identifying_gender : pref.biological_gender
pref.real_name = sanitize_name(pref.real_name, pref.species)
if(!pref.real_name)
pref.real_name = random_name(pref.gender, pref.species)
pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint))
pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name))
pref.real_name = random_name(pref.identifying_gender, pref.species)
pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint))
pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name))
/datum/category_item/player_setup_item/general/basic/content()
. = "<b>Name:</b> "
. = list()
. += "<b>Name:</b> "
. += "<a href='?src=\ref[src];rename=1'><b>[pref.real_name]</b></a><br>"
. += "(<a href='?src=\ref[src];random_name=1'>Random Name</A>) "
. += "(<a href='?src=\ref[src];always_random_name=1'>Always Random Name: [pref.be_random_name ? "Yes" : "No"]</a>)"
. += "<a href='?src=\ref[src];random_name=1'>Randomize Name</A><br>"
. += "<a href='?src=\ref[src];always_random_name=1'>Always Random Name: [pref.be_random_name ? "Yes" : "No"]</a>"
. += "<br>"
. += "<b>Gender:</b> <a href='?src=\ref[src];gender=1'><b>[capitalize(lowertext(pref.gender))]</b></a><br>"
. += "<b>Biological Gender:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Gender Identity:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
if(config.allow_Metadata)
. += "<b>OOC Notes:</b> <a href='?src=\ref[src];metadata=1'> Edit </a><br>"
. = jointext(.,null)
/datum/category_item/player_setup_item/general/basic/OnTopic(var/href,var/list/href_list, var/mob/user)
var/datum/species/S = all_species[pref.species]
if(href_list["rename"])
var/raw_name = input(user, "Choose your character's name:", "Character Name") as text|null
if (!isnull(raw_name) && CanUseTopic(user))
@@ -55,20 +69,27 @@
return TOPIC_NOACTION
else if(href_list["random_name"])
pref.real_name = random_name(pref.gender, pref.species)
pref.real_name = random_name(pref.identifying_gender, pref.species)
return TOPIC_REFRESH
else if(href_list["always_random_name"])
pref.be_random_name = !pref.be_random_name
return TOPIC_REFRESH
else if(href_list["gender"])
pref.gender = next_in_list(pref.gender, valid_player_genders)
else if(href_list["bio_gender"])
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
if(new_gender && CanUseTopic(user))
pref.set_biological_gender(new_gender)
return TOPIC_REFRESH
else if(href_list["id_gender"])
var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
if(new_gender && CanUseTopic(user))
pref.identifying_gender = new_gender
return TOPIC_REFRESH
else if(href_list["age"])
if(!pref.species) pref.species = "Human"
var/datum/species/S = all_species[pref.species]
var/new_age = input(user, "Choose your character's age:\n([S.min_age]-[S.max_age])", "Character Preference", pref.age) as num|null
if(new_age && CanUseTopic(user))
pref.age = max(min(round(text2num(new_age)), S.max_age), S.min_age)
@@ -76,8 +97,8 @@
else if(href_list["spawnpoint"])
var/list/spawnkeys = list()
for(var/S in spawntypes)
spawnkeys += S
for(var/spawntype in spawntypes)
spawnkeys += spawntype
var/choice = input(user, "Where would you like to spawn when late-joining?") as null|anything in spawnkeys
if(!choice || !spawntypes[choice] || !CanUseTopic(user)) return TOPIC_NOACTION
pref.spawnpoint = choice
@@ -90,3 +111,12 @@
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/general/basic/proc/get_genders()
var/datum/species/S = all_species[pref.species]
var/list/possible_genders = S.genders
if(!pref.organ_data || pref.organ_data[BP_TORSO] != "cyborg")
return possible_genders
possible_genders = possible_genders.Copy()
possible_genders |= NEUTER
return possible_genders

View File

@@ -73,6 +73,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(!pref.rlimb_data) pref.rlimb_data = list()
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
. = list()
pref.update_preview_icon()
if(pref.preview_icon_front && pref.preview_icon_side)
user << browse_rsc(pref.preview_icon_front, "preview_icon.png")
@@ -186,12 +187,13 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(has_flag(mob_species, HAS_SKIN_COLOR))
. += "<br><b>Body Color</b><br>"
. += "<a href='?src=\ref[src];skin_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_skin, 2)][num2hex(pref.g_skin, 2)][num2hex(pref.b_skin, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_skin, 2)][num2hex(pref.g_skin, 2)][num2hex(pref.b_skin)]'><tr><td>__</td></tr></table></font><br>"
. = jointext(.,null)
/datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag)
return mob_species && (mob_species.appearance_flags & flag)
/datum/category_item/player_setup_item/general/body/OnTopic(var/href,var/list/href_list, var/mob/user)
var/mob_species = all_species[pref.species]
var/datum/species/mob_species = all_species[pref.species]
if(href_list["random"])
pref.randomize_appearance_for()
@@ -220,13 +222,17 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/prev_species = pref.species
pref.species = href_list["set_species"]
if(prev_species != pref.species)
if(!(pref.biological_gender in mob_species.genders))
pref.set_biological_gender(mob_species.genders[1])
//grab one of the valid hair styles for the newly chosen species
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
if(pref.biological_gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
if(pref.biological_gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
continue
@@ -242,9 +248,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/valid_facialhairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
if(pref.biological_gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
if(pref.biological_gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
continue
@@ -336,9 +342,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/valid_facialhairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
if(pref.biological_gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
if(pref.biological_gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
continue
@@ -536,9 +542,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>"
dat += "<b>Language:</b> [current_species.language]<br/>"
dat += "<small>"
if(current_species.spawn_flags & CAN_JOIN)
if(current_species.spawn_flags & SPECIES_CAN_JOIN)
dat += "</br><b>Often present on human stations.</b>"
if(current_species.spawn_flags & IS_WHITELISTED)
if(current_species.spawn_flags & SPECIES_IS_WHITELISTED)
dat += "</br><b>Whitelist restricted.</b>"
if(!current_species.has_organ[O_HEART])
dat += "</br><b>Does not have a circulatory system.</b>"
@@ -566,9 +572,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/restricted = 0
if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
if(!(current_species.spawn_flags & CAN_JOIN))
if(!(current_species.spawn_flags & SPECIES_CAN_JOIN))
restricted = 2
else if((current_species.spawn_flags & IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),current_species))
else if((current_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),current_species))
restricted = 1
if(restricted)

View File

@@ -61,9 +61,9 @@
. += "<tr><td>[client_pref.description]: </td>"
if(pref_mob.is_preference_enabled(client_pref.key))
. += "<td><b>[client_pref.enabled_description]</b></td> <td><a href='?src=\ref[src];toggle_off=[client_pref.key]'>[client_pref.disabled_description]</a></td>"
. += "<td><span class='linkOn'><b>[client_pref.enabled_description]</b></span></td> <td><a href='?src=\ref[src];toggle_off=[client_pref.key]'>[client_pref.disabled_description]</a></td>"
else
. += "<td><a href='?src=\ref[src];toggle_on=[client_pref.key]'>[client_pref.enabled_description]</a></td> <td><b>[client_pref.disabled_description]</b></td>"
. += "<td><a href='?src=\ref[src];toggle_on=[client_pref.key]'>[client_pref.enabled_description]</a></td> <td><span class='linkOn'><b>[client_pref.disabled_description]</b></span></td>"
. += "</tr>"
. += "</table>"

View File

@@ -0,0 +1,38 @@
/datum/category_item/player_setup_item/player_global/ooc
name = "OOC"
sort_order = 5
/datum/category_item/player_setup_item/player_global/ooc/load_preferences(var/savefile/S)
S["ignored_players"] >> pref.ignored_players
/datum/category_item/player_setup_item/player_global/ooc/save_preferences(var/savefile/S)
S["ignored_players"] << pref.ignored_players
/datum/category_item/player_setup_item/player_global/ooc/sanitize_preferences()
if(isnull(pref.ignored_players))
pref.ignored_players = list()
/datum/category_item/player_setup_item/player_global/ooc/content(var/mob/user)
. += "<b>OOC:</b><br>"
. += "Ignored Players<br>"
for(var/ignored_player in pref.ignored_players)
. += "[ignored_player] (<a href='?src=\ref[src];unignore_player=[ignored_player]'>Unignore</a>)<br>"
. += "(<a href='?src=\ref[src];ignore_player=1'>Ignore Player</a>)"
/datum/category_item/player_setup_item/player_global/ooc/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["unignore_player"])
if(CanUseTopic(user))
pref.ignored_players -= href_list["unignore_player"]
return TOPIC_REFRESH
if(href_list["ignore_player"])
if(CanUseTopic(user))
var/player_to_ignore = input(user, "Who do you want to ignore?","Ignore") as null|text
if(player_to_ignore)
player_to_ignore = sanitize(ckey(player_to_ignore))
pref.ignored_players |= player_to_ignore
return TOPIC_REFRESH
return ..()

View File

@@ -82,6 +82,7 @@ var/list/gear_datums = list()
total_cost += G.cost
/datum/category_item/player_setup_item/loadout/content()
. = list()
var/total_cost = 0
if(pref.gear && pref.gear.len)
for(var/i = 1; i <= pref.gear.len; i++)
@@ -92,8 +93,8 @@ var/list/gear_datums = list()
var/fcolor = "#3366CC"
if(total_cost < MAX_GEAR_COST)
fcolor = "#E67300"
. += list()
. += "<table align = 'center' width = 500px>"
. += "<table align = 'center' width = 100%>"
. += "<tr><td colspan=3><center><b><font color = '[fcolor]'>[total_cost]/[MAX_GEAR_COST]</font> loadout points spent.</b> \[<a href='?src=\ref[src];clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
. += "<tr><td colspan=3><center><b>"
@@ -105,15 +106,18 @@ var/list/gear_datums = list()
else
. += " |"
if(category == current_tab)
. += " [category] "
. += " <span class='linkOn'>[category]</span> "
else
var/datum/loadout_category/LC = loadout_categories[category]
var/tcolor = "#3366CC"
var/make_orange = FALSE
for(var/thing in LC.gear)
if(thing in pref.gear)
tcolor = "#E67300"
make_orange = TRUE
break
. += " <a href='?src=\ref[src];select_category=[category]'><font color = '[tcolor]'>[category]</font></a> "
if(make_orange)
. += " <a href='?src=\ref[src];select_category=[category]'><font color = '#E67300'>[category]</font></a> "
else
. += " <a href='?src=\ref[src];select_category=[category]'>[category]</a> "
. += "</b></center></td></tr>"
var/datum/loadout_category/LC = loadout_categories[current_tab]
@@ -123,7 +127,7 @@ var/list/gear_datums = list()
for(var/gear_name in LC.gear)
var/datum/gear/G = LC.gear[gear_name]
var/ticked = (G.display_name in pref.gear)
. += "<tr style='vertical-align:top'><td width=25%><a href='?src=\ref[src];toggle_gear=[G.display_name]'><font color='[ticked ? "#E67300" : "#3366CC"]'>[G.display_name]</font></a></td>"
. += "<tr style='vertical-align:top;'><td width=25%><a style='white-space:normal;' [ticked ? "class='linkOn' " : ""]href='?src=\ref[src];toggle_gear=[html_encode(G.display_name)]'>[G.display_name]</a></td>"
. += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
. += "<td><font size=2><i>[G.description]</i></font></td></tr>"
if(ticked)
@@ -132,7 +136,7 @@ var/list/gear_datums = list()
. += " <a href='?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
. += "</td></tr>"
. += "</table>"
. = jointext(.)
. = jointext(., null)
/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/datum/gear/G)
. = pref.gear[G.display_name]

View File

@@ -136,6 +136,21 @@
path = /obj/item/clothing/accessory/storage/white_vest
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/brown_drop_pouches
display_name = "drop pouches, engineering"
path = /obj/item/clothing/accessory/storage/brown_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer")
/datum/gear/accessory/black_drop_pouches
display_name = "drop pouches, security"
path = /obj/item/clothing/accessory/storage/black_drop_pouches
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/accessory/white_drop_pouches
display_name = "drop pouches, medical"
path = /obj/item/clothing/accessory/storage/white_drop_pouches
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/webbing
display_name = "webbing, simple"
path = /obj/item/clothing/accessory/storage/webbing

View File

@@ -125,31 +125,31 @@
ponchos[initial(poncho.name)] = poncho
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(ponchos))
/datum/gear/suit/poncho/roles/security
/datum/gear/suit/roles/poncho/security
display_name = "poncho, security"
path = /obj/item/clothing/suit/poncho/roles/security
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer")
/datum/gear/suit/poncho/roles/medical
/datum/gear/suit/roles/poncho/medical
display_name = "poncho, medical"
path = /obj/item/clothing/suit/poncho/roles/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
/datum/gear/suit/poncho/roles/engineering
/datum/gear/suit/roles/poncho/engineering
display_name = "poncho, engineering"
path = /obj/item/clothing/suit/poncho/roles/engineering
allowed_roles = list("Chief Engineer","Atmospheric Technician", "Station Engineer")
/datum/gear/suit/poncho/roles/science
/datum/gear/suit/roles/poncho/science
display_name = "poncho, science"
path = /obj/item/clothing/suit/poncho/roles/science
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobotanist")
/datum/gear/suit/poncho/roles/cargo
/datum/gear/suit/roles/poncho/cargo
display_name = "poncho, cargo"
path = /obj/item/clothing/suit/poncho/roles/cargo
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -195,3 +195,52 @@
display_name = "forensics, red"
path = /obj/item/clothing/suit/storage/forensics/red
allowed_roles = list("Detective")
/datum/gear/suit/wintercoat
display_name = "winter coat"
path = /obj/item/clothing/suit/storage/hooded/wintercoat
/datum/gear/suit/wintercoat/captain
display_name = "winter coat, captain"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/captain
allowed_roles = list("Captain")
/datum/gear/suit/wintercoat/security
display_name = "winter coat, security"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/security
allowed_roles = list("Security Officer, Head of Security, Warden, Detective")
/datum/gear/suit/wintercoat/medical
display_name = "winter coat, medical"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
/datum/gear/suit/wintercoat/science
display_name = "winter coat, science"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/science
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobotanist")
/datum/gear/suit/wintercoat/engineering
display_name = "winter coat, engineering"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/engineering
allowed_roles = list("Chief Engineer","Atmospheric Technician", "Station Engineer")
/datum/gear/suit/wintercoat/atmos
display_name = "winter coat, atmospherics"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos
allowed_roles = list("Chief Engineer", "Atmospheric Technician")
/datum/gear/suit/wintercoat/hydro
display_name = "winter coat, hydroponics"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/hydro
allowed_roles = list("Botanist", "Xenobotanist")
/datum/gear/suit/wintercoat/cargo
display_name = "winter coat, cargo"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/cargo
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/suit/wintercoat/miner
display_name = "winter coat, mining"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/miner
allowed_roles = list("Shaft Miner")

View File

@@ -6,8 +6,15 @@
sort_category = "Uniforms and Casual Dress"
/datum/gear/uniform/cheongsam
display_name = "cheongsam, white"
path = /obj/item/clothing/under/cheongsam
display_name = "cheongsam selection"
/datum/gear/uniform/cheongsam/New()
..()
var/list/cheongasms = list()
for(var/cheongasm in typesof(/obj/item/clothing/under/cheongsam))
var/obj/item/clothing/under/cheongsam/cheongasm_type = cheongasm
cheongasms[initial(cheongasm_type.name)] = cheongasm_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cheongasms))
/datum/gear/uniform/kilt
display_name = "kilt"
@@ -329,4 +336,36 @@
/datum/gear/uniform/navyhossuit
display_name = "uniform, navy blue (Head of Security)"
path = /obj/item/clothing/under/rank/head_of_security/navyblue
allowed_roles = list("Head of Security")
allowed_roles = list("Head of Security")
/datum/gear/uniform/shortplaindress
display_name = "plain dress"
path = /obj/item/clothing/under/dress/white3
/datum/gear/uniform/shortplaindress/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/uniform/longdress
display_name = "long dress"
path = /obj/item/clothing/under/dress/white2
/datum/gear/uniform/longdress/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/uniform/longwidedress
display_name = "long wide dress"
path = /obj/item/clothing/under/dress/white4
/datum/gear/uniform/longwidedress/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/uniform/reddress
display_name = "red dress with belt"
path = /obj/item/clothing/under/dress/darkred
/datum/gear/uniform/whitewedding
display_name= "white wedding dress"
path = /obj/item/clothing/under/dress/white

View File

@@ -58,9 +58,10 @@
if(!job_master)
return
. = list()
. += "<tt><center>"
. += "<b>Choose occupation chances</b><br>Unavailable occupations are crossed out.<br>"
. += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
. += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more columns.
. += "<table width='100%' cellpadding='1' cellspacing='0'>"
var/index = -1
@@ -93,7 +94,7 @@
. += "<del>[rank]</del></td><td> \[MINIMUM CHARACTER AGE: [job.minimum_character_age]]</td></tr>"
continue
if((pref.job_civilian_low & ASSISTANT) && (rank != "Assistant"))
. += "<font color=orange>[rank]</font></td><td></td></tr>"
. += "<font color=grey>[rank]</font></td><td></td></tr>"
continue
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
. += "<b>[rank]</b>"
@@ -106,40 +107,39 @@
if(rank == "Assistant")//Assistant is special
if(pref.job_civilian_low & ASSISTANT)
. += " <font color=green>\[Yes]</font>"
. += " <font color=55cc55>\[Yes]</font>"
else
. += " <font color=red>\[No]</font>"
. += " <font color=black>\[No]</font>"
if(job.alt_titles) //Blatantly cloned from a few lines down.
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'>&nbsp</td><td><a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
. += "</a></td></tr>"
continue
if(pref.GetJobDepartment(job, 1) & job.flag)
. += " <font color=blue>\[High]</font>"
. += " <font color=55cc55>\[High]</font>"
else if(pref.GetJobDepartment(job, 2) & job.flag)
. += " <font color=green>\[Medium]</font>"
. += " <font color=eecc22>\[Medium]</font>"
else if(pref.GetJobDepartment(job, 3) & job.flag)
. += " <font color=orange>\[Low]</font>"
. += " <font color=cc5555>\[Low]</font>"
else
. += " <font color=red>\[NEVER]</font>"
. += " <font color=black>\[NEVER]</font>"
if(job.alt_titles)
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'>&nbsp</td><td><a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
. += "</a></td></tr>"
. += "</td'></tr></table>"
. += "</center></table>"
. += "</center></table><center>"
switch(pref.alternate_option)
if(GET_RANDOM_JOB)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=green>Get random job if preferences unavailable</font></a></u></center><br>"
. += "<u><a href='?src=\ref[src];job_alternative=1'>Get random job if preferences unavailable</a></u>"
if(BE_ASSISTANT)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=red>Be assistant if preference unavailable</font></a></u></center><br>"
. += "<u><a href='?src=\ref[src];job_alternative=1'>Be assistant if preference unavailable</a></u>"
if(RETURN_TO_LOBBY)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=purple>Return to lobby if preference unavailable</font></a></u></center><br>"
. += "<u><a href='?src=\ref[src];job_alternative=1'>Return to lobby if preference unavailable</a></u>"
. += "<center><a href='?src=\ref[src];reset_jobs=1'>\[Reset\]</a></center>"
. += "<a href='?src=\ref[src];reset_jobs=1'>\[Reset\]</a></center>"
. += "</tt>"
. = jointext(.,null)
/datum/category_item/player_setup_item/occupation/OnTopic(href, href_list, user)
if(href_list["reset_jobs"])

View File

@@ -19,6 +19,7 @@
if(pref.used_skillpoints < 0) pref.used_skillpoints = 0
/datum/category_item/player_setup_item/skills/content()
. = list()
. += "<b>Select your Skills</b><br>"
. += "Current skill level: <b>[pref.GetSkillClass(pref.used_skillpoints)]</b> ([pref.used_skillpoints])<br>"
. += "<a href='?src=\ref[src];preconfigured=1'>Use preconfigured skillset</a><br>"
@@ -30,16 +31,22 @@
var/level = pref.skills[S.ID]
. += "<tr style='text-align:left;'>"
. += "<th><a href='?src=\ref[src];skillinfo=\ref[S]'>[S.name]</a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_NONE]'><font color=[(level == SKILL_NONE) ? "red" : "black"]>\[Untrained\]</font></a></th>"
. += skill_to_button(S, "Untrained", level, SKILL_NONE)
// secondary skills don't have an amateur level
if(S.secondary)
. += "<th></th>"
else
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_BASIC]'><font color=[(level == SKILL_BASIC) ? "red" : "black"]>\[Amateur\]</font></a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_ADEPT]'><font color=[(level == SKILL_ADEPT) ? "red" : "black"]>\[Trained\]</font></a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_EXPERT]'><font color=[(level == SKILL_EXPERT) ? "red" : "black"]>\[Professional\]</font></a></th>"
. += skill_to_button(S, "Amateur", level, SKILL_BASIC)
. += skill_to_button(S, "Trained", level, SKILL_ADEPT)
. += skill_to_button(S, "Professional", level, SKILL_EXPERT)
. += "</tr>"
. += "</table>"
. = jointext(.,null)
/datum/category_item/player_setup_item/proc/skill_to_button(var/skill, var/level_name, var/current_level, var/selection_level)
if(current_level == selection_level)
return "<th><span class='linkOn'>[level_name]</span></th>"
return "<th><a href='?src=\ref[src];setskill=\ref[skill];newvalue=[selection_level]'>[level_name]</a></th>"
/datum/category_item/player_setup_item/skills/OnTopic(href, href_list, user)
if(href_list["skillinfo"])

View File

@@ -25,7 +25,6 @@ datum/preferences
//character preferences
var/real_name //our character's name
var/be_random_name = 0 //whether we are a random name every round
var/gender = MALE //gender of character (well duh)
var/age = 30 //age of character
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
var/b_type = "A+" //blood type (not-chooseable)
@@ -108,6 +107,7 @@ datum/preferences
// OOC Metadata:
var/metadata = ""
var/list/ignored_players = list()
var/client/client = null
var/client_ckey = null
@@ -116,11 +116,12 @@ datum/preferences
var/communicator_visibility = 0
var/datum/category_collection/player_setup_collection/player_setup
var/datum/browser/panel
/datum/preferences/New(client/C)
player_setup = new(src)
gender = pick(MALE, FEMALE)
real_name = random_name(gender,species)
set_biological_gender(pick(MALE, FEMALE))
real_name = random_name(identifying_gender,species)
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
gear = list()
@@ -211,7 +212,10 @@ datum/preferences
dat += player_setup.content(user)
dat += "</html></body>"
user << browse(dat, "window=preferences;size=635x736")
//user << browse(dat, "window=preferences;size=635x736")
var/datum/browser/popup = new(user, "Character Setup","Character Setup", 635, 736, src)
popup.set_content(dat)
popup.open()
/datum/preferences/proc/process_link(mob/user, list/href_list)
if(!user) return
@@ -254,7 +258,7 @@ datum/preferences
// Sanitizing rather than saving as someone might still be editing when copy_to occurs.
player_setup.sanitize_setup()
if(be_random_name)
real_name = random_name(gender,species)
real_name = random_name(identifying_gender,species)
if(config.humans_need_surnames)
var/firstspace = findtext(real_name, " ")
@@ -284,7 +288,8 @@ datum/preferences
character.gen_record = gen_record
character.exploit_record = exploit_record
character.gender = gender
character.gender = biological_gender
character.identifying_gender = identifying_gender
character.age = age
character.b_type = b_type
@@ -374,7 +379,11 @@ datum/preferences
dat += "<hr>"
dat += "</center></tt>"
user << browse(dat, "window=saves;size=300x390")
//user << browse(dat, "window=saves;size=300x390")
panel = new(user, "Character Slots", "Character Slots", 300, 390, src)
panel.set_content(dat)
panel.open()
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")
//user << browse(null, "window=saves")
panel.close()

View File

@@ -8,7 +8,7 @@
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear all mob speech as a ghost."
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear all mob speech as a ghost."
prefs.save_preferences()
@@ -23,7 +23,7 @@
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] see all emotes as a ghost."
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] see all emotes as a ghost."
prefs.save_preferences()
@@ -222,4 +222,4 @@
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive attack logs."
prefs.save_preferences()
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -9,6 +9,15 @@
"minimalist" = 'icons/mob/screen/minimalist.dmi'
)
/var/all_ui_styles_robot = list(
"Midnight" = 'icons/mob/screen1_robot.dmi',
"Orange" = 'icons/mob/screen1_robot.dmi',
"old" = 'icons/mob/screen1_robot.dmi',
"White" = 'icons/mob/screen1_robot.dmi',
"old-noborder" = 'icons/mob/screen1_robot.dmi',
"minimalist" = 'icons/mob/screen1_robot_minimalist.dmi'
)
/proc/ui_style2icon(ui_style)
if(ui_style in all_ui_styles)
return all_ui_styles[ui_style]
@@ -21,8 +30,9 @@
set desc = "Configure your user interface"
if(!ishuman(usr))
usr << "<span class='warning'>You must be human to use this verb.</span>"
return
if(!isrobot(usr))
usr << "<span class='warning'>You must be a human or a robot to use this verb.</span>"
return
var/UI_style_new = input(usr, "Select a style. White is recommended for customization") as null|anything in all_ui_styles
if(!UI_style_new) return
@@ -42,6 +52,8 @@
icons.Add(usr.radio_use_icon)
var/icon/ic = all_ui_styles[UI_style_new]
if(isrobot(usr))
ic = all_ui_styles_robot[UI_style_new]
for(var/obj/screen/I in icons)
if(I.name in list(I_HELP, I_HURT, I_DISARM, I_GRAB)) continue

View File

@@ -337,11 +337,11 @@
overlays |= light_overlay_cache["[light_overlay]_icon"]
// Generate and cache the on-mob icon, which is used in update_inv_head().
var/cache_key = "[light_overlay][H ? "_[H.species.get_bodytype()]" : ""]"
var/cache_key = "[light_overlay][H ? "_[H.species.get_bodytype(H)]" : ""]"
if(!light_overlay_cache[cache_key])
var/use_icon = 'icons/mob/light_overlays.dmi'
if(H && sprite_sheets[H.species.get_bodytype()])
use_icon = sprite_sheets[H.species.get_bodytype()]
if(H && sprite_sheets[H.species.get_bodytype(H)])
use_icon = sprite_sheets[H.species.get_bodytype(H)]
light_overlay_cache[cache_key] = image("icon" = use_icon, "icon_state" = "[light_overlay]")
if(H)
@@ -535,8 +535,8 @@
var/icon/under_icon
if(icon_override)
under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype()])
under_icon = sprite_sheets[H.species.get_bodytype()]
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else
@@ -558,8 +558,8 @@
var/icon/under_icon
if(icon_override)
under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype()])
under_icon = sprite_sheets[H.species.get_bodytype()]
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else

View File

@@ -449,8 +449,9 @@
drain_complete(H)
return
// Attempts to drain up to 40kW, determines this value from remaining cell capacity to ensure we don't drain too much..
var/to_drain = min(40000, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
// Attempts to drain up to 12.5*cell-capacity kW, determines this value from remaining cell capacity to ensure we don't drain too much.
// 1Ws/(12.5*CELLRATE) = 40s to charge
var/to_drain = min(12.5*holder.cell.maxcharge, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
var/target_drained = interfaced_with.drain_power(0,0,to_drain)
if(target_drained <= 0)
H << "<span class = 'danger'>Your power sink flashes a red light; there is no power left in [interfaced_with].</span>"
@@ -460,14 +461,14 @@
holder.cell.give(target_drained * CELLRATE)
total_power_drained += target_drained
return 1
return
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
if(M) M << "<font color='blue'><b>Total power drained:</b> [round(total_power_drained/1000)]kJ.</font>"
if(M) M << "<font color='blue'><b>Total power drained:</b> [round(total_power_drained*CELLRATE)] cell units.</font>"
else
if(M) M << "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [round(total_power_drained/1000)]kJ.</font>"
if(M) M << "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [round(total_power_drained*CELLRATE)] cell units.</font>"
interfaced_with.drain_power(0,1,0) // Damage the victim.
drain_loc = null

View File

@@ -67,7 +67,7 @@
name = "teleportation module"
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
icon_state = "teleporter"
use_power_cost = 40
use_power_cost = 200
redundant = 1
usable = 1
selectable = 1
@@ -97,8 +97,6 @@
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return 0
var/mob/living/carbon/human/H = holder.wearer
if(!istype(H.loc, /turf))
@@ -109,9 +107,13 @@
if(target)
T = get_turf(target)
else
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
T = get_teleport_loc(get_turf(H), H, 6, 1, 1, 1)
if(!T || T.density)
if(!T)
H << "<span class='warning'>No valid teleport target found.</span>"
return 0
if(T.density)
H << "<span class='warning'>You cannot teleport into solid walls.</span>"
return 0
@@ -127,6 +129,8 @@
H << "<span class='warning'>You cannot teleport to such a distant object.</span>"
return 0
if(!..()) return 0
phase_out(H,get_turf(H))
H.forceMove(T)
phase_in(H,get_turf(H))

View File

@@ -50,6 +50,7 @@
usable = 1
toggleable = 1
disruptive = 0
module_cooldown = 0
engage_string = "Cycle Visor Mode"
activate_string = "Enable Visor"

View File

@@ -472,8 +472,8 @@
var/species_icon = 'icons/mob/rig_back.dmi'
// Since setting mob_icon will override the species checks in
// update_inv_wear_suit(), handle species checks here.
if(wearer && sprite_sheets && sprite_sheets[wearer.species.get_bodytype()])
species_icon = sprite_sheets[wearer.species.get_bodytype()]
if(wearer && sprite_sheets && sprite_sheets[wearer.species.get_bodytype(wearer)])
species_icon = sprite_sheets[wearer.species.get_bodytype(wearer)]
mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]")
if(installed_modules.len)
@@ -495,6 +495,8 @@
return 1
if(istype(user))
if(!canremove)
return 1
if(malfunction_check(user))
return 0
if(user.back != src)

View File

@@ -9,7 +9,7 @@
offline_slowdown = 10
vision_restriction = 1
offline_vision_restriction = 2
chest_type = /obj/item/clothing/suit/space/rig
helm_type = /obj/item/clothing/head/helmet/space/rig/unathi
boot_type = /obj/item/clothing/shoes/magboots/rig/unathi
@@ -24,9 +24,10 @@
/obj/item/clothing/head/helmet/space/rig/unathi
species_restricted = list("Unathi")
force = 5
/obj/item/clothing/suit/space/rig/unathi
species_restricted = list("Unathi")
/obj/item/clothing/shoes/magboots/rig/unathi
species_restricted = list("Unathi")

View File

@@ -82,6 +82,7 @@
chest_type = /obj/item/clothing/suit/space/rig/light/ninja
glove_type = /obj/item/clothing/gloves/rig/light/ninja
cell_type = /obj/item/weapon/cell/hyper
req_access = list(access_syndicate)

View File

@@ -15,12 +15,14 @@
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi'
//Teshari have a general sprite sheet defined in modules/clothing/clothing.dm
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
"Teshari" = 'icons/obj/clothing/species/seromi/hats.dmi'
)
light_overlay = "helmet_light"
@@ -40,12 +42,14 @@
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi'
//Teshari have a general sprite sheet defined in modules/clothing/clothing.dm
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
"Teshari" = 'icons/obj/clothing/species/seromi/suits.dmi'
)
//Breach thresholds, should ideally be inherited by most (if not all) voidsuits.

View File

@@ -517,8 +517,8 @@
icon_closed = "cti_hoodie"
/obj/item/clothing/suit/storage/toggle/hoodie/mu
name = "mars university hoodie"
desc = "A warm, gray sweatshirt. It bears the letters ‘MU’ on the front, a lettering to the well-known public college, Mars University."
name = "mojave university hoodie"
desc = "A warm, gray sweatshirt. It bears the letters ‘MU’ on the front, a lettering to the well-known public college, Mojave University."
icon_state = "mu_hoodie"
item_state = "mu_hoodie"
icon_open = "mu_hoodie_open"

View File

@@ -68,6 +68,27 @@
icon_state = "vest_white"
slots = 5
/obj/item/clothing/accessory/storage/black_drop_pouches
name = "black drop pouches"
gender = PLURAL
desc = "Robust black synthcotton bags to hold whatever you need, but cannot hold in hands."
icon_state = "thigh_black"
slots = 5
/obj/item/clothing/accessory/storage/brown_drop_pouches
name = "black drop pouches"
gender = PLURAL
desc = "Worn brownish synthcotton bags to hold whatever you need, but cannot hold in hands."
icon_state = "thigh_brown"
slots = 5
/obj/item/clothing/accessory/storage/white_drop_pouches
name = "white drop pouches"
gender = PLURAL
desc = "Durable white synthcotton bags to hold whatever you need, but cannot hold in hands."
icon_state = "thigh_white"
slots = 5
/obj/item/clothing/accessory/storage/knifeharness
name = "decorated harness"
desc = "A heavily decorated harness of sinew and leather with two knife-loops."

View File

@@ -14,7 +14,7 @@
/obj/item/clothing/under/color/blackjumpskirt
name = "black jumpskirt"
desc = "A black jumpskirt, Sol size 0."
desc = "A slimming black jumpskirt."
icon_state = "blackjumpskirt"
item_state = "bl_suit"
worn_state = "blackjumpskirt"

View File

@@ -227,7 +227,6 @@
item_state = "hostrench"
flags_inv = 0
siemens_coefficient = 0.6
body_parts_covered = UPPER_TORSO|ARMS
/*
* Navy uniforms

View File

@@ -561,6 +561,27 @@
worn_state = "mai_yang"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS
/obj/item/clothing/under/cheongsam/red
name = "red cheongsam"
desc = "It is a red cheongsam dress."
icon_state = "cheongsam-red"
item_state = "cheongsam-red"
worn_state = "cheongsam-red"
/obj/item/clothing/under/cheongsam/blue
name = "blue cheongsam"
desc = "It is a blue cheongsam dress."
icon_state = "cheongsam-blue"
item_state = "cheongsam-blue"
worn_state = "cheongsam-blue"
/obj/item/clothing/under/cheongsam/black
name = "black cheongsam"
desc = "It is a black cheongsam dress."
icon_state = "cheongsam-black"
item_state = "cheongsam-black"
worn_state = "cheongsam-black"
/obj/item/clothing/under/blazer
name = "blue blazer"
desc = "A bold but yet conservative outfit, red corduroys, navy blazer and a tie."
@@ -608,4 +629,42 @@
desc = "How... minimalist."
icon_state = "gear_harness"
worn_state = "gear_harness"
body_parts_covered = 0
body_parts_covered = 0
/obj/item/clothing/under/dress/white
name = "white wedding dress"
desc = "A fancy white dress with a blue underdress."
icon_state = "whitedress1"
item_state = "whitedress1"
worn_state = "whitedress1"
flags_inv = HIDESHOES
/obj/item/clothing/under/dress/white2
name = "long dress"
desc = "A long dress."
icon_state = "whitedress2"
item_state = "whitedress2"
worn_state = "whitedress2"
flags_inv = HIDESHOES
/obj/item/clothing/under/dress/white3
name = "short dress"
desc = "A short, plain dress."
icon_state = "whitedress3"
item_state = "whitedress3"
worn_state = "whitedress3"
/obj/item/clothing/under/dress/white4
name = "long flared dress"
desc = "A long white dress that flares out at the bottom."
icon_state = "whitedress4"
item_state = "whitedress4"
worn_state = "whitedress4"
flags_inv = HIDESHOES
/obj/item/clothing/under/dress/darkred
name = "fancy dark red dress"
desc = "A short, red dress with a black belt. Fancy."
icon_state = "darkreddress"
item_state = "darkreddress"
worn_state = "darkreddress"

View File

@@ -11,7 +11,7 @@
icon_state = "jeansclassic"
/obj/item/clothing/under/pants/mustangjeans
name = "Must Hang jeans"
name = "must hang jeans"
desc = "Made in the finest space jeans factory this side of Alpha Centauri."
icon_state = "jeansmustang"
@@ -26,7 +26,7 @@
icon_state = "jeansgrey"
/obj/item/clothing/under/pants/youngfolksjeans
name = "Young Folks jeans"
name = "young folks jeans"
desc = "For those tired of boring old jeans. Relive the passion of your youth!"
icon_state = "jeansyoungfolks"
@@ -63,4 +63,71 @@
/obj/item/clothing/under/pants/camo
name = "camo pants"
desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station."
icon_state = "camopants"
icon_state = "camopants"
//Baggy Pants//
/obj/item/clothing/under/pants/baggy
name = "baggy jeans"
desc = "A nondescript pair of tough baggy blue jeans."
icon_state = "baggy_jeans"
/obj/item/clothing/under/pants/baggy/classicjeans
name = "baggy classic jeans"
desc = "You feel cooler already."
icon_state = "baggy_jeansclassic"
/obj/item/clothing/under/pants/baggy/mustangjeans
name = "maggy must hang jeans"
desc = "Made in the finest space jeans factory this side of Alpha Centauri."
icon_state = "baggy_jeansmustang"
/obj/item/clothing/under/pants/baggy/blackjeans
name = "baggy black jeans"
desc = "Only for those who can pull it off."
icon_state = "baggy_jeansblack"
/obj/item/clothing/under/pants/baggy/greyjeans
name = "baggy grey jeans"
desc = "Only for those who can pull it off."
icon_state = "baggy_jeansgrey"
/obj/item/clothing/under/pants/baggy/youngfolksjeans
name = "baggy young folks jeans"
desc = "For those tired of boring old jeans. Relive the passion of your youth!"
icon_state = "baggy_jeansyoungfolks"
/obj/item/clothing/under/pants/baggy/white
name = "baggy white pants"
desc = "Plain white pants. Boring."
icon_state = "baggy_whitepants"
/obj/item/clothing/under/pants/baggy/red
name = "baggy red pants"
desc = "Bright red pants. Overflowing with personality."
icon_state = "baggy_redpants"
/obj/item/clothing/under/pants/baggy/black
name = "baggy black pants"
desc = "These pants are dark, like your soul."
icon_state = "baggy_blackpants"
/obj/item/clothing/under/pants/baggy/tan
name = "baggy tan pants"
desc = "Some tan pants. You look like a white collar worker with these on."
icon_state = "baggy_tanpants"
/obj/item/clothing/under/pants/baggy/track
name = "baggy track pants"
desc = "A pair of track pants, for the athletic."
icon_state = "baggy_trackpants"
/obj/item/clothing/under/pants/baggy/khaki
name = "baggy khaki pants"
desc = "A pair of dust beige khaki pants."
icon_state = "baggy_khaki"
/obj/item/clothing/under/pants/baggy/camo
name = "baggy camo pants"
desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station."
icon_state = "baggy_camopants"

View File

@@ -6,6 +6,7 @@
icon_state = "dnaopen"
anchored = 1
density = 1
circuit = /obj/item/weapon/circuitboard/dna_analyzer
var/obj/item/weapon/forensics/swab/bloodsamp = null
var/closed = 0
@@ -15,6 +16,15 @@
var/last_process_worldtime = 0
var/report_num = 0
/obj/machinery/dnaforensics/map/New()
circuit = new circuit(src)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
RefreshParts()
/obj/machinery/dnaforensics/attackby(var/obj/item/W, mob/user as mob)
if(bloodsamp)
@@ -22,7 +32,13 @@
return
if(closed)
user << "<span class='warning'>Open the cover before inserting the sample.</span>"
if(!scanning)
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
else
user << "<span class='warning'>Open the cover before inserting the sample.</span>"
return
var/obj/item/weapon/forensics/swab/swab = W

View File

@@ -21,9 +21,11 @@
if(istype(W, /obj/item/weapon/spacecash/ewallet)) return 0
var/obj/item/weapon/spacecash/SC = W
SC.adjust_worth(src.worth)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/h_user = user
h_user.drop_from_inventory(src)
h_user.drop_from_inventory(SC)
h_user.put_in_hands(SC)
@@ -77,6 +79,7 @@
/obj/item/weapon/spacecash/attack_self()
var/amount = input(usr, "How many Thalers do you want to take? (0 to [src.worth])", "Take Money", 20) as num
amount = round(Clamp(amount, 0, src.worth))
if(!amount)
return
@@ -135,6 +138,7 @@
proc/spawn_money(var/sum, spawnloc, mob/living/carbon/human/human_user as mob)
var/obj/item/weapon/spacecash/SC = new (spawnloc)
SC.set_worth(sum)
if (ishuman(human_user) && !human_user.get_active_hand())
human_user.put_in_hands(SC)

View File

@@ -195,9 +195,8 @@ var/list/name_to_material
// General wall debris product placement.
// Not particularly necessary aside from snowflakey cult girders.
/material/proc/place_dismantled_product(var/turf/target,var/is_devastated)
for(var/x=1;x<(is_devastated?2:3);x++)
place_sheet(target)
/material/proc/place_dismantled_product(var/turf/target)
place_sheet(target)
// Debris product. Used ALL THE TIME.
/material/proc/place_sheet(var/turf/target)

View File

@@ -39,10 +39,10 @@
var/need_update_field = 0
var/need_player_check = 0
/obj/machinery/mining/drill/New()
/obj/machinery/mining/drill/map/New()
..()
circuit = new circuit(src)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
@@ -290,7 +290,7 @@
/obj/machinery/mining/brace/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/miningdrillbrace(src)

View File

@@ -16,7 +16,7 @@
if(prob(50))
new /obj/item/weapon/storage/backpack/industrial(src)
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
new /obj/item/weapon/storage/backpack/satchel/eng(src)
new /obj/item/device/radio/headset/headset_cargo(src)
new /obj/item/clothing/under/rank/miner(src)
new /obj/item/clothing/gloves/black(src)

View File

@@ -9,7 +9,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
/mob/observer/dead
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
icon = 'icons/mob/mob.dmi'
icon = 'icons/mob/ghost.dmi'
icon_state = "ghost"
layer = 4
stat = DEAD
@@ -35,6 +35,39 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
var/seedarkness = 1
incorporeal_move = 1
var/is_manifest = 0 //If set to 1, the ghost is able to whisper. Usually only set if a cultist drags them through the veil.
var/ghost_sprite = null
var/global/list/possible_ghost_sprites = list(
"Clear" = "blank",
"Green Blob" = "otherthing",
"Bland" = "ghost",
"Robed-B" = "ghost1",
"Robed-BAlt" = "ghost2",
"Corgi" = "ghostian",
"King" = "ghostking",
"Shade" = "shade",
"Hecate" = "ghost-narsie",
"Glowing Statue" = "armour",
"Artificer" = "artificer",
"Behemoth" = "behemoth",
"Harvester" = "harvester",
"Wraith" = "wraith",
"Viscerator" = "viscerator",
"Bats" = "bat",
"Red Robes" = "robe_red",
"Faithless" = "faithless",
"Shadowform" = "forgotten",
"Black Cat" = "blackcat",
"Dark Ethereal" = "bloodguardian",
"Holy Ethereal" = "lightguardian",
"Red Elemental" = "magicRed",
"Blue Elemental" = "magicBlue",
"Pink Elemental" = "magicPink",
"Orange Elemental" = "magicOrange",
"Green Elemental" = "magicGreen",
"Daemon" = "daemon"
)
/mob/observer/dead/New(mob/body)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER
@@ -155,6 +188,12 @@ Works together with spawning an observer, noted above.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
if(istype(loc, /obj/structure/morgue))
var/obj/structure/morgue/M = loc
M.update()
else if(istype(loc, /obj/structure/closet/body_bag))
var/obj/structure/closet/body_bag/B = loc
B.update()
if(ghost.client)
ghost.client.time_died_as_mouse = ghost.timeofdeath
if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
@@ -224,6 +263,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
mind.current.ajourn=0
mind.current.key = key
mind.current.teleop = null
if(istype(mind.current.loc, /obj/structure/morgue))
var/obj/structure/morgue/M = mind.current.loc
M.update(1)
else if(istype(mind.current.loc, /obj/structure/closet/body_bag))
var/obj/structure/closet/body_bag/B = mind.current.loc
B.update(1)
if(!admin_ghosted)
announce_ghost_joinleave(mind, 0, "They now occupy their body again.")
return 1
@@ -605,11 +650,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 1
/mob/observer/dead/proc/manifest(mob/user)
var/is_manifest = 0
is_manifest = 0
if(!is_manifest)
is_manifest = 1
verbs += /mob/observer/dead/proc/toggle_visibility
verbs += /mob/observer/dead/proc/ghost_whisper
src << "<font color='purple'>As you are now in the realm of the living, you can whisper to the living with the <b>Spectral Whisper</b> verb, inside the IC tab.</font>"
if(src.invisibility != 0)
user.visible_message( \
"<span class='warning'>\The [user] drags ghost, [src], to our plane of reality!</span>", \
@@ -741,3 +787,44 @@ mob/observer/dead/MayRespawn(var/feedback = 0)
if((!target) || (!ghost)) return
. = "<a href='byond://?src=\ref[ghost];track=\ref[target]'>follow</a>"
. += target.extra_ghost_link(ghost)
//Culted Ghosts
/mob/observer/dead/proc/ghost_whisper()
set name = "Spectral Whisper"
set category = "IC"
if(is_manifest) //Only able to whisper if it's hit with a tome.
var/list/options = list()
for(var/mob/living/Ms in view(src))
options += Ms
var/mob/living/M = input(src, "Select who to whisper to:", "Whisper to?", null) as null|mob in options
if(!M)
return 0
var/msg = sanitize(input(src, "Message:", "Spectral Whisper") as text|null)
if(msg)
log_say("SpectralWhisper: [key_name(usr)]->[M.key] : [msg]")
M << "<span class='warning'> You hear a strange, unidentifiable voice in your head... <font color='purple'>[msg]</font></span>"
src << "<span class='warning'> You said: '[msg]' to [M].</span>"
else
return
return 1
else
src << "<span class='danger'>You have not been pulled past the veil!</span>"
/mob/observer/dead/verb/choose_ghost_sprite()
set category = "Ghost"
set name = "Choose Sprite"
icon = 'icons/mob/ghost.dmi'
var/choice
var/finalized = "No"
while(finalized == "No" && src.client)
choice = input(usr,"What would you like to use for your ghost sprite?") as null|anything in possible_ghost_sprites
if(!choice) return
icon_state = possible_ghost_sprites[choice]
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
ghost_sprite = possible_ghost_sprites[choice]

View File

@@ -84,4 +84,7 @@
if(input)
log_emote("Ghost/[src.key] : [input]")
say_dead_direct(input, src)
if(!invisibility) //If the ghost is made visible by admins or cult. And to see if the ghost has toggled its own visibility, as well. -Mech
visible_message("<span class='deadsay'><B>[src]</B> [input]</span>")
else
say_dead_direct(input, src)

View File

@@ -138,7 +138,7 @@ var/list/holder_mob_icon_cache = list()
var/skin_colour = rgb(owner.r_skin, owner.g_skin, owner.b_skin)
var/hair_colour = rgb(owner.r_hair, owner.g_hair, owner.b_hair)
var/eye_colour = rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)
var/species_name = lowertext(owner.species.get_bodytype())
var/species_name = lowertext(owner.species.get_bodytype(owner))
for(var/cache_entry in generate_for_slots)
var/cache_key = "[owner.species]-[cache_entry]-[skin_colour]-[hair_colour]"

View File

@@ -24,7 +24,14 @@ var/list/slot_equipment_priority = list( \
//This proc is called whenever someone clicks an inventory ui slot.
/mob/proc/attack_ui(var/slot)
var/obj/item/W = get_active_hand()
if(istype(W))
var/obj/item/E = get_equipped_item(slot)
if (istype(E))
if(istype(W))
E.attackby(W,src)
else
E.attack_hand(src)
else
equip_to_slot_if_possible(W, slot)
/* Inventory manipulation */
@@ -44,6 +51,7 @@ var/list/slot_equipment_priority = list( \
if(!W.mob_can_equip(src, slot))
if(del_on_fail)
qdel(W)
else
if(!disable_warning)
src << "\red You are unable to equip that." //Only print if del_on_fail is false
@@ -176,6 +184,7 @@ var/list/slot_equipment_priority = list( \
break
return slot
//This differs from remove_from_mob() in that it checks if the item can be unequipped first.
/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress.
if(!(force || canUnEquip(I)))
@@ -183,6 +192,7 @@ var/list/slot_equipment_priority = list( \
drop_from_inventory(I)
return 1
//Attemps to remove an object on a mob.
/mob/proc/remove_from_mob(var/obj/O)
src.u_equip(O)

View File

@@ -158,7 +158,12 @@
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak(datum/language/speaking)
return (speaking.can_speak_special(src) && (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages))
//Prevents someone from speaking a null language.
if(speaking)
return (speaking.can_speak_special(src) && (universal_speak || (speaking && (speaking.flags & INNATE)) || speaking in src.languages))
else
log_debug("[src] attempted to speak a null language.")
return 0
/mob/proc/get_language_prefix()
if(client && client.prefs.language_prefixes && client.prefs.language_prefixes.len)

View File

@@ -22,6 +22,7 @@
var/obj/structure/reagent_dispensers/watertank/tank
/mob/living/bot/farmbot/New(var/newloc, var/newTank)
..(newloc)
if(!newTank)
@@ -29,6 +30,7 @@
tank = newTank
tank.forceMove(src)
/mob/living/bot/farmbot/attack_hand(var/mob/user as mob)
. = ..()
if(.)
@@ -105,10 +107,13 @@
else
icon_state = "farmbot[on]"
/mob/living/bot/farmbot/handleRegular()
if(emagged && prob(1))
flick("farmbot_broke", src)
/mob/living/bot/farmbot/handleAdjacentTarget()
UnarmedAttack(target)
@@ -148,11 +153,13 @@
/mob/living/bot/farmbot/UnarmedAttack(var/atom/A, var/proximity)
if(!..())
return
if(busy)
return
if(istype(A, /obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/T = A
var/t = confirmTarget(T)
switch(t)
if(0)
@@ -161,6 +168,7 @@
action = "water" // Needs a better one
update_icons()
visible_message("<span class='notice'>[src] starts [T.dead? "removing the plant from" : "harvesting"] \the [A].</span>")
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] [T.dead? "removes the plant from" : "harvests"] \the [A].</span>")
@@ -169,6 +177,7 @@
action = "water"
update_icons()
visible_message("<span class='notice'>[src] starts watering \the [A].</span>")
busy = 1
if(do_after(src, 30))
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
@@ -178,6 +187,7 @@
action = "hoe"
update_icons()
visible_message("<span class='notice'>[src] starts uprooting the weeds in \the [A].</span>")
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] uproots the weeds in \the [A].</span>")
@@ -186,10 +196,13 @@
action = "fertile"
update_icons()
visible_message("<span class='notice'>[src] starts fertilizing \the [A].</span>")
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] fertilizes \the [A].</span>")
T.reagents.add_reagent("ammonia", 10)
busy = 0
action = ""
update_icons()
@@ -200,19 +213,23 @@
action = "water"
update_icons()
visible_message("<span class='notice'>[src] starts refilling its tank from \the [A].</span>")
busy = 1
while(do_after(src, 10) && tank.reagents.total_volume < tank.reagents.maximum_volume)
tank.reagents.add_reagent("water", 10)
if(prob(5))
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
busy = 0
action = ""
update_icons()
visible_message("<span class='notice'>[src] finishes refilling its tank.</span>")
else if(emagged && ishuman(A))
var/action = pick("weed", "water")
busy = 1
spawn(50) // Some delay
busy = 0
switch(action)
if("weed")
@@ -225,6 +242,7 @@
A.attack_generic(src, 5, t)
if("water")
flick("farmbot_water", src)
visible_message("<span class='danger'>[src] splashes [A] with water!</span>")
tank.reagents.splash(A, 100)
@@ -249,6 +267,7 @@
qdel(src)
return
/mob/living/bot/farmbot/confirmTarget(var/atom/targ)
if(!..())
return 0
@@ -296,6 +315,7 @@
var/obj/tank
w_class = 3.0
/obj/item/weapon/farmbot_arm_assembly/New(var/newloc, var/theTank)
..(newloc)
if(!theTank) // If an admin spawned it, it won't have a watertank it, so lets make one for em!
@@ -309,7 +329,9 @@
..()
return
user << "You add the robot arm to [src]."
user.drop_from_inventory(S)
qdel(S)
@@ -321,6 +343,7 @@
build_step++
user << "You add the plant analyzer to [src]."
name = "farmbot assembly"
user.remove_from_mob(W)
qdel(W)
@@ -328,6 +351,7 @@
build_step++
user << "You add a bucket to [src]."
name = "farmbot assembly with bucket"
user.remove_from_mob(W)
qdel(W)
@@ -335,14 +359,17 @@
build_step++
user << "You add a minihoe to [src]."
name = "farmbot assembly with bucket and minihoe"
user.remove_from_mob(W)
qdel(W)
else if((isprox(W)) && (build_step == 3))
build_step++
user << "You complete the Farmbot! Beep boop."
var/mob/living/bot/farmbot/S = new /mob/living/bot/farmbot(get_turf(src), tank)
S.name = created_name
user.remove_from_mob(W)
qdel(W)
qdel(src)

View File

@@ -143,13 +143,13 @@
var/datum/species/current_species = all_species[current_species_name]
if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
if(!(current_species.spawn_flags & CAN_JOIN))
if(!(current_species.spawn_flags & SPECIES_CAN_JOIN))
continue
if(whitelist.len && !(current_species_name in whitelist))
continue
if(blacklist.len && (current_species_name in blacklist))
continue
if((current_species.spawn_flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name))
if((current_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name))
continue
valid_species += current_species_name
@@ -158,9 +158,9 @@
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
var/use_species = species.get_bodytype()
var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
if(H) use_species = H.species.get_bodytype()
if(H) use_species = H.species.get_bodytype(src)
var/list/valid_hairstyles = new()
for(var/hairstyle in hair_styles_list)
@@ -180,9 +180,9 @@
/mob/living/carbon/human/proc/generate_valid_facial_hairstyles()
var/use_species = species.get_bodytype()
var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
if(H) use_species = H.species.get_bodytype()
if(H) use_species = H.species.get_bodytype(src)
var/list/valid_facial_hairstyles = new()
for(var/facialhairstyle in facial_hair_styles_list)

View File

@@ -26,7 +26,7 @@
var/msg = "<span class='info'>*---------*\nThis is "
var/datum/gender/T = gender_datums[gender]
var/datum/gender/T = gender_datums[get_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
else
@@ -51,7 +51,12 @@
msg += ", <b><font color='#555555'>[use_gender]!</font></b>"
else if(species.name != "Human")
msg += ", <b><font color='[species.get_flesh_colour(src)]'>\a [species.name]!</font></b>"
msg += ", <b><font color='[species.get_flesh_colour(src)]'>\a [species.get_examine_name()]!</font></b>"
var/extra_species_text = species.get_additional_examine_text(src)
if(extra_species_text)
msg += "[extra_species_text]<br>"
msg += "<br>"
//uniform

View File

@@ -326,11 +326,19 @@
//Removed the horrible safety parameter. It was only being used by ninja code anyways.
//Now checks siemens_coefficient of the affected area by default
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null)
if(status_flags & GODMODE) return 0 //godmode
if (!def_zone)
def_zone = pick("l_hand", "r_hand")
if(species.siemens_coefficient == -1)
if(stored_shock_by_ref["\ref[src]"])
stored_shock_by_ref["\ref[src]"] += shock_damage
else
stored_shock_by_ref["\ref[src]"] = shock_damage
return
var/obj/item/organ/external/affected_organ = get_organ(check_zone(def_zone))
var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ)
@@ -1104,6 +1112,9 @@
if(species.holder_type)
holder_type = species.holder_type
if(!(gender in species.genders))
gender = species.genders[1]
icon_state = lowertext(species.name)
species.create_organs(src)

View File

@@ -92,7 +92,7 @@ emp_act
if (!def_zone)
return 1.0
var/siemens_coefficient = species.siemens_coefficient
var/siemens_coefficient = max(species.siemens_coefficient,0)
var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
for(var/obj/item/clothing/C in clothing_items)

View File

@@ -91,3 +91,5 @@
mob_bump_flag = HUMAN
mob_push_flags = ~HEAVY
mob_swap_flags = ~HEAVY
var/identifying_gender // In case the human identifies as another gender than it's biological

View File

@@ -55,6 +55,8 @@
sum += H.ear_protection
return sum
/mob/living/carbon/human/get_gender()
return identifying_gender ? identifying_gender : gender
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH

View File

@@ -267,7 +267,7 @@ This saves us from having to call add_fingerprint() any time something is put in
update_inv_shoes(redraw_mob)
if(slot_wear_suit)
src.wear_suit = W
if(wear_suit.flags_inv & HIDESHOES)
if((wear_suit.flags_inv & HIDESHOES) || (w_uniform.flags_inv & HIDESHOES))
update_inv_shoes(0)
W.equipped(src, slot)
update_inv_wear_suit(redraw_mob)

View File

@@ -164,8 +164,8 @@
eye_blind = 0
blinded = 0
eye_blurry = 0
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1))
src << "\red You have a seizure!"
@@ -241,7 +241,13 @@
radiation = Clamp(radiation,0,100)
if (radiation)
if(!radiation)
if(species.appearance_flags & RADIATION_GLOWS)
set_light(0)
else
if(species.appearance_flags & RADIATION_GLOWS)
set_light(max(1,min(10,radiation/10)), max(1,min(20,radiation/20)), species.get_flesh_colour(src))
// END DOGSHIT SNOWFLAKE
var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
if(rad_organ && !rad_organ.is_broken())

View File

@@ -19,7 +19,9 @@
death_message = "dissolves into ash..."
flags = NO_SCAN | NO_SLIP | NO_POISON | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
spawn_flags = SPECIES_IS_RESTRICTED
genders = list(NEUTER)
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)

View File

@@ -21,10 +21,12 @@
var/prone_icon // If set, draws this from icobase when mob is prone.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previes..
var/base_color // Used by changelings. Should also be used for icon previews.
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail_hair
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/mob_size = MOB_MEDIUM
@@ -147,6 +149,8 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
var/list/genders = list(MALE, FEMALE)
// Bump vars
var/bump_flag = HUMAN // What are we considered to be when bumped?
var/push_flags = ~HEAVY // What can we push?
@@ -173,71 +177,9 @@
inherent_verbs = list()
inherent_verbs |= /mob/living/carbon/human/proc/regurgitate
/datum/species/proc/get_station_variant()
return name
/datum/species/proc/get_bodytype()
return name
/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message)
/datum/species/proc/get_death_message(var/mob/living/carbon/human/H)
if(config.show_human_death_message)
return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message)
else
return "no message"
/datum/species/proc/get_ssd(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd)
/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? SYNTH_BLOOD_COLOUR : blood_color)
/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? 1 : virus_immune)
/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color)
/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type)
if(!prob(5))
return
var/covered = 0 // Basic coverage can help.
for(var/obj/item/clothing/clothes in H)
if(H.item_is_in_hands(clothes))
continue
if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO))
covered = 1
break
switch(msg_type)
if("cold")
if(!covered)
H << "<span class='danger'>[pick(cold_discomfort_strings)]</span>"
if("heat")
if(covered)
H << "<span class='danger'>[pick(heat_discomfort_strings)]</span>"
/datum/species/proc/sanitize_name(var/name)
return sanitizeName(name)
/datum/species/proc/get_random_name(var/gender)
if(!name_language)
if(gender == FEMALE)
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
else
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
var/datum/language/species_language = all_languages[name_language]
if(!species_language)
species_language = all_languages[default_language]
if(!species_language)
return "unknown"
return species_language.get_random_name(gender)
/datum/species/proc/equip_survival_gear(var/mob/living/carbon/human/H,var/extendedtank = 1)
if(H.backbag == 1)
if (extendedtank) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand)
@@ -349,6 +291,3 @@
// Called in life() when the mob has no client.
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
return
/datum/species/proc/get_vision_flags(var/mob/living/carbon/human/H)
return vision_flags

View File

@@ -67,9 +67,9 @@
attack_noun = list("body")
damage = 2
/datum/unarmed_attack/slime_glomp/apply_effects()
//Todo, maybe have a chance of causing an electrical shock?
return
/datum/unarmed_attack/slime_glomp/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
..()
user.apply_stored_shock_to(target)
/datum/unarmed_attack/stomp/weak
attack_verb = list("jumped on")

View File

@@ -0,0 +1,97 @@
/datum/species/proc/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
return list()
/datum/species/proc/get_additional_examine_text(var/mob/living/carbon/human/H)
return
/datum/species/proc/get_tail(var/mob/living/carbon/human/H)
return tail
/datum/species/proc/get_tail_animation(var/mob/living/carbon/human/H)
return tail_animation
/datum/species/proc/get_tail_hair(var/mob/living/carbon/human/H)
return tail_hair
/datum/species/proc/get_blood_mask(var/mob/living/carbon/human/H)
return blood_mask
/datum/species/proc/get_damage_overlays(var/mob/living/carbon/human/H)
return damage_overlays
/datum/species/proc/get_damage_mask(var/mob/living/carbon/human/H)
return damage_mask
/datum/species/proc/get_examine_name(var/mob/living/carbon/human/H)
return name
/datum/species/proc/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
return (get_deform ? deform : icobase)
/datum/species/proc/get_station_variant()
return name
/datum/species/proc/get_race_key(var/mob/living/carbon/human/H)
return race_key
/datum/species/proc/get_bodytype(var/mob/living/carbon/human/H)
return name
/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message)
/datum/species/proc/get_death_message(var/mob/living/carbon/human/H)
if(config.show_human_death_message)
return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message)
else
return "no message"
/datum/species/proc/get_ssd(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd)
/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? SYNTH_BLOOD_COLOUR : blood_color)
/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? 1 : virus_immune)
/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H)
return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color)
/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type)
if(!prob(5))
return
var/covered = 0 // Basic coverage can help.
for(var/obj/item/clothing/clothes in H)
if(H.item_is_in_hands(clothes))
continue
if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO))
covered = 1
break
switch(msg_type)
if("cold")
if(!covered)
H << "<span class='danger'>[pick(cold_discomfort_strings)]</span>"
if("heat")
if(covered)
H << "<span class='danger'>[pick(heat_discomfort_strings)]</span>"
/datum/species/proc/get_random_name(var/gender)
if(!name_language)
if(gender == FEMALE)
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
else
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
var/datum/language/species_language = all_languages[name_language]
if(!species_language)
species_language = all_languages[default_language]
if(!species_language)
return "unknown"
return species_language.get_random_name(gender)
/datum/species/proc/get_vision_flags(var/mob/living/carbon/human/H)
return vision_flags

View File

@@ -0,0 +1,6 @@
var/list/stored_shock_by_ref = list()
/mob/living/proc/apply_stored_shock_to(var/mob/living/target)
if(stored_shock_by_ref["\ref[src]"])
target.electrocute_act(stored_shock_by_ref["\ref[src]"]*0.9, src)
stored_shock_by_ref["\ref[src]"] = 0

View File

@@ -0,0 +1,187 @@
// This is something of an intermediary species used for species that
// need to emulate the appearance of another race. Currently it is only
// used for slimes but it may be useful for changelings later.
var/list/wrapped_species_by_ref = list()
/datum/species/shapeshifter
inherent_verbs = list(
/mob/living/carbon/human/proc/shapeshifter_select_shape,
/mob/living/carbon/human/proc/shapeshifter_select_hair,
/mob/living/carbon/human/proc/shapeshifter_select_gender
)
var/list/valid_transform_species = list()
var/monochromatic
var/default_form = "Human"
/datum/species/shapeshifter/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
return valid_transform_species
/datum/species/shapeshifter/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
if(!H) return ..(null, get_deform)
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_icobase(H, get_deform)
/datum/species/shapeshifter/get_race_key(var/mob/living/carbon/human/H)
return "[..()]-[wrapped_species_by_ref["\ref[H]"]]"
/datum/species/shapeshifter/get_bodytype(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_bodytype(H)
/datum/species/shapeshifter/get_blood_mask(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_blood_mask(H)
/datum/species/shapeshifter/get_damage_mask(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_damage_mask(H)
/datum/species/shapeshifter/get_damage_overlays(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_damage_overlays(H)
/datum/species/shapeshifter/get_tail(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_tail(H)
/datum/species/shapeshifter/get_tail_animation(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_tail_animation(H)
/datum/species/shapeshifter/get_tail_hair(var/mob/living/carbon/human/H)
if(!H) return ..()
var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
return S.get_tail_hair(H)
/datum/species/shapeshifter/handle_post_spawn(var/mob/living/carbon/human/H)
..()
wrapped_species_by_ref["\ref[H]"] = default_form
if(monochromatic)
H.r_hair = H.r_skin
H.g_hair = H.g_skin
H.b_hair = H.b_skin
H.r_facial = H.r_skin
H.g_facial = H.g_skin
H.b_facial = H.b_skin
for(var/obj/item/organ/external/E in H.organs)
E.sync_colour_to_human(H)
// Verbs follow.
/mob/living/carbon/human/proc/shapeshifter_select_hair()
set name = "Select Hair"
set category = "Abilities"
if(stat || world.time < last_special)
return
last_special = world.time + 10
var/list/valid_hairstyles = list()
var/list/valid_facialhairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(gender == MALE && S.gender == FEMALE)
continue
if(gender == FEMALE && S.gender == MALE)
continue
if(!(species.get_bodytype(src) in S.species_allowed))
continue
valid_hairstyles += hairstyle
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
if(gender == MALE && S.gender == FEMALE)
continue
if(gender == FEMALE && S.gender == MALE)
continue
if(!(species.get_bodytype(src) in S.species_allowed))
continue
valid_facialhairstyles += facialhairstyle
visible_message("<span class='notice'>\The [src]'s form contorts subtly.</span>")
if(valid_hairstyles.len)
var/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in valid_hairstyles
change_hair(new_hair ? new_hair : "Bald")
if(valid_facialhairstyles.len)
var/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in valid_facialhairstyles
change_facial_hair(new_hair ? new_hair : "Shaved")
/mob/living/carbon/human/proc/shapeshifter_select_gender()
set name = "Select Gender"
set category = "Abilities"
if(stat || world.time < last_special)
return
last_special = world.time + 50
var/new_gender = input("Please select a gender.", "Shapeshifter Gender") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL)
if(!new_gender)
return
visible_message("<span class='notice'>\The [src]'s form contorts subtly.</span>")
change_gender(new_gender)
/mob/living/carbon/human/proc/shapeshifter_select_shape()
set name = "Select Body Shape"
set category = "Abilities"
if(stat || world.time < last_special)
return
last_special = world.time + 50
var/new_species = input("Please select a species to emulate.", "Shapeshifter Body") as null|anything in species.get_valid_shapeshifter_forms(src)
if(!new_species || !all_species[new_species] || wrapped_species_by_ref["\ref[src]"] == new_species)
return
wrapped_species_by_ref["\ref[src]"] = new_species
visible_message("<span class='notice'>\The [src] shifts and contorts, taking the form of \a [new_species]!</span>")
regenerate_icons()
/mob/living/carbon/human/proc/shapeshifter_select_colour()
set name = "Select Body Colour"
set category = "Abilities"
if(stat || world.time < last_special)
return
last_special = world.time + 50
var/new_skin = input("Please select a new body color.", "Shapeshifter Colour") as color
if(!new_skin)
return
shapeshifter_set_colour(new_skin)
/mob/living/carbon/human/proc/shapeshifter_set_colour(var/new_skin)
r_skin = hex2num(copytext(new_skin, 2, 4))
g_skin = hex2num(copytext(new_skin, 4, 6))
b_skin = hex2num(copytext(new_skin, 6, 8))
var/datum/species/shapeshifter/S = species
if(S.monochromatic)
r_hair = r_skin
g_hair = g_skin
b_hair = b_skin
r_facial = r_skin
g_facial = g_skin
b_facial = b_skin
for(var/obj/item/organ/external/E in organs)
E.sync_colour_to_human(src)
regenerate_icons()

View File

@@ -8,7 +8,7 @@
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch)
flags = NO_PAIN | NO_SCAN | NO_POISON | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
breath_type = null
@@ -23,6 +23,8 @@
death_message = "becomes completely motionless..."
genders = list(NEUTER)
/datum/species/golem/handle_post_spawn(var/mob/living/carbon/human/H)
if(H.mind)
H.mind.assigned_role = "Golem"

View File

@@ -30,7 +30,7 @@
brute_mod = 1.5
burn_mod = 1.5
spawn_flags = IS_RESTRICTED
spawn_flags = SPECIES_IS_RESTRICTED
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL

View File

@@ -0,0 +1,188 @@
var/datum/species/shapeshifter/promethean/prometheans
// Species definition follows.
/datum/species/shapeshifter/promethean
name = "Promethean"
name_plural = "Prometheans"
blurb = "What has Science done?"
show_ssd = "totally quiescent"
death_message = "rapidly loses cohesion, splattering across the ground..."
knockout_message = "collapses inwards, forming a disordered puddle of goo."
remains_type = /obj/effect/decal/cleanable/ash
blood_color = "#05FF9B"
flesh_color = "#05FFFB"
hunger_factor = DEFAULT_HUNGER_FACTOR //todo
reagent_tag = IS_SLIME
mob_size = MOB_SMALL
bump_flag = SLIME
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS
spawn_flags = SPECIES_IS_RESTRICTED
breath_type = null
poison_type = null
gluttonous = 2
virus_immune = 1
blood_volume = 600
min_age = 1
max_age = 5
brute_mod = 0.5
burn_mod = 2
oxy_mod = 0
total_health = 120
cold_level_1 = 260
cold_level_2 = 200
cold_level_3 = 120
heat_level_1 = 360
heat_level_2 = 400
heat_level_3 = 1000
body_temperature = 310.15
siemens_coefficient = -1
rarity_value = 5
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime) // Slime core.
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/slime),
BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable/slime),
BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable/slime),
BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable/slime),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable/slime),
BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable/slime),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable/slime),
BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable/slime),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable/slime),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable/slime),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/slime)
)
heat_discomfort_strings = list("You feel too warm.")
cold_discomfort_strings = list("You feel too cool.")
inherent_verbs = list(
/mob/living/carbon/human/proc/shapeshifter_select_shape,
/mob/living/carbon/human/proc/shapeshifter_select_colour,
/mob/living/carbon/human/proc/shapeshifter_select_hair,
/mob/living/carbon/human/proc/shapeshifter_select_gender
)
valid_transform_species = list("Human", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey")
monochromatic = 1
var/heal_rate = 5 // Temp. Regen per tick.
/datum/species/shapeshifter/promethean/New()
..()
prometheans = src
/datum/species/shapeshifter/promethean/equip_survival_gear(var/mob/living/carbon/human/H)
var/boxtype = pick(typesof(/obj/item/weapon/storage/toolbox/lunchbox))
var/obj/item/weapon/storage/toolbox/lunchbox/L = new boxtype(get_turf(H))
var/mob/living/simple_animal/mouse/mouse = new (L)
var/obj/item/weapon/holder/holder = new (L)
mouse.forceMove(holder)
holder.sync(mouse)
if(H.backbag == 1)
H.equip_to_slot_or_del(L, slot_r_hand)
else
H.equip_to_slot_or_del(L, slot_in_backpack)
/datum/species/shapeshifter/promethean/hug(var/mob/living/carbon/human/H,var/mob/living/target)
var/t_him = "them"
switch(target.gender)
if(MALE)
t_him = "him"
if(FEMALE)
t_him = "her"
H.visible_message("<span class='notice'>\The [H] glomps [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You glomps [target] to make [t_him] feel better!</span>")
H.apply_stored_shock_to(target)
/datum/species/shapeshifter/promethean/handle_death(var/mob/living/carbon/human/H)
spawn(1)
if(H)
H.gib()
/datum/species/shapeshifter/promethean/handle_environment_special(var/mob/living/carbon/human/H)
var/turf/T = H.loc
if(istype(T))
var/obj/effect/decal/cleanable/C = locate() in T
if(C)
qdel(C)
//TODO: gain nutriment
// Regenerate limbs and heal damage if we have any. Copied from Bay xenos code.
// Theoretically the only internal organ a slime will have
// is the slime core. but we might as well be thorough.
for(var/obj/item/organ/I in H.internal_organs)
if(I.damage > 0)
I.damage = max(I.damage - heal_rate, 0)
if (prob(5))
H << "<span class='notice'>You feel a soothing sensation within your [I.name]...</span>"
return 1
// Replace completely missing limbs.
for(var/limb_type in has_limbs)
var/obj/item/organ/external/E = H.organs_by_name[limb_type]
if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
E.removed()
qdel(E)
E = null
if(!E)
var/list/organ_data = has_limbs[limb_type]
var/limb_path = organ_data["path"]
var/obj/item/organ/O = new limb_path(H)
organ_data["descriptor"] = O.name
H << "<span class='notice'>You feel a slithering sensation as your [O.name] reforms.</span>"
H.update_body()
return 1
// Heal remaining damage.
if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
H.adjustBruteLoss(-heal_rate)
H.adjustFireLoss(-heal_rate)
H.adjustOxyLoss(-heal_rate)
H.adjustToxLoss(-heal_rate)
return 1
/datum/species/shapeshifter/promethean/get_blood_colour(var/mob/living/carbon/human/H)
return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())
/datum/species/shapeshifter/promethean/get_flesh_colour(var/mob/living/carbon/human/H)
return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())
/datum/species/shapeshifter/promethean/get_additional_examine_text(var/mob/living/carbon/human/H)
if(!stored_shock_by_ref["\ref[H]"])
return
var/t_she = "She is"
if(H.gender == MALE)
t_she = "He is"
else if(H.gender == PLURAL)
t_she = "They are"
else if(H.gender == NEUTER)
t_she = "It is"
switch(stored_shock_by_ref["\ref[H]"])
if(1 to 10)
return "[t_she] flickering gently with a little electrical activity."
if(11 to 20)
return "[t_she] glowing gently with moderate levels of electrical activity.\n"
if(21 to 35)
return "<span class='warning'>[t_she] glowing brightly with high levels of electrical activity.</span>"
if(35 to INFINITY)
return "<span class='danger'>[t_she] radiating massive levels of electrical activity!</span>"

View File

@@ -36,7 +36,7 @@
blood_volume = 400
hunger_factor = 0.2
spawn_flags = CAN_JOIN | IS_WHITELISTED
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL

View File

@@ -1,50 +0,0 @@
/datum/species/slime
name = "Slime"
name_plural = "slimes"
mob_size = MOB_SMALL
icobase = 'icons/mob/human_races/r_slime.dmi'
deform = 'icons/mob/human_races/r_slime.dmi'
language = null //todo?
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
siemens_coefficient = 3 //conductive
darksight = 3
blood_color = "#05FF9B"
flesh_color = "#05FFFB"
remains_type = /obj/effect/decal/cleanable/ash
death_message = "rapidly loses cohesion, splattering across the ground..."
has_organ = list(
"brain" = /obj/item/organ/internal/brain/slime
)
breath_type = null
poison_type = null
bump_flag = SLIME
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable),
BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable),
BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable),
BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable),
BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable),
BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable)
)
/datum/species/slime/handle_death(var/mob/living/carbon/human/H)
spawn(1)
if(H)
H.gib()

View File

@@ -14,10 +14,10 @@
min_age = 17
max_age = 110
spawn_flags = CAN_JOIN
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
/datum/species/human/get_bodytype()
/datum/species/human/get_bodytype(var/mob/living/carbon/human/H)
return "Human"
/datum/species/unathi
@@ -54,7 +54,7 @@
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
spawn_flags = CAN_JOIN | IS_WHITELISTED
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
@@ -116,7 +116,7 @@
primitive_form = "Farwa"
spawn_flags = CAN_JOIN | IS_WHITELISTED
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E"
@@ -149,13 +149,13 @@
herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \
the secrets of their empire to their allies."
num_alternate_languages = 2
secondary_langs = list("Skrellian", "Teshari")
secondary_langs = list("Skrellian", "Schechi")
name_language = null
min_age = 19
max_age = 80
spawn_flags = CAN_JOIN | IS_WHITELISTED
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
@@ -246,13 +246,14 @@
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = NO_SCAN | IS_PLANT | NO_PAIN | NO_SLIP | NO_MINOR_CUT
spawn_flags = CAN_JOIN | IS_WHITELISTED
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
blood_color = "#004400"
flesh_color = "#907E4A"
reagent_tag = IS_DIONA
genders = list(PLURAL)
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/carbon/alien/diona/D = other
if(istype(D))

View File

@@ -174,9 +174,6 @@ var/global/list/damage_icon_parts = list()
for(var/obj/item/organ/external/O in organs)
if(O.is_stump())
continue
//if(O.status & ORGAN_DESTROYED) damage_appearance += "d" //what is this?
//else
// damage_appearance += O.damage_state
damage_appearance += O.damage_state
if(damage_appearance == previous_damage_appearance)
@@ -194,15 +191,14 @@ var/global/list/damage_icon_parts = list()
if(O.is_stump())
continue
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.get_blood_colour(src)]/[species.get_bodytype(src)]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(species.blood_color, ICON_MULTIPLY)
DI = new /icon(species.get_damage_overlays(src), O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.get_damage_mask(src), O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(species.get_blood_colour(src), ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
@@ -236,7 +232,7 @@ var/global/list/damage_icon_parts = list()
if(gender == FEMALE)
g = "female"
var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]"
var/icon_key = "[species.get_race_key(src)][g][s_tone][r_skin][g_skin][b_skin]"
if(lip_style)
icon_key += "[lip_style]"
else
@@ -258,7 +254,7 @@ var/global/list/damage_icon_parts = list()
else
icon_key += "1"
if(part)
icon_key += "[part.species.race_key]"
icon_key += "[part.species.get_race_key(part.owner)]"
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
if(part.s_col && part.s_col.len >= 3)
@@ -357,7 +353,7 @@ var/global/list/damage_icon_parts = list()
if(f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
if(facial_hair_style && facial_hair_style.species_allowed && (src.species.get_bodytype() in facial_hair_style.species_allowed))
if(facial_hair_style && facial_hair_style.species_allowed && (src.species.get_bodytype(src) in facial_hair_style.species_allowed))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
@@ -366,13 +362,16 @@ var/global/list/damage_icon_parts = list()
if(h_style && !(head && (head.flags_inv & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style && (src.species.get_bodytype() in hair_style.species_allowed))
if(hair_style && (src.species.get_bodytype(src) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration)
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
face_standing.Blend(hair_s, ICON_OVERLAY)
if(head_organ.nonsolid)
face_standing += rgb(,,,120)
overlays_standing[HAIR_LAYER] = image(face_standing)
if(update_icons) update_icons()
@@ -464,8 +463,8 @@ var/global/list/damage_icon_parts = list()
var/icon/under_icon
if(w_uniform.icon_override)
under_icon = w_uniform.icon_override
else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.get_bodytype()])
under_icon = w_uniform.sprite_sheets[species.get_bodytype()]
else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.get_bodytype(src)])
under_icon = w_uniform.sprite_sheets[species.get_bodytype(src)]
else if(w_uniform.item_icons && w_uniform.item_icons[slot_w_uniform_str])
under_icon = w_uniform.item_icons[slot_w_uniform_str]
else
@@ -486,7 +485,7 @@ var/global/list/damage_icon_parts = list()
//apply blood overlay
if(w_uniform.blood_DNA)
var/image/bloodsies = image(icon = species.blood_mask, icon_state = "uniformblood")
var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "uniformblood")
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
@@ -510,8 +509,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(wear_id.icon_override)
standing = image("icon" = wear_id.icon_override, "icon_state" = "[icon_state]")
else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype()])
standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype()], "icon_state" = "[icon_state]")
else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[icon_state]")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
overlays_standing[ID_LAYER] = standing
@@ -533,13 +532,13 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(gloves.icon_override)
standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]")
else if(gloves.sprite_sheets && gloves.sprite_sheets[species.get_bodytype()])
standing = image("icon" = gloves.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_state]")
else if(gloves.sprite_sheets && gloves.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = gloves.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_state]")
else
standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
if(gloves.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
gloves.screen_loc = ui_gloves
@@ -547,7 +546,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands")
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
else
@@ -560,8 +559,8 @@ var/global/list/damage_icon_parts = list()
if(glasses.icon_override)
overlays_standing[GLASSES_LAYER] = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]")
else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype()])
overlays_standing[GLASSES_LAYER]= image("icon" = glasses.sprite_sheets[species.get_bodytype()], "icon_state" = "[glasses.icon_state]")
else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype(src)])
overlays_standing[GLASSES_LAYER]= image("icon" = glasses.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[glasses.icon_state]")
else
overlays_standing[GLASSES_LAYER]= image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
@@ -582,9 +581,9 @@ var/global/list/damage_icon_parts = list()
if(l_ear.icon_override)
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]")
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype()])
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype(src)])
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_type]")
overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -594,9 +593,9 @@ var/global/list/damage_icon_parts = list()
if(r_ear.icon_override)
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]")
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype()])
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype(src)])
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_type]")
overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -605,25 +604,25 @@ var/global/list/damage_icon_parts = list()
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
if(shoes && !(wear_suit && wear_suit.flags_inv & HIDESHOES))
if(shoes && !((wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES)))
var/image/standing
if(shoes.icon_override)
standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]")
else if(shoes.sprite_sheets && shoes.sprite_sheets[species.get_bodytype()])
standing = image("icon" = shoes.sprite_sheets[species.get_bodytype()], "icon_state" = "[shoes.icon_state]")
else if(shoes.sprite_sheets && shoes.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = shoes.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[shoes.icon_state]")
else
standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
standing.color = shoes.color
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood")
bloodsies.color = feet_blood_color
overlays_standing[SHOES_LAYER] = bloodsies
else
@@ -649,8 +648,8 @@ var/global/list/damage_icon_parts = list()
var/t_icon
if(head.icon_override)
t_icon = head.icon_override
else if(head.sprite_sheets && head.sprite_sheets[species.get_bodytype()])
t_icon = head.sprite_sheets[species.get_bodytype()]
else if(head.sprite_sheets && head.sprite_sheets[species.get_bodytype(src)])
t_icon = head.sprite_sheets[species.get_bodytype(src)]
else if(head.item_icons && (slot_head_str in head.item_icons))
t_icon = head.item_icons[slot_head_str]
@@ -675,13 +674,13 @@ var/global/list/damage_icon_parts = list()
var/image/standing = image(icon = t_icon, icon_state = t_state)
if(head.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
if(istype(head,/obj/item/clothing/head))
var/obj/item/clothing/head/hat = head
var/cache_key = "[hat.light_overlay]_[species.get_bodytype()]"
var/cache_key = "[hat.light_overlay]_[species.get_bodytype(src)]"
if(hat.on && light_overlay_cache[cache_key])
standing.overlays |= light_overlay_cache[cache_key]
@@ -701,8 +700,8 @@ var/global/list/damage_icon_parts = list()
if(belt.icon_override)
standing.icon = belt.icon_override
else if(belt.sprite_sheets && belt.sprite_sheets[species.get_bodytype()])
standing.icon = belt.sprite_sheets[species.get_bodytype()]
else if(belt.sprite_sheets && belt.sprite_sheets[species.get_bodytype(src)])
standing.icon = belt.sprite_sheets[species.get_bodytype(src)]
else
standing.icon = 'icons/mob/belt.dmi'
@@ -739,7 +738,7 @@ var/global/list/damage_icon_parts = list()
var/t_icon = INV_SUIT_DEF_ICON
if(wear_suit.icon_override)
t_icon = wear_suit.icon_override
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype()])
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype(src)])
t_icon = wear_suit.sprite_sheets[species.name]
else if(wear_suit.item_icons && wear_suit.item_icons[slot_wear_suit_str])
t_icon = wear_suit.item_icons[slot_wear_suit_str]
@@ -755,7 +754,7 @@ var/global/list/damage_icon_parts = list()
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
if(istype(S)) //You can put non-suits in your suit slot (diona nymphs etc).
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
@@ -784,14 +783,14 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(wear_mask.icon_override)
standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state]")
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.get_bodytype()])
standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype()], "icon_state" = "[wear_mask.icon_state]")
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[wear_mask.icon_state]")
else
standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]")
standing.color = wear_mask.color
if( !istype(wear_mask, /obj/item/clothing/mask/smokable/cigarette) && wear_mask.blood_DNA )
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood")
var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
overlays_standing[FACEMASK_LAYER] = standing
@@ -812,8 +811,8 @@ var/global/list/damage_icon_parts = list()
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
var/obj/item/weapon/rig/rig = back
overlay_icon = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[species.get_bodytype()])
overlay_icon = back.sprite_sheets[species.get_bodytype()]
else if(back.sprite_sheets && back.sprite_sheets[species.get_bodytype(src)])
overlay_icon = back.sprite_sheets[species.get_bodytype(src)]
else if(back.item_icons && (slot_back_str in back.item_icons))
overlay_icon = back.item_icons[slot_back_str]
else
@@ -857,8 +856,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(handcuffed.icon_override)
standing = image("icon" = handcuffed.icon_override, "icon_state" = "handcuff1")
else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype()])
standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "handcuff1")
else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "handcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
overlays_standing[HANDCUFF_LAYER] = standing
@@ -873,8 +872,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(legcuffed.icon_override)
standing = image("icon" = legcuffed.icon_override, "icon_state" = "legcuff1")
else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype()])
standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "legcuff1")
else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype(src)])
standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "legcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
overlays_standing[LEGCUFF_LAYER] = standing
@@ -963,24 +962,29 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_standing[TAIL_LAYER] = null
if(species.tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
var/species_tail = species.get_tail(src)
if(species_tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
var/icon/tail_s = get_tail_icon()
overlays_standing[TAIL_LAYER] = image(tail_s, icon_state = "[species.tail]_s")
overlays_standing[TAIL_LAYER] = image(tail_s, icon_state = "[species_tail]_s")
animate_tail_reset(0)
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/get_tail_icon()
var/icon_key = "[species.race_key][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
var/icon_key = "[species.get_race_key(src)][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
var/icon/tail_icon = tail_icon_cache[icon_key]
if(!tail_icon)
//generate a new one
tail_icon = new/icon(icon = (species.tail_animation? species.tail_animation : 'icons/effects/species.dmi'))
var/species_tail_anim = species.get_tail_animation(src)
if(!species_tail_anim) species_tail_anim = 'icons/effects/species.dmi'
tail_icon = new/icon(species_tail_anim)
tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
// The following will not work with animated tails.
if(species.tail_hair)
var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.tail]_[species.tail_hair]")
var/use_species_tail = species.get_tail_hair(src)
if(use_species_tail)
var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.get_tail(src)]_[use_species_tail]")
hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
tail_icon.Blend(hair_icon, ICON_OVERLAY)
tail_icon_cache[icon_key] = tail_icon
@@ -991,7 +995,7 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/set_tail_state(var/t_state)
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
if(tail_overlay && species.tail_animation)
if(tail_overlay && species.get_tail_animation(src))
tail_overlay.icon_state = t_state
return tail_overlay
return null
@@ -999,7 +1003,7 @@ var/global/list/damage_icon_parts = list()
//Not really once, since BYOND can't do that.
//Update this if the ability to flick() images or make looping animation start at the first frame is ever added.
/mob/living/carbon/human/proc/animate_tail_once(var/update_icons=1)
var/t_state = "[species.tail]_once"
var/t_state = "[species.get_tail(src)]_once"
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
if(tail_overlay && tail_overlay.icon_state == t_state)
@@ -1016,29 +1020,28 @@ var/global/list/damage_icon_parts = list()
update_icons()
/mob/living/carbon/human/proc/animate_tail_start(var/update_icons=1)
set_tail_state("[species.tail]_slow[rand(0,9)]")
set_tail_state("[species.get_tail(src)]_slow[rand(0,9)]")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_fast(var/update_icons=1)
set_tail_state("[species.tail]_loop[rand(0,9)]")
set_tail_state("[species.get_tail(src)]_loop[rand(0,9)]")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_reset(var/update_icons=1)
if(stat != DEAD)
set_tail_state("[species.tail]_idle[rand(0,9)]")
set_tail_state("[species.get_tail(src)]_idle[rand(0,9)]")
else
set_tail_state("[species.tail]_static")
set_tail_state("[species.get_tail(src)]_static")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1)
set_tail_state("[species.tail]_static")
set_tail_state("[species.get_tail(src)]_static")
if(update_icons)
update_icons()

View File

@@ -217,7 +217,7 @@
if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
if(H.species.name == "Slime")
if(H.species.name == "Promethean")
continue
if(!L.canmove) // Only one slime can latch on at a time.

View File

@@ -566,7 +566,7 @@ default behaviour is:
set name = "Resist"
set category = "IC"
if(!stat && canClick())
if(!incapacitated(INCAPACITATION_KNOCKOUT) && canClick())
setClickCooldown(20)
resist_grab()
if(!weakened)
@@ -631,7 +631,9 @@ default behaviour is:
if(GRAB_PASSIVE)
qdel(G)
if(GRAB_AGGRESSIVE)
if(prob(60)) //same chance of breaking the grab as disarm
//Not standing up makes it much harder to break, so it is easier to cuff someone who is down without forcing them into unconsciousness.
//Otherwise, it's the same chance of breaking the grab as disarm.
if(incapacitated(INCAPACITATION_KNOCKDOWN)? prob(15) : prob(60))
visible_message("<span class='warning'>[src] has broken free of [G.assailant]'s grip!</span>")
qdel(G)
if(GRAB_NECK)
@@ -862,7 +864,7 @@ default behaviour is:
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(cannot_stand())
if(is_physically_disabled())
lying = 0
canmove = 1
pixel_y = V.mob_offset_y - 5
@@ -880,18 +882,13 @@ default behaviour is:
anchored = 0
canmove = 1
else if(cannot_stand())
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
lying = 0
canmove = 1
lying = incapacitated(INCAPACITATION_KNOCKDOWN)
canmove = !incapacitated(INCAPACITATION_DISABLED)
if(lying)
density = 0

View File

@@ -151,11 +151,13 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
add_language("Galactic Common", 1)
add_language("Sol Common", 0)
add_language("Sinta'unathi", 0)
add_language("Siik'maas", 0)
add_language("Siik'tajr", 0)
add_language("Skrellian", 0)
add_language("Tradeband", 1)
add_language("Gutter", 0)
add_language("Encoded Audio Language", 1)
add_language("Schechi", 0)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.

View File

@@ -7,6 +7,9 @@
pass_flags = 1
mob_size = MOB_SMALL
can_pull_size = 2
can_pull_mobs = MOB_PULL_SMALLER
idcard_type = /obj/item/weapon/card/id
var/idaccessible = 0

View File

@@ -75,7 +75,7 @@
/datum/robot_component/armour
name = "armour plating"
external_type = /obj/item/robot_parts/robot_component/armour
max_damage = 60
max_damage = 90
// ACTUATOR

View File

@@ -23,7 +23,7 @@ var/global/list/robot_modules = list(
var/hide_on_manifest = 0
var/channels = list()
var/networks = list()
var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK_TAJR = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0)
var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK_TAJR = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0, LANGUAGE_SCHECHI = 0)
var/sprites = list()
var/can_be_pushed = 1
var/no_slip = 0
@@ -479,11 +479,12 @@ var/global/list/robot_modules = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_UNATHI = 1,
LANGUAGE_SIIK_MAAS = 1,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_SIIK_TAJR = 1,
LANGUAGE_SKRELLIAN = 1,
LANGUAGE_ROOTSPEAK = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_GUTTER = 1
LANGUAGE_GUTTER = 1,
LANGUAGE_SCHECHI = 1
)
/obj/item/weapon/robot_module/clerical/butler
@@ -623,9 +624,12 @@ var/global/list/robot_modules = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 0,
LANGUAGE_SIIK_MAAS = 0,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_SKRELLIAN = 0,
LANGUAGE_GUTTER = 1
LANGUAGE_ROOTSPEAK = 0,
LANGUAGE_GUTTER = 1,
LANGUAGE_SCHECHI = 0
)
sprites = list(
"Dread" = "securityrobot",

View File

@@ -33,7 +33,7 @@
var/datum/preferences/p = speaker.client.prefs
name = p.real_name
real_name = name
gender = p.gender
gender = p.identifying_gender
for(var/language in p.alternate_languages)
add_language(language)

View File

@@ -158,8 +158,20 @@
return UNBUCKLED
return restrained() ? FULLY_BUCKLED : PARTIALLY_BUCKLED
/mob/proc/is_physically_disabled()
return incapacitated(INCAPACITATION_DISABLED)
/mob/proc/cannot_stand()
return incapacitated(INCAPACITATION_KNOCKDOWN)
/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT)
if (stat || paralysis || stunned || weakened || resting || sleeping || (status_flags & FAKEDEATH))
if ((incapacitation_flags & INCAPACITATION_STUNNED) && stunned)
return 1
if ((incapacitation_flags & INCAPACITATION_FORCELYING) && (weakened || resting))
return 1
if ((incapacitation_flags & INCAPACITATION_KNOCKOUT) && (stat || paralysis || sleeping || (status_flags & FAKEDEATH)))
return 1
if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained())
@@ -687,9 +699,6 @@
/mob/proc/can_stand_overridden()
return 0
/mob/proc/cannot_stand()
return incapacitated(INCAPACITATION_DEFAULT & (~INCAPACITATION_RESTRAINED))
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
return canmove

View File

@@ -130,8 +130,6 @@
var/in_throw_mode = 0
var/coughedtime = null
var/inertia_dir = 0
var/music_lastplayed = "null"
@@ -154,7 +152,7 @@
var/voice_name = "unidentifiable voice"
var/faction = "neutral" //Used for checking whether hostile simple animals will attack you, possibly more stuff later
var/captured = 0 //Functionally, should give the same effect as being buckled into a chair when true.
var/captured = 0 //Functionally, should give the same effect as being buckled into a chair when true. Only used by energy nets, TODO replace with buckling
//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed.
var/proc_holder_list[] = list()//Right now unused.

View File

@@ -142,14 +142,14 @@
/obj/item/weapon/grab/proc/devour(mob/target, mob/user)
var/can_eat
if((FAT in user.mutations) && issmall(target))
if((FAT in user.mutations) && ismini(target))
can_eat = 1
else
var/mob/living/carbon/human/H = user
if(istype(H) && H.species.gluttonous)
if(H.species.gluttonous == 2)
can_eat = 2
else if((H.mob_size > target.mob_size) && !ishuman(target) && iscarbon(target))
else if((H.mob_size > target.mob_size) && !ishuman(target) && ismini(target))
can_eat = 1
if(can_eat)
@@ -158,7 +158,7 @@
if(can_eat == 2)
if(!do_mob(user, target)||!do_after(user, 30)) return
else
if(!do_mob(user, target)||!do_after(user, 100)) return
if(!do_mob(user, target)||!do_after(user, 70)) return
user.visible_message("<span class='danger'>[user] devours [target]!</span>")
target.loc = user
attacker.stomach_contents.Add(target)

View File

@@ -5,6 +5,21 @@
return L.mob_size <= MOB_SMALL
return 0
/proc/istiny(A)
if(A && istype(A, /mob/living))
var/mob/living/L = A
return L.mob_size <= MOB_TINY
return 0
/proc/ismini(A)
if(A && istype(A, /mob/living))
var/mob/living/L = A
return L.mob_size <= MOB_MINISCULE
return 0
// If they are 100% robotic, they count as synthetic.
/mob/living/carbon/human/isSynthetic()
if(isnull(full_prosthetic))
@@ -389,6 +404,8 @@ proc/is_blind(A)
var/follow
var/lname
if(subject)
if(M.is_key_ignored(subject.client.key)) // If we're ignored, do nothing.
continue
if(subject != M)
follow = "([ghost_follow_link(subject, M)]) "
if(M.stat != DEAD && M.client.holder)

View File

@@ -5,6 +5,7 @@
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
var/totalPlayers = 0 //Player counts for the Lobby tab
var/totalPlayersReady = 0
var/datum/browser/panel
universal_speak = 1
invisibility = 101
@@ -24,15 +25,15 @@
/mob/new_player/proc/new_player_panel_proc()
var/output = "<div align='center'><B>New Player Options</B>"
var/output = "<div align='center'>"
output +="<hr>"
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
if(ready)
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
output += "<p>\[ <span class='linkOn'><b>Ready</b></span> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
else
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <b>Not Ready</b> \]</p>"
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <span class='linkOn'><b>Not Ready</b></span> \]</p>"
else
output += "<a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</A><br><br>"
@@ -61,7 +62,10 @@
output += "</div>"
src << browse(output,"window=playersetup;size=210x280;can_close=0")
panel = new(src, "Welcome","Welcome", 210, 280, src)
panel.set_window_options("can_close=0")
panel.set_content(output)
panel.open()
return
/mob/new_player/Stat()
@@ -98,7 +102,8 @@
ready = 0
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
//src << browse(null, "window=playersetup") //closes the player setup window
panel.close()
new_player_panel_proc()
if(href_list["observe"])
@@ -127,7 +132,7 @@
observer.alpha = 127
if(client.prefs.be_random_name)
client.prefs.real_name = random_name(client.prefs.gender)
client.prefs.real_name = random_name(client.prefs.identifying_gender)
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
@@ -149,7 +154,7 @@
return 0
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & IS_WHITELISTED))
if(!(S.spawn_flags & SPECIES_IS_WHITELISTED))
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
return 0
@@ -173,7 +178,7 @@
return 0
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & CAN_JOIN))
if(!(S.spawn_flags & SPECIES_CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
@@ -458,25 +463,29 @@
return new_character
/mob/new_player/proc/ViewManifest()
var/dat = "<html><body>"
dat += "<h4>Show Crew Manifest</h4>"
var/dat = "<div align='center'>"
dat += data_core.get_manifest(OOC = 1)
src << browse(dat, "window=manifest;size=370x420;can_close=1")
//src << browse(dat, "window=manifest;size=370x420;can_close=1")
var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src)
popup.set_content(dat)
popup.open()
/mob/new_player/Move()
return 0
/mob/new_player/proc/close_spawn_windows()
src << browse(null, "window=latechoices") //closes late choices window
src << browse(null, "window=playersetup") //closes the player setup window
//src << browse(null, "window=playersetup") //closes the player setup window
panel.close()
/mob/new_player/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
/mob/new_player/proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & IS_WHITELISTED)
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & SPECIES_IS_WHITELISTED)
/mob/new_player/get_species()
var/datum/species/chosen_species
@@ -493,7 +502,7 @@
/mob/new_player/get_gender()
if(!client || !client.prefs) ..()
return client.prefs.gender
return client.prefs.biological_gender
/mob/new_player/is_ready()
return ready && ..()

View File

@@ -1,8 +1,8 @@
/datum/preferences
//The mob should have a gender you want before running this proc. Will run fine without H
/datum/preferences/proc/randomize_appearance_for(var/mob/living/carbon/human/H)
gender = pick(MALE, FEMALE)
var/datum/species/current_species = all_species[species]
var/datum/species/current_species = all_species[species ? species : "Human"]
set_biological_gender(pick(current_species.genders))
if(current_species)
if(current_species.flags & HAS_SKIN_TONE)
@@ -25,8 +25,8 @@
use_head_species = H.species.get_bodytype()
if(use_head_species)
h_style = random_hair_style(gender, species)
f_style = random_facial_hair_style(gender, species)
h_style = random_hair_style(biological_gender, species)
f_style = random_facial_hair_style(biological_gender, species)
randomize_hair_color("hair")
randomize_hair_color("facial")
@@ -202,7 +202,7 @@
qdel(preview_icon)
var/g = "m"
if(gender == FEMALE) g = "f"
if(biological_gender == FEMALE) g = "f"
var/icon/icobase
var/datum/species/current_species = all_species[species]

View File

@@ -27,10 +27,14 @@
cut_and_generate_data()
return 1
if(href_list["gender"])
if(can_change(APPEARANCE_GENDER))
if(can_change(APPEARANCE_GENDER) && (href_list["gender"] in get_genders()))
if(owner.change_gender(href_list["gender"]))
cut_and_generate_data()
return 1
if(href_list["gender_id"])
if(can_change(APPEARANCE_GENDER) && (href_list["gender_id"] in all_genders_define_list))
owner.identifying_gender = href_list["gender_id"]
return 1
if(href_list["skin_tone"])
if(can_change_skin_tone())
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -owner.s_tone + 35) as num|null
@@ -100,6 +104,7 @@
data["specimen"] = owner.species.name
data["gender"] = owner.gender
data["gender_id"] = owner.identifying_gender
data["change_race"] = can_change(APPEARANCE_RACE)
if(data["change_race"])
var/species[0]
@@ -108,6 +113,17 @@
data["species"] = species
data["change_gender"] = can_change(APPEARANCE_GENDER)
if(data["change_gender"])
var/genders[0]
for(var/gender in get_genders())
genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
data["genders"] = genders
var/id_genders[0]
for(var/gender in all_genders_define_list)
id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
data["id_genders"] = id_genders
data["change_skin_tone"] = can_change_skin_tone()
data["change_skin_color"] = can_change_skin_color()
data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR)
@@ -163,3 +179,13 @@
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
valid_hairstyles = owner.generate_valid_hairstyles(check_gender = 0)
valid_facial_hairstyles = owner.generate_valid_facial_hairstyles()
/datum/nano_module/appearance_changer/proc/get_genders()
var/datum/species/S = owner.species
var/list/possible_genders = S.genders
if(!owner.internal_organs_by_name["cell"])
return possible_genders
possible_genders = possible_genders.Copy()
possible_genders |= NEUTER
return possible_genders

View File

@@ -17,10 +17,10 @@
smeslist.Add(list(list(
"charge" = round(SMES.Percentage()),
"input_set" = SMES.input_attempt,
"input_val" = round(SMES.input_level),
"input_val" = round(SMES.input_level/1000, 0.1),
"output_set" = SMES.output_attempt,
"output_val" = round(SMES.output_level),
"output_load" = round(SMES.output_used),
"output_val" = round(SMES.output_level/1000, 0.1),
"output_load" = round(SMES.output_used/1000, 0.1),
"RCON_tag" = SMES.RCon_tag
)))
@@ -63,12 +63,12 @@
if(href_list["smes_in_set"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"])
if(SMES)
var/inputset = input(usr, "Enter new input level (0-[SMES.input_level_max])", "SMES Input Power Control") as num
var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000
SMES.set_input(inputset)
if(href_list["smes_out_set"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"])
if(SMES)
var/outputset = input(usr, "Enter new output level (0-[SMES.output_level_max])", "SMES Input Power Control") as num
var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Input Power Control", SMES.output_level/1000) as num) * 1000
SMES.set_output(outputset)
if(href_list["toggle_breaker"])

View File

@@ -26,6 +26,7 @@
var/last_dam = -1 // used in healing/processing calculations.
// Appearance vars.
var/nonsolid // Snowflake warning, reee. Used for slime limbs.
var/icon_name = null // Icon state base.
var/body_part = null // Part flag
var/icon_position = 0 // Used in mob overlay layering calculations.
@@ -199,11 +200,11 @@
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
owner = target
forceMove(owner)
if(istype(owner))
owner.organs_by_name[organ_tag] = src
owner.organs |= src
for(var/obj/item/organ/organ in src)
organ.loc = owner
organ.replaced(owner,src)
if(parent_organ)
@@ -212,6 +213,12 @@
if(!parent.children)
parent.children = list()
parent.children.Add(src)
//Remove all stump wounds since limb is not missing anymore
for(var/datum/wound/lost_limb/W in parent.wounds)
parent.wounds -= W
qdel(W)
break
parent.update_damages()
/****************************************************
DAMAGE PROCS
@@ -249,7 +256,10 @@
if(is_damageable(brute + burn) || !config.limbs_can_break)
if(brute)
if(can_cut)
createwound( CUT, brute )
if(sharp && !edge)
createwound( PIERCE, brute )
else
createwound( CUT, brute )
else
createwound( BRUISE, brute )
if(burn)
@@ -263,7 +273,10 @@
if (brute > 0)
//Inflict all burte damage we can
if(can_cut)
createwound( CUT, min(brute,can_inflict) )
if(sharp && !edge)
createwound( PIERCE, min(brute,can_inflict) )
else
createwound( CUT, min(brute,can_inflict) )
else
createwound( BRUISE, min(brute,can_inflict) )
var/temp = can_inflict
@@ -326,10 +339,10 @@
break
// heal brute damage
if(W.damage_type == CUT || W.damage_type == BRUISE)
brute = W.heal_damage(brute)
else if(W.damage_type == BURN)
if(W.damage_type == BURN)
burn = W.heal_damage(burn)
else
brute = W.heal_damage(brute)
if(internal)
status &= ~ORGAN_BROKEN
@@ -653,10 +666,10 @@ Note that amputating the affected organ does in fact remove the infection from t
//update damage counts
for(var/datum/wound/W in wounds)
if(!W.internal) //so IB doesn't count towards crit/paincrit
if(W.damage_type == CUT || W.damage_type == BRUISE)
brute_dam += W.damage
else if(W.damage_type == BURN)
if(W.damage_type == BURN)
burn_dam += W.damage
else
brute_dam += W.damage
if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ(O_HEART)))
W.bleed_timer--
@@ -719,6 +732,9 @@ Note that amputating the affected organ does in fact remove the infection from t
if(cannot_amputate || !owner)
return
if(disintegrate == DROPLIMB_EDGE && nonsolid)
disintegrate = DROPLIMB_BLUNT //splut
switch(disintegrate)
if(DROPLIMB_EDGE)
if(!clean)
@@ -747,10 +763,13 @@ Note that amputating the affected organ does in fact remove the infection from t
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
var/obj/item/organ/external/parent_organ = parent
var/use_flesh_colour = species.get_flesh_colour(owner)
var/use_blood_colour = species.get_blood_colour(owner)
removed(null, ignore_children)
victim.traumatic_shock += 60
wounds.Cut()
if(parent_organ)
var/datum/wound/lost_limb/W = new (src, disintegrate, clean)
if(clean)
@@ -795,10 +814,8 @@ Note that amputating the affected organ does in fact remove the infection from t
else
gore = new /obj/effect/decal/cleanable/blood/gibs(get_turf(victim))
if(species)
if(species.get_flesh_colour())
gore.fleshcolor = species.get_flesh_colour()
if(species.get_blood_colour())
gore.basecolor = species.get_blood_colour()
gore.fleshcolor = use_flesh_colour
gore.basecolor = use_blood_colour
gore.update_icon()
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
@@ -840,15 +857,46 @@ Note that amputating the affected organ does in fact remove the infection from t
"\The [holder.legcuffed.name] falls off you.")
holder.drop_from_inventory(holder.legcuffed)
// checks if all wounds on the organ are bandaged
/obj/item/organ/external/proc/is_bandaged()
for(var/datum/wound/W in wounds)
if(W.internal) continue
if(!W.bandaged)
return 0
return 1
// checks if all wounds on the organ are salved
/obj/item/organ/external/proc/is_salved()
for(var/datum/wound/W in wounds)
if(W.internal) continue
if(!W.salved)
return 0
return 1
// checks if all wounds on the organ are disinfected
/obj/item/organ/external/proc/is_disinfected()
for(var/datum/wound/W in wounds)
if(W.internal) continue
if(!W.disinfected)
return 0
return 1
/obj/item/organ/external/proc/bandage()
var/rval = 0
src.status &= ~ORGAN_BLEEDING
status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
if(W.internal) continue
rval |= !W.bandaged
W.bandaged = 1
return rval
/obj/item/organ/external/proc/salve()
var/rval = 0
for(var/datum/wound/W in wounds)
rval |= !W.salved
W.salved = 1
return rval
/obj/item/organ/external/proc/disinfect()
var/rval = 0
for(var/datum/wound/W in wounds)
@@ -867,13 +915,6 @@ Note that amputating the affected organ does in fact remove the infection from t
W.clamped = 1
return rval
/obj/item/organ/external/proc/salve()
var/rval = 0
for(var/datum/wound/W in wounds)
rval |= !W.salved
W.salved = 1
return rval
/obj/item/organ/external/proc/fracture()
if(status & ORGAN_ROBOT)
return //ORGAN_BROKEN doesn't have the same meaning for robot limbs

View File

@@ -71,7 +71,7 @@ var/global/list/limb_icon_cache = list()
if(owner.f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype() in facial_hair_style.species_allowed))
if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype(owner) in facial_hair_style.species_allowed))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
@@ -79,7 +79,7 @@ var/global/list/limb_icon_cache = list()
if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
if(hair_style && (species.get_bodytype() in hair_style.species_allowed))
if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3)
hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_ADD)
@@ -113,36 +113,47 @@ var/global/list/limb_icon_cache = list()
else if (status & ORGAN_ROBOT)
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
else
if (status & ORGAN_MUTATED)
mob_icon = new /icon(species.deform, "[icon_name][gender ? "_[gender]" : ""]")
else
mob_icon = new /icon(species.icobase, "[icon_name][gender ? "_[gender]" : ""]")
if(status & ORGAN_DEAD)
mob_icon.ColorTone(rgb(10,50,0))
mob_icon.SetIntensity(0.7)
if(!isnull(s_tone))
if(s_tone >= 0)
mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
else
mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
else if(s_col && s_col.len >= 3)
mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
mob_icon = new /icon(species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]")
apply_colouration(mob_icon)
if(body_hair && islist(h_col) && h_col.len >= 3)
var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]"
if(!limb_icon_cache[cache_key])
var/icon/I = icon(species.icobase, "[icon_name]_[body_hair]")
var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]")
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_ADD)
limb_icon_cache[cache_key] = I
mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY)
dir = EAST
icon = mob_icon
return mob_icon
/obj/item/organ/external/proc/apply_colouration(var/icon/applying)
if(nonsolid)
applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000")
if(species && species.get_bodytype(owner) != "Human")
applying.SetIntensity(1.5) // Unathi, Taj and Skrell have -very- dark base icons.
else
applying.SetIntensity(0.7)
else if(status & ORGAN_DEAD)
applying.ColorTone(rgb(10,50,0))
applying.SetIntensity(0.7)
if(!isnull(s_tone))
if(s_tone >= 0)
applying.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
else
applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
else if(s_col && s_col.len >= 3)
applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
// Translucency.
if(nonsolid) applying += rgb(,,,180) // SO INTUITIVE TY BYOND
return applying
// new damage icon system
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
/obj/item/organ/external/update_icon()

View File

@@ -1,4 +1,3 @@
// Slime limbs.
/obj/item/organ/external/chest/unbreakable
cannot_break = 1
dislocated = -1
@@ -42,3 +41,48 @@
/obj/item/organ/external/head/unbreakable
cannot_break = 1
dislocated = -1
// Slime limbs.
/obj/item/organ/external/chest/unbreakable/slime
nonsolid = 1
max_damage = 50
/obj/item/organ/external/groin/unbreakable/slime
nonsolid = 1
max_damage = 30
/obj/item/organ/external/arm/unbreakable/slime
nonsolid = 1
max_damage = 15
/obj/item/organ/external/arm/right/unbreakable/slime
nonsolid = 1
max_damage = 15
/obj/item/organ/external/leg/unbreakable/slime
nonsolid = 1
max_damage = 15
/obj/item/organ/external/leg/right/unbreakable/slime
nonsolid = 1
max_damage = 15
/obj/item/organ/external/foot/unbreakable/slime
nonsolid = 1
max_damage = 5
/obj/item/organ/external/foot/right/unbreakable/slime
nonsolid = 1
max_damage = 5
/obj/item/organ/external/hand/unbreakable/slime
nonsolid = 1
max_damage = 5
/obj/item/organ/external/hand/right/unbreakable/slime
nonsolid = 1
max_damage = 5
/obj/item/organ/external/head/unbreakable/slime
nonsolid = 1
max_damage = 15

View File

@@ -38,7 +38,7 @@
var/internal = 0
// maximum stage at which bleeding should still happen. Beyond this stage bleeding is prevented.
var/max_bleeding_stage = 0
// one of CUT, BRUISE, BURN
// one of CUT, PIERCE, BRUISE, BURN
var/damage_type = CUT
// whether this wound needs a bandage/salve to heal at all
// the maximum amount of damage that this wound can have and still autoheal
@@ -140,6 +140,15 @@
return 0
proc/bandage()
bandaged = 1
proc/salve()
salved = 1
proc/disinfect()
disinfected = 1
// heal the given amount of damage, and if the given amount of damage was more
// than what needed to be healed, return how much heal was left
// set @heals_internal to also heal internal organ damage
@@ -202,7 +211,7 @@
if (wound_damage() <= 30 && bleed_timer <= 0)
return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own.
return (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5)
return 1
/** WOUND DEFINITIONS **/
@@ -226,6 +235,18 @@
return /datum/wound/cut/deep
if(0 to 15)
return /datum/wound/cut/small
if(PIERCE)
switch(damage)
if(60 to INFINITY)
return /datum/wound/puncture/massive
if(50 to 60)
return /datum/wound/puncture/gaping_big
if(30 to 50)
return /datum/wound/puncture/gaping
if(15 to 30)
return /datum/wound/puncture/flesh
if(0 to 15)
return /datum/wound/puncture/small
if(BRUISE)
return /datum/wound/bruise
if(BURN)
@@ -243,6 +264,9 @@
return null //no wound
/** CUTS **/
/datum/wound/cut/bleeding()
return ..() || wound_damage() >= 5
/datum/wound/cut/small
// link wound descriptions to amounts of damage
// Minor cuts have max_bleeding_stage set to the stage that bears the wound type's name.
@@ -276,7 +300,43 @@ datum/wound/cut/massive
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
damage_type = CUT
/** PUNCTURES **/
/datum/wound/puncture/can_worsen(damage_type, damage)
return 0
/datum/wound/puncture/can_merge(var/datum/wound/other)
return 0
/datum/wound/puncture/bleeding()
return ..() || wound_damage() >= 5
/datum/wound/puncture/small
max_bleeding_stage = 2
stages = list("puncture" = 5, "healing puncture" = 2, "small scab" = 0)
damage_type = PIERCE
/datum/wound/puncture/flesh
max_bleeding_stage = 2
stages = list("puncture wound" = 15, "blood soaked clot" = 5, "large scab" = 2, "small round scar" = 0)
damage_type = PIERCE
/datum/wound/puncture/gaping
max_bleeding_stage = 3
stages = list("gaping hole" = 30, "large blood soaked clot" = 15, "blood soaked clot" = 10, "small angry scar" = 5, "small round scar" = 0)
damage_type = PIERCE
/datum/wound/puncture/gaping_big
max_bleeding_stage = 3
stages = list("big gaping hole" = 50, "healing gaping hole" = 20, "large blood soaked clot" = 15, "large angry scar" = 10, "large round scar" = 0)
damage_type = PIERCE
datum/wound/puncture/massive
max_bleeding_stage = 3
stages = list("massive wound" = 60, "massive healing wound" = 30, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
damage_type = PIERCE
/** BRUISES **/
/datum/wound/bruise/bleeding()
return ..() || wound_damage() >= 20
/datum/wound/bruise
stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,
"moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
@@ -285,6 +345,11 @@ datum/wound/cut/massive
damage_type = BRUISE
/** BURNS **/
/datum/wound/burn
max_bleeding_stage = 0
/datum/wound/burn/bleeding()
return 0
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
damage_type = BURN
@@ -318,15 +383,15 @@ datum/wound/cut/massive
/datum/wound/lost_limb/New(var/obj/item/organ/external/lost_limb, var/losstype, var/clean)
var/damage_amt = lost_limb.max_damage
if(clean) damage_amt /= 2
switch(losstype)
if(DROPLIMB_EDGE, DROPLIMB_BLUNT)
damage_type = CUT
max_bleeding_stage = 3 //clotted stump and above can bleed.
stages = list(
"ripped stump" = damage_amt*1.3,
"bloody stump" = damage_amt,
"clotted stump" = damage_amt*0.5,
"bloody stump" = damage_amt,
"clotted stump" = damage_amt*0.5,
"scarred stump" = 0
)
if(DROPLIMB_BURN)
@@ -337,7 +402,7 @@ datum/wound/cut/massive
"scarred stump" = damage_amt*0.5,
"scarred stump" = 0
)
..(damage_amt)
/datum/wound/lost_limb/can_merge(var/datum/wound/other)

View File

@@ -14,7 +14,6 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
use_power = 1
idle_power_usage = 30
active_power_usage = 200
frame_type = "fax"
var/obj/item/weapon/card/id/scan = null // identification
var/authenticated = 0
@@ -29,6 +28,16 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
if( !(("[department]" in alldepartments) || ("[department]" in admin_departments)) )
alldepartments |= department
/obj/machinery/photocopier/faxmachine/map/New()
..()
circuit = new circuit(src)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/motor(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
RefreshParts()
/obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob)
user.set_machine(src)

View File

@@ -10,13 +10,13 @@
active_power_usage = 200
power_channel = EQUIP
circuit = /obj/item/weapon/circuitboard/photocopier
frame_type = "photocopier"
var/obj/item/copyitem = null //what's in the copier!
var/copies = 1 //how many copies to print!
var/toner = 30 //how much toner is left! woooooo~
var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
/obj/machinery/photocopier/New()
/obj/machinery/photocopier/map/New()
circuit = new circuit(src)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/motor(src)

View File

@@ -16,7 +16,6 @@
/obj/machinery/power/smes/batteryrack/New()
..()
add_parts()
RefreshParts()
return

View File

@@ -344,7 +344,7 @@
PN.trigger_warning(5)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.siemens_coefficient == 0)
if(H.species.siemens_coefficient <= 0)
return
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves

View File

@@ -1,7 +1,7 @@
// the SMES
// stores power
#define SMESRATE 0.05
#define SMESRATE 0.03333 //translates Watt into Kilowattminutes with respect to machinery schedule_interval ~(2s*1W*1min/60s)
#define SMESMAXCHARGELEVEL 250000
#define SMESMAXOUTPUT 250000
@@ -301,14 +301,17 @@
var/data[0]
data["nameTag"] = name_tag
data["storedCapacity"] = round(100.0*charge/capacity, 0.1)
data["storedCapacityAbs"] = round(charge/(1000*60), 0.1)
data["storedCapacityMax"] = round(capacity/(1000*60))
data["charging"] = inputting
data["chargeMode"] = input_attempt
data["chargeLevel"] = input_level
data["chargeMax"] = input_level_max
data["chargeLevel"] = round(input_level/1000, 0.1)
data["chargeMax"] = round(input_level_max/1000)
data["chargeLoad"] = round(terminal.powernet.avail/1000, 0.1)
data["outputOnline"] = output_attempt
data["outputLevel"] = output_level
data["outputMax"] = output_level_max
data["outputLoad"] = round(output_used)
data["outputLevel"] = round(output_level/1000, 0.1)
data["outputMax"] = round(output_level_max/1000)
data["outputLoad"] = round(output_used/1000, 0.1)
if(outputting)
data["outputting"] = 2 // smes is outputting
@@ -351,7 +354,7 @@
if("max")
input_level = input_level_max
if("set")
input_level = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", input_level) as num
input_level = (input(usr, "Enter new input level (0-[input_level_max/1000] kW)", "SMES Input Power Control", input_level/1000) as num) * 1000
input_level = max(0, min(input_level_max, input_level)) // clamp to range
else if( href_list["output"] )
@@ -361,7 +364,7 @@
if("max")
output_level = output_level_max
if("set")
output_level = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output_level) as num
output_level = (input(usr, "Enter new output level (0-[output_level_max/1000] kW)", "SMES Output Power Control", output_level/1000) as num) * 1000
output_level = max(0, min(output_level_max, output_level)) // clamp to range
investigate_log("input/output; <font color='[input_level>output_level?"green":"red"][input_level]/[output_level]</font> | Output-mode: [output_attempt?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [input_attempt?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [usr.key]","singulo")

View File

@@ -12,29 +12,29 @@
icon = 'icons/obj/stock_parts.dmi'
icon_state = "smes_coil" // Just few icons patched together. If someone wants to make better icon, feel free to do so!
w_class = 4.0 // It's LARGE (backpack size)
var/ChargeCapacity = 5000000
var/IOCapacity = 250000
var/ChargeCapacity = 6000000 // 100 kWh
var/IOCapacity = 250000 // 250 kW
// 20% Charge Capacity, 60% I/O Capacity. Used for substation/outpost SMESs.
/obj/item/weapon/smes_coil/weak
name = "basic superconductive magnetic coil"
desc = "Cheaper model of standard superconductive magnetic coil. It's capacity and I/O rating are considerably lower."
ChargeCapacity = 1000000
IOCapacity = 150000
ChargeCapacity = 1200000 // 20 kWh
IOCapacity = 150000 // 150 kW
// 1000% Charge Capacity, 20% I/O Capacity
/obj/item/weapon/smes_coil/super_capacity
name = "superconductive capacitance coil"
desc = "Specialised version of standard superconductive magnetic coil. This one has significantly stronger containment field, allowing for significantly larger power storage. It's IO rating is much lower, however."
ChargeCapacity = 50000000
IOCapacity = 50000
ChargeCapacity = 60000000 // 1000 kWh
IOCapacity = 50000 // 50 kW
// 10% Charge Capacity, 400% I/O Capacity. Technically turns SMES into large super capacitor.Ideal for shields.
/obj/item/weapon/smes_coil/super_io
name = "superconductive transmission coil"
desc = "Specialised version of standard superconductive magnetic coil. While this one won't store almost any power, it rapidly transfers power, making it useful in systems which require large throughput."
ChargeCapacity = 500000
IOCapacity = 1000000
ChargeCapacity = 600000 // 10 kWh
IOCapacity = 1000000 // 1000 kW
// SMES SUBTYPES - THESE ARE MAPPED IN AND CONTAIN DIFFERENT TYPES OF COILS

View File

@@ -142,6 +142,10 @@
name = "magazine (5.56mm practice)"
ammo_type = /obj/item/ammo_casing/a556p
/obj/item/ammo_magazine/a556/ap
name = "magazine (5.56mm armor-piercing)"
ammo_type = /obj/item/ammo_casing/a556/ap
/obj/item/ammo_magazine/a50
name = "magazine (.50)"
icon_state = "50ae"
@@ -179,6 +183,10 @@
max_ammo = 50
multiple_sprites = 1
/obj/item/ammo_magazine/a762/ap
name = "magazine box (7.62mm armor-piercing)"
ammo_type = /obj/item/ammo_casing/a762/ap
/obj/item/ammo_magazine/a762/empty
initial_ammo = 0
@@ -192,6 +200,10 @@
max_ammo = 20
multiple_sprites = 1
/obj/item/ammo_magazine/c762/ap
name = "magazine (7.62mm armor-piercing)"
ammo_type = /obj/item/ammo_casing/a762/ap
/obj/item/ammo_magazine/caps
name = "speed loader (caps)"
icon_state = "T38"
@@ -201,6 +213,7 @@
matter = list(DEFAULT_WALL_MATERIAL = 600)
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/g12
name = "magazine (12 gauge)"
icon_state = "g12"

View File

@@ -133,6 +133,11 @@
caliber = "a762"
projectile_type = /obj/item/projectile/bullet/rifle/a762
/obj/item/ammo_casing/a762/ap
desc = "A 7.62mm armor-piercing bullet casing."
caliber = "a762"
projectile_type = /obj/item/projectile/bullet/rifle/a762/ap
/obj/item/ammo_casing/a145
name = "shell casing"
desc = "A 14.5mm shell."
@@ -147,6 +152,11 @@
caliber = "a556"
projectile_type = /obj/item/projectile/bullet/rifle/a556
/obj/item/ammo_casing/a556/ap
desc = "A 5.56mm armor-piercing bullet casing."
caliber = "a556"
projectile_type = /obj/item/projectile/bullet/rifle/a556/ap
/obj/item/ammo_casing/a556p
desc = "A 5.56mm practice bullet casing."
caliber = "a556"

View File

@@ -66,6 +66,7 @@
var/mode_name = null
var/requires_two_hands
var/wielded_icon = "gun_wielded"
var/one_handed_penalty = 0 // Penalty applied if someone fires a two-handed gun with one hand.
var/next_fire_time = 0
@@ -182,8 +183,8 @@
var/held_disp_mod = 0
if(requires_two_hands)
if(user.item_is_in_hands(src) && user.hands_are_full())
held_acc_mod = -3
held_disp_mod = 3
held_acc_mod = held_acc_mod - one_handed_penalty
held_disp_mod = held_disp_mod - round(one_handed_penalty / 2)
//actually attempt to shoot
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
@@ -211,6 +212,12 @@
target = targloc
pointblank = 0
// We do this down here, so we don't get the message if we fire an empty gun.
if(requires_two_hands)
if(user.item_is_in_hands(src) && user.hands_are_full())
if(one_handed_penalty >= 2)
user << "<span class='warning'>You struggle to keep \the [src] pointed at the correct position with just one hand!</span>"
admin_attack_log(usr, attacker_message="Fired [src]", admin_message="fired a gun ([src]) (MODE: [src.mode_name]) [reflex ? "by reflex" : "manually"].")
//update timing

View File

@@ -1,6 +1,7 @@
/obj/item/weapon/gun/energy/laser
name = "laser carbine"
desc = "An Hesphaistos Industries G40E carbine, designed to kill with concentrated energy blasts."
desc = "An Hesphaistos Industries G40E carbine, designed to kill with concentrated energy blasts. This varient has the ability to \
switch between standard fire and a more efficent but weaker 'suppressive' fire."
icon_state = "laser"
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
@@ -10,16 +11,29 @@
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
matter = list(DEFAULT_WALL_MATERIAL = 2000)
projectile_type = /obj/item/projectile/beam/midlaser
// requires_two_hands = 1
one_handed_penalty = 2
firemodes = list(
list(mode_name="normal", projectile_type=/obj/item/projectile/beam/midlaser, charge_cost = 200),
list(mode_name="suppressive", projectile_type=/obj/item/projectile/beam/weaklaser, charge_cost = 50),
)
/obj/item/weapon/gun/energy/laser/mounted
self_recharge = 1
use_external_power = 1
requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
/obj/item/weapon/gun/energy/laser/practice
name = "practice laser carbine"
desc = "A modified version of the HI G40E, this one fires less concentrated energy bolts designed for target practice."
projectile_type = /obj/item/projectile/beam/practice
firemodes = list(
list(mode_name="normal", projectile_type=/obj/item/projectile/beam/practice, charge_cost = 200),
list(mode_name="suppressive", projectile_type=/obj/item/projectile/beam/practice, charge_cost = 50),
)
obj/item/weapon/gun/energy/retro
name = "retro laser"
icon_state = "retro"
@@ -47,7 +61,8 @@ obj/item/weapon/gun/energy/retro
/obj/item/weapon/gun/energy/lasercannon
name = "laser cannon"
desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron \
flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
icon_state = "lasercannon"
item_state = null
fire_sound = 'sound/weapons/lasercannonfire.ogg'
@@ -55,30 +70,36 @@ obj/item/weapon/gun/energy/retro
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = /obj/item/projectile/beam/heavylaser
charge_cost = 400
max_shots = 5
max_shots = 6
fire_delay = 20
// requires_two_hands = 1
one_handed_penalty = 6 // The thing's heavy and huge.
accuracy = 2
/obj/item/weapon/gun/energy/lasercannon/mounted
name = "mounted laser cannon"
self_recharge = 1
use_external_power = 1
recharge_time = 10
accuracy = 0 // Mounted cannons are just fine the way they are.
requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
/obj/item/weapon/gun/energy/xray
name = "xray laser gun"
desc = "A high-power laser gun capable of expelling concentrated xray blasts."
desc = "A high-power laser gun capable of expelling concentrated xray blasts, which are able to penetrate matter easier than \
standard photonic beams, resulting in an effective 'anti-armor' energy weapon."
icon_state = "xray"
item_state = "xray"
fire_sound = 'sound/weapons/laser3.ogg'
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 3, TECH_MAGNET = 2, TECH_ILLEGAL = 2)
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 3, TECH_MAGNET = 2)
projectile_type = /obj/item/projectile/beam/xray
charge_cost = 100
max_shots = 20
fire_delay = 1
max_shots = 12
/obj/item/weapon/gun/energy/sniperrifle
name = "marksman energy rifle"
desc = "The HI DMR 9E is an older design of Hesphaistos Industries. A designated marksman rifle capable of shooting powerful ionized beams, this is a weapon to kill from a distance."
desc = "The HI DMR 9E is an older design of Hesphaistos Industries. A designated marksman rifle capable of shooting powerful \
ionized beams, this is a weapon to kill from a distance."
icon_state = "sniper"
item_state = "laser"
fire_sound = 'sound/weapons/marauder.ogg'
@@ -92,6 +113,8 @@ obj/item/weapon/gun/energy/retro
w_class = 5 // So it can't fit in a backpack.
accuracy = -3 //shooting at the hip
scoped_accuracy = 0
// requires_two_hands = 1
one_handed_penalty = 4 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand.
/obj/item/weapon/gun/energy/sniperrifle/verb/scope()
set category = "Object"

View File

@@ -5,13 +5,14 @@
item_state = null //so the human update icon uses the icon_state instead.
fire_sound = 'sound/weapons/Taser.ogg'
max_shots = 10
fire_delay = 10 // Handguns should be inferior to two-handed weapons.
projectile_type = /obj/item/projectile/beam/stun
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
modifystate = "energystun"
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="energystun", fire_sound='sound/weapons/Taser.ogg'),
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="energystun", fire_sound='sound/weapons/Taser.ogg'),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill", fire_sound='sound/weapons/Laser.ogg'),
)
@@ -33,6 +34,9 @@
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3)
modifystate = "fm-2tstun"
// requires_two_hands = 1
one_handed_penalty = 2
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'),
list(mode_name="stun 3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), projectile_type=/obj/item/projectile/beam/stun, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'),
@@ -50,6 +54,9 @@
self_recharge = 1
modifystate = null
// requires_two_hands = 1
one_handed_penalty = 1 // It's rather bulky, so holding it in one hand is a little harder than with two, however it's not 'required'.
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg'),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_sound='sound/weapons/Laser.ogg'),

View File

@@ -13,12 +13,12 @@
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg', fire_delay=null, charge_cost=null),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_sound='sound/weapons/Laser.ogg', fire_delay=null, charge_cost=null),
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/pulse.ogg', fire_delay=25, charge_cost=400),
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/pulse.ogg', fire_delay=null, charge_cost=100),
)
/obj/item/weapon/gun/energy/pulse_rifle/mounted
self_recharge = 1
use_external_power = 1
use_external_power = 1
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
name = "pulse destroyer"

View File

@@ -1,10 +1,10 @@
/obj/item/weapon/gun/energy/taser
name = "taser gun"
desc = "The NT Mk30 NL is a small, low capacity gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T design."
desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T design."
icon_state = "taser"
item_state = null //so the human update icon uses the icon_state instead.
fire_sound = 'sound/weapons/Taser.ogg'
max_shots = 5
max_shots = 10
projectile_type = /obj/item/projectile/beam/stun
/obj/item/weapon/gun/energy/taser/mounted
@@ -25,7 +25,7 @@
item_state = "stunrevolver"
fire_sound = 'sound/weapons/Gunshot.ogg'
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
projectile_type = /obj/item/projectile/energy/electrode
projectile_type = /obj/item/projectile/energy/electrode/strong
max_shots = 8

View File

@@ -11,6 +11,10 @@
ammo_type = /obj/item/ammo_casing/c9mm
multi_aim = 1
burst_delay = 2
// requires_two_hands = 1
one_handed_penalty = 1
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
@@ -44,6 +48,9 @@
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
// requires_two_hands = 1
one_handed_penalty = 2
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
..()
if(ammo_magazine)
@@ -65,6 +72,8 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/c762
one_handed_penalty = 4
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6)),
@@ -115,6 +124,8 @@
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
one_handed_penalty = 4
burst_delay = 4
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, use_launcher=null, burst_accuracy=null, dispersion=null),
@@ -149,12 +160,13 @@
else
..()
/obj/item/weapon/gun/projectile/automatic/z8/update_icon()
/obj/item/weapon/gun/projectile/automatic/z8/update_icon(var/ignore_inhands)
..()
if(ammo_magazine)
icon_state = "carbine-[round(ammo_magazine.stored_ammo.len,2)]"
else
icon_state = "carbine"
if(!ignore_inhands) update_held_icon()
return
/obj/item/weapon/gun/projectile/automatic/z8/examine(mob/user)
@@ -181,6 +193,8 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/a762
one_handed_penalty = 6
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
@@ -240,6 +254,8 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/g12
one_handed_penalty = 4
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0),
list(mode_name="3-round bursts", burst=3, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.0, 0.6, 0.6)),

View File

@@ -23,6 +23,11 @@
check_armour = "laser"
eyeblur = 2
/obj/item/projectile/beam/weaklaser
name = "weak laser"
icon_state = "laser"
damage = 15
/obj/item/projectile/beam/midlaser
damage = 40
armor_penetration = 10
@@ -37,15 +42,6 @@
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
/obj/item/projectile/beam/weaklaser
name = "weak laser"
icon_state = "laser"
damage = 15
muzzle_type = /obj/effect/projectile/laser_heavy/muzzle
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
/obj/item/projectile/beam/xray
name = "xray beam"
icon_state = "xray"
@@ -160,11 +156,4 @@
/obj/item/projectile/beam/stun/weak
name = "weak stun beam"
icon_state = "stun"
nodamage = 1
taser_effect = 1
agony = 25
damage_type = HALLOSS
muzzle_type = /obj/effect/projectile/stun/muzzle
tracer_type = /obj/effect/projectile/stun/tracer
impact_type = /obj/effect/projectile/stun/impact

View File

@@ -169,15 +169,23 @@
/* "Rifle" rounds */
/obj/item/projectile/bullet/rifle
armor_penetration = 20
armor_penetration = 15
penetrating = 1
/obj/item/projectile/bullet/rifle/a762
damage = 25
/obj/item/projectile/bullet/rifle/a762/ap
damage = 20
armor_penetration = 50 // At 40 or more armor, this will do more damage than standard rounds.
/obj/item/projectile/bullet/rifle/a556
damage = 35
/obj/item/projectile/bullet/rifle/a556/ap
damage = 30
armor_penetration = 50 // At 30 or more armor, this will do more damage than standard rounds.
/obj/item/projectile/bullet/rifle/a145
damage = 80
stun = 3

View File

@@ -28,7 +28,7 @@
//snap pop
playsound(src, 'sound/effects/snap.ogg', 50, 1)
src.visible_message("<span class='warning'>\The [src] explodes in a bright flash!</span>")
new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows
new /obj/effect/effect/sparks(T)
new /obj/effect/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration)
@@ -49,6 +49,9 @@
damage_type = HALLOSS
//Damage will be handled on the MOB side, to prevent window shattering.
/obj/item/projectile/energy/electrode/strong
agony = 55
/obj/item/projectile/energy/electrode/stunshot
name = "stunshot"
damage = 5

View File

@@ -21,7 +21,7 @@
var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null
var/mode = 0
var/condi = 0
var/useramount = 30 // Last used amount
var/useramount = 15 // Last used amount
var/pillamount = 10
var/bottlesprite = "bottle-1" //yes, strings
var/pillsprite = "1"
@@ -265,6 +265,8 @@
dat += "<A href='?src=\ref[src];add=[G.id];amount=1'>(1)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=5'>(5)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=10'>(10)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=30'>(30)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=60'>(60)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=[G.volume]'>(All)</A> "
dat += "<A href='?src=\ref[src];addcustom=[G.id]'>(Custom)</A><BR>"
@@ -276,6 +278,8 @@
dat += "<A href='?src=\ref[src];remove=[N.id];amount=1'>(1)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=5'>(5)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=10'>(10)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=30'>(30)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=60'>(60)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=[N.volume]'>(All)</A> "
dat += "<A href='?src=\ref[src];removecustom=[N.id]'>(Custom)</A><BR>"
else

View File

@@ -476,9 +476,11 @@
/datum/reagent/slimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species.name != "Slime")
if(H.species.name != "Promethean")
M << "<span class='danger'>Your flesh rapidly mutates!</span>"
H.set_species("Slime")
H.set_species("Promethean")
H.shapeshifter_set_colour("#05FF9B")
H.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_colour
/datum/reagent/aslimetoxin
name = "Advanced Mutation Toxin"

View File

@@ -8,6 +8,7 @@
volume = 30
unacidable = 1 //glass
center_of_mass = list("x"=16, "y"=10)
matter = list("glass" = 500)
on_reagent_change()
/*if(reagents.reagent_list.len > 1 )

View File

@@ -2892,6 +2892,19 @@
var/list/boxes = list() // If the boxes are stacked, they come here
var/boxtag = ""
/obj/item/pizzabox/proc/closepizzabox()
if( boxes.len > 0 )
return
open = !open
if( open && pizza )
ismessy = 1
update_icon()
/obj/item/pizzabox/update_icon()
overlays = list()
@@ -2970,15 +2983,12 @@
/obj/item/pizzabox/attack_self( mob/user as mob )
if( boxes.len > 0 )
return
closepizzabox()
open = !open
/obj/item/pizzabox/AltClick()
if( open && pizza )
ismessy = 1
update_icon()
if(Adjacent(usr))
closepizzabox()
/obj/item/pizzabox/attackby( obj/item/I as obj, mob/user as mob )
if( istype(I, /obj/item/pizzabox/) )

View File

@@ -9,7 +9,6 @@
layer = 2 // so they appear under stuff
anchored = 1
circuit = /obj/item/weapon/circuitboard/conveyor
frame_type = "conveyor"
var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off
var/operable = 1 // true if can operate (no broken segments in this belt run)
var/forwards // this is the default (forward) direction, set by the map dir
@@ -39,6 +38,9 @@
operating = 1
setmove()
/obj/machinery/conveyor/map/New()
..()
circuit = new circuit(src)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/gear(src)
component_parts += new /obj/item/weapon/stock_parts/motor(src)

Some files were not shown because too many files have changed in this diff Show More