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

This commit is contained in:
Anewbe
2018-07-21 12:49:19 -05:00
116 changed files with 1379 additions and 299 deletions

View File

@@ -12,7 +12,7 @@
else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC.
var/datum/antagonist/A = get_antag_data(usr.mind.special_role)
if(!A || !A.can_use_aooc)
if(!A || !A.can_speak_aooc || !A.can_hear_aooc)
to_chat(usr, "<span class='warning'>Sorry, but your antagonist type is not allowed to speak in AOOC.</span>")
return
@@ -36,7 +36,7 @@
var/datum/antagonist/A = null
if(M.mind) // Observers don't have minds, but they should still see AOOC.
A = get_antag_data(M.mind.special_role)
if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
if((M.mind && M.mind.special_role && A && A.can_hear_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
to_chat(M, "<span class='ooc'><span class='aooc'>[create_text_tag("aooc", "Antag-OOC:", M.client)] <EM>[player_display]:</EM> <span class='message'>[msg]</span></span></span>")
log_aooc(msg,src)

View File

@@ -0,0 +1,184 @@
/obj/item/weapon/deadringer
name = "silver pocket watch"
desc = "A fancy silver-plated digital pocket watch. Looks expensive."
icon = 'icons/obj/deadringer.dmi'
icon_state = "deadringer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_ID | SLOT_BELT | SLOT_TIE
origin_tech = list(TECH_ILLEGAL = 3)
var/activated = 0
var/timer = 0
var/bruteloss_prev = 999999
var/fireloss_prev = 999999
var/mob/living/carbon/human/corpse = null
var/mob/living/carbon/human/watchowner = null
/obj/item/weapon/deadringer/New()
..()
processing_objects |= src
/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch
uncloak()
processing_objects -= src
..()
/obj/item/weapon/deadringer/dropped()
if(timer > 20)
uncloak()
watchowner = null
return
/obj/item/weapon/deadringer/attack_self(var/mob/living/user as mob)
var/mob/living/H = src.loc
if (!istype(H, /mob/living/carbon/human))
to_chat(H,"<font color='blue'>You have no clue what to do with this thing.</font>")
return
if(!activated)
if(timer == 0)
to_chat(H, "<font color='blue'>You press a small button on [src]'s side. It starts to hum quietly.</font>")
bruteloss_prev = H.getBruteLoss()
fireloss_prev = H.getFireLoss()
activated = 1
return
else
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It buzzes a little.</font>")
return
if(activated)
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It stops humming.</font>")
activated = 0
return
/obj/item/weapon/deadringer/process()
if(activated)
if (ismob(src.loc))
var/mob/living/carbon/human/H = src.loc
watchowner = H
if(H.getBruteLoss() > bruteloss_prev || H.getFireLoss() > fireloss_prev)
deathprevent()
activated = 0
if(watchowner.isSynthetic())
to_chat(watchowner, "<font color='blue'>You fade into nothingness! [src]'s screen blinks, being unable to copy your synthetic body!</font>")
else
to_chat(watchowner, "<font color='blue'>You fade into nothingness, leaving behind a fake body!</font>")
icon_state = "deadringer_cd"
timer = 50
return
if(timer > 0)
timer--
if(timer == 20)
uncloak()
if(corpse)
new /obj/effect/effect/smoke/chem(corpse.loc)
qdel(corpse)
if(timer == 0)
icon_state = "deadringer"
return
/obj/item/weapon/deadringer/proc/deathprevent()
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
watchowner.emote("deathgasp")
watchowner.invisibility = 85
watchowner.alpha = 127
makeacorpse(watchowner)
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
return
/obj/item/weapon/deadringer/proc/uncloak()
if(watchowner)
watchowner.invisibility = 0
watchowner.alpha = 255
playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1)
return
/obj/item/weapon/deadringer/proc/makeacorpse(var/mob/living/carbon/human/H)
if(H.isSynthetic())
return
corpse = new /mob/living/carbon/human(H.loc)
corpse.setDNA(H.dna.Clone())
corpse.death(1) //Kills the new mob
var/obj/item/clothing/temp = null
if(H.get_equipped_item(slot_w_uniform))
corpse.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon/changeling(corpse), slot_w_uniform)
temp = corpse.get_equipped_item(slot_w_uniform)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_w_uniform)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_suit))
corpse.equip_to_slot_or_del(new /obj/item/clothing/suit/chameleon/changeling(corpse), slot_wear_suit)
temp = corpse.get_equipped_item(slot_wear_suit)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_suit)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_shoes))
corpse.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon/changeling(corpse), slot_shoes)
temp = corpse.get_equipped_item(slot_shoes)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_shoes)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_gloves))
corpse.equip_to_slot_or_del(new /obj/item/clothing/gloves/chameleon/changeling(corpse), slot_gloves)
temp = corpse.get_equipped_item(slot_gloves)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_gloves)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_l_ear))
temp = H.get_equipped_item(slot_l_ear)
corpse.equip_to_slot_or_del(new temp.type(corpse), slot_l_ear)
temp = corpse.get_equipped_item(slot_l_ear)
temp.canremove = 0
if(H.get_equipped_item(slot_glasses))
corpse.equip_to_slot_or_del(new /obj/item/clothing/glasses/chameleon/changeling(corpse), slot_glasses)
temp = corpse.get_equipped_item(slot_glasses)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_glasses)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_mask))
corpse.equip_to_slot_or_del(new /obj/item/clothing/mask/chameleon/changeling(corpse), slot_wear_mask)
temp = corpse.get_equipped_item(slot_wear_mask)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_mask)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_head))
corpse.equip_to_slot_or_del(new /obj/item/clothing/head/chameleon/changeling(corpse), slot_head)
temp = corpse.get_equipped_item(slot_head)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_head)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_belt))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/chameleon/changeling(corpse), slot_belt)
temp = corpse.get_equipped_item(slot_belt)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_belt)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_back))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chameleon/changeling(corpse), slot_back)
temp = corpse.get_equipped_item(slot_back)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_back)
temp.disguise(c_type.type)
temp.canremove = 0
corpse.identifying_gender = H.identifying_gender
corpse.flavor_texts = H.flavor_texts.Copy()
corpse.real_name = H.real_name
corpse.name = H.name
corpse.set_species(corpse.dna.species)
corpse.change_hair(H.h_style)
corpse.change_facial_hair(H.f_style)
corpse.change_hair_color(H.r_hair, H.g_hair, H.b_hair)
corpse.change_facial_hair_color(H.r_facial, H.g_facial, H.b_facial)
corpse.change_skin_color(H.r_skin, H.g_skin, H.b_skin)
corpse.adjustFireLoss(H.getFireLoss())
corpse.adjustBruteLoss(H.getBruteLoss())
corpse.UpdateAppearance()
corpse.regenerate_icons()
for(var/obj/item/organ/internal/I in corpse.internal_organs)
var/obj/item/organ/internal/G = I
G.Destroy()
return

View File

@@ -250,9 +250,8 @@
return
/obj/effect/beam/i_beam/Destroy()
. = ..()
if(master.first == src)
master.first = null
if(next)
qdel(next)
next = null
..()
if(next && !next.gc_destroyed)
qdel_null(next)

View File

@@ -71,8 +71,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
. += "<b>Nickname:</b> "
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</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>Biological Sex:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Pronouns:</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)
@@ -111,13 +111,13 @@ datum/preferences/proc/set_biological_gender(var/gender)
return TOPIC_NOACTION
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()
var/new_gender = input(user, "Choose your character's biological sex:", "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_UPDATE_PREVIEW
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
var/new_gender = input(user, "Choose your character's pronouns:", "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
@@ -158,4 +158,4 @@ datum/preferences/proc/set_biological_gender(var/gender)
return possible_genders
possible_genders = possible_genders.Copy()
possible_genders |= NEUTER
return possible_genders
return possible_genders

View File

@@ -36,6 +36,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] >> pref.r_synth
S["synth_green"] >> pref.g_synth
S["synth_blue"] >> pref.b_synth
S["synth_markings"] >> pref.synth_markings
pref.preview_icon = null
S["bgstate"] >> pref.bgstate
@@ -65,6 +66,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] << pref.r_synth
S["synth_green"] << pref.g_synth
S["synth_blue"] << pref.b_synth
S["synth_markings"] << pref.synth_markings
S["bgstate"] << pref.bgstate
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
@@ -120,6 +122,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
character.r_synth = pref.r_synth
character.g_synth = pref.g_synth
character.b_synth = pref.b_synth
character.synth_markings = pref.synth_markings
// Destroy/cyborgize organs and limbs.
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
@@ -305,6 +308,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<br>"
. += "<br>"
. += "<b>Allow Synth markings:</b> <a href='?src=\ref[src];synth_markings=1'><b>[pref.synth_markings ? "Yes" : "No"]</b></a><br>"
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
if(pref.synth_color)
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><tr><td>__</td></tr></table></font> "
@@ -702,6 +706,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.b_synth = hex2num(copytext(new_color, 6, 8))
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth_markings"])
pref.synth_markings = !pref.synth_markings
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["cycle_bg"])
pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
return TOPIC_REFRESH_UPDATE_PREVIEW

View File

@@ -241,6 +241,46 @@ datum/gear/suit/duster
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
allowed_roles = list("Head of Personnel")
/datum/gear/suit/roles/poncho/cloak/cargo
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo
allowed_roles = list("Cargo Technician","Quartermaster")
/datum/gear/suit/roles/poncho/cloak/mining
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
allowed_roles = list("Quartermaster","Shaft Miner")
/datum/gear/suit/roles/poncho/cloak/security
display_name = "cloak, security"
path = /obj/item/clothing/accessory/poncho/roles/cloak/security
allowed_roles = list("Head of Security","Detective","Warden","Security Officer")
/datum/gear/suit/roles/poncho/cloak/service
display_name = "cloak, service"
path = /obj/item/clothing/accessory/poncho/roles/cloak/service
allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian")
/datum/gear/suit/roles/poncho/cloak/engineer
display_name = "cloak, engineer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer
allowed_roles = list("Chief Engineer","Station Engineer")
/datum/gear/suit/roles/poncho/cloak/atmos
display_name = "cloak, atmos"
path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos
allowed_roles = list("Chief Engineer","Atmospheric Technician")
/datum/gear/suit/roles/poncho/cloak/research
display_name = "cloak, science"
path = /obj/item/clothing/accessory/poncho/roles/cloak/research
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist")
/datum/gear/suit/roles/poncho/cloak/medical
display_name = "cloak, medical"
path = /obj/item/clothing/accessory/poncho/roles/cloak/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe

View File

@@ -114,12 +114,6 @@
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant
exploitable = 1
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
display_name = "implant, language, EAL"
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1
@@ -127,8 +121,20 @@
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 10
slot = "implant"
exploitable = 1
/datum/gear/utility/implant/language
cost = 2
exploitable = 0
/datum/gear/utility/implant/language/eal
display_name = "vocal synthesizer, EAL"
description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it."
path = /obj/item/weapon/implant/language/eal
/datum/gear/utility/implant/language/skrellian
display_name = "vocal synthesizer, Skrellian"
description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it."
path = /obj/item/weapon/implant/language/skrellian
/datum/gear/utility/pen
display_name = "Fountain Pen"

View File

@@ -60,6 +60,7 @@ datum/preferences
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enable/disable markings on synth parts.
//Some faction information.
var/home_system = "Unset" //System of birth.

View File

@@ -128,6 +128,7 @@
/obj/item/clothing/suit/syndicatefake
name = "red space suit replica"
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "syndicate"
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
w_class = ITEMSIZE_NORMAL

View File

@@ -121,8 +121,8 @@
* Cloak
*/
/obj/item/clothing/accessory/poncho/roles/cloak
name = "brown cloak"
desc = "An elaborate brown cloak."
name = "quartermaster's cloak"
desc = "An elaborate brown and gold cloak."
icon_state = "qmcloak"
item_state = "qmcloak"
body_parts_covered = null
@@ -169,6 +169,54 @@
icon_state = "capcloak"
item_state = "capcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/cargo
name = "brown cloak"
desc = "A simple brown and black cloak."
icon_state = "cargocloak"
item_state = "cargocloak"
/obj/item/clothing/accessory/poncho/roles/cloak/mining
name = "trimmed purple cloak"
desc = "A trimmed purple and brown cloak."
icon_state = "miningcloak"
item_state = "miningcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/security
name = "red cloak"
desc = "A simple red and black cloak."
icon_state = "seccloak"
item_state = "seccloak"
/obj/item/clothing/accessory/poncho/roles/cloak/service
name = "green cloak"
desc = "A simple green and blue cloak."
icon_state = "servicecloak"
item_state = "servicecloak"
/obj/item/clothing/accessory/poncho/roles/cloak/engineer
name = "gold cloak"
desc = "A simple gold and brown cloak."
icon_state = "engicloak"
item_state = "engicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/atmos
name = "yellow cloak"
desc = "A trimmed yellow and blue cloak."
icon_state = "atmoscloak"
item_state = "atmoscloak"
/obj/item/clothing/accessory/poncho/roles/cloak/research
name = "purple cloak"
desc = "A simple purple and white cloak."
icon_state = "scicloak"
item_state = "scicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/medical
name = "blue cloak"
desc = "A simple blue and white cloak."
icon_state = "medcloak"
item_state = "medcloak"
/obj/item/clothing/accessory/hawaii
name = "flower-pattern shirt"
desc = "You probably need some welder googles to look at this."

View File

@@ -162,13 +162,16 @@
return 1
var/cost = 1
if(isnull(current_category))
current_category = recipe_list[1]
if(ispath(build_type, /obj/item/device/electronic_assembly))
var/obj/item/device/electronic_assembly/E = build_type
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
else if(ispath(build_type, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = build_type
cost = initial(IC.w_class)
else
var/obj/item/I = build_type
cost = initial(I.w_class)
if(!(locate(build_type) in recipe_list[current_category]))
return
if(metal - cost < 0)
@@ -198,4 +201,4 @@
name = "integrated circuit printer upgrade disk - circuit cloner"
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
icon_state = "upgrade_disk_clone"
origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6)
origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6)

View File

@@ -53,6 +53,7 @@
recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0)
recipes += new/datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20)
recipes += new/datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20)
recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60)
recipes += new/datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1)

View File

@@ -168,6 +168,12 @@ var/list/mining_overlay_cache = list()
if(istype(get_step(src, direction), /turf/space) && !istype(get_step(src, direction), /turf/space/cracked_asteroid))
add_overlay(get_cached_border("asteroid_edge",direction,icon,"asteroid_edges", 0))
//Or any time
else
var/turf/T = get_step(src, direction)
if(istype(T) && T.density)
add_overlay(get_cached_border("rock_side",direction,'icons/turf/walls.dmi',"rock_side"))
if(overlay_detail)
add_overlay('icons/turf/flooring/decals.dmi',overlay_detail)

View File

@@ -133,6 +133,6 @@
key = "s"
flags = SIGNLANG|NO_STUTTER|NONVERBAL
/datum/language/sign/can_speak_special(var/mob/speaker)
/datum/language/sign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
return (hands || !iscarbon(speaker))

View File

@@ -133,7 +133,15 @@
return speech_verb
/datum/language/proc/can_speak_special(var/mob/speaker)
return 1
. = TRUE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(src.name in H.species.assisted_langs)
. = FALSE
var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever
if(vox)
if(!vox.is_broken() && (src in vox.assists_languages))
. = TRUE
// Language handling.
/mob/proc/add_language(var/language)

View File

@@ -63,6 +63,14 @@
"ka","aasi","far","wa","baq","ara","qara","zir","saam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
/datum/language/tajaran/get_random_name(var/gender)
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
/datum/language/tajaranakhani
name = LANGUAGE_AKHANI
desc = "The language of the sea-faring Njarir'Akhan Tajaran. Borrowing some elements from Siik, the language is distinctly more structured."
@@ -78,7 +86,7 @@
"nai","ou","kah","oa","ama","uuk","bel","chi","ayt","kay","kas","akor","tam","yir","enai")
/datum/language/tajsign
name = LANGUAGE_SIIK_ALAI
name = LANGUAGE_ALAI
desc = "A standardized Tajaran sign language that was developed in Zarraya and gradually adopted by other nations, incorporating \
hand gestures and movements of the ears and tail."
signlang_verb = list("gestures with their hands", "gestures with their ears and tail", "gestures with their ears, tail and hands")
@@ -86,14 +94,18 @@
key = "l"
flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL
/datum/language/tajaran/get_random_name(var/gender)
/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this.
if(iscarbon(speaker))
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
if(!hands)
return FALSE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(H.species.get_bodytype(H) in allowed_species)
return TRUE
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
return FALSE
/datum/language/skrell
name = LANGUAGE_SKRELLIAN
@@ -161,11 +173,6 @@
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz","shh","shk")
space_chance = 10
/datum/language/machine/can_speak_special(var/mob/speaker)
var/obj/item/weapon/implant/language/eal/beep = locate() in speaker
return ((beep && beep.implanted) || speaker.isSynthetic() || isvoice(speaker))
//thank you sweet zuhayr
/datum/language/machine/get_random_name()
if(prob(70))
return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"

View File

@@ -14,9 +14,10 @@
var/muzzled = is_muzzled()
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
for(var/obj/item/organ/O in src.organs)
for (var/obj/item/weapon/implant/I in O)
if (I.implanted)
I.trigger(act, src)
if(src.stat == 2.0 && (act != "deathgasp"))
return

View File

@@ -165,25 +165,12 @@
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if(update) UpdateDamageIcon()
/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/utility/implant)
var/obj/item/weapon/implant/I = new G.path(src)
I.imp_in = src
I.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += I
I.part = affected
I.implanted(src)
/mob/living/carbon/human/proc/implant_loyalty(override = FALSE) // Won't override by default.
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)
L.imp_in = src
L.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += L
L.part = affected
L.implanted(src)
if(L.handle_implant(src, BP_HEAD))
L.post_implant(src)
/mob/living/carbon/human/proc/is_loyalty_implanted()
for(var/L in src.contents)
@@ -1120,6 +1107,8 @@
remove_language(species.language)
if(species.default_language)
remove_language(species.default_language)
for(var/datum/language/L in species.assisted_langs)
remove_language(L)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
holder_type = null

View File

@@ -167,45 +167,35 @@ emp_act
//this proc returns the armour value for a particular external organ.
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
if(!type || !def_zone)
return 0
var/protection = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
var/list/protective_gear = def_zone.get_covering_clothing()
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & def_zone.body_part)
protection += gear.armor[type]
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & def_zone.body_part)
protection += bling.armor[type]
protection += gear.armor[type]
return protection
/mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
if(!type || !def_zone)
return 0
var/soaked = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
var/list/protective_gear = def_zone.get_covering_clothing()
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & def_zone.body_part)
soaked += gear.armorsoak[type]
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & def_zone.body_part)
soaked += bling.armorsoak[type]
soaked += gear.armorsoak[type]
return soaked
// Checked in borer code
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & HEAD)
return 1
var/obj/item/organ/external/H = organs_by_name[BP_HEAD]
var/list/body_parts = H.get_covering_clothing()
if(LAZYLEN(body_parts))
return 1
return 0
//Used to check if they can be fed food/drinks/pills
/mob/living/carbon/human/proc/check_mouth_coverage()
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform)
var/obj/item/organ/external/H = organs_by_name[BP_HEAD]
var/list/protective_gear = H.get_covering_clothing()
for(var/obj/item/gear in protective_gear)
if(istype(gear) && (gear.body_parts_covered & FACE) && !(gear.item_flags & FLEXIBLEMATERIAL))
return gear

View File

@@ -30,6 +30,7 @@
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enables/disables markings on synth parts.
var/damage_multiplier = 1 //multiplies melee combat damage
var/icon_update = 1 //whether icon updating shall take place

View File

@@ -70,6 +70,7 @@ Variables you may want to make use of are:
num_alternate_languages = 3
species_language = LANGUAGE_GALCOM
secondary_langs = list()
assisted_langs = list()
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 0

View File

@@ -25,6 +25,8 @@
genders = list(NEUTER)
assisted_langs = list()
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)
new /obj/effect/decal/cleanable/ash(H.loc)

View File

@@ -7,6 +7,7 @@
language = LANGUAGE_GALCOM
species_language = LANGUAGE_VOX
num_alternate_languages = 1
assisted_langs = list(LANGUAGE_ROOTGLOBAL)
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -71,6 +72,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart/vox,
O_LUNGS = /obj/item/organ/internal/lungs/vox,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver/vox,
O_KIDNEYS = /obj/item/organ/internal/kidneys/vox,
O_BRAIN = /obj/item/organ/internal/brain/vox,

View File

@@ -52,13 +52,17 @@
// Language/culture vars.
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/species_language = list(LANGUAGE_GALCOM) // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds = list() // A list of sounds to potentially play when speaking.
var/list/speech_chance = list() // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
// The languages the species can't speak without an assisted organ.
// This list is a guess at things that no one other than the parent species should be able to speak
var/list/assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
@@ -183,6 +187,7 @@
var/list/has_organ = list( // which required-organ checks are conducted.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -11,6 +11,8 @@
spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
assisted_langs = list()
breath_type = null
poison_type = null

View File

@@ -45,6 +45,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -30,6 +30,7 @@ var/datum/species/shapeshifter/promethean/prometheans
health_hud_intensity = 2
num_alternate_languages = 3
species_language = LANGUAGE_SOL_COMMON
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language.
breath_type = null
poison_type = null

View File

@@ -104,6 +104,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -12,6 +12,7 @@
species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS)
name_language = null // Use the first-name last-name generator rather than a language scrambler
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
min_age = 17
max_age = 130
@@ -157,7 +158,7 @@
metabolic_rate = 1.1
gluttonous = 1
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI, LANGUAGE_SIIK_ALAI)
secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI, LANGUAGE_ALAI)
name_language = LANGUAGE_SIIK
species_language = LANGUAGE_SIIK
health_hud_intensity = 2.5
@@ -215,6 +216,7 @@
has_organ = list( //No appendix.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -241,6 +243,7 @@
secondary_langs = list(LANGUAGE_SKRELLIAN, LANGUAGE_SCHECHI)
name_language = LANGUAGE_SKRELLIAN
species_language = LANGUAGE_SKRELLIAN
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
health_hud_intensity = 2
water_movement = -3
@@ -315,13 +318,14 @@
hud_type = /datum/hud_data/diona
siemens_coefficient = 0.3
show_ssd = "completely quiescent"
num_alternate_languages = 2
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
health_hud_intensity = 2.5
item_slowdown_mod = 0.25
num_alternate_languages = 2
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
assisted_langs = list(LANGUAGE_VOX) // Diona are weird, let's just assume they can use basically any language.
min_age = 1
max_age = 300

View File

@@ -16,6 +16,8 @@
speech_bubble_appearance = "cyber"
assisted_langs = list()
male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'

View File

@@ -5,6 +5,7 @@
default_language = "Xenomorph"
language = "Hivemind"
assisted_langs = list()
unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno, /datum/unarmed_attack/bite/strong/xeno)
hud_type = /datum/hud_data/alien
rarity_value = 3

View File

@@ -1239,4 +1239,8 @@ default behaviour is:
/mob/living/proc/has_vision()
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
/mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc.
return makes_dirt

View File

@@ -18,7 +18,6 @@
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/halloss = 0 //Hallucination damage. 'Fake' damage obtained through hallucinating or the holodeck. Sleeping should cause it to wear off.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
@@ -62,3 +61,5 @@
var/list/hud_list //Holder for health hud, status hud, wanted hud, etc (not like inventory slots)
var/has_huds = FALSE //Whether or not we should bother initializing the above list
var/makes_dirt = TRUE //FALSE if the mob shouldn't be making dirt on the ground when it walks

View File

@@ -64,6 +64,7 @@ var/list/ai_verbs_default = list(
var/datum/announcement/priority/announcement
var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object.
var/hologram_follow = 1 //This is used for the AI eye, to determine if a holopad's hologram should follow it or not.
var/is_dummy = 0 //Used to prevent dummy AIs from spawning with communicators.
//NEWMALF VARIABLES
var/malfunctioning = 0 // Master var that determines if AI is malfunctioning.
var/datum/malf_hardware/hardware = null // Installed piece of hardware.
@@ -111,15 +112,16 @@ var/list/ai_verbs_default = list(
possibleNames -= pickedName
pickedName = null
aiPDA = new/obj/item/device/pda/ai(src)
if(!is_dummy)
aiPDA = new/obj/item/device/pda/ai(src)
SetName(pickedName)
anchored = 1
canmove = 0
density = 1
loc = loc
aiCommunicator = new /obj/item/device/communicator/integrated(src)
if(!is_dummy)
aiCommunicator = new /obj/item/device/communicator/integrated(src)
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
@@ -792,6 +794,9 @@ var/list/ai_verbs_default = list(
return TRUE
//Special subtype kept around for global announcements
/mob/living/silicon/ai/announcer/
is_dummy = 1
/mob/living/silicon/ai/announcer/initialize()
. = ..()
mob_list -= src

View File

@@ -84,6 +84,7 @@ var/list/datum/ai_icon/ai_icons
/datum/ai_icon/glitchman
name = "Glitchman"
alive_icon = "ai-glitchman"
dead_icon = "ai-glitchman-crash"
/datum/ai_icon/goon
name = "Goon"
@@ -110,6 +111,7 @@ var/list/datum/ai_icon/ai_icons
name = "Inverted"
alive_icon = "ai-u"
alive_light = "#81DDFF"
dead_icon = "ai-u-crash"
/datum/ai_icon/lonestar
name = "Lonestar"
@@ -163,14 +165,87 @@ var/list/datum/ai_icon/ai_icons
/datum/ai_icon/trapped
name = "Trapped"
alive_icon = "ai-hades"
dead_icon = "ai-hades_dead"
dead_icon = "ai-hades-crash"
/datum/ai_icon/triumvirate_static
/datum/ai_icon/triumvirate
name = "Triumvirate"
alive_icon = "ai-triumvirate"
alive_light = "#020B2B"
/datum/ai_icon/triumvirate_static
name = "Triumvirate Static"
alive_icon = "ai-static"
alive_icon = "ai-triumvirate-malf"
alive_light = "#020B2B"
//Eros Research Platform Ports
/datum/ai_icon/clown2
name = "Honk"
alive_icon = "ai-clown2"
dead_icon = "ai-clown2-crash"
/datum/ai_icon/boxfort
name = "Boxfort"
alive_icon = "ai-boxfort"
dead_icon = "ai-boxfort_dead"
/datum/ai_icon/ravensdale
name = "Integration"
alive_icon = "ai-ravensdale"
dead_icon = "ai-ravensdale-crash"
/datum/ai_icon/gentoo
name = "Gentoo"
alive_icon = "ai-gentoo"
dead_icon = "ai-gentoo_dead"
/datum/ai_icon/serithi
name = "Mechanicus"
alive_icon = "ai-serithi"
dead_icon = "ai-serithi-crash"
/datum/ai_icon/alien
name = "Xenomorph"
alive_icon = "ai-alien"
dead_icon = "ai-alien-crash"
/datum/ai_icon/syndicat
name = "Syndi-cat"
alive_icon = "ai-syndicatmeow"
/datum/ai_icon/wasp
name = "Wasp"
alive_icon = "ai-wasp"
/datum/ai_icon/house
name = "Doctor"
alive_icon = "ai-house"
/datum/ai_icon/fabulous
name = "Fabulous"
alive_icon = "ai-fabulous"
/datum/ai_icon/yesman
name = "Yes Man"
alive_icon = "ai-yes-man"
dead_icon = "ai-alien-crash"
/datum/ai_icon/royal
name = "Royal"
alive_icon = "ai-royal"
/datum/ai_icon/pirate
name = "Pirate"
alive_icon = "ai-pirate"
/datum/ai_icon/gygas
name = "Love"
alive_icon = "ai-gygas"
/datum/ai_icon/xerxes
name = "Xerxes"
alive_icon = "ai-xerxes"
/datum/ai_icon/godfrey
name = "Godfrey"
alive_icon = "ai-godfrey"

View File

@@ -213,6 +213,7 @@ var/global/list/robot_modules = list(
..()
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/weapon/autopsy_scanner(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)

View File

@@ -148,6 +148,7 @@
src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src)
// Surgery things.
src.modules += new /obj/item/weapon/autopsy_scanner(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)

View File

@@ -763,6 +763,8 @@
var/mob/living/L = target_mob
if(L.stat != DEAD)
return 1
if(L.invisibility < INVISIBILITY_LEVEL_ONE)
return 1
if (istype(target_mob,/obj/mecha))
var/obj/mecha/M = target_mob
if (M.occupant)
@@ -882,6 +884,8 @@
continue
else if(L in friends)
continue
else if(L.invisibility >= INVISIBILITY_LEVEL_ONE)
continue
else if(!SA_attackable(L))
continue
else if(!special_target_check(L))
@@ -1209,7 +1213,7 @@
ai_log("AttackTarget() Bailing because we're disabled",2)
LoseTarget()
return 0
if(!target_mob || !SA_attackable(target_mob))
if(!target_mob || !SA_attackable(target_mob) || (target_mob.invisibility >= INVISIBILITY_LEVEL_ONE)) //if the target went invisible, you can't follow it
LoseTarget()
return 0
if(!(target_mob in ListTargets(view_range)))

View File

@@ -1257,6 +1257,24 @@
name = "Tattoo (Campbell, L.Arm)"
body_parts = list(BP_L_ARM)
rightleg
name = "Tattoo (Campbell, R.Leg)"
body_parts = list(BP_R_LEG)
leftleg
name = "Tattoo (Campbell, L.Leg)"
body_parts = list (BP_L_LEG)
tat_silverburgh
name = "Tattoo (Silverburgh, R.Leg)"
icon_state = "tat_silverburgh"
body_parts = list (BP_R_LEG)
left
name = "Tattoo (Silverburgh, L.Leg)"
icon_state = "tat_silverburgh"
body_parts = list (BP_L_LEG)
tat_tiger
name = "Tattoo (Tiger Stripes, Body)"
icon_state = "tat_tiger"

View File

@@ -0,0 +1,42 @@
/*
* Voicebox/Vocal Synthesizers
* TL;DR: Assists with speaking languages that a species doesn't normally have,
* such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters.
*/
/obj/item/organ/internal/voicebox
name = "larynx"
icon_state = "larynx"
parent_organ = BP_TORSO // We don't have a neck area
organ_tag = O_VOICE
will_assist_languages = list(LANGUAGE_GALCOM)
/obj/item/organ/internal/voicebox/New()
..()
amend_assist_langs()
/obj/item/organ/internal/voicebox/proc/amend_assist_langs() // Adds the list of language datums assisted by the voicebox to the list used in speaking
for(var/L in will_assist_languages)
assists_languages |= all_languages[L]
/obj/item/organ/internal/voicebox/proc/add_assistable_langs(var/language) // Adds a new language (by string/define) to the list of things the voicebox can assist
will_assist_languages |= language
amend_assist_langs() // Can't think of a better place to put this, makes the voicebox actually start to assist with the added language
/////////////////////////////////
// Voicebox Subtypes
/////////////////////////////////
/obj/item/organ/internal/voicebox/assist // In the off chance we get a species that doesn't speak GalCom by default
/obj/item/organ/internal/voicebox/assist/New()
..()
mechassist()
/obj/item/organ/internal/voicebox/robot
name = "vocal synthesizer"
will_assist_languages = list(LANGUAGE_GALCOM, LANGUAGE_EAL) // Synthetics spawn with this by default
/obj/item/organ/internal/voicebox/robot/New()
..()
robotize()

View File

@@ -31,6 +31,10 @@ var/list/organ_cache = list()
var/rejecting // Is this organ already being rejected?
var/preserved = 0 // If this is 1, prevents organ decay.
// Language vars. Putting them here in case we decide to do something crazy with sign-or-other-nonverbal languages.
var/list/will_assist_languages = list()
var/list/datum/language/assists_languages = list()
/obj/item/organ/Destroy()
if(owner) owner = null

View File

@@ -72,6 +72,8 @@
var/open = 0
var/stage = 0
var/cavity = 0
var/burn_stage = 0 //Surgical repair stage for burn.
var/brute_stage = 0 //Surgical repair stage for brute.
// HUD element variable, see organ_icon.dm get_damage_hud_image()
var/image/hud_damage_image
@@ -1328,3 +1330,18 @@ Note that amputating the affected organ does in fact remove the infection from t
if(6 to INFINITY)
flavor_text += "a ton of [wound]\s"
return english_list(flavor_text)
// Returns a list of the clothing (not glasses) that are covering this part
/obj/item/organ/external/proc/get_covering_clothing()
var/list/covering_clothing = list()
if(owner)
var/list/protective_gear = list(owner.head, owner.wear_mask, owner.wear_suit, owner.w_uniform, owner.gloves, owner.shoes)
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & src.body_part)
covering_clothing |= gear
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & src.body_part)
covering_clothing |= bling
return covering_clothing

View File

@@ -179,6 +179,14 @@ var/global/list/limb_icon_cache = list()
if(model)
icon_cache_key += "_model_[model]"
apply_colouration(mob_icon)
if(owner && owner.synth_markings)
for(var/M in markings)
var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"]
var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]")
mark_s.Blend(markings[M]["color"], ICON_ADD)
add_overlay(mark_s) //So when it's not on your body, it has icons
mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons
icon_cache_key += "[M][markings[M]["color"]]"
dir = EAST
icon = mob_icon

View File

@@ -25,8 +25,9 @@
/obj/item/organ/external/chest/robotize()
if(..())
// Give them a new cell.
owner.internal_organs_by_name["cell"] = new /obj/item/organ/internal/cell(owner,1)
// Give them fancy new organs.
owner.internal_organs_by_name[O_CELL] = new /obj/item/organ/internal/cell(owner,1)
owner.internal_organs_by_name[O_VOICE] = new /obj/item/organ/internal/voicebox/robot(owner, 1)
/obj/item/organ/external/chest/handle_germ_effects()
. = ..() //Should return an infection level

View File

@@ -134,7 +134,7 @@ var/global/photo_count = 0
var/icon_on = "camera"
var/icon_off = "camera_off"
var/size = 3
var/picture_planes = list(PLANE_WORLD)
var/list/picture_planes = list()
/obj/item/device/camera/verb/change_size()
set name = "Set Photo Focus"
@@ -185,7 +185,7 @@ var/global/photo_count = 0
// As well as anything that isn't invisible.
for(var/atom/A in the_turf)
if(A.invisibility) continue
if(!(A.plane in picture_planes)) continue
if(A.plane > 0 && !(A.plane in picture_planes)) continue
atoms.Add(A)
// Sort the atoms into their layers
@@ -194,7 +194,7 @@ var/global/photo_count = 0
for(var/i; i <= sorted.len; i++)
var/atom/A = sorted[i]
if(A)
var/icon/img = getFlatIcon(A, picture_planes = picture_planes)//build_composite_icon(A)
var/icon/img = getFlatIcon(A, picture_planes)//build_composite_icon(A)
// If what we got back is actually a picture, draw it.
if(istype(img, /icon))

View File

@@ -160,6 +160,7 @@ var/list/possible_cable_coil_colours = list(
return
if(istype(W, /obj/item/weapon/wirecutters))
var/obj/item/stack/cable_coil/CC
if(d1 == UP || d2 == UP)
to_chat(user, "<span class='warning'>You must cut this cable from above.</span>")
return
@@ -172,9 +173,12 @@ var/list/possible_cable_coil_colours = list(
return
if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long
new/obj/item/stack/cable_coil(T, 2, color)
CC = new/obj/item/stack/cable_coil(T, 2, color)
else
new/obj/item/stack/cable_coil(T, 1, color)
CC = new/obj/item/stack/cable_coil(T, 1, color)
src.add_fingerprint(user)
src.transfer_fingerprints_to(CC)
for(var/mob/O in viewers(src, null))
O.show_message("<span class='warning'>[user] cuts the cable.</span>", 1)

View File

@@ -3,21 +3,20 @@
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "core_control"
light_color = COLOR_ORANGE
circuit = /obj/item/weapon/circuitboard/fusion_core_control
var/id_tag
var/scan_range = 25
var/list/connected_devices = list()
var/obj/machinery/power/fusion_core/cur_viewed_device
/obj/machinery/computer/fusion_core_control/attackby(var/obj/item/thing, var/mob/user)
..()
if(ismultitool(thing))
var/new_ident = input("Enter a new ident tag.", "Core Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
cur_viewed_device = null
return
else
return ..()
/obj/machinery/computer/fusion_core_control/attack_ai(mob/user)
attack_hand(user)
@@ -28,6 +27,11 @@
/obj/machinery/computer/fusion_core_control/interact(mob/user)
if(stat & (BROKEN|NOPOWER))
user.unset_machine()
user << browse(null, "window=fusion_control")
return
if(!cur_viewed_device || !check_core_status(cur_viewed_device))
cur_viewed_device = null
@@ -174,3 +178,19 @@
if(C.idle_power_usage > C.avail())
return
. = 1
/obj/machinery/computer/fusion_core_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)

View File

@@ -35,7 +35,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics,
/obj/machinery/air_sensor,
/mob/observer/dead,
/mob/observer,
/obj/machinery/power/hydromagnetic_trap
)
@@ -672,4 +672,4 @@
#undef FUSION_HEAT_CAP
#undef FUSION_MAX_ENVIRO_HEAT
#undef PLASMA_TEMP_RADIATION_DIVISIOR
#undef PLASMA_TEMP_RADIATION_DIVISIOR

View File

@@ -2,6 +2,7 @@
name = "fuel injection control computer"
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "fuel"
circuit = /obj/item/weapon/circuitboard/fusion_fuel_control
var/id_tag
var/scan_range = 25
@@ -94,9 +95,25 @@
/obj/machinery/computer/fusion_fuel_control/attackby(var/obj/item/W, var/mob/user)
..()
if(ismultitool(W))
var/new_ident = input("Enter a new ident tag.", "Fuel Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
return
return ..()
/obj/machinery/computer/fusion_fuel_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)

View File

@@ -3,6 +3,7 @@
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "engine"
light_color = COLOR_BLUE
circuit = /obj/item/weapon/circuitboard/gyrotron_control
var/id_tag
var/scan_range = 25
@@ -16,6 +17,11 @@
/obj/machinery/computer/gyrotron_control/interact(var/mob/user)
if(stat & (BROKEN|NOPOWER))
user.unset_machine()
user << browse(null, "window=gyrotron_controller_[id_tag]")
return
if(!id_tag)
to_chat(user, "<span class='warning'>This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>")
return
@@ -89,9 +95,25 @@
return 0
/obj/machinery/computer/gyrotron_control/attackby(var/obj/item/W, var/mob/user)
..()
if(ismultitool(W))
var/new_ident = input("Enter a new ident tag.", "Gyrotron Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
return
return ..()
/obj/machinery/computer/gyrotron_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)

View File

@@ -325,6 +325,31 @@
/obj/item/ammo_magazine/box/c9mm/empty
initial_ammo = 0
/obj/item/ammo_magazine/m9mmR/saber
desc = "A very high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm bullets."
icon_state = "S9mm-22"
mag_type = MAGAZINE
ammo_type = /obj/item/ammo_casing/a9mm
matter = list(DEFAULT_WALL_MATERIAL = 1200)
caliber = "9mm"
max_ammo = 22
origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1)
multiple_sprites = 1
/obj/item/ammo_magazine/m9mmR/saber/ap
desc = "A high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm armor piercing bullets."
icon_state = "S9mm-22"
mag_type = MAGAZINE
ammo_type = /obj/item/ammo_casing/a9mm/ap
matter = list(DEFAULT_WALL_MATERIAL = 2000)
caliber = "9mm"
max_ammo = 22
origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1)
multiple_sprites = 1
/obj/item/ammo_magazine/m9mmR/saber/empty
initial_ammo = 0
///////// 10mm /////////
/obj/item/ammo_magazine/m10mm

View File

@@ -1,25 +1,40 @@
/obj/item/weapon/gun/projectile/automatic //Hopefully someone will find a way to make these fire in bursts or something. --Superxpdude //Except burstfire isn't fit for an rp server --Mark
/obj/item/weapon/gun/projectile/automatic //This should never be spawned in, it is just here because of code necessities.
name = "daka SMG"
desc = "A small SMG. You really shouldn't be able to get this gun. Uses 9mm rounds."
icon_state = "c05r" //Used because it's not used anywhere else
load_method = SPEEDLOADER
ammo_type = /obj/item/ammo_casing/a9mm
projectile_type = /obj/item/projectile/bullet/pistol
//Burst is the number of bullets fired; Fire delay is the time you have to wait to shoot the gun again, Move delay is the same but for moving after shooting. .
//Burst accuracy is the accuracy of each bullet fired in the burst. Dispersion is how much the bullets will 'spread' away from where you aimed.
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,-15,-15), dispersion=list(0.0, 0.6, 1.0)))
/obj/item/weapon/gun/projectile/automatic/saber //Fixed it
name = "prototype SMG"
desc = "A protoype lightweight, fast firing gun. Uses 9mm rounds."
icon_state = "saber" //ugly
icon = 'icons/obj/gun.dmi'
icon_state = "saber"//Still ugly
w_class = ITEMSIZE_NORMAL
load_method = SPEEDLOADER //yup. until someone sprites a magazine for it.
load_method = MAGAZINE //This should fix it
max_shells = 22
caliber = "9mm"
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
slot_flags = SLOT_BELT
ammo_type = /obj/item/ammo_casing/a9mm
magazine_type = /obj/item/ammo_magazine/m9mmR/saber
allowed_magazines = list(/obj/item/ammo_magazine/m9mmR/saber, /obj/item/ammo_magazine/m9mmR/saber/ap)
projectile_type = /obj/item/projectile/bullet/pistol
multi_aim = 1
burst_delay = 2
// one_handed_penalty = 15
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,-15,-15), dispersion=list(0.0, 0.6, 1.0))
// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/projectile/automatic/c20r
name = "submachine gun"

View File

@@ -858,7 +858,7 @@
glass_name = "lime tea"
glass_desc = "A tasty mixture of lime and tea. It's apparently good for you!"
cup_name = "cup of berry tea"
cup_name = "cup of lime tea"
cup_desc = "A tasty mixture of lime and tea. It's apparently good for you!"
/datum/reagent/drink/tea/orangetea

View File

@@ -49,7 +49,7 @@
if(H.a_intent != I_HELP)
to_chat(user, "<span class='notice'>[H] is resisting your attempt to inject them with \the [src].</span>")
to_chat(H, "<span class='danger'> [user] is trying to inject you with \the [src]!</span>")
if(!do_after(user, 30))
if(!do_after(user, 30, H))
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)

View File

@@ -47,9 +47,10 @@
/datum/design/item/weapon/smg
id = "smg"
desc = "An compact reliable SMG firing armor piercing ammo."
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 8000, "silver" = 2000, "diamond" = 1000)
build_path = /obj/item/weapon/gun/projectile/automatic
build_path = /obj/item/weapon/gun/projectile/automatic/saber
sort_string = "TAABA"
/datum/design/item/weapon/ammo_9mm

View File

@@ -0,0 +1,215 @@
//Procedures in this file: Organic limb repair
//////////////////////////////////////////////////////////////////
// LIMB REPAIR SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/
priority = 1
can_infect = 1
blood_level = 1
req_open = 1
/datum/surgery_step/repairflesh/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (target.stat == DEAD) // Sorry defibs, your subjects need to have pumping fluids for these to work.
return 0
if (isslime(target))
return 0
if (target_zone == O_EYES || target_zone == O_MOUTH)
return 0
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected == null)
return 0
if (affected.is_stump())
return 0
if (affected.robotic >= ORGAN_ROBOT)
return 0
return 1
//////////////////////////////////////////////////////////////////
// SCAN STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/scan_injury
allowed_tools = list(
/obj/item/weapon/autopsy_scanner = 100,
/obj/item/device/healthanalyzer = 80,
/obj/item/device/analyzer = 10
)
priority = 2
can_infect = 0 //The only exception here. Sweeping a scanner probably won't transfer many germs.
min_duration = 20
max_duration = 40
/datum/surgery_step/repairflesh/scan_injury/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.burn_stage || affected.brute_stage)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/scan_injury/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='notice'>[user] begins scanning [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin scanning [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/scan_injury/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='notice'>[user] finishes scanning [target]'s [affected].</span>", \
"<span class='notice'>You finish scanning [target]'s [affected].</span>")
if(affected.brute_dam)
to_chat(user, "<span class='notice'>The muscle in [target]'s [affected] is notably bruised.</span>")
if(affected.status & ORGAN_BROKEN)
to_chat(user, "<span class='warning'>\The [target]'s [affected] is broken!</span>")
affected.brute_stage = max(1, affected.brute_stage)
if(affected.burn_dam)
to_chat(user, "<span class='notice'>\The muscle in [target]'s [affected] is notably charred.</span>")
affected.burn_stage = max(1, affected.burn_stage)
/datum/surgery_step/repairflesh/scan_injury/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='warning'>[user]'s hand slips, dropping \the [tool] onto [target]'s [affected]!</span>" , \
"<span class='warning'>Your hand slips, dropping \the [tool] onto [target]'s [affected]!</span>" )
affected.createwound(BRUISE, 10)
//////////////////////////////////////////////////////////////////
// BURN STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/repair_burns
allowed_tools = list(
/obj/item/stack/medical/advanced/ointment = 100,
/obj/item/weapon/surgical/FixOVein = 100,
/obj/item/weapon/surgical/hemostat = 60,
/obj/item/stack/medical/ointment = 50,
/obj/item/weapon/tape_roll = 30,
/obj/item/taperoll = 10
)
priority = 3
min_duration = 90
max_duration = 120
/datum/surgery_step/repairflesh/repair_burns/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.burn_stage < 1 || !(affected.burn_dam))
return 0
if(affected.burn_dam < affected.brute_dam)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/repair_burns/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='warning'>[user] begins taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin taping up [target]'s [affected] with \the [tool].</span>")
affected.jostle_bone(10)
else if(istype(tool, /obj/item/weapon/surgical/hemostat) || istype(tool, /obj/item/weapon/surgical/FixOVein))
user.visible_message("<span class='notice'>[user] begins mending the charred blood vessels in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin mending the charred blood vessels in [target]'s [affected] with \the [tool].</span>")
else
user.visible_message("<span class='notice'>[user] begins coating the charred tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin coating the charred tissue in [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/repair_burns/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='notice'>[user] finishes taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You finish taping up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.heal_damage(0, 25, 0, 0)
if(!(affected.burn_dam))
affected.burn_stage = 0
if(istype(tool, /obj/item/stack))
var/obj/item/stack/T = tool
T.use(1)
..()
/datum/surgery_step/repairflesh/repair_burns/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='danger'>[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].</span>", \
"<span class='danger'>Your hand slips, tearing up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)
..()
//////////////////////////////////////////////////////////////////
// BRUTE STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/repair_brute
allowed_tools = list(
/obj/item/stack/medical/advanced/bruise_pack = 100,
/obj/item/weapon/surgical/cautery = 100,
/obj/item/weapon/surgical/bonesetter = 60,
/obj/item/stack/medical/bruise_pack = 50,
/obj/item/weapon/tape_roll = 40,
/obj/item/taperoll = 10
)
priority = 3
min_duration = 90
max_duration = 120
/datum/surgery_step/repairflesh/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.brute_stage < 1 || !(affected.brute_dam))
return 0
if(affected.brute_dam < affected.burn_dam)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/repair_brute/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='warning'>[user] begins taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin taping up [target]'s [affected] with \the [tool].</span>")
affected.jostle_bone(10)
else if(istype(tool, /obj/item/weapon/surgical/FixOVein) || istype(tool, /obj/item/weapon/surgical/bonesetter))
user.visible_message("<span class='notice'>[user] begins mending the torn tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin mending the torn tissue in [target]'s [affected] with \the [tool].</span>")
else
user.visible_message("<span class='notice'>[user] begins coating the tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin coating the tissue in [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='notice'>[user] finishes taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You finish taping up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.heal_damage(25, 0, 0, 0)
if(!(affected.brute_dam))
affected.brute_stage = 0
if(istype(tool, /obj/item/stack))
var/obj/item/stack/T = tool
T.use(1)
..()
/datum/surgery_step/repairflesh/repair_brute/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='danger'>[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].</span>", \
"<span class='danger'>Your hand slips, tearing up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)
..()

View File

@@ -4,6 +4,7 @@
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "engspace_suit"
item_state = "engspace_suit"
update_icon_define = "icons/mob/spacesuit.dmi"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
/obj/item/clothing/head/bio_hood/anomaly