diff --git a/baystation12.dme b/baystation12.dme index d4087c917df..c667276b934 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1129,6 +1129,7 @@ #include "code\modules\mob\living\carbon\human\human_defense.dm" #include "code\modules\mob\living\carbon\human\human_defines.dm" #include "code\modules\mob\living\carbon\human\human_movement.dm" +#include "code\modules\mob\living\carbon\human\human_organs.dm" #include "code\modules\mob\living\carbon\human\human_powers.dm" #include "code\modules\mob\living\carbon\human\human_species.dm" #include "code\modules\mob\living\carbon\human\inventory.dm" @@ -1283,9 +1284,11 @@ #include "code\modules\organs\organ.dm" #include "code\modules\organs\organ_alien.dm" #include "code\modules\organs\organ_external.dm" +#include "code\modules\organs\organ_icon.dm" #include "code\modules\organs\organ_internal.dm" -#include "code\modules\organs\organ_objects.dm" +#include "code\modules\organs\organ_stump.dm" #include "code\modules\organs\pain.dm" +#include "code\modules\organs\robolimbs.dm" #include "code\modules\organs\wound.dm" #include "code\modules\overmap\_defines.dm" #include "code\modules\overmap\sectors.dm" diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index 6cd983732ba..391f5b719a9 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -120,7 +120,7 @@ obj/var/contaminated = 0 if(!species.has_organ["eyes"]) return - var/datum/organ/internal/eyes/E = internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = internal_organs_by_name["eyes"] if(E) if(prob(20)) src << "\red Your eyes burn!" E.damage += 2.5 diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 7e6e072ead4..0cc2ad33652 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -379,7 +379,8 @@ if(!usr.stat && isturf(usr.loc) && !usr.restrained()) usr:toggle_throw_mode() if("drop") - usr.drop_item_v() + if(usr.client) + usr.client.drop_item() if("module") if(isrobot(usr)) @@ -429,7 +430,7 @@ if("Allow Walking") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetMove() @@ -438,7 +439,7 @@ if("Disallow Walking") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetMove() @@ -447,7 +448,7 @@ if("Allow Running") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetRun() @@ -456,7 +457,7 @@ if("Disallow Running") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetRun() @@ -465,7 +466,7 @@ if("Allow Item Use") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetClick() @@ -475,7 +476,7 @@ if("Disallow Item Use") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetClick() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index a81c6f30fa9..1d68fb54e8e 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -41,16 +41,23 @@ // TODO: needs to be refactored into a mob/living level attacked_by() proc. ~Z if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/hit = H.attacked_by(src, user, def_zone) - if(hit && hitsound) + + // Handle striking to cripple. + var/dislocation_str + if(user.a_intent == "disarm") + dislocation_str = H.attack_joint(src, user, def_zone) + if(H.attacked_by(src, user, def_zone) && hitsound) playsound(loc, hitsound, 50, 1, -1) - return hit + spawn(1) //ugh I hate this but I don't want to root through human attack procs to print it after this call resolves. + if(dislocation_str) user.visible_message("[dislocation_str]") + return 1 + return 0 else if(attack_verb.len) user.visible_message("[M] has been [pick(attack_verb)] with [src] by [user]!") else user.visible_message("[M] has been attacked with [src] by [user]!") - + if (hitsound) playsound(loc, hitsound, 50, 1, -1) switch(damtype) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 2e3d2cc5449..5fc86c420ad 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -155,12 +155,8 @@ proc/get_id_photo(var/mob/living/carbon/human/H) temp = new /icon(icobase, "head_[g]") preview_icon.Blend(temp, ICON_OVERLAY) - for(var/datum/organ/external/E in H.organs) - if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue - temp = new /icon(icobase, "[E.name]") - if(E.status & ORGAN_ROBOT) - temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) - preview_icon.Blend(temp, ICON_OVERLAY) + for(var/obj/item/organ/external/E in H.organs) + preview_icon.Blend(E.get_icon(), ICON_OVERLAY) //Tail if(H.species.tail) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 8daad7bfc16..2e8e4bfd3fa 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,982 +1,955 @@ - -// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - -client - proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world - - - if(!usr.client || !usr.client.holder) - usr << "\red You need to be an administrator to access this." - return - - - var/title = "" - var/body = "" - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - title = "[A.name] (\ref[A]) = [A.type]" - - #ifdef VARSICON - if (A.icon) - body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) - #endif - - var/icon/sprite - - if(istype(D,/atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") - - title = "[D] (\ref[D]) = [D.type]" - - body += {" "} - - body += "" - - body += "
" - - if(sprite) - body += "" - - body += "
" - else - body += "
" - - body += "
" - - if(istype(D,/atom)) - var/atom/A = D - if(isliving(A)) - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - var/mob/living/M = A - body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" - body += {" -
- BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - - - - "} - else - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - else - body += "[D]" - - body += "
" - - body += "
" - - var/formatted_type = text("[D.type]") - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - body += "
[formatted_type]" - - if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) - body += "
Marked Object" - - body += "
" - - body += "
Refresh" - - //if(ismob(D)) - // body += "
Show player panel

" - - body += {"
-
" - - body += "

" - - body += "E - Edit, tries to determine the variable type by itself.
" - body += "C - Change, asks you for the var type first.
" - body += "M - Mass modify: changes this variable for all objects of this type.

" - - body += "
Search:

" - - body += "
    " - - var/list/names = list() - for (var/V in D.vars) - names += V - - names = sortList(names) - - for (var/V in names) - body += debug_variable(V, D.vars[V], 0, D) - - body += "
" - - var/html = "" - if (title) - html += "[title]" - html += {""} - html += "" - html += body - - html += {" - - "} - - html += "" - - usr << browse(html, "window=variables\ref[D];size=475x650") - - return - - proc/debug_variable(name, value, level, var/datum/DA = null) - var/html = "" - - if(DA) - html += "
  • (E) (C) (M) " - else - html += "
  • " - - if (isnull(value)) - html += "[name] = null" - - else if (istext(value)) - html += "[name] = \"[value]\"" - - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - html += "[name] = ([value]) " - #else - html += "[name] = /icon ([value])" - #endif - -/* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value - - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif -*/ - else if (isfile(value)) - html += "[name] = '[value]'" - - else if (istype(value, /datum)) - var/datum/D = value - html += "[name] \ref[value] = [D.type]" - - else if (istype(value, /client)) - var/client/C = value - html += "[name] \ref[value] = [C] [C.type]" - // - else if (istype(value, /list)) - var/list/L = value - html += "[name] = /list ([L.len])" - - if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) - // not sure if this is completely right... - if(0) //(L.vars.len > 0) - html += "
      " - html += "
    " - else - html += "" - - else - html += "[name] = [value]" - - html += "
  • " - - return html - -/client/proc/view_var_Topic(href, href_list, hsrc) - //This should all be moved over to datum/admins/Topic() or something ~Carn - if( (usr.client != src) || !src.holder ) - return - if(href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) - - //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). - else if(href_list["rename"]) - if(!check_rights(R_VAREDIT)) return - - var/mob/M = locate(href_list["rename"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - var/new_name = sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null, MAX_NAME_LEN) - if( !new_name || !M ) return - - message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") - M.fully_replace_character_name(M.real_name,new_name) - href_list["datumrefresh"] = href_list["rename"] - - else if(href_list["varnameedit"] && href_list["datumedit"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locate(href_list["datumedit"]) - if(!istype(D,/datum) && !istype(D,/client)) - usr << "This can only be used on instances of types /client or /datum" - return - - modify_variables(D, href_list["varnameedit"], 1) - - else if(href_list["varnamechange"] && href_list["datumchange"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locate(href_list["datumchange"]) - if(!istype(D,/datum) && !istype(D,/client)) - usr << "This can only be used on instances of types /client or /datum" - return - - modify_variables(D, href_list["varnamechange"], 0) - - else if(href_list["varnamemass"] && href_list["datummass"]) - if(!check_rights(R_VAREDIT)) return - - var/atom/A = locate(href_list["datummass"]) - if(!istype(A)) - usr << "This can only be used on instances of type /atom" - return - - cmd_mass_modify_object_variables(A, href_list["varnamemass"]) - - else if(href_list["mob_player_panel"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["mob_player_panel"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.holder.show_player_panel(M) - href_list["datumrefresh"] = href_list["mob_player_panel"] - - else if(href_list["give_spell"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_spell"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_spell(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["give_disease"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_disease"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_disease(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["give_disease2"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_disease2"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_disease2(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["godmode"]) - if(!check_rights(R_REJUVINATE)) return - - var/mob/M = locate(href_list["godmode"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.cmd_admin_godmode(M) - href_list["datumrefresh"] = href_list["godmode"] - - else if(href_list["gib"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["gib"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.cmd_admin_gib(M) - - else if(href_list["build_mode"]) - if(!check_rights(R_BUILDMODE)) return - - var/mob/M = locate(href_list["build_mode"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - togglebuildmode(M) - href_list["datumrefresh"] = href_list["build_mode"] - - else if(href_list["drop_everything"]) - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/mob/M = locate(href_list["drop_everything"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - if(usr.client) - usr.client.cmd_admin_drop_everything(M) - - else if(href_list["direct_control"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["direct_control"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - if(usr.client) - usr.client.cmd_assume_direct_control(M) - - else if(href_list["make_skeleton"]) - if(!check_rights(R_FUN)) return - - var/mob/living/carbon/human/H = locate(href_list["make_skeleton"]) - if(!istype(H)) - usr << "This can only be used on instances of type /mob/living/carbon/human" - return - - H.ChangeToSkeleton() - href_list["datumrefresh"] = href_list["make_skeleton"] - - else if(href_list["delall"]) - if(!check_rights(R_DEBUG|R_SERVER)) return - - var/obj/O = locate(href_list["delall"]) - if(!isobj(O)) - usr << "This can only be used on instances of type /obj" - return - - var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") - if(action_type == "Cancel" || !action_type) - return - - if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") - return - - if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") - return - - var/O_type = O.type - switch(action_type) - if("Strict type") - var/i = 0 - for(var/obj/Obj in world) - if(Obj.type == O_type) - i++ - del(Obj) - if(!i) - usr << "No objects of this type exist" - return - log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - if("Type and subtypes") - var/i = 0 - for(var/obj/Obj in world) - if(istype(Obj,O_type)) - i++ - del(Obj) - if(!i) - usr << "No objects of this type exist" - return - log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - - else if(href_list["explode"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["explode"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_explosion(A) - href_list["datumrefresh"] = href_list["explode"] - - else if(href_list["emp"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["emp"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_emp(A) - href_list["datumrefresh"] = href_list["emp"] - - else if(href_list["mark_object"]) - if(!check_rights(0)) return - - var/datum/D = locate(href_list["mark_object"]) - if(!istype(D)) - usr << "This can only be done to instances of type /datum" - return - - src.holder.marked_datum = D - href_list["datumrefresh"] = href_list["mark_object"] - - else if(href_list["rotatedatum"]) - if(!check_rights(0)) return - - var/atom/A = locate(href_list["rotatedatum"]) - if(!istype(A)) - usr << "This can only be done to instances of type /atom" - return - - switch(href_list["rotatedir"]) - if("right") A.set_dir(turn(A.dir, -45)) - if("left") A.set_dir(turn(A.dir, 45)) - href_list["datumrefresh"] = href_list["rotatedatum"] - - else if(href_list["makemonkey"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) - - else if(href_list["makerobot"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makerobot"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makerobot"=href_list["makerobot"])) - - else if(href_list["makealien"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makealien"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makealien"=href_list["makealien"])) - - else if(href_list["makeslime"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makeslime"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makeslime"=href_list["makeslime"])) - - else if(href_list["makeai"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makeai"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makeai"=href_list["makeai"])) - - else if(href_list["setspecies"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["setspecies"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.set_species(new_species)) - usr << "Set species of [H] to [H.species]." - else - usr << "Failed! Something went wrong." - - else if(href_list["addlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locate(href_list["addlanguage"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - - var/new_language = input("Please choose a language to add.","Language",null) as null|anything in all_languages - - if(!new_language) - return - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.add_language(new_language)) - usr << "Added [new_language] to [H]." - else - usr << "Mob already knows that language." - - else if(href_list["remlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locate(href_list["remlanguage"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - - if(!H.languages.len) - usr << "This mob knows no languages." - return - - var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages - - if(!rem_language) - return - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.remove_language(rem_language.name)) - usr << "Removed [rem_language] from [H]." - else - usr << "Mob doesn't know that language." - - else if(href_list["addverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/living/H = locate(href_list["addverb"]) - - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living" - return - var/list/possibleverbs = list() - possibleverbs += "Cancel" // One for the top... - possibleverbs += typesof(/mob/proc,/mob/verb,/mob/living/proc,/mob/living/verb) - switch(H.type) - if(/mob/living/carbon/human) - possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc) - if(/mob/living/silicon/robot) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb) - if(/mob/living/silicon/ai) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb) - possibleverbs -= H.verbs - possibleverbs += "Cancel" // ...And one for the bottom - - var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs - if(!H) - usr << "Mob doesn't exist anymore" - return - if(!verb || verb == "Cancel") - return - else - H.verbs += verb - - else if(href_list["remverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/H = locate(href_list["remverb"]) - - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - var/verb = input("Please choose a verb to remove.","Verbs",null) as null|anything in H.verbs - if(!H) - usr << "Mob doesn't exist anymore" - return - if(!verb) - return - else - H.verbs -= verb - - else if(href_list["addorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locate(href_list["addorgan"]) - if(!istype(M)) - usr << "This can only be done to instances of type /mob/living/carbon" - return - - var/new_organ = input("Please choose an organ to add.","Organ",null) as null|anything in typesof(/datum/organ/internal)-/datum/organ/internal - if(!new_organ) return - - if(!M) - usr << "Mob doesn't exist anymore" - return - - if(locate(new_organ) in M.internal_organs) - usr << "Mob already has that organ." - return - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/datum/organ/internal/I = new new_organ(H) - - var/organ_slot = input(usr, "Which slot do you want the organ to go in ('default' for default)?") as text|null - - if(!organ_slot) - return - - if(organ_slot != "default") - organ_slot = sanitize(organ_slot) - else - if(I.removed_type) - var/obj/item/organ/O = new I.removed_type() - organ_slot = O.organ_tag - del(O) - else - organ_slot = "unknown organ" - - if(H.internal_organs_by_name[organ_slot]) - usr << "[H] already has an organ in that slot." - del(I) - return - - H.internal_organs |= I - H.internal_organs_by_name[organ_slot] = I - usr << "Added new [new_organ] to [H] as slot [organ_slot]." - else - new new_organ(M) - usr << "Added new [new_organ] to [M]." - - else if(href_list["remorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locate(href_list["remorgan"]) - if(!istype(M)) - usr << "This can only be done to instances of type /mob/living/carbon" - return - - var/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs - - if(!M) - usr << "Mob doesn't exist anymore" - return - - if(!(locate(rem_organ) in M.internal_organs)) - usr << "Mob does not have that organ." - return - - usr << "Removed [rem_organ] from [M]." - del(rem_organ) - - else if(href_list["fix_nano"]) - if(!check_rights(R_DEBUG)) return - - var/mob/H = locate(href_list["fix_nano"]) - - if(!istype(H) || !H.client) - usr << "This can only be done on mobs with clients" - return - - nanomanager.send_resources(H.client) - - usr << "Resource files sent" - H << "Your NanoUI Resource files have been refreshed" - - log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ") - - else if(href_list["regenerateicons"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["regenerateicons"]) - if(!ismob(M)) - usr << "This can only be done to instances of type /mob" - return - M.regenerate_icons() - - else if(href_list["adjustDamage"] && href_list["mobToDamage"]) - if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return - - var/mob/living/L = locate(href_list["mobToDamage"]) - if(!istype(L)) return - - var/Text = href_list["adjustDamage"] - - var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num - - if(!L) - usr << "Mob doesn't exist anymore" - return - - switch(Text) - if("brute") L.adjustBruteLoss(amount) - if("fire") L.adjustFireLoss(amount) - if("toxin") L.adjustToxLoss(amount) - if("oxygen")L.adjustOxyLoss(amount) - if("brain") L.adjustBrainLoss(amount) - if("clone") L.adjustCloneLoss(amount) - else - usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]" - return - - if(amount != 0) - log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - href_list["datumrefresh"] = href_list["mobToDamage"] - - if(href_list["datumrefresh"]) - var/datum/DAT = locate(href_list["datumrefresh"]) - if(!istype(DAT, /datum)) - return - src.debug_variables(DAT) - - return - + +// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) + +client + proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + //set src in world + + + if(!usr.client || !usr.client.holder) + usr << "\red You need to be an administrator to access this." + return + + + var/title = "" + var/body = "" + + if(!D) return + if(istype(D, /atom)) + var/atom/A = D + title = "[A.name] (\ref[A]) = [A.type]" + + #ifdef VARSICON + if (A.icon) + body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) + #endif + + var/icon/sprite + + if(istype(D,/atom)) + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + usr << browse_rsc(sprite, "view_vars_sprite.png") + + title = "[D] (\ref[D]) = [D.type]" + + body += {" "} + + body += "" + + body += "
    " + + if(sprite) + body += "" + + body += "
    " + else + body += "
    " + + body += "
    " + + if(istype(D,/atom)) + var/atom/A = D + if(isliving(A)) + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + var/mob/living/M = A + body += "
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" + body += {" +
    + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getBrainLoss()] + + + + "} + else + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + else + body += "[D]" + + body += "
    " + + body += "
    " + + var/formatted_type = text("[D.type]") + if(length(formatted_type) > 25) + var/middle_point = length(formatted_type) / 2 + var/splitpoint = findtext(formatted_type,"/",middle_point) + if(splitpoint) + formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" + else + formatted_type = "Type too long" //No suitable splitpoint (/) found. + + body += "
    [formatted_type]" + + if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) + body += "
    Marked Object" + + body += "
    " + + body += "
    Refresh" + + //if(ismob(D)) + // body += "
    Show player panel

    " + + body += {"
    +
    " + + body += "

    " + + body += "E - Edit, tries to determine the variable type by itself.
    " + body += "C - Change, asks you for the var type first.
    " + body += "M - Mass modify: changes this variable for all objects of this type.

    " + + body += "
    Search:

    " + + body += "
      " + + var/list/names = list() + for (var/V in D.vars) + names += V + + names = sortList(names) + + for (var/V in names) + body += debug_variable(V, D.vars[V], 0, D) + + body += "
    " + + var/html = "" + if (title) + html += "[title]" + html += {""} + html += "" + html += body + + html += {" + + "} + + html += "" + + usr << browse(html, "window=variables\ref[D];size=475x650") + + return + + proc/debug_variable(name, value, level, var/datum/DA = null) + var/html = "" + + if(DA) + html += "
  • (E) (C) (M) " + else + html += "
  • " + + if (isnull(value)) + html += "[name] = null" + + else if (istext(value)) + html += "[name] = \"[value]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + html += "[name] = ([value]) " + #else + html += "[name] = /icon ([value])" + #endif + +/* else if (istype(value, /image)) + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value + + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif +*/ + else if (isfile(value)) + html += "[name] = '[value]'" + + else if (istype(value, /datum)) + var/datum/D = value + html += "[name] \ref[value] = [D.type]" + + else if (istype(value, /client)) + var/client/C = value + html += "[name] \ref[value] = [C] [C.type]" + // + else if (istype(value, /list)) + var/list/L = value + html += "[name] = /list ([L.len])" + + if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) + // not sure if this is completely right... + if(0) //(L.vars.len > 0) + html += "
      " + html += "
    " + else + html += "" + + else + html += "[name] = [value]" + + html += "
  • " + + return html + +/client/proc/view_var_Topic(href, href_list, hsrc) + //This should all be moved over to datum/admins/Topic() or something ~Carn + if( (usr.client != src) || !src.holder ) + return + if(href_list["Vars"]) + debug_variables(locate(href_list["Vars"])) + + //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). + else if(href_list["rename"]) + if(!check_rights(R_VAREDIT)) return + + var/mob/M = locate(href_list["rename"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + var/new_name = sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null, MAX_NAME_LEN) + if( !new_name || !M ) return + + message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") + M.fully_replace_character_name(M.real_name,new_name) + href_list["datumrefresh"] = href_list["rename"] + + else if(href_list["varnameedit"] && href_list["datumedit"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locate(href_list["datumedit"]) + if(!istype(D,/datum) && !istype(D,/client)) + usr << "This can only be used on instances of types /client or /datum" + return + + modify_variables(D, href_list["varnameedit"], 1) + + else if(href_list["varnamechange"] && href_list["datumchange"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locate(href_list["datumchange"]) + if(!istype(D,/datum) && !istype(D,/client)) + usr << "This can only be used on instances of types /client or /datum" + return + + modify_variables(D, href_list["varnamechange"], 0) + + else if(href_list["varnamemass"] && href_list["datummass"]) + if(!check_rights(R_VAREDIT)) return + + var/atom/A = locate(href_list["datummass"]) + if(!istype(A)) + usr << "This can only be used on instances of type /atom" + return + + cmd_mass_modify_object_variables(A, href_list["varnamemass"]) + + else if(href_list["mob_player_panel"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["mob_player_panel"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.holder.show_player_panel(M) + href_list["datumrefresh"] = href_list["mob_player_panel"] + + else if(href_list["give_spell"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_spell"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_spell(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["give_disease"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_disease(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["give_disease2"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease2"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_disease2(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["godmode"]) + if(!check_rights(R_REJUVINATE)) return + + var/mob/M = locate(href_list["godmode"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.cmd_admin_godmode(M) + href_list["datumrefresh"] = href_list["godmode"] + + else if(href_list["gib"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["gib"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.cmd_admin_gib(M) + + else if(href_list["build_mode"]) + if(!check_rights(R_BUILDMODE)) return + + var/mob/M = locate(href_list["build_mode"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + togglebuildmode(M) + href_list["datumrefresh"] = href_list["build_mode"] + + else if(href_list["drop_everything"]) + if(!check_rights(R_DEBUG|R_ADMIN)) return + + var/mob/M = locate(href_list["drop_everything"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + if(usr.client) + usr.client.cmd_admin_drop_everything(M) + + else if(href_list["direct_control"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["direct_control"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + if(usr.client) + usr.client.cmd_assume_direct_control(M) + + else if(href_list["make_skeleton"]) + if(!check_rights(R_FUN)) return + + var/mob/living/carbon/human/H = locate(href_list["make_skeleton"]) + if(!istype(H)) + usr << "This can only be used on instances of type /mob/living/carbon/human" + return + + H.ChangeToSkeleton() + href_list["datumrefresh"] = href_list["make_skeleton"] + + else if(href_list["delall"]) + if(!check_rights(R_DEBUG|R_SERVER)) return + + var/obj/O = locate(href_list["delall"]) + if(!isobj(O)) + usr << "This can only be used on instances of type /obj" + return + + var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") + if(action_type == "Cancel" || !action_type) + return + + if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") + return + + if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") + return + + var/O_type = O.type + switch(action_type) + if("Strict type") + var/i = 0 + for(var/obj/Obj in world) + if(Obj.type == O_type) + i++ + del(Obj) + if(!i) + usr << "No objects of this type exist" + return + log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + if("Type and subtypes") + var/i = 0 + for(var/obj/Obj in world) + if(istype(Obj,O_type)) + i++ + del(Obj) + if(!i) + usr << "No objects of this type exist" + return + log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + + else if(href_list["explode"]) + if(!check_rights(R_DEBUG|R_FUN)) return + + var/atom/A = locate(href_list["explode"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + usr << "This can only be done to instances of type /obj, /mob and /turf" + return + + src.cmd_admin_explosion(A) + href_list["datumrefresh"] = href_list["explode"] + + else if(href_list["emp"]) + if(!check_rights(R_DEBUG|R_FUN)) return + + var/atom/A = locate(href_list["emp"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + usr << "This can only be done to instances of type /obj, /mob and /turf" + return + + src.cmd_admin_emp(A) + href_list["datumrefresh"] = href_list["emp"] + + else if(href_list["mark_object"]) + if(!check_rights(0)) return + + var/datum/D = locate(href_list["mark_object"]) + if(!istype(D)) + usr << "This can only be done to instances of type /datum" + return + + src.holder.marked_datum = D + href_list["datumrefresh"] = href_list["mark_object"] + + else if(href_list["rotatedatum"]) + if(!check_rights(0)) return + + var/atom/A = locate(href_list["rotatedatum"]) + if(!istype(A)) + usr << "This can only be done to instances of type /atom" + return + + switch(href_list["rotatedir"]) + if("right") A.set_dir(turn(A.dir, -45)) + if("left") A.set_dir(turn(A.dir, 45)) + href_list["datumrefresh"] = href_list["rotatedatum"] + + else if(href_list["makemonkey"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) + + else if(href_list["makerobot"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makerobot"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makerobot"=href_list["makerobot"])) + + else if(href_list["makealien"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makealien"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makealien"=href_list["makealien"])) + + else if(href_list["makeslime"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makeslime"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makeslime"=href_list["makeslime"])) + + else if(href_list["makeai"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makeai"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makeai"=href_list["makeai"])) + + else if(href_list["setspecies"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["setspecies"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.set_species(new_species)) + usr << "Set species of [H] to [H.species]." + else + usr << "Failed! Something went wrong." + + else if(href_list["addlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["addlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + var/new_language = input("Please choose a language to add.","Language",null) as null|anything in all_languages + + if(!new_language) + return + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.add_language(new_language)) + usr << "Added [new_language] to [H]." + else + usr << "Mob already knows that language." + + else if(href_list["remlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["remlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + if(!H.languages.len) + usr << "This mob knows no languages." + return + + var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages + + if(!rem_language) + return + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.remove_language(rem_language.name)) + usr << "Removed [rem_language] from [H]." + else + usr << "Mob doesn't know that language." + + else if(href_list["addverb"]) + if(!check_rights(R_DEBUG)) return + + var/mob/living/H = locate(href_list["addverb"]) + + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living" + return + var/list/possibleverbs = list() + possibleverbs += "Cancel" // One for the top... + possibleverbs += typesof(/mob/proc,/mob/verb,/mob/living/proc,/mob/living/verb) + switch(H.type) + if(/mob/living/carbon/human) + possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc) + if(/mob/living/silicon/robot) + possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb) + if(/mob/living/silicon/ai) + possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb) + possibleverbs -= H.verbs + possibleverbs += "Cancel" // ...And one for the bottom + + var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs + if(!H) + usr << "Mob doesn't exist anymore" + return + if(!verb || verb == "Cancel") + return + else + H.verbs += verb + + else if(href_list["remverb"]) + if(!check_rights(R_DEBUG)) return + + var/mob/H = locate(href_list["remverb"]) + + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + var/verb = input("Please choose a verb to remove.","Verbs",null) as null|anything in H.verbs + if(!H) + usr << "Mob doesn't exist anymore" + return + if(!verb) + return + else + H.verbs -= verb + + else if(href_list["addorgan"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/M = locate(href_list["addorgan"]) + if(!istype(M)) + usr << "This can only be done to instances of type /mob/living/carbon" + return + + var/new_organ = input("Please choose an organ to add.","Organ",null) as null|anything in typesof(/obj/item/organ)-/obj/item/organ + if(!new_organ) return + + if(!M) + usr << "Mob doesn't exist anymore" + return + + if(locate(new_organ) in M.internal_organs) + usr << "Mob already has that organ." + return + + new new_organ(M) + + + else if(href_list["remorgan"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/M = locate(href_list["remorgan"]) + if(!istype(M)) + usr << "This can only be done to instances of type /mob/living/carbon" + return + + var/obj/item/organ/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs + + if(!M) + usr << "Mob doesn't exist anymore" + return + + if(!(locate(rem_organ) in M.internal_organs)) + usr << "Mob does not have that organ." + return + + usr << "Removed [rem_organ] from [M]." + rem_organ.removed() + del(rem_organ) + + else if(href_list["fix_nano"]) + if(!check_rights(R_DEBUG)) return + + var/mob/H = locate(href_list["fix_nano"]) + + if(!istype(H) || !H.client) + usr << "This can only be done on mobs with clients" + return + + nanomanager.send_resources(H.client) + + usr << "Resource files sent" + H << "Your NanoUI Resource files have been refreshed" + + log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ") + + else if(href_list["regenerateicons"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["regenerateicons"]) + if(!ismob(M)) + usr << "This can only be done to instances of type /mob" + return + M.regenerate_icons() + + else if(href_list["adjustDamage"] && href_list["mobToDamage"]) + if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return + + var/mob/living/L = locate(href_list["mobToDamage"]) + if(!istype(L)) return + + var/Text = href_list["adjustDamage"] + + var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num + + if(!L) + usr << "Mob doesn't exist anymore" + return + + switch(Text) + if("brute") L.adjustBruteLoss(amount) + if("fire") L.adjustFireLoss(amount) + if("toxin") L.adjustToxLoss(amount) + if("oxygen")L.adjustOxyLoss(amount) + if("brain") L.adjustBrainLoss(amount) + if("clone") L.adjustCloneLoss(amount) + else + usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]" + return + + if(amount != 0) + log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") + message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") + href_list["datumrefresh"] = href_list["mobToDamage"] + + if(href_list["datumrefresh"]) + var/datum/DAT = locate(href_list["datumrefresh"]) + if(!istype(DAT, /datum)) + return + src.debug_variables(DAT) + + return + diff --git a/code/datums/datumvars.dm.orig b/code/datums/datumvars.dm.orig new file mode 100644 index 00000000000..fd8c7f4590a --- /dev/null +++ b/code/datums/datumvars.dm.orig @@ -0,0 +1,988 @@ + +// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) + +client + proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + //set src in world + + + if(!usr.client || !usr.client.holder) + usr << "\red You need to be an administrator to access this." + return + + + var/title = "" + var/body = "" + + if(!D) return + if(istype(D, /atom)) + var/atom/A = D + title = "[A.name] (\ref[A]) = [A.type]" + + #ifdef VARSICON + if (A.icon) + body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) + #endif + + var/icon/sprite + + if(istype(D,/atom)) + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + usr << browse_rsc(sprite, "view_vars_sprite.png") + + title = "[D] (\ref[D]) = [D.type]" + + body += {" "} + + body += "" + + body += "
    " + + if(sprite) + body += "" + + body += "
    " + else + body += "
    " + + body += "
    " + + if(istype(D,/atom)) + var/atom/A = D + if(isliving(A)) + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + var/mob/living/M = A + body += "
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" + body += {" +
    + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getBrainLoss()] + + + + "} + else + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + else + body += "[D]" + + body += "
    " + + body += "
    " + + var/formatted_type = text("[D.type]") + if(length(formatted_type) > 25) + var/middle_point = length(formatted_type) / 2 + var/splitpoint = findtext(formatted_type,"/",middle_point) + if(splitpoint) + formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" + else + formatted_type = "Type too long" //No suitable splitpoint (/) found. + + body += "
    [formatted_type]" + + if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) + body += "
    Marked Object" + + body += "
    " + + body += "
    Refresh" + + //if(ismob(D)) + // body += "
    Show player panel

    " + + body += {"
    +
    " + + body += "

    " + + body += "E - Edit, tries to determine the variable type by itself.
    " + body += "C - Change, asks you for the var type first.
    " + body += "M - Mass modify: changes this variable for all objects of this type.

    " + + body += "
    Search:

    " + + body += "
      " + + var/list/names = list() + for (var/V in D.vars) + names += V + + names = sortList(names) + + for (var/V in names) + body += debug_variable(V, D.vars[V], 0, D) + + body += "
    " + + var/html = "" + if (title) + html += "[title]" + html += {""} + html += "" + html += body + + html += {" + + "} + + html += "" + + usr << browse(html, "window=variables\ref[D];size=475x650") + + return + + proc/debug_variable(name, value, level, var/datum/DA = null) + var/html = "" + + if(DA) + html += "
  • (E) (C) (M) " + else + html += "
  • " + + if (isnull(value)) + html += "[name] = null" + + else if (istext(value)) + html += "[name] = \"[value]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + html += "[name] = ([value]) " + #else + html += "[name] = /icon ([value])" + #endif + +/* else if (istype(value, /image)) + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value + + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif +*/ + else if (isfile(value)) + html += "[name] = '[value]'" + + else if (istype(value, /datum)) + var/datum/D = value + html += "[name] \ref[value] = [D.type]" + + else if (istype(value, /client)) + var/client/C = value + html += "[name] \ref[value] = [C] [C.type]" + // + else if (istype(value, /list)) + var/list/L = value + html += "[name] = /list ([L.len])" + + if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) + // not sure if this is completely right... + if(0) //(L.vars.len > 0) + html += "
      " + html += "
    " + else + html += "" + + else + html += "[name] = [value]" + + html += "
  • " + + return html + +/client/proc/view_var_Topic(href, href_list, hsrc) + //This should all be moved over to datum/admins/Topic() or something ~Carn + if( (usr.client != src) || !src.holder ) + return + if(href_list["Vars"]) + debug_variables(locate(href_list["Vars"])) + + //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). + else if(href_list["rename"]) + if(!check_rights(R_VAREDIT)) return + + var/mob/M = locate(href_list["rename"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + var/new_name = sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null, MAX_NAME_LEN) + if( !new_name || !M ) return + + message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") + M.fully_replace_character_name(M.real_name,new_name) + href_list["datumrefresh"] = href_list["rename"] + + else if(href_list["varnameedit"] && href_list["datumedit"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locate(href_list["datumedit"]) + if(!istype(D,/datum) && !istype(D,/client)) + usr << "This can only be used on instances of types /client or /datum" + return + + modify_variables(D, href_list["varnameedit"], 1) + + else if(href_list["varnamechange"] && href_list["datumchange"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locate(href_list["datumchange"]) + if(!istype(D,/datum) && !istype(D,/client)) + usr << "This can only be used on instances of types /client or /datum" + return + + modify_variables(D, href_list["varnamechange"], 0) + + else if(href_list["varnamemass"] && href_list["datummass"]) + if(!check_rights(R_VAREDIT)) return + + var/atom/A = locate(href_list["datummass"]) + if(!istype(A)) + usr << "This can only be used on instances of type /atom" + return + + cmd_mass_modify_object_variables(A, href_list["varnamemass"]) + + else if(href_list["mob_player_panel"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["mob_player_panel"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.holder.show_player_panel(M) + href_list["datumrefresh"] = href_list["mob_player_panel"] + + else if(href_list["give_spell"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_spell"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_spell(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["give_disease"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_disease(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["give_disease2"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease2"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_disease2(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["godmode"]) + if(!check_rights(R_REJUVINATE)) return + + var/mob/M = locate(href_list["godmode"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.cmd_admin_godmode(M) + href_list["datumrefresh"] = href_list["godmode"] + + else if(href_list["gib"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["gib"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.cmd_admin_gib(M) + + else if(href_list["build_mode"]) + if(!check_rights(R_BUILDMODE)) return + + var/mob/M = locate(href_list["build_mode"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + togglebuildmode(M) + href_list["datumrefresh"] = href_list["build_mode"] + + else if(href_list["drop_everything"]) + if(!check_rights(R_DEBUG|R_ADMIN)) return + + var/mob/M = locate(href_list["drop_everything"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + if(usr.client) + usr.client.cmd_admin_drop_everything(M) + + else if(href_list["direct_control"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["direct_control"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + if(usr.client) + usr.client.cmd_assume_direct_control(M) + + else if(href_list["make_skeleton"]) + if(!check_rights(R_FUN)) return + + var/mob/living/carbon/human/H = locate(href_list["make_skeleton"]) + if(!istype(H)) + usr << "This can only be used on instances of type /mob/living/carbon/human" + return + + H.ChangeToSkeleton() + href_list["datumrefresh"] = href_list["make_skeleton"] + + else if(href_list["delall"]) + if(!check_rights(R_DEBUG|R_SERVER)) return + + var/obj/O = locate(href_list["delall"]) + if(!isobj(O)) + usr << "This can only be used on instances of type /obj" + return + + var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") + if(action_type == "Cancel" || !action_type) + return + + if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") + return + + if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") + return + + var/O_type = O.type + switch(action_type) + if("Strict type") + var/i = 0 + for(var/obj/Obj in world) + if(Obj.type == O_type) + i++ + del(Obj) + if(!i) + usr << "No objects of this type exist" + return + log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + if("Type and subtypes") + var/i = 0 + for(var/obj/Obj in world) + if(istype(Obj,O_type)) + i++ + del(Obj) + if(!i) + usr << "No objects of this type exist" + return + log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + + else if(href_list["explode"]) + if(!check_rights(R_DEBUG|R_FUN)) return + + var/atom/A = locate(href_list["explode"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + usr << "This can only be done to instances of type /obj, /mob and /turf" + return + + src.cmd_admin_explosion(A) + href_list["datumrefresh"] = href_list["explode"] + + else if(href_list["emp"]) + if(!check_rights(R_DEBUG|R_FUN)) return + + var/atom/A = locate(href_list["emp"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + usr << "This can only be done to instances of type /obj, /mob and /turf" + return + + src.cmd_admin_emp(A) + href_list["datumrefresh"] = href_list["emp"] + + else if(href_list["mark_object"]) + if(!check_rights(0)) return + + var/datum/D = locate(href_list["mark_object"]) + if(!istype(D)) + usr << "This can only be done to instances of type /datum" + return + + src.holder.marked_datum = D + href_list["datumrefresh"] = href_list["mark_object"] + + else if(href_list["rotatedatum"]) + if(!check_rights(0)) return + + var/atom/A = locate(href_list["rotatedatum"]) + if(!istype(A)) + usr << "This can only be done to instances of type /atom" + return + + switch(href_list["rotatedir"]) + if("right") A.set_dir(turn(A.dir, -45)) + if("left") A.set_dir(turn(A.dir, 45)) + href_list["datumrefresh"] = href_list["rotatedatum"] + + else if(href_list["makemonkey"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) + + else if(href_list["makerobot"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makerobot"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makerobot"=href_list["makerobot"])) + + else if(href_list["makealien"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makealien"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makealien"=href_list["makealien"])) + + else if(href_list["makeslime"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makeslime"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makeslime"=href_list["makeslime"])) + + else if(href_list["makeai"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makeai"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!H) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makeai"=href_list["makeai"])) + + else if(href_list["setspecies"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["setspecies"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.set_species(new_species)) + usr << "Set species of [H] to [H.species]." + else + usr << "Failed! Something went wrong." + + else if(href_list["addlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["addlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + var/new_language = input("Please choose a language to add.","Language",null) as null|anything in all_languages + + if(!new_language) + return + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.add_language(new_language)) + usr << "Added [new_language] to [H]." + else + usr << "Mob already knows that language." + + else if(href_list["remlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["remlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + if(!H.languages.len) + usr << "This mob knows no languages." + return + + var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages + + if(!rem_language) + return + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.remove_language(rem_language.name)) + usr << "Removed [rem_language] from [H]." + else + usr << "Mob doesn't know that language." + + else if(href_list["addverb"]) + if(!check_rights(R_DEBUG)) return + + var/mob/living/H = locate(href_list["addverb"]) + + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living" + return + var/list/possibleverbs = list() + possibleverbs += "Cancel" // One for the top... + possibleverbs += typesof(/mob/proc,/mob/verb,/mob/living/proc,/mob/living/verb) + switch(H.type) + if(/mob/living/carbon/human) + possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc) + if(/mob/living/silicon/robot) + possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb) + if(/mob/living/silicon/ai) + possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb) + possibleverbs -= H.verbs + possibleverbs += "Cancel" // ...And one for the bottom + + var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs + if(!H) + usr << "Mob doesn't exist anymore" + return + if(!verb || verb == "Cancel") + return + else + H.verbs += verb + + else if(href_list["remverb"]) + if(!check_rights(R_DEBUG)) return + + var/mob/H = locate(href_list["remverb"]) + + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + var/verb = input("Please choose a verb to remove.","Verbs",null) as null|anything in H.verbs + if(!H) + usr << "Mob doesn't exist anymore" + return + if(!verb) + return + else + H.verbs -= verb + + else if(href_list["addorgan"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/M = locate(href_list["addorgan"]) + if(!istype(M)) + usr << "This can only be done to instances of type /mob/living/carbon" + return + + var/new_organ = input("Please choose an organ to add.","Organ",null) as null|anything in typesof(/obj/item/organ)-/obj/item/organ + if(!new_organ) return + + if(!M) + usr << "Mob doesn't exist anymore" + return + + if(locate(new_organ) in M.internal_organs) + usr << "Mob already has that organ." + return + +<<<<<<< HEAD + new new_organ(M) + +======= + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/internal/I = new new_organ(H) + + var/organ_slot = input(usr, "Which slot do you want the organ to go in ('default' for default)?") as text|null + + if(!organ_slot) + return + + if(organ_slot != "default") + organ_slot = sanitize(organ_slot) + else + if(I.removed_type) + var/obj/item/organ/O = new I.removed_type() + organ_slot = O.organ_tag + del(O) + else + organ_slot = "unknown organ" + + if(H.internal_organs_by_name[organ_slot]) + usr << "[H] already has an organ in that slot." + del(I) + return + + H.internal_organs |= I + H.internal_organs_by_name[organ_slot] = I + usr << "Added new [new_organ] to [H] as slot [organ_slot]." + else + new new_organ(M) + usr << "Added new [new_organ] to [M]." +>>>>>>> 2aa4646fa0425bed412e2ef0e7852591ecb4bc40 + + else if(href_list["remorgan"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/M = locate(href_list["remorgan"]) + if(!istype(M)) + usr << "This can only be done to instances of type /mob/living/carbon" + return + + var/obj/item/organ/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs + + if(!M) + usr << "Mob doesn't exist anymore" + return + + if(!(locate(rem_organ) in M.internal_organs)) + usr << "Mob does not have that organ." + return + + usr << "Removed [rem_organ] from [M]." + rem_organ.removed() + del(rem_organ) + + else if(href_list["fix_nano"]) + if(!check_rights(R_DEBUG)) return + + var/mob/H = locate(href_list["fix_nano"]) + + if(!istype(H) || !H.client) + usr << "This can only be done on mobs with clients" + return + + nanomanager.send_resources(H.client) + + usr << "Resource files sent" + H << "Your NanoUI Resource files have been refreshed" + + log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ") + + else if(href_list["regenerateicons"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["regenerateicons"]) + if(!ismob(M)) + usr << "This can only be done to instances of type /mob" + return + M.regenerate_icons() + + else if(href_list["adjustDamage"] && href_list["mobToDamage"]) + if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return + + var/mob/living/L = locate(href_list["mobToDamage"]) + if(!istype(L)) return + + var/Text = href_list["adjustDamage"] + + var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num + + if(!L) + usr << "Mob doesn't exist anymore" + return + + switch(Text) + if("brute") L.adjustBruteLoss(amount) + if("fire") L.adjustFireLoss(amount) + if("toxin") L.adjustToxLoss(amount) + if("oxygen")L.adjustOxyLoss(amount) + if("brain") L.adjustBrainLoss(amount) + if("clone") L.adjustCloneLoss(amount) + else + usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]" + return + + if(amount != 0) + log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") + message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") + href_list["datumrefresh"] = href_list["mobToDamage"] + + if(href_list["datumrefresh"]) + var/datum/DAT = locate(href_list["datumrefresh"]) + if(!istype(DAT, /datum)) + return + src.debug_variables(DAT) + + return + diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index 8ab0f1b491e..37a2adecb6f 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -46,7 +46,7 @@ H << "\red Your abdomen is a world of pain!" H.Weaken(10) - var/datum/organ/external/groin = H.get_organ("groin") + var/obj/item/organ/external/groin = H.get_organ("groin") var/datum/wound/W = new /datum/wound/internal_bleeding(20) H.adjustToxLoss(25) groin.wounds += W diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 1d6d703c167..f6fbbc110c8 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -309,7 +309,7 @@ datum/mind switch(href_list["implant"]) if("remove") for(var/obj/item/weapon/implant/loyalty/I in H.contents) - for(var/datum/organ/external/organs in H.organs) + for(var/obj/item/organ/external/organs in H.organs) if(I in organs.implants) I.Del() break diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm index 2b45d1f778e..9fe4226e5bb 100644 --- a/code/game/antagonist/alien/borer.dm +++ b/code/game/antagonist/alien/borer.dm @@ -27,8 +27,8 @@ var/datum/antagonist/xenos/borer/borers borer.host = host borer.host_brain.name = host.name borer.host_brain.real_name = host.real_name - var/datum/organ/external/head = host.get_organ("head") - head.implants += borer + var/obj/item/organ/external/head = host.get_organ("head") + if(head) head.implants += borer /datum/antagonist/xenos/borer/proc/get_hosts() var/list/possible_hosts = list() diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 4ffa5ea5126..9bfdf9f0b65 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -146,6 +146,7 @@ H.r_eyes = dna.GetUIValueRange(DNA_UI_EYES_R, 255) H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255) H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255) + H.update_eyes() H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. diff --git a/code/game/dna/dna_misc.dm b/code/game/dna/dna_misc.dm index 08a479963b1..1362aa68882 100644 --- a/code/game/dna/dna_misc.dm +++ b/code/game/dna/dna_misc.dm @@ -235,6 +235,9 @@ H.r_eyes = hex2num(getblock(structure,8,3)) H.g_eyes = hex2num(getblock(structure,9,3)) H.b_eyes = hex2num(getblock(structure,10,3)) + if(H.internal_organs_by_name["eyes"]) + var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] + eyes.eye_colour = list(H.r_eyes,H.g_eyes,H.b_eyes) if (isblockon(getblock(structure, 11,3),11 , 1)) H.gender = FEMALE @@ -461,7 +464,7 @@ O.adjustToxLoss(M.getToxLoss() + 20) O.adjustOxyLoss(M.getOxyLoss()) O.stat = M.stat - O.a_intent = I_HURT + O.a_intent = "hurt" for (var/obj/item/weapon/implant/I in implants) I.loc = O I.implanted = O diff --git a/code/game/dna/dna_misc.dm.orig b/code/game/dna/dna_misc.dm.orig new file mode 100644 index 00000000000..00810f50e16 --- /dev/null +++ b/code/game/dna/dna_misc.dm.orig @@ -0,0 +1,1123 @@ +<<<<<<< HEAD +/////////////////////////// DNA HELPER-PROCS +/proc/getleftblocks(input,blocknumber,blocksize) + var/string + + if (blocknumber > 1) + string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + return string + else + return null + +/proc/getrightblocks(input,blocknumber,blocksize) + var/string + if (blocknumber < (length(input)/blocksize)) + string = copytext(input,blocksize*blocknumber+1,length(input)+1) + return string + else + return null + +/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen + var/string + var/subpos = 1 // keeps track of the current sub block + var/blockpos = 1 // keeps track of the current block + + + for(var/i = 1, i <= length(input), i++) // loop through each letter + + var/pushstring + + if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it + pushstring = "[copytext(input, i, i+1)]" + else + if(ui) //This is for allowing block clicks to be differentiated + pushstring = "[copytext(input, i, i+1)]" + else + pushstring = "[copytext(input, i, i+1)]" + + string += pushstring // push the string to the return string + + if(subpos >= blocksize) // add a line break for every block + string += " | " + subpos = 0 + blockpos++ + + subpos++ + + return string + + +/proc/getblock(input,blocknumber,blocksize) + var/result + result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + return result + +/proc/getblockbuffer(input,blocknumber,blocksize) + var/result[3] + var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + for(var/i = 1, i <= 3, i++) + result[i] = copytext(block, i, i+1) + return result + +/proc/setblock(istring, blocknumber, replacement, blocksize) + if(!blocknumber) + return istring + if(!istring || !replacement || !blocksize) return 0 + var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) + return result + +/proc/add_zero2(t, u) + var/temp1 + while (length(t) < u) + t = "0[t]" + temp1 = t + if (length(t) > u) + temp1 = copytext(t,2,u+1) + return temp1 + +/proc/miniscramble(input,rs,rd) + var/output + output = null + if (input == "C" || input == "D" || input == "E" || input == "F") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") + if (input == "8" || input == "9" || input == "A" || input == "B") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "4" || input == "5" || input == "6" || input == "7") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "0" || input == "1" || input == "2" || input == "3") + output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") + if (!output) output = "5" + return output + +//Instead of picking a value far from the input, this will pick values closer to it. +//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text +/proc/miniscrambletarget(input,rs,rd) + var/output = null + switch(input) + if("0") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") + if("1") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") + if("2") + output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") + if("3") + output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") + if("4") + output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") + if("5") + output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") + if("6") + output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") + if("7") + output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") + if("8") + output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") + if("9") + output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") + if("10")//A + output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") + if("11")//B + output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") + if("12")//C + output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") + if("13")//D + output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") + if("14")//E + output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + if("15")//F + output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + + if(!input || !output) //How did this happen? + output = "8" + + return output + +/proc/isblockon(hnumber, bnumber , var/UI = 0) + + var/temp2 + temp2 = hex2num(hnumber) + + if(UI) + if(temp2 >= 2050) + return 1 + else + return 0 + + if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) + if (temp2 >= 3500 + BLOCKADD) + return 1 + else + return 0 + if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) + if (temp2 >= 3050 + BLOCKADD) + return 1 + else + return 0 + + + if (temp2 >= 2050 + BLOCKADD) + return 1 + else + return 0 + +/proc/ismuton(var/block,var/mob/M) + return isblockon(getblock(M.dna.struc_enzymes, block,3),block) + +/proc/randmutb(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/randmutg(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/scramble(var/type, mob/M as mob, var/p) + if(!M) return + M.dna.check_integrity() + if(type) + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + updateappearance(M, M.dna.uni_identity) + + else + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + domutcheck(M, null) + return + +/proc/randmuti(mob/M as mob) + if(!M) return + var/num + var/newdna + num = rand(1,UNIDNASIZE) + M.dna.check_integrity() + newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) + M.dna.uni_identity = newdna + return + +/proc/toggledblock(hnumber) //unused + var/temp3 + var/chtemp + temp3 = hex2num(hnumber) + if (temp3 < 2050) + chtemp = rand(2050,4095) + return add_zero2(num2hex(chtemp,1),3) + else + chtemp = rand(1,2049) + return add_zero2(num2hex(chtemp,1),3) +/////////////////////////// DNA HELPER-PROCS + +/////////////////////////// DNA MISC-PROCS +/proc/updateappearance(mob/M as mob , structure) + if(istype(M, /mob/living/carbon/human)) + M.dna.check_integrity() + var/mob/living/carbon/human/H = M + H.r_hair = hex2num(getblock(structure,1,3)) + H.b_hair = hex2num(getblock(structure,2,3)) + H.g_hair = hex2num(getblock(structure,3,3)) + H.r_facial = hex2num(getblock(structure,4,3)) + H.b_facial = hex2num(getblock(structure,5,3)) + H.g_facial = hex2num(getblock(structure,6,3)) + H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) + H.r_eyes = hex2num(getblock(structure,8,3)) + H.g_eyes = hex2num(getblock(structure,9,3)) + H.b_eyes = hex2num(getblock(structure,10,3)) + + if (isblockon(getblock(structure, 11,3),11 , 1)) + H.gender = FEMALE + else + H.gender = MALE + + //Hair + var/hairnum = hex2num(getblock(structure,13,3)) + var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) + if((0 < index) && (index <= hair_styles_list.len)) + H.h_style = hair_styles_list[index] + + //Facial Hair + var/beardnum = hex2num(getblock(structure,12,3)) + index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) + if((0 < index) && (index <= facial_hair_styles_list.len)) + H.f_style = facial_hair_styles_list[index] + + H.update_body(0) + H.update_hair() + + return 1 + else + return 0 + +/proc/probinj(var/pr, var/inj) + return prob(pr+inj*pr) + +/proc/domutcheck(mob/living/M as mob, connected, inj) + if (!M) return + + M.dna.check_integrity() + + M.disabilities = 0 + M.sdisabilities = 0 + var/old_mutations = M.mutations + M.mutations = list() + +// M.see_in_dark = 2 +// M.see_invisible = 0 + + if(PLANT in old_mutations) + M.mutations.Add(PLANT) + if(SKELETON in old_mutations) + M.mutations.Add(SKELETON) + if(FAT in old_mutations) + M.mutations.Add(FAT) + if(HUSK in old_mutations) + M.mutations.Add(HUSK) + + if(ismuton(NOBREATHBLOCK,M)) + if(probinj(45,inj) || (mNobreath in old_mutations)) + M << "\blue You feel no need to breathe." + M.mutations.Add(mNobreath) + if(ismuton(REMOTEVIEWBLOCK,M)) + if(probinj(45,inj) || (mRemote in old_mutations)) + M << "\blue Your mind expands" + M.mutations.Add(mRemote) + if(ismuton(REGENERATEBLOCK,M)) + if(probinj(45,inj) || (mRegen in old_mutations)) + M << "\blue You feel strange" + M.mutations.Add(mRegen) + if(ismuton(INCREASERUNBLOCK,M)) + if(probinj(45,inj) || (mRun in old_mutations)) + M << "\blue You feel quick" + M.mutations.Add(mRun) + if(ismuton(REMOTETALKBLOCK,M)) + if(probinj(45,inj) || (mRemotetalk in old_mutations)) + M << "\blue You expand your mind outwards" + M.mutations.Add(mRemotetalk) + if(ismuton(MORPHBLOCK,M)) + if(probinj(45,inj) || (mMorph in old_mutations)) + M.mutations.Add(mMorph) + M << "\blue Your skin feels strange" + if(ismuton(BLENDBLOCK,M)) + if(probinj(45,inj) || (mBlend in old_mutations)) + M.mutations.Add(mBlend) + M << "\blue You feel alone" + if(ismuton(HALLUCINATIONBLOCK,M)) + if(probinj(45,inj) || (mHallucination in old_mutations)) + M.mutations.Add(mHallucination) + M << "\blue Your mind says 'Hello'" + if(ismuton(NOPRINTSBLOCK,M)) + if(probinj(45,inj) || (mFingerprints in old_mutations)) + M.mutations.Add(mFingerprints) + M << "\blue Your fingers feel numb" + if(ismuton(SHOCKIMMUNITYBLOCK,M)) + if(probinj(45,inj) || (mShock in old_mutations)) + M.mutations.Add(mShock) + M << "\blue You feel strange" + if(ismuton(SMALLSIZEBLOCK,M)) + if(probinj(45,inj) || (mSmallsize in old_mutations)) + M << "\blue Your skin feels rubbery" + M.mutations.Add(mSmallsize) + + + + if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) + if(probinj(5,inj) || (HULK in old_mutations)) + M << "\blue Your muscles hurt." + M.mutations.Add(HULK) + if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) + M.disabilities |= EPILEPSY + M << "\red You get a headache." + if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) + M << "\red You feel strange." + if (prob(95)) + if(prob(50)) + randmutb(M) + else + randmuti(M) + else + randmutg(M) + if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) + M.disabilities |= COUGHING + M << "\red You start coughing." + if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) + M << "\red You feel lightheaded." + M.mutations.Add(CLUMSY) + if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) + M.disabilities |= TOURETTES + M << "\red You twitch." + if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) + if(probinj(30,inj) || (XRAY in old_mutations)) + M << "\blue The walls suddenly disappear." +// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) +// M.see_in_dark = 8 +// M.see_invisible = 2 + M.mutations.Add(XRAY) + if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) + M.disabilities |= NERVOUS + M << "\red You feel nervous." + if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) + if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) + M << "\blue Your body feels warm." + M.mutations.Add(COLD_RESISTANCE) + if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) + M.sdisabilities |= BLIND + M << "\red You can't seem to see anything." + if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) + if(probinj(15,inj) || (TK in old_mutations)) + M << "\blue You feel smarter." + M.mutations.Add(TK) + if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) + M.sdisabilities |= DEAF + M.ear_deaf = 1 + M << "\red Its kinda quiet.." + if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) + M.disabilities |= NEARSIGHTED + M << "Your eyes feel weird..." + + /* If you want the new mutations to work, UNCOMMENT THIS. + if(istype(M, /mob/living/carbon)) + for (var/datum/mutations/mut in global_mutations) + mut.check_mutation(M) + */ + +//////////////////////////////////////////////////////////// Monkey Block + if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) + // human > monkey + var/mob/living/carbon/human/H = M + H.monkeyizing = 1 + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + W.loc = null + + if(!connected) + for(var/obj/item/W in (H.contents-implants)) + if (W==H.w_uniform) // will be teared + continue + H.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(48) + del(animation) + + + var/mob/living/carbon/monkey/O = null + if(H.species.primitive) + O = new H.species.primitive(src) + else + H.gib() //Trying to change the species of a creature with no primitive var set is messy. + return + + if(M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + + for(var/obj/T in (M.contents-implants)) + del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the cute little monkey + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) + O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss() + 20) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + O.a_intent = I_HURT + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return + + if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) + // monkey > human, + var/mob/living/carbon/monkey/Mo = M + Mo.monkeyizing = 1 + var/list/implants = list() //Still preserving implants + for(var/obj/item/weapon/implant/W in Mo) + implants += W + W.loc = null + if(!connected) + for(var/obj/item/W in (Mo.contents-implants)) + Mo.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + del(animation) + + var/mob/living/carbon/human/O = new( src ) + if(Mo.greaterform) + O.set_species(Mo.greaterform) + + if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) + O.gender = FEMALE + else + O.gender = MALE + + if (M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + //for(var/obj/T in M) + // del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the human + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + + var/i + while (!i) + var/randomname + if (O.gender == MALE) + randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) + else + randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) + if (findname(randomname)) + continue + else + O.real_name = randomname + i++ + updateappearance(O,O.dna.uni_identity) + O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss()) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return +//////////////////////////////////////////////////////////// Monkey Block + if(M) + M.update_icon = 1 //queue a full icon update at next life() call + return null +======= +/////////////////////////// DNA HELPER-PROCS +/proc/getleftblocks(input,blocknumber,blocksize) + var/string + + if (blocknumber > 1) + string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + return string + else + return null + +/proc/getrightblocks(input,blocknumber,blocksize) + var/string + if (blocknumber < (length(input)/blocksize)) + string = copytext(input,blocksize*blocknumber+1,length(input)+1) + return string + else + return null + +/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen + var/string + var/subpos = 1 // keeps track of the current sub block + var/blockpos = 1 // keeps track of the current block + + + for(var/i = 1, i <= length(input), i++) // loop through each letter + + var/pushstring + + if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it + pushstring = "[copytext(input, i, i+1)]" + else + if(ui) //This is for allowing block clicks to be differentiated + pushstring = "[copytext(input, i, i+1)]" + else + pushstring = "[copytext(input, i, i+1)]" + + string += pushstring // push the string to the return string + + if(subpos >= blocksize) // add a line break for every block + string += " | " + subpos = 0 + blockpos++ + + subpos++ + + return string + + +/proc/getblock(input,blocknumber,blocksize) + var/result + result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + return result + +/proc/getblockbuffer(input,blocknumber,blocksize) + var/result[3] + var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + for(var/i = 1, i <= 3, i++) + result[i] = copytext(block, i, i+1) + return result + +/proc/setblock(istring, blocknumber, replacement, blocksize) + if(!blocknumber) + return istring + if(!istring || !replacement || !blocksize) return 0 + var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) + return result + +/proc/add_zero2(t, u) + var/temp1 + while (length(t) < u) + t = "0[t]" + temp1 = t + if (length(t) > u) + temp1 = copytext(t,2,u+1) + return temp1 + +/proc/miniscramble(input,rs,rd) + var/output + output = null + if (input == "C" || input == "D" || input == "E" || input == "F") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") + if (input == "8" || input == "9" || input == "A" || input == "B") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "4" || input == "5" || input == "6" || input == "7") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "0" || input == "1" || input == "2" || input == "3") + output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") + if (!output) output = "5" + return output + +//Instead of picking a value far from the input, this will pick values closer to it. +//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text +/proc/miniscrambletarget(input,rs,rd) + var/output = null + switch(input) + if("0") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") + if("1") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") + if("2") + output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") + if("3") + output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") + if("4") + output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") + if("5") + output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") + if("6") + output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") + if("7") + output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") + if("8") + output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") + if("9") + output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") + if("10")//A + output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") + if("11")//B + output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") + if("12")//C + output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") + if("13")//D + output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") + if("14")//E + output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + if("15")//F + output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + + if(!input || !output) //How did this happen? + output = "8" + + return output + +/proc/isblockon(hnumber, bnumber , var/UI = 0) + + var/temp2 + temp2 = hex2num(hnumber) + + if(UI) + if(temp2 >= 2050) + return 1 + else + return 0 + + if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) + if (temp2 >= 3500 + BLOCKADD) + return 1 + else + return 0 + if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) + if (temp2 >= 3050 + BLOCKADD) + return 1 + else + return 0 + + + if (temp2 >= 2050 + BLOCKADD) + return 1 + else + return 0 + +/proc/ismuton(var/block,var/mob/M) + return isblockon(getblock(M.dna.struc_enzymes, block,3),block) + +/proc/randmutb(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/randmutg(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/scramble(var/type, mob/M as mob, var/p) + if(!M) return + M.dna.check_integrity() + if(type) + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + updateappearance(M, M.dna.uni_identity) + + else + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + domutcheck(M, null) + return + +/proc/randmuti(mob/M as mob) + if(!M) return + var/num + var/newdna + num = rand(1,UNIDNASIZE) + M.dna.check_integrity() + newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) + M.dna.uni_identity = newdna + return + +/proc/toggledblock(hnumber) //unused + var/temp3 + var/chtemp + temp3 = hex2num(hnumber) + if (temp3 < 2050) + chtemp = rand(2050,4095) + return add_zero2(num2hex(chtemp,1),3) + else + chtemp = rand(1,2049) + return add_zero2(num2hex(chtemp,1),3) +/////////////////////////// DNA HELPER-PROCS + +/////////////////////////// DNA MISC-PROCS +/proc/updateappearance(mob/M as mob , structure) + if(istype(M, /mob/living/carbon/human)) + M.dna.check_integrity() + var/mob/living/carbon/human/H = M + H.r_hair = hex2num(getblock(structure,1,3)) + H.b_hair = hex2num(getblock(structure,2,3)) + H.g_hair = hex2num(getblock(structure,3,3)) + H.r_facial = hex2num(getblock(structure,4,3)) + H.b_facial = hex2num(getblock(structure,5,3)) + H.g_facial = hex2num(getblock(structure,6,3)) + H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) + H.r_eyes = hex2num(getblock(structure,8,3)) + H.g_eyes = hex2num(getblock(structure,9,3)) + H.b_eyes = hex2num(getblock(structure,10,3)) + if(H.internal_organs_by_name["eyes"]) + var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] + eyes.eye_colour = list(H.r_eyes,H.g_eyes,H.b_eyes) + + if (isblockon(getblock(structure, 11,3),11 , 1)) + H.gender = FEMALE + else + H.gender = MALE + + //Hair + var/hairnum = hex2num(getblock(structure,13,3)) + var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) + if((0 < index) && (index <= hair_styles_list.len)) + H.h_style = hair_styles_list[index] + + //Facial Hair + var/beardnum = hex2num(getblock(structure,12,3)) + index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) + if((0 < index) && (index <= facial_hair_styles_list.len)) + H.f_style = facial_hair_styles_list[index] + + H.update_body(0) + H.update_hair() + + return 1 + else + return 0 + +/proc/probinj(var/pr, var/inj) + return prob(pr+inj*pr) + +/proc/domutcheck(mob/living/M as mob, connected, inj) + if (!M) return + + M.dna.check_integrity() + + M.disabilities = 0 + M.sdisabilities = 0 + var/old_mutations = M.mutations + M.mutations = list() + +// M.see_in_dark = 2 +// M.see_invisible = 0 + + if(PLANT in old_mutations) + M.mutations.Add(PLANT) + if(SKELETON in old_mutations) + M.mutations.Add(SKELETON) + if(FAT in old_mutations) + M.mutations.Add(FAT) + if(HUSK in old_mutations) + M.mutations.Add(HUSK) + + if(ismuton(NOBREATHBLOCK,M)) + if(probinj(45,inj) || (mNobreath in old_mutations)) + M << "\blue You feel no need to breathe." + M.mutations.Add(mNobreath) + if(ismuton(REMOTEVIEWBLOCK,M)) + if(probinj(45,inj) || (mRemote in old_mutations)) + M << "\blue Your mind expands" + M.mutations.Add(mRemote) + if(ismuton(REGENERATEBLOCK,M)) + if(probinj(45,inj) || (mRegen in old_mutations)) + M << "\blue You feel strange" + M.mutations.Add(mRegen) + if(ismuton(INCREASERUNBLOCK,M)) + if(probinj(45,inj) || (mRun in old_mutations)) + M << "\blue You feel quick" + M.mutations.Add(mRun) + if(ismuton(REMOTETALKBLOCK,M)) + if(probinj(45,inj) || (mRemotetalk in old_mutations)) + M << "\blue You expand your mind outwards" + M.mutations.Add(mRemotetalk) + if(ismuton(MORPHBLOCK,M)) + if(probinj(45,inj) || (mMorph in old_mutations)) + M.mutations.Add(mMorph) + M << "\blue Your skin feels strange" + if(ismuton(BLENDBLOCK,M)) + if(probinj(45,inj) || (mBlend in old_mutations)) + M.mutations.Add(mBlend) + M << "\blue You feel alone" + if(ismuton(HALLUCINATIONBLOCK,M)) + if(probinj(45,inj) || (mHallucination in old_mutations)) + M.mutations.Add(mHallucination) + M << "\blue Your mind says 'Hello'" + if(ismuton(NOPRINTSBLOCK,M)) + if(probinj(45,inj) || (mFingerprints in old_mutations)) + M.mutations.Add(mFingerprints) + M << "\blue Your fingers feel numb" + if(ismuton(SHOCKIMMUNITYBLOCK,M)) + if(probinj(45,inj) || (mShock in old_mutations)) + M.mutations.Add(mShock) + M << "\blue You feel strange" + if(ismuton(SMALLSIZEBLOCK,M)) + if(probinj(45,inj) || (mSmallsize in old_mutations)) + M << "\blue Your skin feels rubbery" + M.mutations.Add(mSmallsize) + + + + if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) + if(probinj(5,inj) || (HULK in old_mutations)) + M << "\blue Your muscles hurt." + M.mutations.Add(HULK) + if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) + M.disabilities |= EPILEPSY + M << "\red You get a headache." + if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) + M << "\red You feel strange." + if (prob(95)) + if(prob(50)) + randmutb(M) + else + randmuti(M) + else + randmutg(M) + if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) + M.disabilities |= COUGHING + M << "\red You start coughing." + if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) + M << "\red You feel lightheaded." + M.mutations.Add(CLUMSY) + if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) + M.disabilities |= TOURETTES + M << "\red You twitch." + if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) + if(probinj(30,inj) || (XRAY in old_mutations)) + M << "\blue The walls suddenly disappear." +// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) +// M.see_in_dark = 8 +// M.see_invisible = 2 + M.mutations.Add(XRAY) + if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) + M.disabilities |= NERVOUS + M << "\red You feel nervous." + if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) + if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) + M << "\blue Your body feels warm." + M.mutations.Add(COLD_RESISTANCE) + if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) + M.sdisabilities |= BLIND + M << "\red You can't seem to see anything." + if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) + if(probinj(15,inj) || (TK in old_mutations)) + M << "\blue You feel smarter." + M.mutations.Add(TK) + if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) + M.sdisabilities |= DEAF + M.ear_deaf = 1 + M << "\red Its kinda quiet.." + if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) + M.disabilities |= NEARSIGHTED + M << "Your eyes feel weird..." + + /* If you want the new mutations to work, UNCOMMENT THIS. + if(istype(M, /mob/living/carbon)) + for (var/datum/mutations/mut in global_mutations) + mut.check_mutation(M) + */ + +//////////////////////////////////////////////////////////// Monkey Block + if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) + // human > monkey + var/mob/living/carbon/human/H = M + H.monkeyizing = 1 + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + W.loc = null + + if(!connected) + for(var/obj/item/W in (H.contents-implants)) + if (W==H.w_uniform) // will be teared + continue + H.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(48) + del(animation) + + + var/mob/living/carbon/monkey/O = null + if(H.species.primitive) + O = new H.species.primitive(src) + else + H.gib() //Trying to change the species of a creature with no primitive var set is messy. + return + + if(M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + + for(var/obj/T in (M.contents-implants)) + del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the cute little monkey + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) + O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss() + 20) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + O.a_intent = "hurt" + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return + + if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) + // monkey > human, + var/mob/living/carbon/monkey/Mo = M + Mo.monkeyizing = 1 + var/list/implants = list() //Still preserving implants + for(var/obj/item/weapon/implant/W in Mo) + implants += W + W.loc = null + if(!connected) + for(var/obj/item/W in (Mo.contents-implants)) + Mo.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + del(animation) + + var/mob/living/carbon/human/O = new( src ) + if(Mo.greaterform) + O.set_species(Mo.greaterform) + + if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) + O.gender = FEMALE + else + O.gender = MALE + + if (M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + //for(var/obj/T in M) + // del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the human + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + + var/i + while (!i) + var/randomname + if (O.gender == MALE) + randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) + else + randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) + if (findname(randomname)) + continue + else + O.real_name = randomname + i++ + updateappearance(O,O.dna.uni_identity) + O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss()) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return +//////////////////////////////////////////////////////////// Monkey Block + if(M) + M.update_icon = 1 //queue a full icon update at next life() call + return null +>>>>>>> d77010221cbd08f6373edebee25d727b6409413b +/////////////////////////// DNA MISC-PROCS \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 530a009b67e..6f5ca5d8e92 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -213,7 +213,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E src << "We stab [T] with the proboscis." src.visible_message("[src] stabs [T] with the proboscis!") T << "You feel a sharp stabbing pain!" - var/datum/organ/external/affecting = T.get_organ(src.zone_sel.selecting) + var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting) if(affecting.take_damage(39,0,1,0,"large organic needle")) T:UpdateDamageIcon() @@ -388,13 +388,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E del(animation) for(var/obj/item/W in src) - C.u_equip(W) - if (C.client) - C.client.screen -= W - if (W) - W.loc = C.loc - W.dropped(C) - W.layer = initial(W.layer) + C.drop_from_inventory(W) var/mob/living/carbon/human/O = new /mob/living/carbon/human( src ) if (C.dna.GetUIState(DNA_UI_GENDER)) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 51f77c2cc01..f2f5f96de78 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -17,7 +17,7 @@ user.Paralyse(5) user << "\red An unexplicable force powerfully repels the sword from [target]!" var/organ = ((user.hand ? "l_":"r_") + "arm") - var/datum/organ/external/affecting = user.get_organ(organ) + var/obj/item/organ/external/affecting = user.get_organ(organ) if(affecting.take_damage(rand(force/2, force))) //random amount of damage between half of the blade's force and the full force of the blade. user.UpdateDamageIcon() return diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 30ce1206e57..9230436a056 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -433,10 +433,9 @@ var/list/sacrificed = list() D.b_eyes = 200 D.r_eyes = 200 D.g_eyes = 200 + D.update_eyes() D.underwear = 0 - D.key = ghost.key - cult.add_antagonist(D.mind) if(!chose_name) @@ -797,7 +796,7 @@ var/list/sacrificed = list() if (cultist.legcuffed) cultist.drop_from_inventory(cultist.legcuffed) if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.u_equip(cultist.wear_mask) + cultist.drop_from_inventory(cultist.wear_mask) if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) cultist.loc:welded = 0 if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index ba53c38525c..27236dd8fbf 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -455,15 +455,21 @@ datum/objective/harm return 0 var/mob/living/carbon/human/H = target.current - for(var/datum/organ/external/E in H.organs) + for(var/obj/item/organ/external/E in H.organs) if(E.status & ORGAN_BROKEN) - already_completed = 1 return 1 - if(E.status & ORGAN_DESTROYED && !E.amputated) - already_completed = 1 + for(var/limb_tag in H.species.has_limbs) //todo check prefs for robotic limbs and amputations. + var/list/organ_data = H.species.has_limbs[limb_tag] + var/limb_type = organ_data["path"] + var/found + for(var/obj/item/organ/external/E in H.organs) + if(limb_type == E.type) + found = 1 + break + if(!found) return 1 - var/datum/organ/external/head/head = H.get_organ("head") + var/obj/item/organ/external/head/head = H.get_organ("head") if(head.disfigured) return 1 return 0 diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 6d2b5e33d67..da346f9fce8 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -110,23 +110,11 @@ return null /obj/proc/check_access(obj/item/I) - if(!(!req_access || req_access.len) && !(req_one_access || req_one_access.len)) //no requirements - return 1 - if(!I) - return 0 - for(var/req in src.req_access) - if(!(req in I.GetAccess())) //doesn't have this access - return 0 - if(src.req_one_access.len) - for(var/req in src.req_one_access) - if(req in I.GetAccess()) //has an access from the single access list - return 1 - return 0 - return 1 - + return check_access_list(I ? I.GetAccess() : list()) /obj/proc/check_access_list(var/list/L) - if(!src.req_access.len && !src.req_one_access.len) return 1 + if(!req_access) req_access = list() + if(!req_one_access) req_one_access = list() if(!L) return 0 if(!istype(L, /list)) return 0 for(var/req in src.req_access) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index f6ec2ad87db..360245ccf13 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -514,8 +514,8 @@ var/global/datum/controller/occupations/job_master H.internals.icon_state = "internal1" if(istype(H)) //give humans wheelchairs, if they need them. - var/datum/organ/external/l_foot = H.get_organ("l_foot") - var/datum/organ/external/r_foot = H.get_organ("r_foot") + var/obj/item/organ/external/l_foot = H.get_organ("l_foot") + var/obj/item/organ/external/r_foot = H.get_organ("r_foot") if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED)) var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc) H.buckled = W diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 98ebc5a6265..51e1ec75103 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -346,7 +346,7 @@ dat += "Other Wounds" dat += "" - for(var/datum/organ/external/e in occ["external_organs"]) + for(var/obj/item/organ/external/e in occ["external_organs"]) var/AN = "" var/open = "" var/infected = "" @@ -362,7 +362,7 @@ for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
    Internal bleeding" break - if(istype(e, /datum/organ/external/chest) && occ["lung_ruptured"]) + if(istype(e, /obj/item/organ/external/chest) && occ["lung_ruptured"]) lung_ruptured = "Lung ruptured:" if(e.status & ORGAN_SPLINTED) splint = "Splinted:" @@ -404,12 +404,12 @@ if(!AN && !open && !infected & !imp) AN = "None:" if(!(e.status & ORGAN_DESTROYED)) - dat += "[e.display_name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]" + dat += "[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]" else - dat += "[e.display_name]--Not Found" + dat += "[e.name]--Not Found" dat += "" - for(var/datum/organ/internal/i in occ["internal_organs"]) + for(var/obj/item/organ/i in occ["internal_organs"]) var/mech = "" if(i.robotic == 1) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 9b5cfaa526c..d537d113f9b 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -189,7 +189,7 @@ var/obj/item/stack/stack = eating stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. else - user.drop_item(O) + user.remove_from_mob(O) del(O) updateUsrDialog() diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index a8df2abaad3..87399b597ac 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -52,7 +52,7 @@ if(beaker) user << "]The [src] is already loaded." else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src beaker = O updateUsrDialog() @@ -74,6 +74,7 @@ if(i < 10) user << "You empty \the [O] into \the [src]." + else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) user << "You cannot put this in \the [src]." else @@ -83,7 +84,7 @@ if(i >= 10) user << "\The [src] is full! Activate it." else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src user << "You put \the [O] in \the [src]" update_icon() diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 207da09a041..48c0edb9846 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -43,18 +43,14 @@ if(prints_prosthetics) O.robotic = 2 else if(loaded_dna) - visible_message("The printer injects stored DNA in used biomass..") - var/datum/organ/internal/I = new O.organ_type - I.transplant_data = list() + visible_message("The printer injects the stored DNA into the biomass..") + O.transplant_data = list() var/mob/living/carbon/C = loaded_dna["donor"] - I.transplant_data["species"] = C.species.name - I.transplant_data["blood_type"] = loaded_dna["blood_type"] - I.transplant_data["blood_DNA"] = loaded_dna["blood_DNA"] - O.organ_data = I - I.organ_holder = O + O.transplant_data["species"] = C.species.name + O.transplant_data["blood_type"] = loaded_dna["blood_type"] + O.transplant_data["blood_DNA"] = loaded_dna["blood_DNA"] - - visible_message("The bioprinter spits out a new organ.") + visible_message("The bioprinter spits out a new organ.") else user << "There is not enough matter in the printer." diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index f225b9ce8d3..a955efaa1f2 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -84,7 +84,7 @@ lasercolor = "r" else if( istype(W, /obj/item/clothing/suit/bluetag) ) lasercolor = "b" - if( lasercolor || istype(W, /obj/item/clothing/suit/armor/vest) ) + if( lasercolor || istype(W, /obj/item/clothing/suit/storage/vest) ) user.drop_item() del(W) build_step++ diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index f91607eeb56..ca32e937ed3 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -542,7 +542,7 @@ A.loc = src.loc user << "You add the robot arm to the [src]" src.loc = A //Place the water tank into the assembly, it will be needed for the finished bot - user.u_equip(S) + user.remove_from_mob(S) del(S) /obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -551,21 +551,21 @@ src.build_step++ user << "You add the plant analyzer to [src]!" src.name = "farmbot assembly" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if(( istype(W, /obj/item/weapon/reagent_containers/glass/bucket)) && (src.build_step == 1)) src.build_step++ user << "You add a bucket to [src]!" src.name = "farmbot assembly with bucket" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if(( istype(W, /obj/item/weapon/minihoe)) && (src.build_step == 2)) src.build_step++ user << "You add a minihoe to [src]!" src.name = "farmbot assembly with bucket and minihoe" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if((isprox(W)) && (src.build_step == 3)) @@ -577,7 +577,7 @@ S.tank = wTank S.loc = get_turf(src) S.name = src.created_name - user.u_equip(W) + user.remove_from_mob(W) del(W) del(src) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index a038ece4140..e56e5446492 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -125,7 +125,7 @@ if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. user << "You attach \the [W] into the assembly inner circuits." upgrades += W - user.drop_item(W) + user.remove_from_mob(W) W.loc = src return diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm index e650185f855..80d60afd072 100644 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ b/code/game/machinery/computer3/computers/HolodeckControl.dm @@ -154,7 +154,7 @@ if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) + M.remove_from_mob(obj) M.update_icons() //so their overlays update if(!silent) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0040ac0e920..40c137e77b3 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -593,7 +593,7 @@ About the new airlock wires panel: playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) if(!istype(H.head, /obj/item/clothing/head/helmet)) visible_message("\red [user] headbutts the airlock.") - var/datum/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ("head") H.Stun(8) H.Weaken(5) if(affecting.take_damage(10, 0)) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 4f310de8b96..1a47ae81fdb 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -82,7 +82,7 @@ O.Weaken(strength) if (istype(O, /mob/living/carbon/human)) var/mob/living/carbon/human/H = O - var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] if (E && (E.damage > E.min_bruised_damage && prob(E.damage + 50))) flick("e_flash", O:flash) E.damage += rand(1, 5) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 74e7de99346..1283e7e52c3 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -228,7 +228,7 @@ for (var/obj/thing in contents) // Todo: unify limbs and internal organs // There's a chance that the gibber will fail to destroy some evidence. - if((istype(thing,/obj/item/weapon/organ) || istype(thing,/obj/item/organ)) && prob(80)) + if((istype(thing,/obj/item/organ) || istype(thing,/obj/item/organ)) && prob(80)) del(thing) continue thing.loc = get_turf(thing) // Drop it onto the turf for throwing. diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 76fdf631d6c..fbdcfd2760c 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -112,7 +112,7 @@ "\blue [user] has added one of [O] to \the [src].", \ "\blue You add one of [O] to \the [src].") else - // user.before_take_item(O) //This just causes problems so far as I can tell. -Pete + // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete user.drop_item() O.loc = src user.visible_message( \ diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 11688adc161..1b1bb9bfb5f 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -197,7 +197,7 @@ user << "\The [src] is full." return 1 else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src if(item_quants[O.name]) item_quants[O.name]++ diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index 4778ac13ead..4418586e9dd 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -11,7 +11,7 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob // Fruits and vegetables. if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown)) - user.drop_item(O) + user.remove_from_mob(O) var/datum/seed/new_seed_type if(istype(O, /obj/item/weapon/grown)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 534e59c0c63..940ec0f104c 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -331,7 +331,7 @@ sleep(50) if(src.OCCUPANT) OCCUPANT.radiation += 50 - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs + var/obj/item/organ/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs if (!rad_organ) if(src.issuperUV) var/burndamage = rand(28,35) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 1499af49961..176b6dea6c2 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -41,7 +41,7 @@ var/mob/living/carbon/human/H = target // if (M.health <= 0) return - var/datum/organ/external/temp = H.get_organ(pick("chest", "chest", "chest", "head")) + var/obj/item/organ/external/temp = H.get_organ(pick("chest", "chest", "chest", "head")) if(temp) var/update = 0 switch(damtype) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 87b8375bbb4..f000499ffdc 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -13,6 +13,7 @@ idle_power_usage = 20 active_power_usage = 5000 req_access = list(access_robotics) + var/current_manufacturer var/time_coeff = 1.5 //can be upgraded with research var/resource_coeff = 1.5 //can be upgraded with research var/list/resources = list( @@ -143,6 +144,7 @@ /obj/machinery/mecha_part_fabricator/New() ..() + component_parts = list() component_parts += new /obj/item/weapon/circuitboard/mechfab(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) @@ -165,6 +167,9 @@ */ return +/obj/machinery/mecha_part_fabricator/initialize() + current_manufacturer = basic_robolimb.company + /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) @@ -361,7 +366,11 @@ if( !(locate(part, src.contents)) || !(part.vars.Find("construction_time")) || !(part.vars.Find("construction_cost")) ) // these 3 are the current requirements for an object being buildable by the mech_fabricator return - src.being_built = new part.type(src) + if(current_manufacturer) + src.being_built = new part.type(src, current_manufacturer) + else + src.being_built = new part.type(src, basic_robolimb.company) + src.desc = "It's building [src.being_built]." src.remove_resources(part) src.overlays += "fab-active" @@ -562,7 +571,7 @@ switch(screen) if("main") left_part = output_available_resources()+"
    " - left_part += "Sync with R&D servers
    " + left_part += "Sync with R&D servers | Set manufacturer ([current_manufacturer])
    " for(var/part_set in part_sets) left_part += "[part_set] - \[Add all parts to queue\]
    " if("parts") @@ -623,6 +632,9 @@ return var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(href_list["set_manufacturer"]) + var/choice = input(usr, "Which manufacturer do you wish to use for this fabricator?") as null|anything in all_robolimbs + if(choice) current_manufacturer = choice if(href_list["part_set"]) var/tpart_set = filter.getStr("part_set") if(tpart_set) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index cdc7b26bbfc..840d779510f 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -113,7 +113,7 @@ // Aliens can get straight through these. if(istype(usr,/mob/living/carbon)) var/mob/living/carbon/M = usr - if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs) + if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) for(var/mob/O in oviewers(src)) O.show_message("\red [usr] strokes the [name] and it melts away!", 1) health = 0 @@ -355,7 +355,7 @@ Alien plants should do something if theres a lot of poison /obj/effect/alien/egg/attack_hand(user as mob) var/mob/living/carbon/M = user - if(!istype(M) || !(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs)) + if(!istype(M) || !(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)) return attack_hand(user) switch(status) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index db86bf36a1b..c6b3137806d 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -51,8 +51,8 @@ var/global/list/image/splatter_cache=list() if(amount < 1) return - var/datum/organ/external/l_foot = perp.get_organ("l_foot") - var/datum/organ/external/r_foot = perp.get_organ("r_foot") + var/obj/item/organ/external/l_foot = perp.get_organ("l_foot") + var/obj/item/organ/external/r_foot = perp.get_organ("r_foot") var/hasfeet = 1 if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED)) hasfeet = 0 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b52c5930f9e..87ab21e6108 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -40,6 +40,11 @@ var/zoomdevicename = null //name used for message when binoculars/scope is used var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars. + // Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used. + // If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question. + // Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed. + var/list/item_icons = null + /* Species-specific sprites, concept stolen from Paradise//vg/. ex: sprite_sheets = list( @@ -58,6 +63,15 @@ /obj/item/device icon = 'icons/obj/device.dmi' +//Checks if the item is being held by a mob, and if so, updates the held icons +/obj/item/proc/update_held_icon() + if(ismob(src.loc)) + var/mob/M = src.loc + if(M.l_hand == src) + M.update_inv_l_hand() + if(M.r_hand == src) + M.update_inv_r_hand() + /obj/item/ex_act(severity) switch(severity) if(1.0) @@ -119,11 +133,12 @@ /obj/item/attack_hand(mob/user as mob) if (!user) return if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if (user.hand) - temp = user:organs_by_name["l_hand"] + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return if (istype(src.loc, /obj/item/weapon/storage)) @@ -496,11 +511,11 @@ M.adjustBruteLoss(10) */ - if(istype(M, /mob/living/carbon/human)) + if(istype(H)) - var/datum/organ/internal/eyes/eyes = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] - if(M != user) + if(H != user) for(var/mob/O in (viewers(M) - user - M)) O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1) M << "\red [user] stabs you in the eye with [src]!" @@ -526,7 +541,7 @@ if (eyes.damage >= eyes.min_broken_damage) if(M.stat != 2) M << "\red You go blind!" - var/datum/organ/external/affecting = M:get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ("head") if(affecting.take_damage(7)) M:UpdateDamageIcon() else diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index 1e2fc4884fc..0d386623ecd 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -21,7 +21,7 @@ if (contents.len >= max_butts) user << "This ashtray is full." return - user.u_equip(W) + user.remove_from_mob(W) W.loc = src if (istype(W,/obj/item/clothing/mask/smokable/cigarette)) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 2746c70a74c..87f7b0fd8a6 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1207,8 +1207,8 @@ var/global/list/obj/item/device/pda/PDAs = list() var/list/damaged = H.get_damaged_organs(1,1) user.show_message("\blue Localized Damage, Brute/Burn:",1) if(length(damaged)>0) - for(var/datum/organ/external/org in damaged) - user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.display_name),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1) + for(var/obj/item/organ/external/org in damaged) + user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.name),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1) else user.show_message("\blue \t Limbs are OK.",1) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index e0731443d5a..1a646d3fe1f 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -123,9 +123,9 @@ REAGENT SCANNER var/list/damaged = H.get_damaged_organs(1,1) user.show_message("\blue Localized Damage, Brute/Burn:",1) if(length(damaged)>0) - for(var/datum/organ/external/org in damaged) + for(var/obj/item/organ/external/org in damaged) user.show_message(text("\blue \t []: [][]\blue - []", \ - "[capitalize(org.display_name)][org.status & ORGAN_ROBOT ? "(Cybernetic)" : ""]", \ + "[capitalize(org.name)][org.status & ORGAN_ROBOT ? "(Cybernetic)" : ""]", \ (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \ (org.status & ORGAN_BLEEDING)?"\red \[Bleeding\]":"\t", \ (org.burn_dam > 0) ? "[org.burn_dam]" :0),1) @@ -180,8 +180,10 @@ REAGENT SCANNER if(ishuman(M)) var/mob/living/carbon/human/H = M for(var/name in H.organs_by_name) - var/datum/organ/external/e = H.organs_by_name[name] - var/limb = e.display_name + var/obj/item/organ/external/e = H.organs_by_name[name] + if(!e) + continue + var/limb = e.name if(e.status & ORGAN_BROKEN) if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport." @@ -189,11 +191,11 @@ REAGENT SCANNER user << "\red Infected wound detected in subject [limb]. Disinfection recommended." for(var/name in H.organs_by_name) - var/datum/organ/external/e = H.organs_by_name[name] + var/obj/item/organ/external/e = H.organs_by_name[name] if(e.status & ORGAN_BROKEN) user.show_message(text("\red Bone fractures detected. Advanced scanner required for location."), 1) break - for(var/datum/organ/external/e in H.organs) + for(var/obj/item/organ/external/e in H.organs) for(var/datum/wound/W in e.wounds) if(W.internal) user.show_message(text("\red Internal bleeding detected. Advanced scanner required for location."), 1) break diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 8deb8d7a507..9c262243c68 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -7,43 +7,65 @@ slot_flags = SLOT_BELT var/construction_time = 100 var/list/construction_cost = list("metal"=20000,"glass"=5000) - var/list/part = null + var/list/part = null // Order of args is important for installing robolimbs. var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics. + var/model_info + dir = SOUTH + +/obj/item/robot_parts/set_dir() + return + +/obj/item/robot_parts/New(var/newloc, var/model) + ..(newloc) + if(model_info && model) + model_info = model + var/datum/robolimb/R = all_robolimbs[model] + if(R) + name = "[R.company] [initial(name)]" + desc = "[R.desc]" + if(icon_state in icon_states(R.icon)) + icon = R.icon + else + name = "robot [initial(name)]" /obj/item/robot_parts/l_arm - name = "robot left arm" + name = "left arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_arm" construction_time = 200 construction_cost = list("metal"=18000) part = list("l_arm","l_hand") + model_info = 1 /obj/item/robot_parts/r_arm - name = "robot right arm" + name = "right arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_arm" construction_time = 200 construction_cost = list("metal"=18000) part = list("r_arm","r_hand") + model_info = 1 /obj/item/robot_parts/l_leg - name = "robot left leg" + name = "left leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_leg" construction_time = 200 construction_cost = list("metal"=15000) part = list("l_leg","l_foot") + model_info = 1 /obj/item/robot_parts/r_leg - name = "robot right leg" + name = "right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_leg" construction_time = 200 construction_cost = list("metal"=15000) part = list("r_leg","r_foot") + model_info = 1 /obj/item/robot_parts/chest - name = "robot torso" + name = "torso" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" construction_time = 350 @@ -52,7 +74,7 @@ var/obj/item/weapon/cell/cell = null /obj/item/robot_parts/head - name = "robot head" + name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." icon_state = "head" construction_time = 350 @@ -61,7 +83,7 @@ var/obj/item/device/flash/flash2 = null /obj/item/robot_parts/robot_suit - name = "robot endoskeleton" + name = "endoskeleton" desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." icon_state = "robo_suit" construction_time = 500 @@ -110,7 +132,7 @@ B.loc = get_turf(src) user << "You armed the robot frame." if (user.get_inactive_hand()==src) - user.before_take_item(src) + user.remove_from_mob(src) user.put_in_inactive_hand(B) del(src) else diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 27e3eea6f7f..e59220c8482 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -22,9 +22,9 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) - if(affecting.display_name == "head") + if(affecting.name == "head") if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space)) user << "\red You can't apply [src] through [H.head]!" return 1 @@ -62,33 +62,33 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open == 0) if(!affecting.bandage()) - user << "\red The wounds on [M]'s [affecting.display_name] have already been bandaged." + user << "\red The wounds on [M]'s [affecting.name] have already been bandaged." return 1 else for (var/datum/wound/W in affecting.wounds) if (W.internal) continue if (W.current_stage <= W.max_bleeding_stage) - user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You bandage [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.name].", \ + "\blue You bandage [W.desc] on [M]'s [affecting.name]." ) //H.add_side_effect("Itch") else if (istype(W,/datum/wound/bruise)) - user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You place bruise patch over [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.name].", \ + "\blue You place bruise patch over [W.desc] on [M]'s [affecting.name]." ) else - user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You place bandaid over [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.name].", \ + "\blue You place bandaid over [W.desc] on [M]'s [affecting.name]." ) use(1) else if (can_operate(H)) //Checks if mob is lying down on table for surgery if (do_surgery(H,user,src)) return else - user << "The [affecting.display_name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/ointment name = "ointment" @@ -105,22 +105,22 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open == 0) if(!affecting.salve()) - user << "\red The wounds on [M]'s [affecting.display_name] have already been salved." + user << "\red The wounds on [M]'s [affecting.name] have already been salved." return 1 else - user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.display_name].", \ - "\blue You salve wounds on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.name].", \ + "\blue You salve wounds on [M]'s [affecting.name]." ) use(1) else if (can_operate(H)) //Checks if mob is lying down on table for surgery if (do_surgery(H,user,src)) return else - user << "The [affecting.display_name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/advanced/bruise_pack name = "advanced trauma kit" @@ -136,29 +136,29 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open == 0) var/bandaged = affecting.bandage() var/disinfected = affecting.disinfect() if(!(bandaged || disinfected)) - user << "\red The wounds on [M]'s [affecting.display_name] have already been treated." + user << "\red The wounds on [M]'s [affecting.name] have already been treated." return 1 else for (var/datum/wound/W in affecting.wounds) if (W.internal) continue if (W.current_stage <= W.max_bleeding_stage) - user.visible_message( "\blue [user] cleans [W.desc] on [M]'s [affecting.display_name] and seals edges with bioglue.", \ - "\blue You clean and seal [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] cleans [W.desc] on [M]'s [affecting.name] and seals edges with bioglue.", \ + "\blue You clean and seal [W.desc] on [M]'s [affecting.name]." ) //H.add_side_effect("Itch") else if (istype(W,/datum/wound/bruise)) - user.visible_message( "\blue [user] places medicine patch over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You place medicine patch over [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] places medicine patch over [W.desc] on [M]'s [affecting.name].", \ + "\blue You place medicine patch over [W.desc] on [M]'s [affecting.name]." ) else - user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You smear some bioglue over [W.desc] on [M]'s [affecting.display_name]." ) + user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.name].", \ + "\blue You smear some bioglue over [W.desc] on [M]'s [affecting.name]." ) if (bandaged) affecting.heal_damage(heal_brute,0) use(1) @@ -167,7 +167,7 @@ if (do_surgery(H,user,src)) return else - user << "The [affecting.display_name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/advanced/ointment name = "advanced burn kit" @@ -184,15 +184,15 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open == 0) if(!affecting.salve()) - user << "\red The wounds on [M]'s [affecting.display_name] have already been salved." + user << "\red The wounds on [M]'s [affecting.name] have already been salved." return 1 else - user.visible_message( "\blue [user] covers wounds on [M]'s [affecting.display_name] with regenerative membrane.", \ - "\blue You cover wounds on [M]'s [affecting.display_name] with regenerative membrane." ) + user.visible_message( "\blue [user] covers wounds on [M]'s [affecting.name] with regenerative membrane.", \ + "\blue You cover wounds on [M]'s [affecting.name] with regenerative membrane." ) affecting.heal_damage(0,heal_burn) use(1) else @@ -200,7 +200,7 @@ if (do_surgery(H,user,src)) return else - user << "The [affecting.display_name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/splint name = "medical splints" @@ -215,8 +215,8 @@ if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) - var/limb = affecting.display_name + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/limb = affecting.name if(!((affecting.name == "l_arm") || (affecting.name == "r_arm") || (affecting.name == "l_leg") || (affecting.name == "r_leg"))) user << "\red You can't apply a splint there!" return diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 798c6c0511f..f85bc336be9 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -25,7 +25,7 @@ if (istype(M,/mob/living/carbon/human)) //Repairing robolimbs var/mob/living/carbon/human/H = M - var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) if(S.open == 1) if (S && (S.status & ORGAN_ROBOT)) @@ -33,8 +33,8 @@ S.heal_damage(15, 15, robo_repair = 1) H.updatehealth() use(1) - user.visible_message("\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src].",\ - "You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name].") + user.visible_message("\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.name] with \the [src].",\ + "You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.name].") else user << "Nothing to fix here." else diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index ab1f767a429..a4e7d94fad9 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -186,7 +186,7 @@ spawn(0) //delete the empty stack once the current context yields if (amount <= 0) //check again in case someone transferred stuff to us if(usr) - usr.before_take_item(src) + usr.remove_from_mob(src) del(src) return 1 else diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index d78c7d40936..dc6787a73b0 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -37,7 +37,7 @@ W.time_inflicted = time_inflicted return W -/obj/item/weapon/autopsy_scanner/proc/add_data(var/datum/organ/external/O) +/obj/item/weapon/autopsy_scanner/proc/add_data(var/obj/item/organ/external/O) if(!O.autopsy_data.len && !O.trace_chemicals.len) return for(var/V in O.autopsy_data) @@ -64,9 +64,9 @@ if(!D.organs_scanned[O.name]) if(D.organ_names == "") - D.organ_names = O.display_name + D.organ_names = O.name else - D.organ_names += ", [O.display_name]" + D.organ_names += ", [O.name]" del D.organs_scanned[O.name] D.organs_scanned[O.name] = W.copy() @@ -191,7 +191,7 @@ src.timeofdeath = M.timeofdeath - var/datum/organ/external/S = M.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting) if(!S) usr << "You can't scan this body part." return @@ -199,7 +199,7 @@ usr << "You have to cut the limb open first!" return for(var/mob/O in viewers(M)) - O.show_message("\red [user.name] scans the wounds on [M.name]'s [S.display_name] with \the [src.name]", 1) + O.show_message("\red [user.name] scans the wounds on [M.name]'s [S.name] with \the [src.name]", 1) src.add_data(S) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 67e322496c0..fbba55b0400 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -157,7 +157,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/mob/living/M = loc if (!nomessage) M << "Your [name] goes out." - M.u_equip(src) //un-equip it so the overlays can update + M.remove_from_mob(src) //un-equip it so the overlays can update M.update_inv_wear_mask(0) M.update_inv_l_hand(0) M.update_inv_r_hand(1) diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 8ed63b88aa3..dd3d0886fb1 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -109,7 +109,7 @@ if(!ispath(gift_type,/obj/item)) return var/obj/item/I = new gift_type(M) - M.u_equip(src) + M.remove_from_mob(src) M.put_in_hands(I) I.add_fingerprint(M) del(src) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index bda28f83b1b..03d8ccdffcb 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -84,7 +84,7 @@ //This really should be in mob not every check if(ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] if (E && E.damage >= E.min_bruised_damage) M << "\red Your eyes start to burn badly!" if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 73c14edc887..85bec3a8ea2 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -79,11 +79,11 @@ var/last_chew = 0 if (H.wear_mask) return if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return - var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] + var/obj/item/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] if (!O) return - var/s = "\red [H.name] chews on \his [O.display_name]!" - H.visible_message(s, "\red You chew on your [O.display_name]!") + var/s = "\red [H.name] chews on \his [O.name]!" + H.visible_message(s, "\red You chew on your [O.name]!") H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") log_attack("[s] ([H.ckey])") diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index ea3b7d5752d..50b4135dd79 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -8,7 +8,7 @@ icon_state = "implant" var/implanted = null var/mob/imp_in = null - var/datum/organ/external/part = null + var/obj/item/organ/external/part = null item_color = "b" var/allow_reagents = 0 var/malfunction = 0 @@ -35,7 +35,7 @@ return 0 proc/meltdown() //breaks it down, making implant unrecongizible - imp_in << "\red You feel something melting inside [part ? "your [part.display_name]" : "you"]!" + imp_in << "\red You feel something melting inside [part ? "your [part.name]" : "you"]!" if (part) part.take_damage(burn = 15, used_weapon = "Electronics meltdown") else @@ -171,18 +171,18 @@ Implant Specifics:
    "} if(ishuman(imp_in)) if (elevel == "Localized Limb") if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste. - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!") + imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) sleep(25) - if (istype(part,/datum/organ/external/chest) || \ - istype(part,/datum/organ/external/groin) || \ - istype(part,/datum/organ/external/head)) + if (istype(part,/obj/item/organ/external/chest) || \ + istype(part,/obj/item/organ/external/groin) || \ + istype(part,/obj/item/organ/external/head)) part.createwound(BRUISE, 60) //mangle them instead explosion(get_turf(imp_in), -1, -1, 2, 3) del(src) else explosion(get_turf(imp_in), -1, -1, 2, 3) - part.droplimb(1) + part.droplimb(0,DROPLIMB_BLUNT) del(src) if (elevel == "Destroy Body") explosion(get_turf(T), -1, 0, 1, 6) @@ -236,18 +236,18 @@ Implant Specifics:
    "} proc/small_boom() if (ishuman(imp_in) && part) - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!") + imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) spawn(25) if (ishuman(imp_in) && part) //No tearing off these parts since it's pretty much killing //and you can't replace groins - if (istype(part,/datum/organ/external/chest) || \ - istype(part,/datum/organ/external/groin) || \ - istype(part,/datum/organ/external/head)) + if (istype(part,/obj/item/organ/external/chest) || \ + istype(part,/obj/item/organ/external/groin) || \ + istype(part,/obj/item/organ/external/head)) part.createwound(BRUISE, 60) //mangle them instead else - part.droplimb(1) + part.droplimb(0,DROPLIMB_BLUNT) explosion(get_turf(imp_in), -1, -1, 2, 3) del(src) diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 6d6e5ad4cbc..150f77e5e2d 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -43,7 +43,7 @@ src.imp.implanted = 1 if (ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affected = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) affected.implants += src.imp imp.part = affected @@ -123,7 +123,7 @@ c.scanned = A if(istype(A.loc,/mob/living/carbon/human)) var/mob/living/carbon/human/H = A.loc - H.u_equip(A) + H.remove_from_mob(A) else if(istype(A.loc,/obj/item/weapon/storage)) var/obj/item/weapon/storage/S = A.loc S.remove_from_storage(A) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 1b1d5b04f35..f04be5d33a2 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -111,6 +111,8 @@ w_class = 2 flags = NOSHIELD | NOBLOODY origin_tech = "magnets=3;syndicate=4" + sharp = 1 + edge = 1 /obj/item/weapon/melee/energy/sword/dropped(var/mob/user) ..() @@ -207,7 +209,7 @@ if(istype(loc,/mob/living)) var/mob/living/carbon/human/host = loc if(istype(host)) - for(var/datum/organ/external/organ in host.organs) + for(var/obj/item/organ/external/organ in host.organs) for(var/obj/item/O in organ.implants) if(O == src) organ.implants -= src diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index a4fc0081c20..6b48653a6a5 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -80,7 +80,7 @@ return if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) ) - var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) + var/obj/item/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) if(affecting.status & ORGAN_ROBOT) return if(affecting.take_damage(5, 0)) diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index ab5e1894202..0ee5df08e06 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -156,7 +156,7 @@ break if(!inserted || !S.amount) - usr.u_equip(S) + usr.remove_from_mob(S) usr.update_icons() //update our overlays if (usr.client && usr.s_active != src) usr.client.screen -= S diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 822b986488c..626ed7aba21 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -20,79 +20,9 @@ new /obj/item/weapon/spacecash(src) new /obj/item/weapon/spacecash(src) new /obj/item/weapon/spacecash(src) -//BS12 EDIT -/* // All cult functionality moved to Null Rod -/obj/item/weapon/storage/bible/proc/bless(mob/living/carbon/M as mob) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/heal_amt = 10 - for(var/datum/organ/external/affecting in H.organs) - if(affecting.heal_damage(heal_amt, heal_amt)) - H.UpdateDamageIcon() - return -/obj/item/weapon/storage/bible/attack(mob/living/M as mob, mob/living/user as mob) - - var/chaplain = 0 - if(user.mind && (user.mind.assigned_role == "Chaplain")) - chaplain = 1 - - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - - log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") - - if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - user << "\red You don't have the dexterity to do this!" - return - if(!chaplain) - user << "\red The book sizzles in your hands." - user.take_organ_damage(0,10) - return - - if ((CLUMSY in user.mutations) && prob(50)) - user << "\red The [src] slips out of your hand and hits your head." - user.take_organ_damage(10) - user.Paralyse(20) - return - -// if(..() == BLOCKED) -// return - - if (M.stat !=2) - if(M.mind && (M.mind.assigned_role == "Chaplain")) - user << "\red You can't heal yourself!" - return - /*if((M.mind in ticker.mode.cult) && (prob(20))) - M << "\red The power of [src.deity_name] clears your mind of heresy!" - user << "\red You see how [M]'s eyes become clear, the cult no longer holds control over him!" - ticker.mode.remove_cultist(M.mind)*/ - if ((istype(M, /mob/living/carbon/human) && prob(60))) - bless(M) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] heals [] with the power of [src.deity_name]!", user, M), 1) - M << "\red May the power of [src.deity_name] compel you to be healed!" - playsound(src.loc, "punch", 25, 1, -1) - else - if(ishuman(M) && !istype(M:head, /obj/item/clothing/head/helmet)) - M.adjustBrainLoss(10) - M << "\red You feel dumber." - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] beats [] over the head with []!", user, M, src), 1) - playsound(src.loc, "punch", 25, 1, -1) - else if(M.stat == 2) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] smacks []'s lifeless corpse with [].", user, M, src), 1) - playsound(src.loc, "punch", 25, 1, -1) - return -*/ /obj/item/weapon/storage/bible/afterattack(atom/A, mob/user as mob, proximity) if(!proximity) return -/* if (istype(A, /turf/simulated/floor)) - user << "\blue You hit the floor with the bible." - if(user.mind && (user.mind.assigned_role == "Chaplain")) - call(/obj/effect/rune/proc/revealrunes)(src)*/ if(user.mind && (user.mind.assigned_role == "Chaplain")) if(A.reagents && A.reagents.has_reagent("water")) //blesses all the water in the holder user << "\blue You bless [A]." diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index f24ff6bb2ca..495d4d75167 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -247,7 +247,7 @@ /obj/item/weapon/storage/proc/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) if(!istype(W)) return 0 if(usr) - usr.u_equip(W) + usr.remove_from_mob(W) usr.update_icons() //update our overlays W.loc = src W.on_enter_storage(src) @@ -463,4 +463,4 @@ return depth /obj/item/proc/get_storage_cost() - return 2**(w_class-1) //1,2,4,8,16,... \ No newline at end of file + return 2**(w_class-1) //1,2,4,8,16,... diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index bd34960a353..8747bbfacf0 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -53,7 +53,7 @@ /obj/item/weapon/melee/baton/examine(mob/user) if(!..(user, 1)) return - + if(bcell) user <<"The baton is [round(bcell.percent())]% charged." if(!bcell) @@ -133,13 +133,13 @@ return 0 var/mob/living/carbon/human/H = L - var/datum/organ/external/affecting = H.get_organ(target_zone) + var/obj/item/organ/external/affecting = H.get_organ(target_zone) if (affecting) if(!status) - L.visible_message("[L] has been prodded in the [affecting.display_name] with [src] by [user]. Luckily it was off.") + L.visible_message("[L] has been prodded in the [affecting.name] with [src] by [user]. Luckily it was off.") return 1 else - H.visible_message("[L] has been prodded in the [affecting.display_name] with [src] by [user]!") + H.visible_message("[L] has been prodded in the [affecting.name] with [src] by [user]!") else if(!status) L.visible_message("[L] has been prodded with [src] by [user]. Luckily it was off.") diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 02d50e0d267..3f2bbb18265 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -103,7 +103,7 @@ if ((!F.status)||(F.ptank)) return src.master = F F.ptank = src - user.before_take_item(src) + user.remove_from_mob(src) src.loc = F return diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index d8c811d2f65..20d96676ed8 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -79,7 +79,7 @@ Frequency: src.temp += "Extranneous Signals:
    " for (var/obj/item/weapon/implant/tracking/W in world) - if (!W.implanted || !(istype(W.loc,/datum/organ/external) || ismob(W.loc))) + if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc))) continue else var/mob/M = W.loc diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 5b23e90a019..10904319163 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -190,12 +190,12 @@ if (user.client) user.client.screen -= src if (user.r_hand == src) - user.u_equip(src) + user.remove_from_mob(src) else - user.u_equip(src) + user.remove_from_mob(src) src.master = F src.layer = initial(src.layer) - user.u_equip(src) + user.remove_from_mob(src) if (user.client) user.client.screen -= src src.loc = F @@ -362,7 +362,7 @@ var/safety = user:eyecheck() if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] if(!E) return if(H.species.flags & IS_SYNTHETIC) @@ -457,7 +457,7 @@ if(hasorgans(M)) - var/datum/organ/external/S = M:organs_by_name[user.zone_sel.selecting] + var/obj/item/organ/external/S = M:organs_by_name[user.zone_sel.selecting] if (!S) return if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) @@ -472,7 +472,7 @@ if(S.brute_dam) S.heal_damage(15,0,0,1) - user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.display_name] with \the [src].") + user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.name] with \the [src].") return else user << "Nothing to fix!" diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 8a1e35ca98c..bce7eabe9dd 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -128,12 +128,12 @@ base_icon = "fireaxe" name = "fire axe" desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?" - force = 10 + force = 15 sharp = 1 edge = 1 w_class = 4.0 slot_flags = SLOT_BACK - force_wielded = 40 + force_wielded = 30 attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") /obj/item/weapon/twohanded/fireaxe/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) @@ -198,7 +198,7 @@ base_icon = "spearglass" name = "spear" desc = "A haphazardly-constructed yet still deadly weapon of ancient design." - force = 14 + force = 10 w_class = 4.0 slot_flags = SLOT_BACK force_wielded = 22 // Was 13, Buffed - RR @@ -219,13 +219,13 @@ sharp = 0 edge = 0 w_class = 3 - force = 15 + force = 10 throw_speed = 3 throw_range = 7 throwforce = 7 - attack_verb = list("smashed", "beaten", "slammed", "smacked", "striked", "battered", "bonked") + attack_verb = list("smashed", "beaten", "slammed", "smacked", "struck", "battered", "bonked") hitsound = 'sound/weapons/genhit3.ogg' - force_wielded = 23 + force_wielded = 20 /obj/item/weapon/twohanded/baseballbat/metal name = "metal bat" @@ -233,6 +233,6 @@ icon_state = "metalbat0" base_icon = "metalbat" item_state = "metalbat" - force = 18 + force = 15 w_class = 3.0 - force_wielded = 27 \ No newline at end of file + force_wielded = 25 \ No newline at end of file diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index a23bb65cf87..900baea3f35 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -133,7 +133,7 @@ M.adjustBruteLoss(damage) return - var/datum/organ/external/affecting + var/obj/item/organ/external/affecting switch(pick(list("ankle","wrist","head","knee","elbow"))) if("ankle") @@ -148,7 +148,7 @@ affecting = H.get_organ("head") if(affecting) - M << "You land heavily on your [affecting.display_name]!" + M << "You land heavily on your [affecting.name]!" affecting.take_damage(damage, 0) if(affecting.parent) affecting.parent.add_autopsy_data("Misadventure", damage) diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index ac3e89000cf..a54c40b755e 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -21,8 +21,7 @@ if (can_hang && !coat) user.visible_message("[user] hangs [W] on \the [src].", "You hang [W] on the \the [src]") coat = W - user.drop_item(src) - coat.loc = src + user.drop_from_inventory(coat, src) update_icon() else user << "You cannot hang [W] on [src]" diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index 0728a9befae..8dacfa4c40f 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -61,7 +61,7 @@ user << "\red Unwield the axe first." return fireaxe = O - user.drop_item(O) + user.remove_from_mob(O) src.contents += O user << "\blue You place the fire axe back in the [src.name]." update_icon() diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 40ba963efd0..872b8ff9885 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -17,7 +17,7 @@ return if(istype(O, /obj/item/weapon/extinguisher)) if(!has_extinguisher && opened) - user.drop_item(O) + user.remove_from_mob(O) contents += O has_extinguisher = O user << "You place [O] in [src]." @@ -31,12 +31,13 @@ /obj/structure/extinguisher_cabinet/attack_hand(mob/user) if(isrobot(user)) return - if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] + if (ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if (user.hand) - temp = user:organs_by_name["l_hand"] + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return if(has_extinguisher) user.put_in_hands(has_extinguisher) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 47d9f7289ba..8ce25ddb671 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -249,7 +249,7 @@ TryToSwitchState(atom/user) var/mob/living/carbon/M = user - if(istype(M) && locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs) + if(istype(M) && locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) return ..() Open() diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 489e81a7395..fad0c3d0bd2 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -45,10 +45,10 @@ var/mob/living/carbon/xenos = user var/mob/living/carbon/victim = M - if(istype(victim) && locate(/datum/organ/internal/xenos/hivenode) in victim.internal_organs) + if(istype(victim) && locate(/obj/item/organ/xenos/hivenode) in victim.internal_organs) return - if(istype(xenos) && !(locate(/datum/organ/internal/xenos/hivenode) in xenos.internal_organs)) + if(istype(xenos) && !(locate(/obj/item/organ/xenos/hivenode) in xenos.internal_organs)) return if(M == usr) diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 8f26e5fb261..16e9161dcfc 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -10,7 +10,7 @@ /obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) if (prob(5) && istype(M,/mob/living)) user.visible_message("\red [user] breaks [src] over [M]'s back!") - user.u_equip(src) + user.remove_from_mob(src) var/obj/item/stack/sheet/metal/m = new/obj/item/stack/sheet/metal m.loc = get_turf(src) del src @@ -43,5 +43,5 @@ if(istype(W, /obj/item/weapon/wrench)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) new /obj/item/stack/sheet/metal(src.loc) - del(src) + del(src) ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 6b857ae4cf3..d14ddf1405f 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -431,7 +431,7 @@ user.visible_message("The [src] was sliced apart by [user]!") destroy() - user.drop_item(src) + user.drop_item(src.loc) return /obj/structure/table/proc/straight_table_check(var/direction) diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index bf80024a5e2..fa45f657369 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -26,7 +26,7 @@ if(istype(W, /obj/item/target)) density = 0 W.density = 1 - user.drop_item(src) + user.remove_from_mob(W) W.loc = loc W.layer = 3.1 pinned_target = W diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index e77f1e602ca..62f3ef60c1e 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -346,12 +346,13 @@ var/busy = 0 //Something's being washed at the moment /obj/structure/sink/attack_hand(mob/user as mob) - if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] + if (ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if (user.hand) - temp = user:organs_by_name["l_hand"] + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return if(isrobot(user) || isAI(user)) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index a821cde4aef..07b68a329a7 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -456,7 +456,7 @@ turf/simulated/floor/proc/update_icon() if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles if(is_light_floor()) if(get_lightfloor_state()) - user.drop_item(C) + user.remove_from_mob(C) del(C) set_lightfloor_state(0) //fixing it by bashing it with a light bulb, fun eh? update_icon() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1702fc4dbc1..d83d4da7474 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -802,6 +802,7 @@ var/list/admin_verbs_mentor = list( M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) + M.update_eyes() var/new_skin = input("Please select body color. This is for Tajaran, Unathi, and Skrell only!", "Character Generation") as color if(new_skin) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 5ffd58353ef..fc2ee0a0b26 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -968,11 +968,7 @@ //strip their stuff and stick it in the crate for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = locker - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I, locker) M.update_icons() //so they black out before warping @@ -1005,11 +1001,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) M.Paralyse(5) sleep(5) @@ -1034,11 +1026,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) M.Paralyse(5) sleep(5) @@ -1085,11 +1073,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/observer = M @@ -1835,16 +1819,10 @@ if(!security) //strip their stuff before they teleport into a cell :downs: for(var/obj/item/weapon/W in H) - if(istype(W, /datum/organ/external)) + if(istype(W, /obj/item/organ/external)) continue //don't strip organs - H.u_equip(W) - if (H.client) - H.client.screen -= W - if (W) - W.loc = H.loc - W.dropped(H) - W.layer = initial(W.layer) + H.drop_from_inventory(W) //teleport person to cell H.loc = pick(prisonwarp) H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform) diff --git a/code/modules/admin/verbs/BrokenInhands.dm b/code/modules/admin/verbs/BrokenInhands.dm index 43f6d0b7931..914ba1b5df4 100644 --- a/code/modules/admin/verbs/BrokenInhands.dm +++ b/code/modules/admin/verbs/BrokenInhands.dm @@ -1,7 +1,7 @@ /proc/getbrokeninhands() - var/icon/IL = new('icons/mob/items_lefthand.dmi') + var/icon/IL = new('icons/mob/items/lefthand.dmi') var/list/Lstates = IL.IconStates() - var/icon/IR = new('icons/mob/items_righthand.dmi') + var/icon/IR = new('icons/mob/items/righthand.dmi') var/list/Rstates = IR.IconStates() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b9858aa7d5d..325f04f9e89 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -735,19 +735,19 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that commandos.equip(M) if("nanotrasen representative") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Representative" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/clipboard(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_belt) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -757,23 +757,23 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer") W.assignment = "NanoTrasen Navy Representative" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("nanotrasen officer") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) - M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Officer" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -781,24 +781,24 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += get_all_centcom_access() W.assignment = "NanoTrasen Navy Officer" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("nanotrasen captain") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) - M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Captain" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -806,7 +806,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += get_all_centcom_access() W.assignment = "NanoTrasen Navy Captain" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("emergency response team") M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 7f7c3fe8e90..676ee17cd19 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -23,7 +23,7 @@ proc/triggered(mob/target as mob, var/type = "feet") if(!armed) return - var/datum/organ/external/affecting = null + var/obj/item/organ/external/affecting = null if(ishuman(target)) var/mob/living/carbon/human/H = target switch(type) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 493b681be3c..5a5e09a5ac2 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -111,6 +111,7 @@ datum/preferences // maps each organ to either null(intact), "cyborg" or "amputated" // will probably not be able to do this for head and torso ;) var/list/organ_data = list() + var/list/rlimb_data = list() var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor" var/list/flavor_texts = list() @@ -344,7 +345,12 @@ datum/preferences ++ind if(ind > 1) dat += ", " - dat += "\tMechanical [organ_name] prothesis" + var/datum/robolimb/R + if(rlimb_data[name] && all_robolimbs[rlimb_data[name]]) + R = all_robolimbs[rlimb_data[name]] + else + R = basic_robolimb + dat += "\t[R.company] [organ_name] prothesis" else if(status == "amputated") ++ind if(ind > 1) @@ -629,6 +635,8 @@ datum/preferences dat += "
    Has a plantlike physiology." if(current_species.flags & IS_SYNTHETIC) dat += "
    Is machine-based." + if(current_species.flags & REGENERATES_LIMBS) + dat += "
    Has a plantlike physiology." dat += "" dat += "" dat += "

    " @@ -1421,15 +1429,25 @@ datum/preferences switch(new_state) if("Normal") organ_data[limb] = null + rlimb_data[limb] = null if(third_limb) organ_data[third_limb] = null + rlimb_data[third_limb] = null if("Amputated") organ_data[limb] = "amputated" + rlimb_data[limb] = null if(second_limb) organ_data[second_limb] = "amputated" + rlimb_data[second_limb] = null + if("Prothesis") + var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in chargen_robolimbs + if(!choice) + return + rlimb_data[limb] = choice organ_data[limb] = "cyborg" if(second_limb) + organ_data[second_limb] = choice organ_data[second_limb] = "cyborg" if(third_limb && organ_data[third_limb] == "amputated") organ_data[third_limb] = null @@ -1662,21 +1680,28 @@ datum/preferences for(var/name in organ_data) var/status = organ_data[name] - var/datum/organ/external/O = character.organs_by_name[name] + var/obj/item/organ/external/O = character.organs_by_name[name] if(O) if(status == "amputated") - O.amputated = 1 - O.status |= ORGAN_DESTROYED - O.destspawn = 1 + character.organs_by_name[O.limb_name] = null + character.organs -= O + if(O.children) // This might need to become recursive. + for(var/obj/item/organ/external/child in O.children) + character.organs_by_name[child.limb_name] = null + character.organs -= child + else if(status == "cyborg") - O.status |= ORGAN_ROBOT + if(rlimb_data[name]) + O.robotize(rlimb_data[name]) + else + O.robotize() else - var/datum/organ/internal/I = character.internal_organs_by_name[name] + var/obj/item/organ/I = character.internal_organs_by_name[name] if(I) if(status == "assisted") I.mechassist() else if(status == "mechanical") - I.mechanize() + I.robotize() character.underwear = underwear diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index f3d46739f27..a67efd084c0 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -170,6 +170,7 @@ S["skills"] >> skills S["skill_specialization"] >> skill_specialization S["organ_data"] >> organ_data + S["rlimb_data"] >> rlimb_data S["gear"] >> gear S["home_system"] >> home_system S["citizenship"] >> citizenship @@ -240,6 +241,7 @@ if(isnull(disabilities)) disabilities = 0 if(!player_alt_titles) player_alt_titles = new() if(!organ_data) src.organ_data = list() + if(!rlimb_data) src.rlimb_data = list() if(!gear) src.gear = list() //if(!skin_style) skin_style = "Default" @@ -324,6 +326,7 @@ S["skills"] << skills S["skill_specialization"] << skill_specialization S["organ_data"] << organ_data + S["rlimb_data"] << rlimb_data S["gear"] << gear S["home_system"] << home_system S["citizenship"] << citizenship diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index 1436e4e4a28..23ba1d0c558 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -45,21 +45,15 @@ siemens_coefficient = 0.6 heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE - species_restricted = list("Vox", "Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/suit.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi') /obj/item/clothing/head/helmet/space/vox armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.6 flags = HEADCOVERSEYES|STOPPRESSUREDAMAGE - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/head.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/head.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') /obj/item/clothing/head/helmet/space/vox/pressure name = "alien helmet" @@ -137,22 +131,15 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 item_color = "gloves-vox" - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/gloves.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/gloves.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi') /obj/item/clothing/shoes/magboots/vox desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor." name = "vox magclaws" item_state = "boots-vox" icon_state = "boots-vox" - - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/feet.dmi' - ) + species_restricted = list("Vox") action_button_name = "Toggle the magclaws" diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index b106e412554..a9f7f53f8ce 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -85,7 +85,7 @@ desc = "A shoulder-mounted battery-powered laser cannon mount." selectable = 1 usable = 1 - use_power_cost = 10 + module_cooldown = 0 engage_string = "Configure" diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 7bf622b5394..15c4a683088 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -76,7 +76,7 @@ // Some space suits are equipped with reactive membranes that support // broken limbs - at the time of writing, only the ninja suit, but // I can see it being useful for other suits as we expand them. ~ Z -// The actual splinting occurs in /datum/organ/external/proc/fracture() +// The actual splinting occurs in /obj/item/organ/external/proc/fracture() /obj/item/clothing/suit/space/proc/check_limb_support(var/mob/living/carbon/human/user) // If this isn't set, then we don't need to care. @@ -87,7 +87,7 @@ return // Otherwise, remove the splints. - for(var/datum/organ/external/E in supporting_limbs) + for(var/obj/item/organ/external/E in supporting_limbs) E.status &= ~ ORGAN_SPLINTED - user << "The suit stops supporting your [E.display_name]." + user << "The suit stops supporting your [E.name]." supporting_limbs = list() diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index 38f50bf742b..8d575538a45 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -60,7 +60,7 @@ //replace old ID del(C) - ok = M.equip_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail + ok = M.equip_to_slot_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail break else if(istype(Item,/obj/item/weapon/storage/belt)) if(M.ckey == "jakksergal" && M.real_name == "Nashi Ra'hal" && M.mind.role_alt_title && M.mind.role_alt_title != "Nurse" && M.mind.role_alt_title != "Chemist") @@ -72,13 +72,13 @@ for(var/obj/item/weapon/storage/belt/B in M) del(B) M.belt=null - ok = M.equip_if_possible(I, slot_belt, 0) + ok = M.equip_to_slot_if_possible(I, slot_belt, 0) break if(istype(M.belt,/obj/item/device/pda)) for(var/obj/item/device/pda/Pda in M) M.belt=null - M.equip_if_possible(Pda, slot_l_store, 0) - ok = M.equip_if_possible(I, slot_belt, 0) + M.equip_to_slot_if_possible(Pda, slot_l_store, 0) + ok = M.equip_to_slot_if_possible(I, slot_belt, 0) else if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back Item.loc = M.back ok = 1 diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index e82bb3457f6..f516b609ffa 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -26,7 +26,7 @@ finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("dexalin")) for(var/organ_name in list("chest","l_arm","r_arm","r_leg","l_leg","head","groin")) - var/datum/organ/external/E = H.get_organ(organ_name) + var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(0, 5, 0) /datum/genetics/side_effect/bone_snap @@ -42,7 +42,7 @@ finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("bicaridine")) var/organ_name = pick("chest","l_arm","r_arm","r_leg","l_leg","head","groin") - var/datum/organ/external/E = H.get_organ(organ_name) + var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(20, 0, 0) E.fracture() diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index 8ae14ea2db9..f19a8cd4cee 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -251,7 +251,7 @@ var/global/list/holodeck_programs = list( if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) + M.remove_from_mob(obj) M.update_icons() //so their overlays update if(!silent) @@ -384,4 +384,4 @@ var/global/list/holodeck_programs = list( var/area/targetsource = locate(/area/holodeck/source_plating) targetsource.copy_contents_to(linkedholodeck , 1) active = 0 - use_power = 1 \ No newline at end of file + use_power = 1 diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 07bdccef521..7200711b605 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -277,7 +277,7 @@ del(W) return else if (istype(W, /obj/item) && get_dist(src,user)<2) - user.drop_item(src) + user.drop_item(src.loc) visible_message("[user] dunks [W] into the [src]!", 3) return diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 043e44db9df..6734510a5b6 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -110,19 +110,19 @@ if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin") - var/datum/organ/external/affecting = target.get_organ(target_limb) + var/obj/item/organ/external/affecting = target.get_organ(target_limb) var/damage = 0 if(get_trait(TRAIT_CARNIVOROUS)) if(get_trait(TRAIT_CARNIVOROUS) == 2) if(affecting) - target << "\The [fruit]'s thorns pierce your [affecting.display_name] greedily!" + target << "\The [fruit]'s thorns pierce your [affecting.name] greedily!" else target << "\The [fruit]'s thorns pierce your flesh greedily!" damage = get_trait(TRAIT_POTENCY)/2 else if(affecting) - target << "\The [fruit]'s thorns dig deeply into your [affecting.display_name]!" + target << "\The [fruit]'s thorns dig deeply into your [affecting.name]!" else target << "\The [fruit]'s thorns dig deeply into your flesh!" damage = get_trait(TRAIT_POTENCY)/5 diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index cce982372c0..1160235c9ee 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -88,7 +88,7 @@ if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0) user << "That seed is not compatible with our genetics technology." else - user.drop_item(W) + user.remove_from_mob(W) W.loc = src seed = W user << "You load [W] into [src]." @@ -120,7 +120,7 @@ user << "That disk does not have any gene data loaded." return - user.drop_item(W) + user.remove_from_mob(W) W.loc = src loaded_disk = W user << "You load [W] into [src]." diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index 469896018e8..0ee7c6175e7 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -225,7 +225,7 @@ /obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O as obj) if (istype(O.loc, /mob)) var/mob/user = O.loc - user.drop_item(O) + user.remove_from_mob(O) else if(istype(O.loc,/obj/item/weapon/storage)) var/obj/item/weapon/storage/S = O.loc S.remove_from_storage(O, src) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 19f181d03e7..69aa483b031 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -453,7 +453,7 @@ if(!seed) var/obj/item/seeds/S = O - user.drop_item(O) + user.remove_from_mob(O) if(!S.seed) user << "The packet seems to be empty. You throw it away." @@ -497,7 +497,7 @@ else if ( istype(O, /obj/item/weapon/plantspray) ) var/obj/item/weapon/plantspray/spray = O - user.drop_item(O) + user.remove_from_mob(O) toxins += spray.toxicity pestlevel -= spray.pest_kill_str weedlevel -= spray.weed_kill_str diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 67d630119a8..10f5961da71 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -226,7 +226,7 @@ icon_state = "hatchet" flags = CONDUCT force = 12.0 - w_class = 2.0 + w_class = 3.0 throwforce = 15.0 throw_speed = 4 throw_range = 4 diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index a3b601ebce9..698815d0a91 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -118,6 +118,8 @@ origin_tech = "materials=4;phorontech=3;engineering=3" desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff." drill_verb = "cutting" + sharp = 1 + edge = 1 /obj/item/weapon/pickaxe/diamond name = "diamond pickaxe" diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index eb596309156..5428f3f6c0a 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -12,7 +12,7 @@ /obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/ore)) - user.u_equip(W) + user.remove_from_mob(W) src.contents += W if (istype(W, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = W diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 653e33b2ddf..ea56c749b80 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -1,15 +1,81 @@ +//This proc is called whenever someone clicks an inventory ui slot. +/mob/proc/attack_ui(slot) + var/obj/item/W = get_active_hand() + if(istype(W)) + equip_to_slot_if_possible(W, slot) + +/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1) + if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob)) + return 1 + else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob)) + return 1 + return 0 + +//This is a SAFE proc. Use this instead of equip_to_slot()! +//set del_on_fail to have it delete W if it fails to equip +//set disable_warning to disable the 'you are unable to equip that' warning. +//unset redraw_mob to prevent the mob from being redrawn at the end. +/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1) + if(!istype(W)) return 0 + + if(!W.mob_can_equip(src, slot)) + if(del_on_fail) + del(W) + else + if(!disable_warning) + src << "\red You are unable to equip that." //Only print if del_on_fail is false + return 0 + + equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. + return 1 + +//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. +//In most cases you will want to use equip_to_slot_if_possible() +/mob/proc/equip_to_slot(obj/item/W as obj, slot) + return + +//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. +/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) + return equip_to_slot_if_possible(W, slot, 1, 1, 0) + +//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. +var/list/slot_equipment_priority = list( \ + slot_back,\ + slot_wear_id,\ + slot_w_uniform,\ + slot_wear_suit,\ + slot_wear_mask,\ + slot_head,\ + slot_shoes,\ + slot_gloves,\ + slot_l_ear,\ + slot_r_ear,\ + slot_glasses,\ + slot_belt,\ + slot_s_store,\ + slot_tie,\ + slot_l_store,\ + slot_r_store\ + ) + +//puts the item "W" into an appropriate slot in a human's inventory +//returns 0 if it cannot, 1 if successful +/mob/proc/equip_to_appropriate_slot(obj/item/W) + if(!istype(W)) return 0 + + for(var/slot in slot_equipment_priority) + if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) + return 1 + + return 0 + //These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc //as they handle all relevant stuff like adding it to the player's screen and updating their overlays. //Returns the thing in our active hand /mob/proc/get_active_hand() - if(issilicon(src)) - if(isrobot(src)) - if(src:module_active) - return src:module_active - else - if(hand) return l_hand - else return r_hand + if(hand) return l_hand + else return r_hand //Returns the thing in our inactive hand /mob/proc/get_inactive_hand() @@ -77,96 +143,45 @@ W.dropped() return 0 - - -/mob/proc/drop_item_v() //this is dumb. - if(stat == CONSCIOUS && isturf(loc)) - return drop_item() - return 0 - - +// Removes an item from inventory and places it in the target atom /mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null) if(W) if(!Target) Target = loc - if(client) client.screen -= W - u_equip(W) + remove_from_mob(W) if(!W) return 1 // self destroying objects (tk, grabs) - W.layer = initial(W.layer) - W.loc = Target - - var/turf/T = get_turf(Target) - if(isturf(T)) - T.Entered(W) - - W.dropped(src) + + W.forceMove(Target) update_icons() return 1 return 0 - //Drops the item in our left hand /mob/proc/drop_l_hand(var/atom/Target) - if(l_hand) - if(client) client.screen -= l_hand - l_hand.layer = initial(l_hand.layer) - - if(Target) l_hand.loc = Target.loc - else l_hand.loc = loc - - var/turf/T = get_turf(loc) - if(isturf(T)) - T.Entered(l_hand) - - l_hand.dropped(src) - l_hand = null - update_inv_l_hand() - return 1 - return 0 + return drop_from_inventory(l_hand, Target) //Drops the item in our right hand /mob/proc/drop_r_hand(var/atom/Target) - if(r_hand) - if(client) client.screen -= r_hand - r_hand.layer = initial(r_hand.layer) + return drop_from_inventory(r_hand, Target) - if(Target) r_hand.loc = Target.loc - else r_hand.loc = loc - - var/turf/T = get_turf(Target) - if(istype(T)) - T.Entered(r_hand) - - r_hand.dropped(src) - r_hand = null - update_inv_r_hand() - return 1 - return 0 - -//Drops the item in our active hand. +//Drops the item in our active hand. TODO: rename this to drop_active_hand or something /mob/proc/drop_item(var/atom/Target) if(hand) return drop_l_hand(Target) else return drop_r_hand(Target) - - - - - - - - -//TODO: phase out this proc -/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this? - W.loc = null - W.layer = initial(W.layer) - u_equip(W) - update_icons() - return - - -/mob/proc/u_equip(W as obj) +/* + Removes the object from any slots the mob might have, calling the appropriate icon update proc. + Does nothing else. + + DO NOT CALL THIS PROC DIRECTLY. It is meant to be called only by other inventory procs. + It's probably okay to use it if you are transferring the item between slots on the same mob, + but chances are you're safer calling remove_from_mob() or drop_from_inventory() anyways. + + As far as I can tell the proc exists so that mobs with different inventory slots can override + the search through all the slots, without having to duplicate the rest of the item dropping. +*/ +/mob/proc/u_equip(obj/W as obj) if (W == r_hand) r_hand = null update_inv_r_hand(0) @@ -181,40 +196,27 @@ update_inv_wear_mask(0) return +//This differs from remove_from_mob() in that it checks canremove first. /mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress. - if(!I) //If there's nothing to drop, the drop is automatically successful. If(unEquip) should generally be used to check for NODROP. + if(!I) //If there's nothing to drop, the drop is automatically successful. return 1 - /*if((I.flags & NODROP) && !force) - return 0*/ - if(!I.canremove && !force) return 0 - if(I == r_hand) - r_hand = null - update_inv_r_hand() - else if(I == l_hand) - l_hand = null - update_inv_l_hand() - - if(I) - if(client) - client.screen -= I - I.loc = loc - I.dropped(src) - if(I) - I.layer = initial(I.layer) + remove_from_mob(I) return 1 //Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob. -//It does call u_equip() though. So it can drop items to the floor but only if src is human. /mob/proc/remove_from_mob(var/obj/O) src.u_equip(O) if (src.client) src.client.screen -= O O.layer = initial(O.layer) O.screen_loc = null + if(istype(O, /obj/item)) + var/obj/item/I = O + I.dropped() return 1 @@ -240,99 +242,3 @@ //if(hasvar(src,"r_hand")) if(src:r_hand) items += src:r_hand return items - -/** BS12's proc to get the item in the active hand. Couldn't find the /tg/ equivalent. **/ -/mob/proc/equipped() - return get_active_hand() //TODO: get rid of this proc - -/mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, del_on_fail = 1) // since byond doesn't seem to have pointers, this seems like the best way to do this :/ - //warning: icky code - var/equipped = 0 - switch(slot) - if(slot_back) - if(!src.back) - src.back = W - equipped = 1 - if(slot_wear_mask) - if(!src.wear_mask) - src.wear_mask = W - equipped = 1 - if(slot_handcuffed) - if(!src.handcuffed) - src.handcuffed = W - equipped = 1 - if(slot_l_hand) - if(!src.l_hand) - src.l_hand = W - equipped = 1 - if(slot_r_hand) - if(!src.r_hand) - src.r_hand = W - equipped = 1 - if(slot_belt) - if(!src.belt && src.w_uniform) - src.belt = W - equipped = 1 - if(slot_wear_id) - if(!src.wear_id && src.w_uniform) - src.wear_id = W - equipped = 1 - if(slot_l_ear) - if(!src.l_ear) - src.l_ear = W - equipped = 1 - if(slot_r_ear) - if(!src.r_ear) - src.r_ear = W - equipped = 1 - if(slot_glasses) - if(!src.glasses) - src.glasses = W - equipped = 1 - if(slot_gloves) - if(!src.gloves) - src.gloves = W - equipped = 1 - if(slot_head) - if(!src.head) - src.head = W - equipped = 1 - if(slot_shoes) - if(!src.shoes) - src.shoes = W - equipped = 1 - if(slot_wear_suit) - if(!src.wear_suit) - src.wear_suit = W - equipped = 1 - if(slot_w_uniform) - if(!src.w_uniform) - src.w_uniform = W - equipped = 1 - if(slot_l_store) - if(!src.l_store && src.w_uniform) - src.l_store = W - equipped = 1 - if(slot_r_store) - if(!src.r_store && src.w_uniform) - src.r_store = W - equipped = 1 - if(slot_s_store) - if(!src.s_store && src.wear_suit) - src.s_store = W - equipped = 1 - if(slot_in_backpack) - if (src.back && istype(src.back, /obj/item/weapon/storage/backpack)) - var/obj/item/weapon/storage/backpack/B = src.back - if(B.contents.len < B.storage_slots && W.w_class <= B.max_w_class) - W.loc = B - equipped = 1 - - if(equipped) - W.layer = 20 - if(src.back && W.loc != src.back) - W.loc = src - else - if (del_on_fail) - del(W) - return equipped diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index cd12ead3858..1f89c16ff9c 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -24,7 +24,7 @@ var/mob/living/carbon/M = other if(!istype(M)) return 1 - if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs) + if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) return 1 return 0 diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 2369cb9fe58..548eee230b9 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -11,4 +11,4 @@ /mob/living/carbon/alien/larva/New() ..() add_language("Xenomorph") //Bonus language. - internal_organs += new /datum/organ/internal/xenos/hivenode(src) \ No newline at end of file + internal_organs |= new /obj/item/organ/xenos/hivenode(src) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 6ec6b4fce40..d2aa61e635b 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -10,11 +10,6 @@ throw_range = 5 origin_tech = "biotech=3" attack_verb = list("attacked", "slapped", "whacked") - prosthetic_name = "cyberbrain" - prosthetic_icon = "brain-prosthetic" - organ_tag = "brain" - organ_type = /datum/organ/internal/brain - var/mob/living/carbon/brain/brainmob = null /obj/item/organ/brain/xeno @@ -49,19 +44,18 @@ else user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.." -/obj/item/organ/brain/removed(var/mob/living/target,var/mob/living/user) +/obj/item/organ/brain/removed(var/mob/living/user) ..() - var/mob/living/simple_animal/borer/borer = target.has_brain_worms() + var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() if(borer) borer.detatch() //Should remove borer if the brain is removed - RR - var/mob/living/carbon/human/H = target var/obj/item/organ/brain/B = src - if(istype(B) && istype(H)) - B.transfer_identity(target) + if(istype(B) && istype(owner)) + B.transfer_identity(owner) /obj/item/organ/brain/replaced(var/mob/living/target) @@ -78,8 +72,6 @@ /obj/item/organ/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." - prosthetic_name = null - prosthetic_icon = null robotic = 2 icon = 'icons/mob/slimes.dmi' icon_state = "green slime extract" @@ -87,8 +79,6 @@ /obj/item/organ/brain/golem name = "chem" desc = "A tightly furled roll of paper, covered with indecipherable runes." - prosthetic_name = null - prosthetic_icon = null robotic = 2 icon = 'icons/obj/wizard.dmi' icon_state = "scroll" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 26ad526e95f..63eba6e781d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -32,8 +32,8 @@ if(istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src var/organ = H.get_organ("chest") - if (istype(organ, /datum/organ/external)) - var/datum/organ/external/temp = organ + if (istype(organ, /obj/item/organ/external)) + var/obj/item/organ/external/temp = organ if(temp.take_damage(d, 0)) H.UpdateDamageIcon() H.updatehealth() @@ -60,12 +60,13 @@ /mob/living/carbon/attack_hand(mob/M as mob) if(!istype(M, /mob/living/carbon)) return - if (hasorgans(M)) - var/datum/organ/external/temp = M:organs_by_name["r_hand"] - if (M.hand) - temp = M:organs_by_name["l_hand"] + if (ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + if (H.hand) + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - M << "\red You can't use your [temp.display_name]" + H << "\red You can't use your [temp.name]" return for(var/datum/disease/D in viruses) @@ -155,7 +156,7 @@ "\blue You check yourself for injuries." \ ) - for(var/datum/organ/external/org in H.organs) + for(var/obj/item/organ/external/org in H.organs) var/status = "" var/brutedamage = org.brute_dam var/burndamage = org.burn_dam @@ -186,7 +187,7 @@ status = "weirdly shapen." if(status == "") status = "OK" - src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.display_name,status),1) + src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.name,status),1) if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit)) H.play_xylophone() else if (on_fire) @@ -327,16 +328,9 @@ if(!item) return //Grab processing has a chance of returning null - item.layer = initial(item.layer) - u_equip(item) - update_icons() - - if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required. - item.loc = src.loc - if(src.client) - src.client.screen -= item - if(istype(item, /obj/item)) - item:dropped(src) // let it know it's been dropped + + src.remove_from_mob(item) + item.loc = src.loc //actually throw it! if (item) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 4976cba4fb1..311942ca021 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -83,6 +83,7 @@ g_eyes = green b_eyes = blue + update_eyes() update_body() return 1 diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 6b40a641986..338b265a4fe 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -1,19 +1,14 @@ /mob/living/carbon/human/gib() - for(var/datum/organ/internal/I in internal_organs) - var/obj/item/organ/current_organ = I.remove() - if(current_organ) - if(istype(loc,/turf)) - current_organ.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - current_organ.removed(src) + for(var/obj/item/organ/I in internal_organs) + I.removed() + if(istype(loc,/turf)) + I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - for(var/datum/organ/external/E in src.organs) - if(istype(E, /datum/organ/external/chest)) - continue - // Only make the limb drop if it's not too damaged - if(prob(100 - E.get_damage())) - // Override the current limb status and don't cause an explosion - E.droplimb(1,1) + for(var/obj/item/organ/external/E in src.organs) + E.droplimb(0,DROPLIMB_EDGE,1) + + sleep(1) ..(species.gibbed_anim) gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color) @@ -38,7 +33,7 @@ if(species) species.handle_death(src) //Handle brain slugs. - var/datum/organ/external/head = get_organ("head") + var/obj/item/organ/external/head = get_organ("head") var/mob/living/simple_animal/borer/B for(var/I in head.implants) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 73f8fc90eeb..965870f97e7 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -198,9 +198,9 @@ //splints for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = get_organ(organ) + var/obj/item/organ/external/o = get_organ(organ) if(o && o.status & ORGAN_SPLINTED) - msg += "[t_He] [t_has] a splint on [t_his] [o.display_name]!\n" + msg += "[t_He] [t_has] a splint on [t_his] [o.name]!\n" if(suiciding) msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n" @@ -251,33 +251,44 @@ var/list/wound_flavor_text = list() var/list/is_destroyed = list() var/list/is_bleeding = list() - for(var/datum/organ/external/temp in organs) + + for(var/organ_tag in species.has_limbs) + + var/list/organ_data = species.has_limbs[organ_tag] + var/organ_descriptor = organ_data["descriptor"] + is_destroyed["[organ_data["descriptor"]]"] = 1 + + var/obj/item/organ/external/E = organs_by_name[organ_tag] + if(!E) + wound_flavor_text["[organ_descriptor]"] = "[t_He] is missing [t_his] [organ_descriptor].\n" + else if(E.is_stump()) + wound_flavor_text["[organ_descriptor]"] = "[t_He] has a stump where [t_his] [organ_descriptor] should be.\n" + else + continue + + for(var/obj/item/organ/external/temp in organs) if(temp) - if(temp.status & ORGAN_DESTROYED) - is_destroyed["[temp.display_name]"] = 1 - wound_flavor_text["[temp.display_name]"] = "[t_He] is missing [t_his] [temp.display_name].\n" - continue if(temp.status & ORGAN_ROBOT) if(!(temp.brute_dam + temp.burn_dam)) if(!species.flags & IS_SYNTHETIC) - wound_flavor_text["[temp.display_name]"] = "[t_He] has a robot [temp.display_name]!\n" + wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]!\n" continue else - wound_flavor_text["[temp.display_name]"] = "[t_He] has a robot [temp.display_name]. It has" + wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]. It has" if(temp.brute_dam) switch(temp.brute_dam) if(0 to 20) - wound_flavor_text["[temp.display_name]"] += " some dents" + wound_flavor_text["[temp.name]"] += " some dents" if(21 to INFINITY) - wound_flavor_text["[temp.display_name]"] += pick(" a lot of dents"," severe denting") + wound_flavor_text["[temp.name]"] += pick(" a lot of dents"," severe denting") if(temp.brute_dam && temp.burn_dam) - wound_flavor_text["[temp.display_name]"] += " and" + wound_flavor_text["[temp.name]"] += " and" if(temp.burn_dam) switch(temp.burn_dam) if(0 to 20) - wound_flavor_text["[temp.display_name]"] += " some burns" + wound_flavor_text["[temp.name]"] += " some burns" if(21 to INFINITY) - wound_flavor_text["[temp.display_name]"] += pick(" a lot of burns"," severe melting") - if(wound_flavor_text["[temp.display_name]"]) - wound_flavor_text["[temp.display_name]"] += "!\n" + wound_flavor_text["[temp.name]"] += pick(" a lot of burns"," severe melting") + if(wound_flavor_text["[temp.name]"]) + wound_flavor_text["[temp.name]"] += "!\n" else if(temp.wounds.len > 0) var/list/wound_descriptors = list() for(var/datum/wound/W in temp.wounds) @@ -325,14 +336,14 @@ else if(flavor_text.len > 1 && text > 1) flavor_text_string += "," flavor_text_string += flavor_text[text] - flavor_text_string += " on [t_his] [temp.display_name].
    " - wound_flavor_text["[temp.display_name]"] = flavor_text_string + flavor_text_string += " on [t_his] [temp.name].
    " + wound_flavor_text["[temp.name]"] = flavor_text_string else - wound_flavor_text["[temp.display_name]"] = "" + wound_flavor_text["[temp.name]"] = "" if(temp.status & ORGAN_BLEEDING) - is_bleeding["[temp.display_name]"] = 1 + is_bleeding["[temp.name]"] = 1 else - wound_flavor_text["[temp.display_name]"] = "" + wound_flavor_text["[temp.name]"] = "" //Handles the text strings being added to the actual description. //If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b6f1a67597a..9c3057c52d8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -65,7 +65,7 @@ stat("Tank Pressure", internal.air_contents.return_pressure()) stat("Distribution Pressure", internal.distribute_pressure) - var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] if(P) stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]") @@ -129,7 +129,7 @@ var/update = 0 // focus most of the blast on one organ - var/datum/organ/external/take_blast = pick(organs) + var/obj/item/organ/external/take_blast = pick(organs) update |= take_blast.take_damage(b_loss * 0.9, f_loss * 0.9, used_weapon = "Explosive blast") // distribute the remaining 10% on all limbs equally @@ -138,7 +138,7 @@ var/weapon_message = "Explosive Blast" - for(var/datum/organ/external/temp in organs) + for(var/obj/item/organ/external/temp in organs) switch(temp.name) if("head") update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message) @@ -167,7 +167,7 @@ if(stat == 2) return show_message("\red The blob attacks you!") var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) apply_damage(rand(30,40), BRUTE, affecting, run_armor_check(affecting, "melee")) return @@ -176,7 +176,7 @@ if ((M.client && !( M.blinded ))) M.show_message("\red [src] has been hit by [O]", 1) if (health > 0) - var/datum/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head")) + var/obj/item/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head")) if(!affecting) return if (istype(O, /obj/effect/immovablerod)) if(affecting.take_damage(101, 0)) @@ -193,7 +193,7 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M) L.imp_in = M L.implanted = 1 - var/datum/organ/external/affected = M.organs_by_name["head"] + var/obj/item/organ/external/affected = M.organs_by_name["head"] affected.implants += L L.part = affected L.implanted(src) @@ -201,7 +201,7 @@ /mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M) for(var/L in M.contents) if(istype(L, /obj/item/weapon/implant/loyalty)) - for(var/datum/organ/external/O in M.organs) + for(var/obj/item/organ/external/O in M.organs) if(L in O.implants) return 1 return 0 @@ -326,7 +326,7 @@ //Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable /mob/living/carbon/human/proc/get_face_name() - var/datum/organ/external/head/head = get_organ("head") + var/obj/item/organ/external/head/head = get_organ("head") if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible return "Unknown" return real_name @@ -357,7 +357,7 @@ if (!def_zone) def_zone = pick("l_hand", "r_hand") - var/datum/organ/external/affected_organ = get_organ(check_zone(def_zone)) + 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) return ..(shock_damage, source, siemens_coeff, def_zone) @@ -677,7 +677,7 @@ return 2 if(internal_organs_by_name["eyes"]) // Eyes are fucked, not a 'weak point'. - var/datum/organ/internal/I = internal_organs_by_name["eyes"] + var/obj/item/organ/I = internal_organs_by_name["eyes"] if(I.status & ORGAN_CUT_AWAY) return 2 else @@ -795,6 +795,7 @@ r_eyes = hex2num(copytext(new_eyes, 2, 4)) g_eyes = hex2num(copytext(new_eyes, 4, 6)) b_eyes = hex2num(copytext(new_eyes, 6, 8)) + update_eyes() var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-s_tone]") as text @@ -922,19 +923,16 @@ germ_level += n /mob/living/carbon/human/revive() - for (var/datum/organ/external/O in organs) + for (var/obj/item/organ/external/O in organs) O.status &= ~ORGAN_BROKEN O.status &= ~ORGAN_BLEEDING O.status &= ~ORGAN_SPLINTED O.status &= ~ORGAN_CUT_AWAY O.status &= ~ORGAN_ATTACHABLE - if (!O.amputated) - O.status &= ~ORGAN_DESTROYED - O.destspawn = 0 O.wounds.Cut() O.heal_damage(1000,1000,1,1) - var/datum/organ/external/head/h = organs_by_name["head"] + var/obj/item/organ/external/head/h = organs_by_name["head"] h.disfigured = 0 if(species && !(species.flags & NO_BLOOD)) @@ -953,7 +951,7 @@ H.brainmob.mind.transfer_to(src) del(H) - for(var/datum/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) I.damage = 0 for (var/datum/disease/virus in viruses) @@ -968,11 +966,11 @@ ..() /mob/living/carbon/human/proc/is_lung_ruptured() - var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] return L && L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() - var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] if(L && !L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) @@ -1033,7 +1031,7 @@ /mob/living/carbon/human/get_visible_implants(var/class = 0) var/list/visible_implants = list() - for(var/datum/organ/external/organ in src.organs) + for(var/obj/item/organ/external/organ in src.organs) for(var/obj/item/weapon/O in organ.implants) if(!istype(O,/obj/item/weapon/implant) && (O.w_class > class) && !istype(O,/obj/item/weapon/shard/shrapnel)) visible_implants += O @@ -1042,7 +1040,7 @@ /mob/living/carbon/human/proc/handle_embedded_objects() - for(var/datum/organ/external/organ in src.organs) + for(var/obj/item/organ/external/organ in src.organs) if(organ.status & ORGAN_SPLINTED) //Splints prevent movement. continue for(var/obj/item/weapon/O in organ.implants) @@ -1051,11 +1049,11 @@ var/msg = null switch(rand(1,3)) if(1) - msg ="A spike of pain jolts your [organ.display_name] as you bump [O] inside." + msg ="A spike of pain jolts your [organ.name] as you bump [O] inside." if(2) - msg ="Your movement jostles [O] in your [organ.display_name] painfully." + msg ="Your movement jostles [O] in your [organ.name] painfully." if(3) - msg ="[O] in your [organ.display_name] twists painfully as you move." + msg ="[O] in your [organ.name] twists painfully as you move." src << msg organ.take_damage(rand(1,3), 0, 0) @@ -1292,14 +1290,14 @@ /mob/living/carbon/human/has_brain() if(internal_organs_by_name["brain"]) - var/datum/organ/internal/brain = internal_organs_by_name["brain"] + var/obj/item/organ/brain = internal_organs_by_name["brain"] if(brain && istype(brain)) return 1 return 0 /mob/living/carbon/human/has_eyes() if(internal_organs_by_name["eyes"]) - var/datum/organ/internal/eyes = internal_organs_by_name["eyes"] + var/obj/item/organ/eyes = internal_organs_by_name["eyes"] if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY) return 1 return 0 @@ -1308,3 +1306,58 @@ if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP))) return 0 ..(slipped_on,stun_duration) + +/mob/living/carbon/human/proc/undislocate() + set category = "Object" + set name = "Undislocate Joint" + set desc = "Pop a joint back into place. Extremely painful." + set src in view(1) + + if(!isliving(usr) || usr.next_move > world.time) + return + usr.next_move = world.time + 20 + + if(usr.stat > 0) + usr << "You are unconcious and cannot do that!" + return + + if(usr.restrained()) + usr << "You are restrained and cannot do that!" + return + + var/mob/S = src + var/mob/U = usr + var/self = null + + if(S == U) + self = 1 // Removing object from yourself. + + var/list/limbs = list() + for(var/limb in organs_by_name) + var/obj/item/organ/external/current_limb = organs_by_name[limb] + if(current_limb && current_limb.dislocated == 2) + limbs |= limb + + var/choice = input(src,"Which joint do you wish to relocate?") as null|anything in limbs + + if(!choice) + return + + var/obj/item/organ/external/current_limb = organs_by_name[choice] + + if(self) + src << "You brace yourself to relocate your [current_limb.joint]..." + else + U << "You begin to relocate [S]'s [current_limb.joint]..." + + if(!do_after(U, 30)) + return + if(!choice || !current_limb || !S || !U) + return + + if(self) + src << "You pop your [current_limb.joint] back in!" + else + U << "You pop [S]'s [current_limb.joint] back in!" + S << "[U] pops your [current_limb.joint] back in!" + current_limb.undislocate() diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 82c03a181f6..a8e645eeb30 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -2,11 +2,11 @@ var/mob/living/carbon/human/H = M if(istype(H)) - var/datum/organ/external/temp = H.organs_by_name["r_hand"] + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if(H.hand) temp = H.organs_by_name["l_hand"] - if(temp && !temp.is_usable()) - H << "\red You can't use your [temp.display_name]." + if(!temp || !temp.is_usable()) + H << "\red You can't use your hand." return ..() @@ -24,7 +24,7 @@ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("\red [H] has attempted to punch [src]!") return 0 - var/datum/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting)) + var/obj/item/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting)) var/armor_block = run_armor_check(affecting, "melee") if(HULK in H.mutations) @@ -98,7 +98,11 @@ var/block = 0 var/accurate = 0 var/hit_zone = H.zone_sel.selecting - var/datum/organ/external/affecting = get_organ(hit_zone) + var/obj/item/organ/external/affecting = get_organ(hit_zone) + + if(!affecting || affecting.status & ORGAN_DESTROYED) + M << "They are missing that limb!" + return switch(src.a_intent) if(I_HELP) @@ -157,7 +161,7 @@ miss_type = 1 if(!miss_type && block) - attack_message = "[H] went for [src]'s [affecting.display_name] but was blocked!" + attack_message = "[H] went for [src]'s [affecting.name] but was blocked!" miss_type = 2 // See what attack they use @@ -208,7 +212,7 @@ if(w_uniform) w_uniform.add_fingerprint(M) - var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) + var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun)) var/obj/item/weapon/gun/W = null @@ -291,8 +295,23 @@ src.visible_message("[user] has [attack_message] [src]!") var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin") - var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) updatehealth() return 1 + +/mob/living/carbon/human/proc/attack_joint(var/obj/item/W, var/mob/living/user, var/def_zone) + var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src) + if(user == src) // Attacking yourself can't miss + target_zone = user.zone_sel.selecting + if(!target_zone) + return null + var/obj/item/organ/external/organ = get_organ(check_zone(target_zone)) + if(!organ || organ.is_dislocated() || organ.dislocated == -1) + return null + var/dislocation_str + if(prob(W.force)) + dislocation_str = "[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")] with a grisly crunch!" + organ.dislocate() + return dislocation_str diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 561659a27af..e96e526077f 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -5,11 +5,11 @@ health = maxHealth stat = CONSCIOUS return - var/total_burn = 0 - var/total_brute = 0 - for(var/datum/organ/external/O in organs) //hardcoded to streamline things a bit - total_brute += O.brute_dam - total_burn += O.burn_dam + var/total_burn = 0 + var/total_brute = 0 + for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit + total_brute += O.brute_dam + total_burn += O.burn_dam var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss()) var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss()) @@ -27,7 +27,7 @@ if(status_flags & GODMODE) return 0 //godmode if(species && species.has_organ["brain"]) - var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.take_damage(amount) sponge.damage = min(max(brainloss, 0),(maxHealth*2)) @@ -42,7 +42,7 @@ if(status_flags & GODMODE) return 0 //godmode if(species && species.has_organ["brain"]) - var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.damage = min(max(amount, 0),(maxHealth*2)) brainloss = sponge.damage @@ -56,7 +56,7 @@ if(status_flags & GODMODE) return 0 //godmode if(species && species.has_organ["brain"]) - var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) brainloss = min(sponge.damage,maxHealth*2) else @@ -68,13 +68,13 @@ //These procs fetch a cumulative total damage from all organs /mob/living/carbon/human/getBruteLoss() var/amount = 0 - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) amount += O.brute_dam return amount /mob/living/carbon/human/getFireLoss() var/amount = 0 - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) amount += O.burn_dam return amount @@ -104,7 +104,7 @@ amount = amount*species.brute_mod if (organ_name in organs_by_name) - var/datum/organ/external/O = get_organ(organ_name) + var/obj/item/organ/external/O = get_organ(organ_name) if(amount > 0) O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source) @@ -119,7 +119,7 @@ amount = amount*species.burn_mod if (organ_name in organs_by_name) - var/datum/organ/external/O = get_organ(organ_name) + var/obj/item/organ/external/O = get_organ(organ_name) if(amount > 0) O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source) @@ -163,28 +163,28 @@ var/mut_prob = min(80, getCloneLoss()+10) if (amount > 0) if (prob(mut_prob)) - var/list/datum/organ/external/candidates = list() - for (var/datum/organ/external/O in organs) + var/list/obj/item/organ/external/candidates = list() + for (var/obj/item/organ/external/O in organs) if(!(O.status & ORGAN_MUTATED)) candidates |= O if (candidates.len) - var/datum/organ/external/O = pick(candidates) + var/obj/item/organ/external/O = pick(candidates) O.mutate() - src << "Something is not right with your [O.display_name]..." + src << "Something is not right with your [O.name]..." return else if (prob(heal_prob)) - for (var/datum/organ/external/O in organs) + for (var/obj/item/organ/external/O in organs) if (O.status & ORGAN_MUTATED) O.unmutate() - src << "Your [O.display_name] is shaped normally again." + src << "Your [O.name] is shaped normally again." return if (getCloneLoss() < 1) - for (var/datum/organ/external/O in organs) + for (var/obj/item/organ/external/O in organs) if (O.status & ORGAN_MUTATED) O.unmutate() - src << "Your [O.display_name] is shaped normally again." + src << "Your [O.name] is shaped normally again." BITSET(hud_updateflag, HEALTH_HUD) // Defined here solely to take species flags into account without having to recast at mob/living level. @@ -226,16 +226,16 @@ //Returns a list of damaged organs /mob/living/carbon/human/proc/get_damaged_organs(var/brute, var/burn) - var/list/datum/organ/external/parts = list() - for(var/datum/organ/external/O in organs) + var/list/obj/item/organ/external/parts = list() + for(var/obj/item/organ/external/O in organs) if((brute && O.brute_dam) || (burn && O.burn_dam)) parts += O return parts //Returns a list of damageable organs /mob/living/carbon/human/proc/get_damageable_organs() - var/list/datum/organ/external/parts = list() - for(var/datum/organ/external/O in organs) + var/list/obj/item/organ/external/parts = list() + for(var/obj/item/organ/external/O in organs) if(O.brute_dam + O.burn_dam < O.max_damage) parts += O return parts @@ -244,9 +244,9 @@ //It automatically updates damage overlays if necesary //It automatically updates health status /mob/living/carbon/human/heal_organ_damage(var/brute, var/burn) - var/list/datum/organ/external/parts = get_damaged_organs(brute,burn) + var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn) if(!parts.len) return - var/datum/organ/external/picked = pick(parts) + var/obj/item/organ/external/picked = pick(parts) if(picked.heal_damage(brute,burn)) UpdateDamageIcon() BITSET(hud_updateflag, HEALTH_HUD) @@ -260,9 +260,9 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t //It automatically updates damage overlays if necesary //It automatically updates health status /mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0) - var/list/datum/organ/external/parts = get_damageable_organs() + var/list/obj/item/organ/external/parts = get_damageable_organs() if(!parts.len) return - var/datum/organ/external/picked = pick(parts) + var/obj/item/organ/external/picked = pick(parts) if(picked.take_damage(brute,burn,sharp,edge)) UpdateDamageIcon() BITSET(hud_updateflag, HEALTH_HUD) @@ -272,11 +272,11 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t //Heal MANY external organs, in random order /mob/living/carbon/human/heal_overall_damage(var/brute, var/burn) - var/list/datum/organ/external/parts = get_damaged_organs(brute,burn) + var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn) var/update = 0 while(parts.len && (brute>0 || burn>0) ) - var/datum/organ/external/picked = pick(parts) + var/obj/item/organ/external/picked = pick(parts) var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam @@ -295,10 +295,10 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t // damage MANY external organs, in random order /mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null) if(status_flags & GODMODE) return //godmode - var/list/datum/organ/external/parts = get_damageable_organs() + var/list/obj/item/organ/external/parts = get_damageable_organs() var/update = 0 while(parts.len && (brute>0 || burn>0) ) - var/datum/organ/external/picked = pick(parts) + var/obj/item/organ/external/picked = pick(parts) var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam @@ -328,12 +328,12 @@ This function restores the subjects blood to max. This function restores all organs. */ /mob/living/carbon/human/restore_all_organs() - for(var/datum/organ/external/current_organ in organs) + for(var/obj/item/organ/external/current_organ in organs) current_organ.rejuvenate() /mob/living/carbon/human/proc/HealDamage(zone, brute, burn) - var/datum/organ/external/E = get_organ(zone) - if(istype(E, /datum/organ/external)) + var/obj/item/organ/external/E = get_organ(zone) + if(istype(E, /obj/item/organ/external)) if (E.heal_damage(brute, burn)) UpdateDamageIcon() BITSET(hud_updateflag, HEALTH_HUD) @@ -366,7 +366,7 @@ This function restores all organs. if(blocked >= 2) return 0 - var/datum/organ/external/organ = null + var/obj/item/organ/external/organ = null if(isorgan(def_zone)) organ = def_zone else diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index ff02684de80..a0c78d75729 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -10,7 +10,9 @@ emp_act /mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone) - var/datum/organ/external/organ = get_organ(check_zone(def_zone)) + var/obj/item/organ/external/organ = get_organ(check_zone(def_zone)) + if(!organ) + return //Shields if(check_shields(P.damage, "the [P.name]")) @@ -50,7 +52,7 @@ emp_act return (..(P , def_zone)) /mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone) - var/datum/organ/external/affected = get_organ(check_zone(def_zone)) + var/obj/item/organ/external/affected = get_organ(check_zone(def_zone)) var/siemens_coeff = get_siemens_coefficient_organ(affected) stun_amount *= siemens_coeff agony_amount *= siemens_coeff @@ -68,12 +70,12 @@ emp_act if(c_hand && (stun_amount || agony_amount > 10)) msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect") - u_equip(c_hand) + drop_from_inventory(c_hand) if (affected.status & ORGAN_ROBOT) - emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!") + emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!") else var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.display_name]!") + emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.name]!") ..(stun_amount, agony_amount, def_zone) @@ -84,21 +86,23 @@ emp_act if(def_zone) if(isorgan(def_zone)) return getarmor_organ(def_zone, type) - var/datum/organ/external/affecting = get_organ(def_zone) - return getarmor_organ(affecting, type) + var/obj/item/organ/external/affecting = get_organ(def_zone) + if(affecting) + return getarmor_organ(affecting, type) //If a specific bodypart is targetted, check how that bodypart is protected and return the value. //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values for(var/organ_name in organs_by_name) if (organ_name in organ_rel_size) - var/datum/organ/external/organ = organs_by_name[organ_name] - var/weight = organ_rel_size[organ_name] - armorval += getarmor_organ(organ, type) * weight - total += weight + var/obj/item/organ/external/organ = organs_by_name[organ_name] + if(organ) + var/weight = organ_rel_size[organ_name] + armorval += getarmor_organ(organ, type) * weight + total += weight return (armorval/max(total, 1)) //this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. -/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone) +/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) if (!def_zone) return 1.0 @@ -112,14 +116,14 @@ emp_act return siemens_coefficient //this proc returns the armour value for a particular external organ. -/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type) - if(!type) return 0 +/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type) + if(!type || !def_zone) return 0 var/protection = 0 var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) for(var/gear in protective_gear) if(gear && istype(gear ,/obj/item/clothing)) var/obj/item/clothing/C = gear - if(C.body_parts_covered & def_zone.body_part) + if(istype(C) && C.body_parts_covered & def_zone.body_part) protection += C.armor[type] return protection @@ -167,10 +171,10 @@ emp_act for(var/obj/O in src) if(!O) continue O.emp_act(severity) - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) if(O.status & ORGAN_DESTROYED) continue O.emp_act(severity) - for(var/datum/organ/internal/I in O.internal_organs) + for(var/obj/item/organ/I in O.internal_organs) if(I.robotic == 0) continue I.emp_act(severity) ..() @@ -186,17 +190,19 @@ emp_act target_zone = user.zone_sel.selecting if(!target_zone) visible_message("\red [user] misses [src] with \the [I]!") - return 0 + return 1 - var/datum/organ/external/affecting = get_organ(target_zone) - if (!affecting) - return 0 - if(affecting.status & ORGAN_DESTROYED) - user << "What [affecting.display_name]?" - return 0 - var/hit_area = affecting.display_name + var/obj/item/organ/external/affecting = get_organ(target_zone) - if((user != src) && check_shields(I.force, "the [I.name]")) + if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump()) + user << "They are missing that limb!" + return + + var/effective_force = I.force + if(user.a_intent == "disarm") effective_force = round(I.force/2) + var/hit_area = affecting.name + + if((user != src) && check_shields(effective_force, "the [I.name]")) return 0 if(istype(I,/obj/item/weapon/card/emag)) @@ -204,9 +210,9 @@ emp_act user << "\red That limb isn't robotic." return if(affecting.sabotaged) - user << "\red [src]'s [affecting.display_name] is already sabotaged!" + user << "\red [src]'s [affecting.name] is already sabotaged!" else - user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties." + user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.name] and short out the safeties." var/obj/item/weapon/card/emag/emag = I emag.uses-- affecting.sabotaged = 1 @@ -224,14 +230,14 @@ emp_act weapon_sharp = 0 weapon_edge = 0 - if(armor >= 2) return 0 - if(!I.force) return 0 - var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) + if(armor >= 2) return 0 + if(!effective_force) return 0 + var/Iforce = effective_force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - apply_damage(I.force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I) + apply_damage(effective_force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I) var/bloody = 0 - if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2))) + if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (effective_force * 2))) I.add_blood(src) //Make the weapon bloody, not the person. // if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon // else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays @@ -246,36 +252,37 @@ emp_act H.bloody_body(src) H.bloody_hands(src) - switch(hit_area) - if("head")//Harder to score a stun but if you do it lasts a bit longer - if(prob(I.force)) - apply_effect(20, PARALYZE, armor) - visible_message("\red [src] has been knocked unconscious!") - if(bloody)//Apply blood - if(wear_mask) - wear_mask.add_blood(src) - update_inv_wear_mask(0) - if(head) - head.add_blood(src) - update_inv_head(0) - if(glasses && prob(33)) - glasses.add_blood(src) - update_inv_glasses(0) + if(!stat) + switch(hit_area) + if("head")//Harder to score a stun but if you do it lasts a bit longer + if(prob(effective_force)) + apply_effect(20, PARALYZE, armor) + visible_message("\red [src] has been knocked unconscious!") + if(bloody)//Apply blood + if(wear_mask) + wear_mask.add_blood(src) + update_inv_wear_mask(0) + if(head) + head.add_blood(src) + update_inv_head(0) + if(glasses && prob(33)) + glasses.add_blood(src) + update_inv_glasses(0) - if("chest")//Easier to score a stun but lasts less time - if(prob((I.force + 10))) - apply_effect(6, WEAKEN, armor) - visible_message("\red [src] has been knocked down!") + if("chest")//Easier to score a stun but lasts less time + if(prob((effective_force + 10))) + apply_effect(6, WEAKEN, armor) + visible_message("\red [src] has been knocked down!") - if(bloody) - bloody_body(src) + if(bloody) + bloody_body(src) if(Iforce > 10 || Iforce >= 5 && prob(33)) forcesay(hit_appends) //forcesay checks stat already //Melee weapon embedded object code. if (I && I.damtype == BRUTE && !I.anchored && !I.is_robot_module()) - var/damage = I.force + var/damage = effective_force if (armor) damage /= armor+1 @@ -327,8 +334,8 @@ emp_act if ((O.thrower != src) && check_shields(throw_damage, "[O]")) return - var/datum/organ/external/affecting = get_organ(zone) - var/hit_area = affecting.display_name + var/obj/item/organ/external/affecting = get_organ(zone) + var/hit_area = affecting.name src.visible_message("\red [src] has been hit in the [hit_area] by [O].") var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here @@ -390,7 +397,7 @@ emp_act /mob/living/carbon/human/embed(var/obj/O, var/def_zone=null) if(!def_zone) ..() - var/datum/organ/external/affecting = get_organ(def_zone) + var/obj/item/organ/external/affecting = get_organ(def_zone) if(affecting) affecting.embed(O) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 155492a36b6..749903dc2ad 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -28,7 +28,7 @@ if(istype(buckled, /obj/structure/bed/chair/wheelchair)) for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm")) - var/datum/organ/external/E = get_organ(organ_name) + var/obj/item/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) tally += 4 if(E.status & ORGAN_SPLINTED) @@ -40,7 +40,7 @@ tally += shoes.slowdown for(var/organ_name in list("l_foot","r_foot","l_leg","r_leg")) - var/datum/organ/external/E = get_organ(organ_name) + var/obj/item/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) tally += 4 if(E.status & ORGAN_SPLINTED) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm new file mode 100644 index 00000000000..de7a982b1a6 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -0,0 +1,135 @@ +/mob/living/carbon/human/proc/update_eyes() + if(internal_organs_by_name["eyes"]) + var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + eyes.eye_colour = list(r_eyes,g_eyes,b_eyes) + regenerate_icons() + +/mob/living/carbon/var/list/internal_organs = list() +/mob/living/carbon/human/var/list/organs = list() +/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs +/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too + +// Takes care of organ related updates, such as broken and missing limbs +/mob/living/carbon/human/proc/handle_organs() + + number_wounds = 0 + var/force_process = 0 + var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss() + if(damage_this_tick > last_dam) + force_process = 1 + last_dam = damage_this_tick + if(force_process) + bad_external_organs.Cut() + for(var/obj/item/organ/external/Ex in organs) + bad_external_organs |= Ex + + //processing internal organs is pretty cheap, do that first. + for(var/obj/item/organ/I in internal_organs) + I.process() + + handle_stance() + handle_grasp() + + if(!force_process && !bad_external_organs.len) + return + + for(var/obj/item/organ/external/E in bad_external_organs) + if(!E) + continue + if(!E.need_process()) + bad_external_organs -= E + continue + else + E.process() + number_wounds += E.number_wounds + + if (!lying && world.time - l_move_time < 15) + //Moving around with fractured ribs won't do you any good + if (E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15)) + var/obj/item/organ/I = pick(E.internal_organs) + custom_pain("You feel broken bones moving in your [E.name]!", 1) + I.take_damage(rand(3,5)) + + //Moving makes open wounds get infected much faster + if (E.wounds.len) + for(var/datum/wound/W in E.wounds) + if (W.infection_check()) + W.germ_level += 1 + +/mob/living/carbon/human/proc/handle_stance() + // Don't need to process any of this if they aren't standing anyways + // unless their stance is damaged, and we want to check if they should stay down + if (!stance_damage && (lying || resting) && (life_tick % 4) == 0) + return + + stance_damage = 0 + + // Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid + if (istype(buckled, /obj/structure/bed)) + return + + for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot")) + var/obj/item/organ/external/E = organs_by_name[limb_tag] + if(!E) + stance_damage += 2 + else if (E.status & ORGAN_DESTROYED) + stance_damage += 2 // let it fail even if just foot&leg + else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable()) + stance_damage += 1 + + // Canes and crutches help you stand (if the latter is ever added) + // One cane mitigates a broken leg+foot, or a missing foot. + // Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you. + if (l_hand && istype(l_hand, /obj/item/weapon/cane)) + stance_damage -= 2 + if (r_hand && istype(r_hand, /obj/item/weapon/cane)) + stance_damage -= 2 + + // standing is poor + if(stance_damage >= 4 || (stance_damage >= 2 && prob(5))) + if(!(lying || resting)) + if(species && !(species.flags & NO_PAIN)) + emote("scream") + custom_emote(1, "collapses!") + Weaken(5) //can't emote while weakened, apparently. + +/mob/living/carbon/human/proc/handle_grasp() + + if(!l_hand && !r_hand) + return + + for (var/obj/item/organ/external/E in organs) + if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED)) + continue + + if(E.is_broken()) + if(E.body_part == HAND_LEFT) + drop_from_inventory(l_hand) + else + drop_from_inventory(r_hand) + + var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") + emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!") + + else if(E.is_malfunctioning()) + + if(E.body_part == HAND_LEFT) + drop_from_inventory(l_hand) + else + drop_from_inventory(r_hand) + + emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + spark_system.start() + spawn(10) + del(spark_system) + +//Handles chem traces +/mob/living/carbon/human/proc/handle_trace_chems() + //New are added for reagents to random organs. + for(var/datum/reagent/A in reagents.reagent_list) + var/obj/item/organ/O = pick(organs) + O.trace_chemicals[A.name] = 100 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm index 49f1bd4eee8..f7a644646da 100644 --- a/code/modules/mob/living/carbon/human/human_species.dm +++ b/code/modules/mob/living/carbon/human/human_species.dm @@ -18,10 +18,6 @@ h_style = "Short Vox Quills" ..(new_loc, "Vox") -/mob/living/carbon/human/voxarmalis/New(var/new_loc) - h_style = "Bald" - ..(new_loc, "Vox Armalis") - /mob/living/carbon/human/diona/New(var/new_loc) ..(new_loc, "Diona") diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index d1f8b21f057..bc39c3f315b 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -39,7 +39,7 @@ This saves us from having to call add_fingerprint() any time something is put in /mob/living/carbon/human/proc/has_organ(name) - var/datum/organ/external/O = organs_by_name[name] + var/obj/item/organ/external/O = organs_by_name[name] return (O && !(O.status & ORGAN_DESTROYED) ) @@ -69,11 +69,11 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_glasses) return has_organ("head") if(slot_gloves) - return has_organ("l_hand") && has_organ("r_hand") + return has_organ("l_hand") || has_organ("r_hand") if(slot_head) return has_organ("head") if(slot_shoes) - return has_organ("r_foot") && has_organ("l_foot") + return has_organ("r_foot") || has_organ("l_foot") if(slot_wear_suit) return has_organ("chest") if(slot_w_uniform) @@ -89,19 +89,13 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_tie) return 1 -/mob/living/carbon/human/u_equip(obj/item/W as obj) +/mob/living/carbon/human/u_equip(obj/W as obj) if(!W) return 0 - var/success - if (W == wear_suit) if(s_store) drop_from_inventory(s_store) - if(W) - success = 1 wear_suit = null - if(W.flags_inv & HIDESHOES) - update_inv_shoes(0) update_inv_wear_suit() else if (W == w_uniform) if (r_store) @@ -113,43 +107,43 @@ This saves us from having to call add_fingerprint() any time something is put in if (belt) drop_from_inventory(belt) w_uniform = null - success = 1 update_inv_w_uniform() else if (W == gloves) gloves = null - success = 1 update_inv_gloves() else if (W == glasses) glasses = null - success = 1 update_inv_glasses() else if (W == head) head = null - if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)|| (W.flags_inv & HIDEMASK)) + + var/update_hair = 0 + if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) + update_hair = 1 + else if(istype(W, /obj/item)) + var/obj/item/I = W + if(I.flags_inv & HIDEMASK) + update_hair = 1 + if(update_hair) update_hair(0) //rebuild hair update_inv_ears(0) update_inv_wear_mask(0) - success = 1 + update_inv_head() else if (W == l_ear) l_ear = null - success = 1 update_inv_ears() else if (W == r_ear) r_ear = null - success = 1 update_inv_ears() else if (W == shoes) shoes = null - success = 1 update_inv_shoes() else if (W == belt) belt = null - success = 1 update_inv_belt() else if (W == wear_mask) wear_mask = null - success = 1 if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) update_hair(0) //rebuild hair update_inv_ears(0) @@ -160,53 +154,36 @@ This saves us from having to call add_fingerprint() any time something is put in update_inv_wear_mask() else if (W == wear_id) wear_id = null - success = 1 update_inv_wear_id() else if (W == r_store) r_store = null - success = 1 update_inv_pockets() else if (W == l_store) l_store = null - success = 1 update_inv_pockets() else if (W == s_store) s_store = null - success = 1 update_inv_s_store() else if (W == back) back = null - success = 1 update_inv_back() else if (W == handcuffed) - handcuffed = null + handcuffed = null if(buckled && buckled.buckle_require_restraints) - buckled.unbuckle_mob() - success = 1 + buckled.unbuckle_mob() update_inv_handcuffed() else if (W == legcuffed) legcuffed = null - success = 1 update_inv_legcuffed() else if (W == r_hand) r_hand = null - success = 1 update_inv_r_hand() else if (W == l_hand) l_hand = null - success = 1 update_inv_l_hand() else return 0 - - if(success) - if (W) - if (client) - client.screen -= W - W.loc = loc - W.dropped(src) - //if(W) - //W.layer = initial(W.layer) + update_action_buttons() return 1 @@ -319,7 +296,7 @@ This saves us from having to call add_fingerprint() any time something is put in update_inv_s_store(redraw_mob) if(slot_in_backpack) if(src.get_active_hand() == W) - src.u_equip(W) + src.remove_from_mob(W) W.loc = src.back if(slot_tie) var/obj/item/clothing/under/uniform = src.w_uniform @@ -339,6 +316,10 @@ This saves us from having to call add_fingerprint() any time something is put in return +/* + MouseDrop human inventory menu +*/ + /obj/effect/equip_e name = "equip e" var/mob/source = null @@ -407,7 +388,7 @@ This saves us from having to call add_fingerprint() any time something is put in if("splints") var/count = 0 for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.organs_by_name[organ] + var/obj/item/organ/external/o = target.organs_by_name[organ] if(o.status & ORGAN_SPLINTED) count = 1 break @@ -695,7 +676,7 @@ It can still be worn/put on as normal. if(can_reach_splints) for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.get_organ(organ) + var/obj/item/organ/external/o = target.get_organ(organ) if (o && o.status & ORGAN_SPLINTED) var/obj/item/W = new /obj/item/stack/medical/splint(amount=1) o.status &= ~ORGAN_SPLINTED @@ -771,15 +752,12 @@ It can still be worn/put on as normal. W.add_fingerprint(source) if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;) if(target.r_store) - target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. + target.remove_from_mob(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. else if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob if(item.mob_can_equip(target, slot_to_process, 0)) - source.u_equip(item) + source.remove_from_mob(item) target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1) - item.dropped(source) - source.update_icons() - target.update_icons() if(source && target) if(source.machine == target) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 9881ca1311b..10c22f6012a 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -237,7 +237,7 @@ src << "\red It becomes hard to see for some reason." eye_blurry = 10 if(getBrainLoss() >= 35) - if(7 <= rn && rn <= 9) if(hand && equipped()) + if(7 <= rn && rn <= 9) if(get_active_hand()) src << "\red Your hand won't respond properly, you drop what you're holding." drop_item() if(getBrainLoss() >= 50) @@ -276,7 +276,7 @@ radiation = Clamp(radiation,0,100) if (radiation) - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs + var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs if(rad_organ && !rad_organ.is_broken()) var/rads = radiation/25 radiation -= rads @@ -323,7 +323,7 @@ adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT) updatehealth() if(organs.len) - var/datum/organ/external/O = pick(organs) + var/obj/item/organ/external/O = pick(organs) if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) /** breathing **/ @@ -388,7 +388,7 @@ // Lung damage increases the minimum safe pressure. if(species.has_organ["lungs"]) - var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] if(!L) safe_pressure_min = INFINITY //No lungs, how are you breathing? else if(L.is_broken()) @@ -871,7 +871,7 @@ if(status_flags & GODMODE) return 0 //godmode - var/datum/organ/internal/diona/node/light_organ = locate() in internal_organs + var/obj/item/organ/diona/node/light_organ = locate() in internal_organs if(light_organ && !light_organ.is_broken()) var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(loc)) //else, there's considered to be no light @@ -1503,7 +1503,7 @@ if(pulse == PULSE_NONE || !species.has_organ["heart"]) return - var/datum/organ/internal/heart/H = internal_organs_by_name["heart"] + var/obj/item/organ/heart/H = internal_organs_by_name["heart"] if(!H || H.robotic >=2 ) return diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index bf007450e36..853fb4e8d47 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -42,56 +42,15 @@ ) has_organ = list( - "heart" = /datum/organ/internal/heart, - "lungs" = /datum/organ/internal/lungs, - "liver" = /datum/organ/internal/liver, - "kidneys" = /datum/organ/internal/kidney, - "brain" = /datum/organ/internal/brain, - "eyes" = /datum/organ/internal/eyes, - "stack" = /datum/organ/internal/stack/vox + "heart" = /obj/item/organ/heart, + "lungs" = /obj/item/organ/lungs, + "liver" = /obj/item/organ/liver, + "kidneys" = /obj/item/organ/kidney, + "brain" = /obj/item/organ/brain, + "eyes" = /obj/item/organ/eyes, + "stack" = /obj/item/organ/stack/vox ) /datum/species/vox/get_random_name(var/gender) var/datum/language/species_language = all_languages[default_language] return species_language.get_random_name(gender) - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - rarity_value = 10 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - breath_type = "nitrogen" - poison_type = "oxygen" - - flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR - - blood_color = "#2299FC" - flesh_color = "#808D11" - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - reagent_tag = IS_VOX - - inherent_verbs = list( - /mob/living/carbon/human/proc/leap, - /mob/living/carbon/human/proc/gut, - /mob/living/carbon/human/proc/commune - ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index ea03c44e45d..09f3360d45e 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -50,6 +50,7 @@ // Death vars. var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human var/gibber_type = /obj/effect/gibspawner/human + var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs var/remains_type = /obj/effect/decal/remains/xeno var/gibbed_anim = "gibbed-h" var/dusted_anim = "dust-h" @@ -106,13 +107,27 @@ var/rarity_value = 1 // Relative rarity/collector value for this species. // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. - "heart" = /datum/organ/internal/heart, - "lungs" = /datum/organ/internal/lungs, - "liver" = /datum/organ/internal/liver, - "kidneys" = /datum/organ/internal/kidney, - "brain" = /datum/organ/internal/brain, - "appendix" = /datum/organ/internal/appendix, - "eyes" = /datum/organ/internal/eyes + "heart" = /obj/item/organ/heart, + "lungs" = /obj/item/organ/lungs, + "liver" = /obj/item/organ/liver, + "kidneys" = /obj/item/organ/kidney, + "brain" = /obj/item/organ/brain, + "appendix" = /obj/item/organ/appendix, + "eyes" = /obj/item/organ/eyes + ) + + var/list/has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest), + "groin" = list("path" = /obj/item/organ/external/groin), + "head" = list("path" = /obj/item/organ/external/head), + "l_arm" = list("path" = /obj/item/organ/external/arm), + "r_arm" = list("path" = /obj/item/organ/external/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/leg), + "r_leg" = list("path" = /obj/item/organ/external/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/hand), + "r_hand" = list("path" = /obj/item/organ/external/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/foot), + "r_foot" = list("path" = /obj/item/organ/external/foot/right) ) // Bump vars @@ -157,7 +172,10 @@ /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. - //Trying to work out why species changes aren't fixing organs properly. + for(var/obj/item/organ/organ in H.contents) + if((organ in H.organs) || (organ in H.internal_organs)) + del(organ) + if(H.organs) H.organs.Cut() if(H.internal_organs) H.internal_organs.Cut() if(H.organs_by_name) H.organs_by_name.Cut() @@ -168,35 +186,28 @@ H.organs_by_name = list() H.internal_organs_by_name = list() - //This is a basic humanoid limb setup. - H.organs_by_name["chest"] = new/datum/organ/external/chest() - H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"]) - H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"]) - H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"]) - H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"]) - H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"]) - H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"]) - H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"]) - H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"]) - H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"]) - H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"]) + for(var/limb_type in has_limbs) + 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 for(var/organ in has_organ) var/organ_type = has_organ[organ] - H.internal_organs_by_name[organ] = new organ_type(H) + H.internal_organs_by_name[organ] = new organ_type(H,1) for(var/name in H.organs_by_name) - H.organs += H.organs_by_name[name] + H.organs |= H.organs_by_name[name] - for(var/datum/organ/external/O in H.organs) + for(var/obj/item/organ/external/O in H.organs) O.owner = H if(flags & IS_SYNTHETIC) - for(var/datum/organ/external/E in H.organs) + for(var/obj/item/organ/external/E in H.organs) if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue - E.status |= ORGAN_ROBOT - for(var/datum/organ/internal/I in H.internal_organs) - I.mechanize() + E.robotize() + for(var/obj/item/organ/I in H.internal_organs) + I.robotize() /datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target) @@ -268,4 +279,4 @@ // Called in life() when the mob has no client. /datum/species/proc/handle_npc(var/mob/living/carbon/human/H) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm index bb922b905ba..c3312b9a7a9 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -22,13 +22,13 @@ /datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) var/skill = user.skills["combat"] - var/datum/organ/external/affecting = target.get_organ(zone) + var/obj/item/organ/external/affecting = target.get_organ(zone) if(!skill) skill = 1 attack_damage = Clamp(attack_damage, 1, 5) if(target == user) - user.visible_message("[user] [pick(attack_verb)] \himself in the [affecting.display_name]!") + user.visible_message("[user] [pick(attack_verb)] \himself in the [affecting.name]!") return 0 switch(zone) @@ -47,9 +47,9 @@ else // ----- BODY ----- // switch(attack_damage) - if(1 to 2) user.visible_message("[user] scratched [target]'s [affecting.display_name]!") - if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!") - if(5) user.visible_message("[user] tears \his [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.display_name]!") + if(1 to 2) user.visible_message("[user] scratched [target]'s [affecting.name]!") + if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.name]!") + if(5) user.visible_message("[user] tears \his [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.name]!") /datum/unarmed_attack/claws/strong attack_verb = list("slashed") diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index f04a8cb3678..ce106c4191f 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -17,7 +17,7 @@ flesh_color = "#137E8F" has_organ = list( - "brain" = /datum/organ/internal/brain/golem + "brain" = /obj/item/organ/brain/golem ) death_message = "becomes completely motionless..." diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm index 0e148b02369..0f4f8364eea 100644 --- a/code/modules/mob/living/carbon/human/species/station/slime.dm +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -19,7 +19,7 @@ death_message = "rapidly loses cohesion, splattering across the ground..." has_organ = list( - "brain" = /datum/organ/internal/brain/slime + "brain" = /obj/item/organ/brain/slime ) breath_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index 8cf07fc8d58..62907752aaa 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -135,6 +135,7 @@ rarity_value = 3 hud_type = /datum/hud_data/diona siemens_coefficient = 0.3 + eyes = "blank_eyes" blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ @@ -145,12 +146,26 @@ water and other radiation." has_organ = list( - "nutrient channel" = /datum/organ/internal/diona/nutrients, - "neural strata" = /datum/organ/internal/diona/strata, - "response node" = /datum/organ/internal/diona/node, - "gas bladder" = /datum/organ/internal/diona/bladder, - "polyp segment" = /datum/organ/internal/diona/polyp, - "anchoring ligament" = /datum/organ/internal/diona/ligament + "nutrient channel" = /obj/item/organ/diona/nutrients, + "neural strata" = /obj/item/organ/diona/strata, + "response node" = /obj/item/organ/diona/node, + "gas bladder" = /obj/item/organ/diona/bladder, + "polyp segment" = /obj/item/organ/diona/polyp, + "anchoring ligament" = /obj/item/organ/diona/ligament + ) + + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/diona/chest), + "groin" = list("path" = /obj/item/organ/external/diona/groin), + "head" = list("path" = /obj/item/organ/external/diona/head), + "l_arm" = list("path" = /obj/item/organ/external/diona/arm), + "r_arm" = list("path" = /obj/item/organ/external/diona/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/diona/leg), + "r_leg" = list("path" = /obj/item/organ/external/diona/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/diona/hand), + "r_hand" = list("path" = /obj/item/organ/external/diona/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/diona/foot), + "r_foot" = list("path" = /obj/item/organ/external/diona/foot/right) ) warning_low_pressure = 50 @@ -166,7 +181,7 @@ body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not - flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR + flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | REGENERATES_LIMBS blood_color = "#004400" flesh_color = "#907E4A" diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm index 4bdddc2ca6a..093025189b9 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm @@ -108,7 +108,7 @@ Des: Removes all infection images from aliens and places an infection image on a for(var/mob/living/carbon/alien in player_list) - if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) continue if(alien.client) @@ -130,7 +130,7 @@ Des: Checks if the passed mob (C) is infected with the alien egg, then gives eac for(var/mob/living/carbon/alien in player_list) - if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) continue if(alien.client) @@ -149,7 +149,7 @@ Des: Removes the alien infection image from all aliens in the world located in p for(var/mob/living/carbon/alien in player_list) - if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) continue if(alien.client) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm index c7c7fcc9035..6fbdfa8ddbd 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm @@ -108,7 +108,7 @@ var/const/MAX_ACTIVE_TIME = 400 return var/mob/living/carbon/C = M - if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs) + if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs) return @@ -228,7 +228,7 @@ var/const/MAX_ACTIVE_TIME = 400 return 0 var/mob/living/carbon/C = M - if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs) + if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs) return 0 if(ishuman(C)) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index 2fc44af9358..caea1ae7a80 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -11,7 +11,7 @@ /mob/living/carbon/human/proc/gain_plasma(var/amount) - var/datum/organ/internal/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"] if(!istype(I)) return if(amount) @@ -20,13 +20,13 @@ /mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ) - var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] if(!istype(P)) src << "Your plasma vessel has been removed!" return if(needs_organ) - var/datum/organ/internal/I = internal_organs_by_name[needs_organ] + var/obj/item/organ/I = internal_organs_by_name[needs_organ] if(!I) src << "Your [needs_organ] has been removed!" return @@ -62,7 +62,7 @@ src << "You need to be closer." return - var/datum/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"] + var/obj/item/organ/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"] if(!istype(I)) src << "Their plasma vessel is missing." return diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index 4265f1b39a9..913e3e71ad6 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -45,11 +45,11 @@ vision_flags = SEE_MOBS has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain/xeno, - "plasma vessel" = /datum/organ/internal/xenos/plasmavessel, - "hive node" = /datum/organ/internal/xenos/hivenode, - "nutrient vessel" = /datum/organ/internal/diona/nutrients + "heart" = /obj/item/organ/heart, + "brain" = /obj/item/organ/brain/xeno, + "plasma vessel" = /obj/item/organ/xenos/plasmavessel, + "hive node" = /obj/item/organ/xenos/hivenode, + "nutrient vessel" = /obj/item/organ/diona/nutrients ) bump_flag = ALIEN @@ -93,7 +93,7 @@ if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T) if(!regenerate(H)) - var/datum/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"] + var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"] P.stored_plasma += weeds_plasma_rate P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma) ..() @@ -116,7 +116,7 @@ return 1 //next internal organs - for(var/datum/organ/internal/I in H.internal_organs) + 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)) @@ -124,11 +124,11 @@ return 1 //next mend broken bones, approx 10 ticks each - for(var/datum/organ/external/E in H.bad_external_organs) + for(var/obj/item/organ/external/E in H.bad_external_organs) if (E.status & ORGAN_BROKEN) if (prob(mend_prob)) if (E.mend_fracture()) - H << "You feel something mend itself inside your [E.display_name]." + H << "You feel something mend itself inside your [E.name]." return 1 return 0 @@ -153,13 +153,13 @@ deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi' has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain/xeno, - "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen, - "acid gland" = /datum/organ/internal/xenos/acidgland, - "hive node" = /datum/organ/internal/xenos/hivenode, - "resin spinner" = /datum/organ/internal/xenos/resinspinner, - "nutrient vessel" = /datum/organ/internal/diona/nutrients + "heart" = /obj/item/organ/heart, + "brain" = /obj/item/organ/brain/xeno, + "plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen, + "acid gland" = /obj/item/organ/xenos/acidgland, + "hive node" = /obj/item/organ/xenos/hivenode, + "resin spinner" = /obj/item/organ/xenos/resinspinner, + "nutrient vessel" = /obj/item/organ/diona/nutrients ) inherent_verbs = list( @@ -192,11 +192,11 @@ deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi' has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain/xeno, - "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/hunter, - "hive node" = /datum/organ/internal/xenos/hivenode, - "nutrient vessel" = /datum/organ/internal/diona/nutrients + "heart" = /obj/item/organ/heart, + "brain" = /obj/item/organ/brain/xeno, + "plasma vessel" = /obj/item/organ/xenos/plasmavessel/hunter, + "hive node" = /obj/item/organ/xenos/hivenode, + "nutrient vessel" = /obj/item/organ/diona/nutrients ) inherent_verbs = list( @@ -220,12 +220,12 @@ deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi' has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain/xeno, - "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/sentinel, - "acid gland" = /datum/organ/internal/xenos/acidgland, - "hive node" = /datum/organ/internal/xenos/hivenode, - "nutrient vessel" = /datum/organ/internal/diona/nutrients + "heart" = /obj/item/organ/heart, + "brain" = /obj/item/organ/brain/xeno, + "plasma vessel" = /obj/item/organ/xenos/plasmavessel/sentinel, + "acid gland" = /obj/item/organ/xenos/acidgland, + "hive node" = /obj/item/organ/xenos/hivenode, + "nutrient vessel" = /obj/item/organ/diona/nutrients ) inherent_verbs = list( @@ -252,14 +252,14 @@ deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi' has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain/xeno, - "egg sac" = /datum/organ/internal/xenos/eggsac, - "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen, - "acid gland" = /datum/organ/internal/xenos/acidgland, - "hive node" = /datum/organ/internal/xenos/hivenode, - "resin spinner" = /datum/organ/internal/xenos/resinspinner, - "nutrient vessel" = /datum/organ/internal/diona/nutrients + "heart" = /obj/item/organ/heart, + "brain" = /obj/item/organ/brain/xeno, + "egg sac" = /obj/item/organ/xenos/eggsac, + "plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen, + "acid gland" = /obj/item/organ/xenos/acidgland, + "hive node" = /obj/item/organ/xenos/hivenode, + "resin spinner" = /obj/item/organ/xenos/resinspinner, + "nutrient vessel" = /obj/item/organ/diona/nutrients ) inherent_verbs = list( diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index d033e70610d..148baf66187 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -14,7 +14,7 @@ return 0 // Check if they have a functioning hand. - var/datum/organ/external/E = user.organs_by_name["l_hand"] + var/obj/item/organ/external/E = user.organs_by_name["l_hand"] if(E && !(E.status & ORGAN_DESTROYED)) return 1 @@ -74,8 +74,8 @@ target.apply_effect(3, WEAKEN, armour) /datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.display_name]!") + var/obj/item/organ/external/affecting = target.get_organ(zone) + user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.name]!") playsound(user.loc, attack_sound, 25, 1, -1) /datum/unarmed_attack/bite @@ -100,8 +100,8 @@ damage = 0 /datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name + var/obj/item/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.name attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. @@ -154,7 +154,7 @@ if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin"))) return 0 - var/datum/organ/external/E = user.organs_by_name["l_foot"] + var/obj/item/organ/external/E = user.organs_by_name["l_foot"] if(E && !(E.status & ORGAN_DESTROYED)) return 1 @@ -171,8 +171,8 @@ return damage + (shoes ? shoes.force : 0) /datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name + var/obj/item/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.name attack_damage = Clamp(attack_damage, 1, 5) @@ -198,7 +198,7 @@ if (!user.lying && (target.lying || (zone in list("l_foot", "r_foot")))) if(target.grabbed_by == user && target.lying) return 0 - var/datum/organ/external/E = user.organs_by_name["l_foot"] + var/obj/item/organ/external/E = user.organs_by_name["l_foot"] if(E && !(E.status & ORGAN_DESTROYED)) return 1 @@ -213,8 +213,8 @@ return damage + (shoes ? shoes.force : 0) /datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name + var/obj/item/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.name var/obj/item/clothing/shoes = user.shoes attack_damage = Clamp(attack_damage, 1, 5) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index dadebe8c577..0882c558c7e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -182,7 +182,9 @@ var/global/list/damage_icon_parts = list() // first check whether something actually changed about damage appearance var/damage_appearance = "" - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) + if(O.is_stump()) + continue if(O.status & ORGAN_DESTROYED) damage_appearance += "d" else damage_appearance += O.damage_state @@ -198,7 +200,9 @@ var/global/list/damage_icon_parts = list() var/image/standing_image = new /image("icon" = standing) // blend the individual damage states with our icons - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) + if(O.is_stump()) + continue if(!(O.status & ORGAN_DESTROYED)) O.update_icon() if(O.damage_state == "00") continue @@ -223,7 +227,6 @@ var/global/list/damage_icon_parts = list() var/husk_color_mod = rgb(96,88,80) var/hulk_color_mod = rgb(48,224,40) - var/necrosis_color_mod = rgb(10,50,0) var/husk = (HUSK in src.mutations) var/fat = (FAT in src.mutations) @@ -231,7 +234,6 @@ var/global/list/damage_icon_parts = list() var/skeleton = (SKELETON in src.mutations) var/g = (gender == FEMALE ? "f" : "m") - var/has_head = 0 //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. @@ -239,19 +241,14 @@ var/global/list/damage_icon_parts = list() //Create a new, blank icon for our mob to use. if(stand_icon) del(stand_icon) - stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") var/icon_key = "[species.race_key][g][s_tone]" - for(var/datum/organ/external/part in organs) - - if(istype(part,/datum/organ/external/head) && !(part.status & ORGAN_DESTROYED)) - has_head = 1 - - if(part.status & ORGAN_DESTROYED) + for(var/obj/item/organ/external/part in organs) + if(part.is_stump() || (part.status & ORGAN_DESTROYED)) icon_key = "[icon_key]0" else if(part.status & ORGAN_ROBOT) - icon_key = "[icon_key]2" + icon_key = "[icon_key]2[part.model ? "-[part.model]": ""]" else if(part.status & ORGAN_DEAD) icon_key = "[icon_key]3" else @@ -261,69 +258,31 @@ var/global/list/damage_icon_parts = list() var/icon/base_icon if(human_icon_cache[icon_key]) - //Icon is cached, use existing icon. base_icon = human_icon_cache[icon_key] - - //log_debug("Retrieved cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src].") - else + //BEGIN CACHED ICON GENERATION. + var/obj/item/organ/external/chest = get_organ("chest") + base_icon = chest.get_icon() - //BEGIN CACHED ICON GENERATION. - var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) - var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) - - //Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs. - //No icon stored, so we need to start with a basic one. - var/datum/organ/external/chest = get_organ("chest") - base_icon = chest.get_icon(race_icon,deform_icon,g) - - if(chest.status & ORGAN_DEAD) - base_icon.ColorTone(necrosis_color_mod) - base_icon.SetIntensity(0.7) - - for(var/datum/organ/external/part in organs) - - var/icon/temp //Hold the bodypart icon for processing. - - if(part.status & ORGAN_DESTROYED) - continue - - if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head)) - temp = part.get_icon(race_icon,deform_icon,g) - else - temp = part.get_icon(race_icon,deform_icon) - - if(part.status & ORGAN_DEAD) - temp.ColorTone(necrosis_color_mod) - temp.SetIntensity(0.7) - + for(var/obj/item/organ/external/part in organs) + var/icon/temp = part.get_icon(skeleton) //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part) if(part.icon_position&(LEFT|RIGHT)) - var/icon/temp2 = new('icons/mob/human.dmi',"blank") - temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH) temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH) - if(!(part.icon_position & LEFT)) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) - if(!(part.icon_position & RIGHT)) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_OVERLAY) - if(part.icon_position & LEFT) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) - if(part.icon_position & RIGHT) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_UNDERLAY) - else - base_icon.Blend(temp, ICON_OVERLAY) if(!skeleton) @@ -334,46 +293,18 @@ var/global/list/damage_icon_parts = list() base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3])) //Handle husk overlay. - if(husk && ("overlay_husk" in icon_states(race_icon))) + if(husk && ("overlay_husk" in icon_states(species.icobase))) var/icon/mask = new(base_icon) - var/icon/husk_over = new(race_icon,"overlay_husk") + var/icon/husk_over = new(species.icobase,"overlay_husk") mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0) husk_over.Blend(mask, ICON_ADD) base_icon.Blend(husk_over, ICON_OVERLAY) - - //Skin tone. - if(!husk && !hulk) - if(species.flags & HAS_SKIN_TONE) - if(s_tone >= 0) - base_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - else - base_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) - human_icon_cache[icon_key] = base_icon - //log_debug("Generated new cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src]. [human_icon_cache.len] cached mob icons.") - //END CACHED ICON GENERATION. - stand_icon.Blend(base_icon,ICON_OVERLAY) - //Skin colour. Not in cache because highly variable (and relatively benign). - if (species.flags & HAS_SKIN_COLOR) - stand_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - - if(has_head) - //Eyes - if(!skeleton) - var/icon/eyes = new/icon('icons/mob/human_face.dmi', species.eyes) - if (species.flags & HAS_EYE_COLOR) - eyes.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) - stand_icon.Blend(eyes, ICON_OVERLAY) - - //Mouth (lipstick!) - if(lip_style && (species && species.flags & HAS_LIPS)) //skeletons are allowed to wear lipstick no matter what you think, agouri. - stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY) - //Underwear if(underwear && species.flags & HAS_UNDERWEAR) stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY) @@ -392,7 +323,7 @@ var/global/list/damage_icon_parts = list() //Reset our hair overlays_standing[HAIR_LAYER] = null - var/datum/organ/external/head/head_organ = get_organ("head") + var/obj/item/organ/external/head/head_organ = get_organ("head") if( !head_organ || (head_organ.status & ORGAN_DESTROYED) ) if(update_icons) update_icons() return @@ -763,13 +694,12 @@ var/global/list/damage_icon_parts = list() standing.overlays += bloodsies overlays_standing[SUIT_LAYER] = standing - update_tail_showing(0) else overlays_standing[SUIT_LAYER] = null - update_tail_showing(0) + update_inv_shoes(0) update_collar(0) @@ -854,37 +784,47 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/update_inv_r_hand(var/update_icons=1) if(r_hand) r_hand.screen_loc = ui_rhand //TODO + + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + var/t_state = r_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = r_hand.icon_state - if(r_hand.icon_override) t_state = "[t_state]_r" overlays_standing[R_HAND_LAYER] = image("icon" = r_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]") + overlays_standing[R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_r_hand() else overlays_standing[R_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/update_inv_l_hand(var/update_icons=1) if(l_hand) l_hand.screen_loc = ui_lhand //TODO + + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + var/t_state = l_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = l_hand.icon_state - if(l_hand.icon_override) t_state = "[t_state]_l" overlays_standing[L_HAND_LAYER] = image("icon" = l_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]") + overlays_standing[L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_l_hand() else overlays_standing[L_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) overlays_standing[TAIL_LAYER] = null @@ -925,48 +865,13 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/update_surgery(var/update_icons=1) overlays_standing[SURGERY_LEVEL] = null var/image/total = new - for(var/datum/organ/external/E in organs) + for(var/obj/item/organ/external/E in organs) if(E.open) var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.name][round(E.open)]", "layer"=-SURGERY_LEVEL) total.overlays += I overlays_standing[SURGERY_LEVEL] = total if(update_icons) update_icons() -// Used mostly for creating head items -/mob/living/carbon/human/proc/generate_head_icon() -//gender no longer matters for the mouth, although there should probably be seperate base head icons. -// var/g = "m" -// if (gender == FEMALE) g = "f" - - //base icons - var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l") - - if(f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] - if(facial_hair_style) - var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l") - facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) - face_lying.Blend(facial_l, ICON_OVERLAY) - - if(h_style) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] - if(hair_style) - var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l") - hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) - face_lying.Blend(hair_l, ICON_OVERLAY) - - //Eyes - // Note: These used to be in update_face(), and the fact they're here will make it difficult to create a disembodied head - var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l") - eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) - face_lying.Blend(eyes_l, ICON_OVERLAY) - - if(lip_style) - face_lying.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_l"), ICON_OVERLAY) - - var/image/face_lying_image = new /image(icon = face_lying) - return face_lying_image - //Human Overlays Indexes///////// #undef MUTATIONS_LAYER #undef DAMAGE_LAYER diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm new file mode 100644 index 00000000000..1b3da8f49ab --- /dev/null +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -0,0 +1,141 @@ +//Monkey Overlays Indexes//////// +#define M_MASK_LAYER 1 +#define M_BACK_LAYER 2 +#define M_HANDCUFF_LAYER 3 +#define M_L_HAND_LAYER 4 +#define M_R_HAND_LAYER 5 +#define TARGETED_LAYER 6 +#define M_FIRE_LAYER 6 +#define M_TOTAL_LAYERS 7 +///////////////////////////////// + +/mob/living/carbon/monkey + var/list/overlays_lying[M_TOTAL_LAYERS] + var/list/overlays_standing[M_TOTAL_LAYERS] + +/mob/living/carbon/monkey/regenerate_icons() + ..() + update_inv_wear_mask(0) + update_inv_back(0) + update_inv_r_hand(0) + update_inv_l_hand(0) + update_inv_handcuffed(0) + update_fire(0) + update_icons() + //Hud Stuff + update_hud() + return + +/mob/living/carbon/monkey/update_icons() + update_hud() + lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again + overlays.Cut() + for(var/image/I in overlays_standing) + overlays += I + + if(lying) + var/matrix/M = matrix() + M.Turn(90) + M.Translate(1,-6) + src.transform = M + else + var/matrix/M = matrix() + src.transform = M + + +//////// +/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1) + if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) ) + overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]") + wear_mask.screen_loc = ui_monkey_mask + else + overlays_standing[M_MASK_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1) + if(r_hand) + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + + var/t_state = r_hand.item_state + if(!t_state) t_state = r_hand.icon_state + + overlays_standing[M_R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) + r_hand.screen_loc = ui_rhand + if (handcuffed) drop_r_hand() + else + overlays_standing[M_R_HAND_LAYER] = null + + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1) + if(l_hand) + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + + var/t_state = l_hand.item_state + if(!t_state) t_state = l_hand.icon_state + + overlays_standing[M_L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) + l_hand.screen_loc = ui_lhand + if (handcuffed) drop_l_hand() + else + overlays_standing[M_L_HAND_LAYER] = null + + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_back(var/update_icons=1) + if(back) + overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]") + back.screen_loc = ui_monkey_back + else + overlays_standing[M_BACK_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_handcuffed(var/update_icons=1) + if(handcuffed) + drop_r_hand() + drop_l_hand() + stop_pulling() + overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1") + else + overlays_standing[M_HANDCUFF_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_hud() + if (client) + client.screen |= contents + +//Call when target overlay should be added/removed +/mob/living/carbon/monkey/update_targeted(var/update_icons=1) + if (targeted_by && target_locked) + overlays_standing[TARGETED_LAYER] = target_locked + else if (!targeted_by && target_locked) + del(target_locked) + if (!targeted_by) + overlays_standing[TARGETED_LAYER] = null + if(update_icons) update_icons() + +/mob/living/carbon/monkey/update_fire(var/update_icons=1) + if(on_fire) + overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER) + else + overlays_standing[M_FIRE_LAYER] = null + if(update_icons) update_icons() +//Monkey Overlays Indexes//////// +#undef M_MASK_LAYER +#undef M_BACK_LAYER +#undef M_HANDCUFF_LAYER +#undef M_L_HAND_LAYER +#undef M_R_HAND_LAYER +#undef TARGETED_LAYER +#undef M_FIRE_LAYER +#undef M_TOTAL_LAYERS + diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index b76b7a49b7b..a83e76ef760 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -35,11 +35,9 @@ // broken or ripped off organs will add quite a bit of pain if(istype(src,/mob/living/carbon/human)) var/mob/living/carbon/human/M = src - for(var/datum/organ/external/organ in M.organs) + for(var/obj/item/organ/external/organ in M.organs) if (!organ) continue - if((organ.status & ORGAN_DESTROYED) && !organ.amputated) - src.traumatic_shock += 60 else if(organ.status & ORGAN_BROKEN || organ.open) src.traumatic_shock += 30 if(organ.status & ORGAN_SPLINTED) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d040c03e550..00802c5da91 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -169,7 +169,7 @@ default behaviour is: var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part var/divided_damage = (burn_amount)/(H.organs.len) var/extradam = 0 //added to when organ is at max dam - for(var/datum/organ/external/affecting in H.organs) + for(var/obj/item/organ/external/affecting in H.organs) if(!affecting) continue if(affecting.take_damage(0, divided_damage+extradam)) //TODO: fix the extradam stuff. Or, ebtter yet...rewrite this entire proc ~Carn H.UpdateDamageIcon() @@ -339,7 +339,7 @@ default behaviour is: var/t = shooter:zone_sel.selecting if ((t in list( "eyes", "mouth" ))) t = "head" - var/datum/organ/external/def_zone = ran_zone(t) + var/obj/item/organ/external/def_zone = ran_zone(t) return def_zone @@ -528,11 +528,11 @@ default behaviour is: //pull damage with injured people if(prob(25)) M.adjustBruteLoss(1) - visible_message("\red \The [M]'s wounds open more from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!") if(M.pull_damage()) if(prob(25)) M.adjustBruteLoss(2) - visible_message("\red \The [M]'s wounds worsen terribly from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!") var/turf/location = M.loc if (istype(location, /turf/simulated)) location.add_blood(M) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index eb0c9ce8599..e3ce0c93022 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -49,8 +49,8 @@ Stun(2) //Being hit while using a deadman switch - if(istype(equipped(),/obj/item/device/assembly/signaler)) - var/obj/item/device/assembly/signaler/signaler = equipped() + if(istype(get_active_hand(),/obj/item/device/assembly/signaler)) + var/obj/item/device/assembly/signaler/signaler = get_active_hand() if(signaler.deadman && prob(80)) src.visible_message("\red [src] triggers their deadman's switch!") signaler.signal() diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index 0f84806a1f4..cb86e523022 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -65,9 +65,9 @@ var/list/damaged = H.get_damaged_organs(1,1) user.show_message("\blue Localized Damage, Brute/Electronics:",1) if(length(damaged)>0) - for(var/datum/organ/external/org in damaged) + for(var/obj/item/organ/external/org in damaged) user.show_message(text("\blue \t []: [] - []", \ - capitalize(org.display_name), \ + capitalize(org.name), \ (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \ (org.burn_dam > 0) ? "[org.burn_dam]" :0),1) else diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm index 0ca5e36828a..333ea3540dc 100644 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ b/code/modules/mob/living/simple_animal/borer/borer.dm @@ -100,7 +100,7 @@ if(istype(host,/mob/living/carbon/human)) var/mob/living/carbon/human/H = host - var/datum/organ/external/head = H.get_organ("head") + var/obj/item/organ/external/head = H.get_organ("head") head.implants -= src controlling = 0 diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index af2a923c96c..b0fd2a51216 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -69,7 +69,7 @@ if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/E = H.organs_by_name["head"] + var/obj/item/organ/external/E = H.organs_by_name["head"] if(!E || (E.status & ORGAN_DESTROYED)) src << "\The [H] does not have a head!" @@ -115,12 +115,12 @@ if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/I = H.internal_organs_by_name["brain"] + var/obj/item/organ/I = H.internal_organs_by_name["brain"] if(!I) // No brain organ, so the borer moves in and replaces it permanently. replace_brain() else // If they're in normally, implant removal can get them out. - var/datum/organ/external/head = H.get_organ("head") + var/obj/item/organ/external/head = H.get_organ("head") head.implants += src return @@ -183,11 +183,11 @@ H.ChangeToHusk() - var/datum/organ/internal/borer/B = new(H) + var/obj/item/organ/borer/B = new(H) H.internal_organs_by_name["brain"] = B H.internal_organs |= B - var/datum/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ("head") affecting.implants -= src var/s2h_id = src.computer_id diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 5bc3d41afc6..73de95acee7 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -134,7 +134,7 @@ if(ishuman(target_mob)) var/mob/living/carbon/human/H = target_mob var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) + var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1) return H else if(isliving(target_mob)) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 5895c42d71e..729bb3ff050 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -475,7 +475,7 @@ if(ishuman(parrot_interest)) var/mob/living/carbon/human/H = parrot_interest - var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) + var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1) visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons.")) @@ -607,7 +607,7 @@ stolen_item = C.r_hand if(stolen_item) - C.u_equip(stolen_item) + C.remove_from_mob(stolen_item) held_item = stolen_item stolen_item.loc = src visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4379db6c175..e4405c57672 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -117,77 +117,6 @@ /mob/proc/restrained() return -//This proc is called whenever someone clicks an inventory ui slot. -/mob/proc/attack_ui(slot) - var/obj/item/W = get_active_hand() - if(istype(W)) - equip_to_slot_if_possible(W, slot) - -/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1) - if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob)) - return 1 - else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob)) - return 1 - return 0 - -//This is a SAFE proc. Use this instead of equip_to_slot()! -//set del_on_fail to have it delete W if it fails to equip -//set disable_warning to disable the 'you are unable to equip that' warning. -//unset redraw_mob to prevent the mob from being redrawn at the end. -/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1) - if(!istype(W)) return 0 - - if(!W.mob_can_equip(src, slot)) - if(del_on_fail) - del(W) - else - if(!disable_warning) - src << "\red You are unable to equip that." //Only print if del_on_fail is false - return 0 - - equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. - return 1 - -//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. -//In most cases you will want to use equip_to_slot_if_possible() -/mob/proc/equip_to_slot(obj/item/W as obj, slot) - return - -//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. -/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) - return equip_to_slot_if_possible(W, slot, 1, 1, 0) - -//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. -var/list/slot_equipment_priority = list( \ - slot_back,\ - slot_wear_id,\ - slot_w_uniform,\ - slot_wear_suit,\ - slot_wear_mask,\ - slot_head,\ - slot_shoes,\ - slot_gloves,\ - slot_l_ear,\ - slot_r_ear,\ - slot_glasses,\ - slot_belt,\ - slot_s_store,\ - slot_tie,\ - slot_l_store,\ - slot_r_store\ - ) - -//puts the item "W" into an appropriate slot in a human's inventory -//returns 0 if it cannot, 1 if successful -/mob/proc/equip_to_appropriate_slot(obj/item/W) - if(!istype(W)) return 0 - - for(var/slot in slot_equipment_priority) - if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) - return 1 - - return 0 - /mob/proc/reset_view(atom/A) if (client) if (istype(A, /atom/movable)) @@ -589,8 +518,8 @@ var/list/slot_equipment_priority = list( \ var/mob/living/carbon/human/H = src if(H.health - H.halloss <= config.health_threshold_softcrit) for(var/name in H.organs_by_name) - var/datum/organ/external/e = H.organs_by_name[name] - if(H.lying) + var/obj/item/organ/external/e = H.organs_by_name[name] + if(e && H.lying) if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) return 1 break @@ -1101,7 +1030,7 @@ mob/proc/yank_out_object() else U << "You attempt to get a good grip on [selection] in [S]'s body." - if(!do_after(U, 80)) + if(!do_after(U, 30)) return if(!selection || !S || !U) return @@ -1116,9 +1045,9 @@ mob/proc/yank_out_object() if(ishuman(src)) var/mob/living/carbon/human/H = src - var/datum/organ/external/affected + var/obj/item/organ/external/affected - for(var/datum/organ/external/organ in H.organs) //Grab the organ holding the implant. + for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant. for(var/obj/item/O in organ.implants) if(O == selection) affected = organ @@ -1137,6 +1066,8 @@ mob/proc/yank_out_object() human_user.bloody_hands(H) selection.loc = get_turf(src) + if(!(U.l_hand && U.r_hand)) + U.put_in_hands(selection) for(var/obj/item/weapon/O in pinned) if(O == selection) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 4f83216e811..370a921d3c2 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -92,13 +92,22 @@ /mob/living/silicon/ai/isAI() return 1 - -/mob/proc/isRobot() + +/mob/proc/isRobot() return 0 /mob/living/silicon/robot/isRobot() return 1 +/mob/proc/isSynthetic() + return 0 + +/mob/living/carbon/human/isSynthetic() + return species.flags & IS_SYNTHETIC + +/mob/living/silicon/isSynthetic() + return 1 + /proc/ispAI(A) if(istype(A, /mob/living/silicon/pai)) return 1 @@ -125,7 +134,7 @@ proc/isobserver(A) return 0 proc/isorgan(A) - if(istype(A, /datum/organ/external)) + if(istype(A, /obj/item/organ/external)) return 1 return 0 @@ -140,7 +149,7 @@ proc/isnewplayer(A) return 1 return 0 -proc/hasorgans(A) +proc/hasorgans(A) // Fucking really?? return ishuman(A) proc/iscuffed(A) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index bd00faf9533..baf1d299687 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -96,8 +96,8 @@ /client/verb/drop_item() set hidden = 1 - if(!isrobot(mob)) - mob.drop_item_v() + if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc)) + return mob.drop_item() return @@ -289,8 +289,8 @@ else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair)) if(ishuman(mob.buckled)) var/mob/living/carbon/human/driver = mob.buckled - var/datum/organ/external/l_hand = driver.get_organ("l_hand") - var/datum/organ/external/r_hand = driver.get_organ("r_hand") + var/obj/item/organ/external/l_hand = driver.get_organ("l_hand") + var/obj/item/organ/external/r_hand = driver.get_organ("r_hand") if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED))) return // No hands to drive your chair? Tough luck! //drunk wheelchair driving diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index d25b66210e1..6330504e3cc 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -200,12 +200,13 @@ datum/preferences for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) if(organ_data[name] == "amputated") continue - - var/icon/temp = new /icon(icobase, "[name]") if(organ_data[name] == "cyborg") - temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) - - preview_icon.Blend(temp, ICON_OVERLAY) + var/datum/robolimb/R + if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] + if(!R) R = basic_robolimb + preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. + continue + preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) //Tail if(current_species && (current_species.tail)) @@ -375,7 +376,7 @@ datum/preferences if(LAWYER) clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "briefcase"), ICON_UNDERLAY) if(prob(1)) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "suitjacket_blue"), ICON_OVERLAY) switch(backbag) @@ -534,7 +535,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "toolbox_blue"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) @@ -620,7 +621,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) clothes_s.Blend(new /icon('icons/mob/head.dmi', "hardhat0_white"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "blueprints"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "blueprints"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "engiepack"), ICON_OVERLAY) diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm index a6ae6dc4a09..480c4be3223 100644 --- a/code/modules/mob/update_icons.dm +++ b/code/modules/mob/update_icons.dm @@ -1,6 +1,11 @@ //Most of these are defined at this level to reduce on checks elsewhere in the code. //Having them here also makes for a nice reference list of the various overlay-updating procs available +//default item on-mob icons +#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi' +#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' + + /mob/proc/regenerate_icons() //TODO: phase this out completely if possible return diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 5f045736dce..1eab38904c9 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -65,7 +65,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Damaged heart virtually reduces the blood volume, as the blood isn't // being pumped properly anymore. if(species && species.has_organ["heart"]) - var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"] + var/obj/item/organ/heart/heart = internal_organs_by_name["heart"] if(!heart) blood_volume = 0 @@ -127,7 +127,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Bleeding out var/blood_max = 0 - for(var/datum/organ/external/temp in organs) + for(var/obj/item/organ/external/temp in organs) if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT) continue for(var/datum/wound/W in temp.wounds) if(W.bleeding()) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 495ce2762c2..5d307fffcf2 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -1,26 +1,154 @@ -/datum/organ - var/name = "organ" +var/list/organ_cache = list() + +/obj/item/organ + name = "organ" + icon = 'icons/obj/surgery.dmi' + var/mob/living/carbon/human/owner = null var/status = 0 var/vital //Lose a vital limb, die immediately. + var/damage = 0 // amount of damage to the organ + var/min_bruised_damage = 10 + var/min_broken_damage = 30 + var/max_damage + var/organ_tag = "organ" + + var/parent_organ = "chest" + var/robotic = 0 //For being a robot + var/rejecting // Is this organ already being rejected? + + var/list/transplant_data var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood + germ_level = 0 - var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE +/obj/item/organ/proc/update_health() + return - proc/process() - return 0 +/obj/item/organ/New(var/mob/living/carbon/holder, var/internal) + ..(holder) + create_reagents(5) + if(!max_damage) + max_damage = min_broken_damage * 2 + if(istype(holder)) + src.owner = holder + var/mob/living/carbon/human/H = holder + if(istype(H)) + if(internal) + var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ] + if(E) + if(E.internal_organs == null) + E.internal_organs = list() + E.internal_organs |= src + if(H.dna) + if(!blood_DNA) + blood_DNA = list() + blood_DNA[H.dna.unique_enzymes] = H.dna.b_type + if(internal) + holder.internal_organs |= src - proc/receive_chem(chemical as obj) - return 0 +/obj/item/organ/proc/die() + name = "dead [initial(name)]" + health = 0 + processing_objects -= src + //TODO: Grey out the icon state. + //TODO: Inject an organ with peridaxon to make it alive again. -/datum/organ/proc/get_icon(var/icon/race_icon, var/icon/deform_icon) - return icon('icons/mob/human.dmi',"blank") +/obj/item/organ/process() + + // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? + if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) + return + + //Process infections + if (robotic >= 2 || (owner && owner.species && (owner.species.flags & IS_PLANT))) + germ_level = 0 + return + + if(loc != owner) + owner = null + + if(!owner) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list + if(B && prob(40)) + reagents.remove_reagent("blood",0.1) + blood_splatter(src,B,1) + + health -= rand(1,3) + if(health <= 0) + die() + else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs + //** Handle antibiotics and curing infections + handle_antibiotics() + handle_rejection() + handle_germ_effects() + +/obj/item/organ/proc/handle_germ_effects() + //** Handle the effects of infections + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + + if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) + germ_level-- + + if (germ_level >= INFECTION_LEVEL_ONE/2) + //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes + if(antibiotics < 5 && prob(round(germ_level/6))) + germ_level++ + + if(germ_level >= INFECTION_LEVEL_ONE) + var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature + owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) + + if (germ_level >= INFECTION_LEVEL_TWO) + var/obj/item/organ/external/parent = owner.get_organ(parent_organ) + //spread germs + if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) + parent.germ_level++ + + if (prob(3)) //about once every 30 seconds + take_damage(1,silent=prob(30)) + +/obj/item/organ/proc/handle_rejection() + // Process unsuitable transplants. TODO: consider some kind of + // immunosuppressant that changes transplant data to make it match. + if(transplant_data) + if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"])) + rejecting = 1 + else + rejecting++ //Rejection severity increases over time. + if(rejecting % 10 == 0) //Only fire every ten rejection ticks. + switch(rejecting) + if(1 to 50) + take_damage(1) + if(51 to 200) + owner.reagents.add_reagent("toxin", 1) + take_damage(1) + if(201 to 500) + take_damage(rand(2,3)) + owner.reagents.add_reagent("toxin", 2) + if(501 to INFINITY) + take_damage(4) + owner.reagents.add_reagent("toxin", rand(3,5)) + +/obj/item/organ/proc/receive_chem(chemical as obj) + return 0 + +/obj/item/organ/proc/rejuvenate() + damage = 0 + +/obj/item/organ/proc/is_damaged() + return damage > 0 + +/obj/item/organ/proc/is_bruised() + return damage >= min_bruised_damage + +/obj/item/organ/proc/is_broken() + return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))) //Germs -/datum/organ/proc/handle_antibiotics() +/obj/item/organ/proc/handle_antibiotics() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") if (!germ_level || antibiotics < 5) @@ -33,15 +161,8 @@ else germ_level -= 2 //at germ_level == 1000, this will cure the infection in 5 minutes -//Handles chem traces -/mob/living/carbon/human/proc/handle_trace_chems() - //New are added for reagents to random organs. - for(var/datum/reagent/A in reagents.reagent_list) - var/datum/organ/O = pick(organs) - O.trace_chemicals[A.name] = 100 - //Adds autopsy data for used_weapon. -/datum/organ/proc/add_autopsy_data(var/used_weapon, var/damage) +/obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage) var/datum/autopsy_data/W = autopsy_data[used_weapon] if(!W) W = new() @@ -52,88 +173,147 @@ W.damage += damage W.time_inflicted = world.time -/mob/living/carbon/human/var/list/organs = list() -/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs -/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too +/obj/item/organ/proc/take_damage(amount, var/silent=0) + if(src.robotic == 2) + src.damage += (amount * 0.8) + else + src.damage += amount -// Takes care of organ related updates, such as broken and missing limbs -/mob/living/carbon/human/proc/handle_organs() + var/obj/item/organ/external/parent = owner.get_organ(parent_organ) + if (!silent) + owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1) - number_wounds = 0 - var/force_process = 0 - var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss() - if(damage_this_tick > last_dam) - force_process = 1 - last_dam = damage_this_tick - if(force_process) - bad_external_organs.Cut() - for(var/datum/organ/external/Ex in organs) - bad_external_organs += Ex +/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc + robotic = 2 + src.status &= ~ORGAN_BROKEN + src.status &= ~ORGAN_BLEEDING + src.status &= ~ORGAN_SPLINTED + src.status &= ~ORGAN_CUT_AWAY + src.status &= ~ORGAN_ATTACHABLE + src.status &= ~ORGAN_DESTROYED + src.status |= ORGAN_ROBOT + src.status |= ORGAN_ASSISTED - //processing internal organs is pretty cheap, do that first. - for(var/datum/organ/internal/I in internal_organs) - I.process() +/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc + robotize() + src.status &= ~ORGAN_ROBOT + robotic = 1 + min_bruised_damage = 15 + min_broken_damage = 35 - //losing a limb stops it from processing, so this has to be done separately - handle_stance() +/obj/item/organ/emp_act(severity) + switch(robotic) + if(0) + return + if(1) + switch (severity) + if (1.0) + take_damage(20,0) + return + if (2.0) + take_damage(7,0) + return + if(3.0) + take_damage(3,0) + return + if(2) + switch (severity) + if (1.0) + take_damage(40,0) + return + if (2.0) + take_damage(15,0) + return + if(3.0) + take_damage(10,0) + return - if(!force_process && !bad_external_organs.len) +/obj/item/organ/proc/removed(var/mob/living/user) + + if(!istype(owner)) return - for(var/datum/organ/external/E in bad_external_organs) - if(!E) - continue - if(!E.need_process()) - bad_external_organs -= E - continue - else - E.process() - number_wounds += E.number_wounds + owner.internal_organs_by_name[organ_tag] = null + owner.internal_organs_by_name -= organ_tag + owner.internal_organs -= src - if (!lying && world.time - l_move_time < 15) - //Moving around with fractured ribs won't do you any good - if (E.is_broken() && E.internal_organs && prob(15)) - var/datum/organ/internal/I = pick(E.internal_organs) - custom_pain("You feel broken bones moving in your [E.display_name]!", 1) - I.take_damage(rand(3,5)) + var/obj/item/organ/external/affected = owner.get_organ(parent_organ) + if(affected) affected.internal_organs -= src - //Moving makes open wounds get infected much faster - if (E.wounds.len) - for(var/datum/wound/W in E.wounds) - if (W.infection_check()) - W.germ_level += 1 + loc = owner.loc + rejecting = null + var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list + if(!organ_blood || !organ_blood.data["blood_DNA"]) + owner.vessel.trans_to(src, 5, 1, 1) -/mob/living/carbon/human/proc/handle_stance() - // Don't need to process any of this if they aren't standing anyways - // unless their stance is damaged, and we want to check if they should stay down - if (!stance_damage && (lying || resting) && (life_tick % 4) == 0) - return - - stance_damage = 0 - - // Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid - if (istype(buckled, /obj/structure/bed)) + if(owner && vital) + if(user) + user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)])" + owner.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])" + msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)]) (
    JMP)") + owner.death() + +/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected) + + if(!istype(target)) return + + var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list + transplant_data = list() + if(!transplant_blood) + transplant_data["species"] = target.species.name + transplant_data["blood_type"] = target.dna.b_type + transplant_data["blood_DNA"] = target.dna.unique_enzymes + else + transplant_data["species"] = transplant_blood.data["species"] + transplant_data["blood_type"] = transplant_blood.data["blood_type"] + transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"] + + owner = target + target.internal_organs |= src + affected.internal_organs |= src + target.internal_organs_by_name[organ_tag] = src + status |= ORGAN_CUT_AWAY + + del(src) + +/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) + + // Apply our eye colour to the target. + if(istype(target) && eye_colour) + target.r_eyes = eye_colour[1] + target.g_eyes = eye_colour[2] + target.b_eyes = eye_colour[3] + target.update_body() + ..() + +/obj/item/organ/proc/bitten(mob/user) + + if(robotic) return - - for (var/organ in list("l_leg","l_foot","r_leg","r_foot")) - var/datum/organ/external/E = organs_by_name[organ] - if (E.status & ORGAN_DESTROYED) - stance_damage += 2 // let it fail even if just foot&leg - else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable()) - stance_damage += 1 - // Canes and crutches help you stand (if the latter is ever added) - // One cane mitigates a broken leg+foot, or a missing foot. - // Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you. - if (istype(l_hand, /obj/item/weapon/cane)) - stance_damage -= 2 - if (istype(l_hand, /obj/item/weapon/cane)) - stance_damage -= 2 + user << "\blue You take an experimental bite out of \the [src]." + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list + blood_splatter(src,B,1) - // standing is poor - if(stance_damage >= 4 || (stance_damage >= 2 && prob(5))) - if(!(lying || resting)) - if(species && !(species.flags & NO_PAIN)) - emote("scream") - custom_emote(1, "collapses!") - Weaken(5) //can't emote while weakened, apparently. \ No newline at end of file + + user.drop_from_inventory(src) + var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src)) + O.name = name + O.icon_state = icon_state + + // Pass over the blood. + reagents.trans_to(O, reagents.total_volume) + + if(fingerprints) O.fingerprints = fingerprints.Copy() + if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy() + if(fingerprintslast) O.fingerprintslast = fingerprintslast + + user.put_in_active_hand(O) + del(src) + +/obj/item/organ/attack_self(mob/user as mob) + + // Convert it to an edible form, yum yum. + if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth") + bitten(user) + return diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm index 4a36d236597..d326e2ade46 100644 --- a/code/modules/organs/organ_alien.dm +++ b/code/modules/organs/organ_alien.dm @@ -1,51 +1,6 @@ -//DIONA ORGANS. -/datum/organ/internal/diona - removed_type = /obj/item/organ/diona - -/datum/organ/internal/diona/process() - return - -/datum/organ/internal/diona/strata - name = "neural strata" - parent_organ = "chest" - -/datum/organ/internal/diona/bladder - name = "gas bladder" - parent_organ = "head" - -/datum/organ/internal/diona/polyp - name = "polyp segment" - parent_organ = "groin" - -/datum/organ/internal/diona/ligament - name = "anchoring ligament" - parent_organ = "groin" - -/datum/organ/internal/diona/node - name = "receptor node" - parent_organ = "head" - removed_type = /obj/item/organ/diona/node - -/datum/organ/internal/diona/nutrients - name = "nutrient vessel" - parent_organ = "chest" - removed_type = /obj/item/organ/diona/nutrients - -/obj/item/organ/diona - name = "diona nymph" - icon = 'icons/obj/objects.dmi' - icon_state = "nymph" - organ_tag = "special" // Turns into a nymph instantly, no transplanting possible. - -/obj/item/organ/diona/removed(var/mob/living/target,var/mob/living/user) - - ..() - var/mob/living/carbon/human/H = target - if(!istype(target)) - del(src) - - if(!H.internal_organs.len) - H.death() +/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ) + if(!istype(organ)) + return //This is a terrible hack and I should be ashamed. var/datum/seed/diona = plant_controller.seeds["diona"] @@ -53,10 +8,180 @@ del(src) spawn(1) // So it has time to be thrown about by the gib() proc. - var/mob/living/carbon/alien/diona/D = new(get_turf(src)) + var/mob/living/carbon/alien/diona/D = new(get_turf(organ)) diona.request_player(D) + del(organ) + +/obj/item/organ/external/diona + name = "tendril" + cannot_break = 1 + amputation_point = "branch" + joint = "structural ligament" + dislocated = -1 + +/obj/item/organ/external/diona/chest + name = "core trunk" + limb_name = "chest" + icon_name = "torso" + health = 200 + min_broken_damage = 50 + body_part = UPPER_TORSO + vital = 1 + cannot_amputate = 1 + parent_organ = null + +/obj/item/organ/external/diona/groin + name = "fork" + limb_name = "groin" + icon_name = "groin" + health = 100 + min_broken_damage = 50 + body_part = LOWER_TORSO + parent_organ = "chest" + +/obj/item/organ/external/diona/arm + name = "left upper tendril" + limb_name = "l_arm" + icon_name = "l_arm" + health = 35 + min_broken_damage = 20 + body_part = ARM_LEFT + parent_organ = "chest" + can_grasp = 1 + +/obj/item/organ/external/diona/arm/right + name = "right upper tendril" + limb_name = "r_arm" + icon_name = "r_arm" + body_part = ARM_RIGHT + +/obj/item/organ/external/diona/leg + name = "left lower tendril" + limb_name = "l_leg" + icon_name = "l_leg" + health = 35 + min_broken_damage = 20 + body_part = LEG_LEFT + icon_position = LEFT + parent_organ = "groin" + can_stand = 1 + +/obj/item/organ/external/diona/leg/right + name = "right lower tendril" + limb_name = "r_leg" + icon_name = "r_leg" + body_part = LEG_RIGHT + icon_position = RIGHT + +/obj/item/organ/external/diona/foot + name = "left foot" + limb_name = "l_foot" + icon_name = "l_foot" + health = 20 + min_broken_damage = 10 + body_part = FOOT_LEFT + icon_position = LEFT + parent_organ = "l_leg" + can_stand = 1 + +/obj/item/organ/external/diona/foot/right + name = "right foot" + limb_name = "r_foot" + icon_name = "r_foot" + body_part = FOOT_RIGHT + icon_position = RIGHT + parent_organ = "r_leg" + joint = "right ankle" + amputation_point = "right ankle" + +/obj/item/organ/external/diona/hand + name = "left grasper" + limb_name = "l_hand" + icon_name = "l_hand" + health = 30 + min_broken_damage = 15 + body_part = HAND_LEFT + parent_organ = "l_arm" + can_grasp = 1 + +/obj/item/organ/external/diona/hand/right + name = "right grasper" + limb_name = "r_hand" + icon_name = "r_hand" + body_part = HAND_RIGHT + parent_organ = "r_arm" + +/obj/item/organ/external/diona/head + limb_name = "head" + icon_name = "head" + name = "head" + health = 50 + min_broken_damage = 25 + body_part = HEAD + parent_organ = "chest" + +/obj/item/organ/external/diona/head/removed() + if(owner) + owner.u_equip(owner.head) + owner.u_equip(owner.l_ear) + ..() + +//DIONA ORGANS. +/obj/item/organ/external/diona/removed() + ..() + if(!istype(owner)) del(src) + if(!owner.organs.len) + owner.death() + + if(prob(50)) + spawn_diona_nymph_from_organ(src) + +/obj/item/organ/diona/process() + return + +/obj/item/organ/diona/strata + name = "neural strata" + parent_organ = "chest" + +/obj/item/organ/diona/bladder + name = "gas bladder" + parent_organ = "head" + +/obj/item/organ/diona/polyp + name = "polyp segment" + parent_organ = "groin" + +/obj/item/organ/diona/ligament + name = "anchoring ligament" + parent_organ = "groin" + +/obj/item/organ/diona/node + name = "receptor node" + parent_organ = "head" + +/obj/item/organ/diona/nutrients + name = "nutrient vessel" + parent_organ = "chest" + +/obj/item/organ/diona + name = "diona nymph" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + organ_tag = "special" // Turns into a nymph instantly, no transplanting possible. + +/obj/item/organ/diona/removed(var/mob/living/user) + + ..() + if(!istype(owner)) + del(src) + + if(!owner.internal_organs.len) + owner.death() + + spawn_diona_nymph_from_organ(src) + // These are different to the standard diona organs as they have a purpose in other // species (absorbing radiation and light respectively) /obj/item/organ/diona/nutrients @@ -78,13 +203,12 @@ return //CORTICAL BORER ORGANS. -/datum/organ/internal/borer +/obj/item/organ/borer name = "cortical borer" parent_organ = "head" - removed_type = /obj/item/organ/borer vital = 1 -/datum/organ/internal/borer/process() +/obj/item/organ/borer/process() // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss. for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine")) @@ -113,59 +237,54 @@ organ_tag = "brain" desc = "A disgusting space slug." -/obj/item/organ/borer/removed(var/mob/living/target,var/mob/living/user) +/obj/item/organ/borer/removed(var/mob/living/user) ..() - var/mob/living/simple_animal/borer/B = target.has_brain_worms() + var/mob/living/simple_animal/borer/B = owner.has_brain_worms() if(B) B.leave_host() - B.ckey = target.ckey + B.ckey = owner.ckey spawn(0) del(src) //XENOMORPH ORGANS -/datum/organ/internal/xenos/eggsac +/obj/item/organ/xenos/eggsac name = "egg sac" parent_organ = "groin" - removed_type = /obj/item/organ/xenos/eggsac -/datum/organ/internal/xenos/plasmavessel +/obj/item/organ/xenos/plasmavessel name = "plasma vessel" parent_organ = "chest" - removed_type = /obj/item/organ/xenos/plasmavessel var/stored_plasma = 0 var/max_plasma = 500 -/datum/organ/internal/xenos/plasmavessel/queen +/obj/item/organ/xenos/plasmavessel/queen name = "bloated plasma vessel" stored_plasma = 200 max_plasma = 500 -/datum/organ/internal/xenos/plasmavessel/sentinel +/obj/item/organ/xenos/plasmavessel/sentinel stored_plasma = 100 max_plasma = 250 -/datum/organ/internal/xenos/plasmavessel/hunter +/obj/item/organ/xenos/plasmavessel/hunter name = "tiny plasma vessel" stored_plasma = 100 max_plasma = 150 -/datum/organ/internal/xenos/acidgland +/obj/item/organ/xenos/acidgland name = "acid gland" parent_organ = "head" - removed_type = /obj/item/organ/xenos/acidgland -/datum/organ/internal/xenos/hivenode +/obj/item/organ/xenos/hivenode name = "hive node" parent_organ = "chest" - removed_type = /obj/item/organ/xenos/hivenode -/datum/organ/internal/xenos/resinspinner +/obj/item/organ/xenos/resinspinner name = "resin spinner" parent_organ = "head" - removed_type = /obj/item/organ/xenos/resinspinner /obj/item/organ/xenos name = "xeno organ" @@ -198,32 +317,28 @@ organ_tag = "resin spinner" //VOX ORGANS. -/datum/organ/internal/stack +/obj/item/organ/stack name = "cortical stack" - removed_type = /obj/item/organ/stack parent_organ = "head" robotic = 2 vital = 1 var/backup_time = 0 var/datum/mind/backup -/datum/organ/internal/stack/process() +/obj/item/organ/stack/process() if(owner && owner.stat != 2 && !is_broken()) backup_time = world.time if(owner.mind) backup = owner.mind -/datum/organ/internal/stack/vox - removed_type = /obj/item/organ/stack/vox +/obj/item/organ/stack/vox -/datum/organ/internal/stack/vox/stack +/obj/item/organ/stack/vox/stack /obj/item/organ/stack name = "cortical stack" icon_state = "brain-prosthetic" organ_tag = "stack" robotic = 2 - prosthetic_name = null - prosthetic_icon = null /obj/item/organ/stack/vox name = "vox cortical stack" \ No newline at end of file diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 4dcc006df6d..b6f14b64bce 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -1,33 +1,37 @@ /**************************************************** EXTERNAL ORGANS ****************************************************/ -/datum/organ/external +/obj/item/organ/external name = "external" var/icon_name = null var/body_part = null var/icon_position = 0 + var/model + var/force_icon + var/damage_state = "00" var/brute_dam = 0 var/burn_dam = 0 - var/max_damage = 0 var/max_size = 0 var/last_dam = -1 - - var/display_name + var/icon/mob_icon + var/gendered_icon = 0 + var/limb_name + var/disfigured = 1 + var/cannot_amputate + var/cannot_break + var/s_tone + var/list/s_col var/list/wounds = list() var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len! + var/perma_injury = 0 - var/tmp/perma_injury = 0 - var/tmp/destspawn = 0 //Has it spawned the broken limb? - var/tmp/amputated = 0 //Whether this has been cleanly amputated, thus causing no pain - var/min_broken_damage = 30 - - var/datum/organ/external/parent - var/list/datum/organ/external/children + var/obj/item/organ/external/parent + var/list/obj/item/organ/external/children // Internal organs of this body part - var/list/datum/organ/internal/internal_organs + var/list/internal_organs = list() var/damage_msg = "\red You feel an intense pain" var/broken_description @@ -44,33 +48,100 @@ // how often wounds should be updated, a higher number means less often var/wound_update_accuracy = 1 + var/joint = "joint" // Descriptive string used in dislocation. + var/amputation_point // Descriptive string used in amputation. + var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. + var/can_grasp + var/can_stand -/datum/organ/external/New(var/datum/organ/external/P) - if(P) - parent = P - if(!parent.children) - parent.children = list() - parent.children.Add(src) - return ..() + min_broken_damage = 30 + max_damage = 0 + dir = SOUTH + +/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob) + switch(stage) + if(0) + if(istype(W,/obj/item/weapon/scalpel)) + user.visible_message("[user] cuts [src] open with [W]!") + stage++ + return + if(1) + if(istype(W,/obj/item/weapon/retractor)) + user.visible_message("[user] cracks [src] open like an egg with [W]!") + stage++ + return + if(2) + if(istype(W,/obj/item/weapon/hemostat)) + if(contents.len) + var/obj/item/removing = pick(contents) + removing.loc = get_turf(user.loc) + if(!(user.l_hand && user.r_hand)) + user.put_in_hands(removing) + user.visible_message("[user] extracts [removing] from [src] with [W]!") + else + user.visible_message("[user] fishes around fruitlessly in [src] with [W].") + return + ..() + +/obj/item/organ/external/proc/is_dislocated() + if(dislocated > 0) + return 1 + if(parent) + return parent.is_dislocated() + return 0 + +/obj/item/organ/external/proc/dislocate(var/primary) + if(dislocated != -1) + if(primary) + dislocated = 2 + else + dislocated = 1 + owner.verbs |= /mob/living/carbon/human/proc/undislocate + if(children && children.len) + for(var/obj/item/organ/external/child in children) + child.dislocate() + +/obj/item/organ/external/proc/undislocate() + if(dislocated != -1) + dislocated = 0 + if(children && children.len) + for(var/obj/item/organ/external/child in children) + child.undislocate() + if(owner) + owner.shock_stage += 20 + +/obj/item/organ/external/update_health() + damage = min(max_damage, (brute_dam + burn_dam)) + return + + +/obj/item/organ/external/New(var/mob/living/carbon/holder, var/internal) + ..() + if(owner) + replaced(owner) + sync_colour_to_human(owner) + +/obj/item/organ/external/replaced(var/mob/living/carbon/human/target) + owner = target + if(istype(owner)) + owner.organs_by_name[limb_name] = src + owner.organs |= src + for(var/obj/item/organ/organ in src) + organ.loc = owner + organ.replaced(owner,src) + + if(parent_organ) + parent = owner.organs_by_name[src.parent_organ] + if(parent) + if(!parent.children) + parent.children = list() + parent.children.Add(src) /**************************************************** DAMAGE PROCS ****************************************************/ -/datum/organ/external/proc/emp_act(severity) - if(!(status & ORGAN_ROBOT)) //meatbags do not care about EMP - return - var/probability = 30 - var/damage = 15 - if(severity == 2) - probability = 1 - damage = 3 - if(prob(probability)) - droplimb(1) - else - take_damage(damage, 0, 1, 1, used_weapon = "EMP") - -/datum/organ/external/proc/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) +/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) if((brute <= 0) && (burn <= 0)) return 0 @@ -91,11 +162,12 @@ burn *= bumod //~2/3 damage for ROBOLIMBS // High brute damage or sharp objects may damage internal organs - if(internal_organs && ( (sharp && brute >= 5) || brute >= 10) && prob(5)) + if(internal_organs && ((brute_dam >= max_damage) || (sharp && brute >= 5) || brute >= 10) && prob(5)) // Damage an internal organ - var/datum/organ/internal/I = pick(internal_organs) - I.take_damage(brute / 2) - brute -= brute / 2 + if(internal_organs && internal_organs.len) + var/obj/item/organ/I = pick(internal_organs) + I.take_damage(brute / 2) + brute -= brute / 2 if(status & ORGAN_BROKEN && prob(40) && brute) if (!(owner.species && (owner.species.flags & NO_PAIN))) @@ -137,38 +209,32 @@ burn = max(0, burn - can_inflict) //If there are still hurties to dispense if (burn || brute) - if (status & ORGAN_ROBOT) - droplimb(1) //Robot limbs just kinda fail at full damage. - else - //List organs we can pass it to - var/list/datum/organ/external/possible_points = list() - if(parent) - possible_points += parent - if(children) - possible_points += children - if(forbidden_limbs.len) - possible_points -= forbidden_limbs - if(possible_points.len) - //And pass the pain around - var/datum/organ/external/target = pick(possible_points) - target.take_damage(brute, burn, sharp, edge, used_weapon, forbidden_limbs + src) + owner.shock_stage += brute+burn // sync the organ's damage with its wounds src.update_damages() //If limb took enough damage, try to cut or tear it off - if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you. - if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier) - if( (edge && prob(5 * brute)) || (brute > 20 && prob(brute)) ) - droplimb(1) - return + if(owner && loc == owner) + if(!cannot_amputate && config.limbs_can_break && (brute_dam + burn_dam) >= (max_damage * config.organ_health_multiplier)) + var/threshold = max_damage/3 + var/dropped + if((burn >= threshold) && prob(burn/3)) + dropped = 1 + droplimb(0,DROPLIMB_BURN) + if(!dropped && prob(brute)) + if(brute >= threshold) + if((sharp || edge) && istype(used_weapon,/obj/item)) + var/obj/item/W = used_weapon + if(W.w_class >= 3) + droplimb(0,DROPLIMB_EDGE) + else + droplimb(0,DROPLIMB_BLUNT) owner.updatehealth() + return update_icon() - var/result = update_icon() - return result - -/datum/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) +/obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) if(status & ORGAN_ROBOT && !robo_repair) return @@ -187,6 +253,11 @@ status &= ~ORGAN_BROKEN perma_injury = 0 + if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS)) + var/obj/item/organ/external/stump/S = locate() in children + if(S) + world << "Extra healing to go around ([brute+burn]) and [owner] needs a replacement limb." + //Sync the organ's damage with its wounds src.update_damages() owner.updatehealth() @@ -197,7 +268,7 @@ /* This function completely restores a damaged organ to perfect condition. */ -/datum/organ/external/proc/rejuvenate() +/obj/item/organ/external/rejuvenate() damage_state = "00" if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic. status = 128 @@ -211,7 +282,7 @@ This function completely restores a damaged organ to perfect condition. number_wounds = 0 // handle internal organs - for(var/datum/organ/internal/current_organ in internal_organs) + for(var/obj/item/organ/current_organ in internal_organs) current_organ.rejuvenate() // remove embedded objects and drop them on the floor @@ -223,7 +294,7 @@ This function completely restores a damaged organ to perfect condition. owner.updatehealth() -/datum/organ/external/proc/createwound(var/type = CUT, var/damage) +/obj/item/organ/external/proc/createwound(var/type = CUT, var/damage) if(damage == 0) return //moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return) @@ -232,7 +303,7 @@ This function completely restores a damaged organ to perfect condition. if(damage > 15 && type != BURN && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT)) var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15)) wounds += I - owner.custom_pain("You feel something rip in your [display_name]!", 1) + owner.custom_pain("You feel something rip in your [name]!", 1) // first check whether we can widen an existing wound if(wounds.len > 0 && prob(max(50+(number_wounds-1)*10,90))) @@ -248,8 +319,8 @@ This function completely restores a damaged organ to perfect condition. W.open_wound(damage) if(prob(25)) //maybe have a separate message for BRUISE type damage? - owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping noise.",\ - "\red The wound on your [display_name] widens with a nasty ripping noise.",\ + owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\ + "\red The wound on your [name] widens with a nasty ripping noise.",\ "You hear a nasty ripping noise, as if flesh is being torn apart.") return @@ -274,9 +345,7 @@ This function completely restores a damaged organ to perfect condition. //Determines if we even need to process this organ. -/datum/organ/external/proc/need_process() - if(destspawn) //Missing limb is missing - return 0 +/obj/item/organ/external/proc/need_process() if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status. return 1 if(brute_dam || burn_dam) @@ -290,37 +359,41 @@ This function completely restores a damaged organ to perfect condition. return 1 return 0 -/datum/organ/external/process() - //Dismemberment - if(status & ORGAN_DESTROYED) - if(!destspawn && config.limbs_can_break) - droplimb() - return - if(parent) - if(parent.status & ORGAN_DESTROYED) - status |= ORGAN_DESTROYED - owner.update_body(1) +/obj/item/organ/external/process() + if(owner) + //Dismemberment + if(status & ORGAN_DESTROYED) + if(config.limbs_can_break) + droplimb(0,DROPLIMB_EDGE) //Might be worth removing this check since take_damage handles it. return + if(parent) + if(parent.status & ORGAN_DESTROYED) + status |= ORGAN_DESTROYED + owner.update_body(1) + return - // Process wounds, doing healing etc. Only do this every few ticks to save processing power - if(owner.life_tick % wound_update_accuracy == 0) - update_wounds() + // Process wounds, doing healing etc. Only do this every few ticks to save processing power + if(owner.life_tick % wound_update_accuracy == 0) + update_wounds() - //Chem traces slowly vanish - if(owner.life_tick % 10 == 0) - for(var/chemID in trace_chemicals) - trace_chemicals[chemID] = trace_chemicals[chemID] - 1 - if(trace_chemicals[chemID] <= 0) - trace_chemicals.Remove(chemID) + //Chem traces slowly vanish + if(owner.life_tick % 10 == 0) + for(var/chemID in trace_chemicals) + trace_chemicals[chemID] = trace_chemicals[chemID] - 1 + if(trace_chemicals[chemID] <= 0) + trace_chemicals.Remove(chemID) - //Bone fracurtes - if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT)) - src.fracture() - if(!(status & ORGAN_BROKEN)) - perma_injury = 0 + //Bone fractures + if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT)) + src.fracture() - //Infections - update_germs() + if(!(status & ORGAN_BROKEN)) + perma_injury = 0 + + //Infections + update_germs() + else + ..() //Updating germ levels. Handles organ germ levels and necrosis. /* @@ -341,7 +414,7 @@ INFECTION_LEVEL_THREE above this germ level the player will take additional toxi Note that amputating the affected organ does in fact remove the infection from the player's body. */ -/datum/organ/external/proc/update_germs() +/obj/item/organ/external/proc/update_germs() if(status & (ORGAN_ROBOT|ORGAN_DESTROYED) || (owner.species && owner.species.flags & IS_PLANT)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. germ_level = 0 @@ -357,7 +430,7 @@ Note that amputating the affected organ does in fact remove the infection from t //** Handle the effects of infections handle_germ_effects() -/datum/organ/external/proc/handle_germ_sync() +/obj/item/organ/external/proc/handle_germ_sync() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") for(var/datum/wound/W in wounds) //Open wounds can become infected @@ -371,29 +444,17 @@ Note that amputating the affected organ does in fact remove the infection from t germ_level++ break //limit increase to a maximum of one per second -/datum/organ/external/proc/handle_germ_effects() +/obj/item/organ/external/handle_germ_effects() + + if(germ_level < INFECTION_LEVEL_TWO) + return ..() + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE && prob(60)) //this could be an else clause, but it looks cleaner this way - germ_level-- //since germ_level increases at a rate of 1 per second with dirty wounds, prob(60) should give us about 5 minutes before level one. - - if(germ_level >= INFECTION_LEVEL_ONE) - //having an infection raises your body temperature - var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature - //need to make sure we raise temperature fast enough to get around environmental cooling preventing us from reaching fever_temperature - owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) - - if(prob(round(germ_level/10))) - if (antibiotics < 5) - germ_level++ - - if (prob(10)) //adjust this to tweak how fast people take toxin damage from infections - owner.adjustToxLoss(1) - - if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < 5) + if(germ_level >= INFECTION_LEVEL_TWO) //spread the infection to internal organs - var/datum/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once - for (var/datum/organ/internal/I in internal_organs) + var/obj/item/organ/target_organ = null //make internal organs become infected one at a time instead of all at once + for (var/obj/item/organ/I in internal_organs) if (I.germ_level > 0 && I.germ_level < min(germ_level, INFECTION_LEVEL_TWO)) //once the organ reaches whatever we can give it, or level two, switch to a different one if (!target_organ || I.germ_level > target_organ.germ_level) //choose the organ with the highest germ_level target_organ = I @@ -401,9 +462,9 @@ Note that amputating the affected organ does in fact remove the infection from t if (!target_organ) //figure out which organs we can spread germs to and pick one at random var/list/candidate_organs = list() - for (var/datum/organ/internal/I in internal_organs) + for (var/obj/item/organ/I in internal_organs) if (I.germ_level < germ_level) - candidate_organs += I + candidate_organs |= I if (candidate_organs.len) target_organ = pick(candidate_organs) @@ -412,7 +473,7 @@ Note that amputating the affected organ does in fact remove the infection from t //spread the infection to child and parent organs if (children) - for (var/datum/organ/external/child in children) + for (var/obj/item/organ/external/child in children) if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT)) if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) child.germ_level++ @@ -425,14 +486,14 @@ Note that amputating the affected organ does in fact remove the infection from t if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections if (!(status & ORGAN_DEAD)) status |= ORGAN_DEAD - owner << "You can't feel your [display_name] anymore..." + owner << "You can't feel your [name] anymore..." owner.update_body(1) germ_level++ owner.adjustToxLoss(1) //Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections -/datum/organ/external/proc/update_wounds() +/obj/item/organ/external/proc/update_wounds() if((status & ORGAN_ROBOT)) //Robotic limbs don't heal or get worse. return @@ -455,7 +516,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.vessel.remove_reagent("blood", wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place. if(prob(1 * wound_update_accuracy)) - owner.custom_pain("You feel a stabbing pain in your [display_name]!",1) + owner.custom_pain("You feel a stabbing pain in your [name]!",1) // slow healing var/heal_amt = 0 @@ -485,7 +546,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.UpdateDamageIcon(1) //Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status. -/datum/organ/external/proc/update_damages() +/obj/item/organ/external/proc/update_damages() number_wounds = 0 brute_dam = 0 burn_dam = 0 @@ -517,7 +578,7 @@ Note that amputating the affected organ does in fact remove the infection from t // new damage icon system // adjusted to set damage_state to brute/burn code only (without r_name0 as before) -/datum/organ/external/proc/update_icon() +/obj/item/organ/external/update_icon() var/n_is = damage_state_text() if (n_is != damage_state) damage_state = n_is @@ -526,7 +587,7 @@ Note that amputating the affected organ does in fact remove the infection from t // new damage icon system // returns just the brute/burn damage code -/datum/organ/external/proc/damage_state_text() +/obj/item/organ/external/proc/damage_state_text() if(status & ORGAN_DESTROYED) return "--" @@ -556,127 +617,104 @@ Note that amputating the affected organ does in fact remove the infection from t DISMEMBERMENT ****************************************************/ -//Recursive setting of all child organs to amputated -/datum/organ/external/proc/setAmputatedTree() - for(var/datum/organ/external/O in children) - O.amputated=amputated - O.setAmputatedTree() - //Handles dismemberment -/datum/organ/external/proc/droplimb(var/override = 0,var/no_explode = 0,var/amputation=0) - if(destspawn) return - if(override) - status |= ORGAN_DESTROYED - if(status & ORGAN_DESTROYED) - if(body_part == UPPER_TORSO) - return +/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children) - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_DEAD - for(var/implant in implants) - del(implant) + if(cannot_amputate || !owner) + return - germ_level = 0 + if(!disintegrate) + disintegrate = DROPLIMB_EDGE - // If any organs are attached to this, destroy them - for(var/datum/organ/external/O in children) - O.droplimb(1, no_explode, amputation) + switch(disintegrate) + if(DROPLIMB_EDGE) + if(!clean) + owner.visible_message( + "\The [owner]'s [src.name] flies off in an arc!",\ + "Your [src.name] goes flying off!",\ + "You hear a terrible sound of ripping tendons and flesh.") + if(DROPLIMB_BURN) + owner.visible_message( + "\The [owner]'s [src.name] flashes away into ashes!",\ + "Your [src.name] flashes away into ashes!",\ + "You hear the crackling sound of burning flesh.") + if(DROPLIMB_BLUNT) + owner.visible_message( + "\The [owner]'s [src.name] explodes in a shower of gore!",\ + "Your [src.name] explodes in a shower of gore!",\ + "You hear the sickening splatter of gore.") - //Replace all wounds on that arm with one wound on parent organ. - wounds.Cut() - if (parent && !amputation) - var/datum/wound/W - if(max_damage < 50) - W = new/datum/wound/lost_limb/small(max_damage) - else - W = new/datum/wound/lost_limb(max_damage) - parent.wounds += W + src.removed(null, ignore_children) + owner.traumatic_shock += 60 + + wounds.Cut() + if(parent) + var/datum/wound/W + if(max_damage < 50) + W = new/datum/wound/lost_limb/small(max_damage) + else + W = new/datum/wound/lost_limb(max_damage) + parent.children -= src + if(clean) + parent.wounds |= W parent.update_damages() - update_damages() + else + var/obj/item/organ/external/stump/stump = new (owner, 0, src) + stump.wounds |= W + owner.organs |= stump + stump.update_damages() + parent = null - var/obj/organ //Dropped limb object - var/list/dropped_items - switch(body_part) - if(HEAD) - organ = new /obj/item/weapon/organ/head(owner.loc, owner) - dropped_items = list(owner.glasses, owner.head, owner.l_ear, owner.r_ear, owner.wear_mask) - if(ARM_RIGHT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/r_arm(owner.loc) - else - organ= new /obj/item/weapon/organ/r_arm(owner.loc, owner) - if(ARM_LEFT) - if(status & ORGAN_ROBOT) - organ= new /obj/item/robot_parts/l_arm(owner.loc) - else - organ= new /obj/item/weapon/organ/l_arm(owner.loc, owner) - if(LEG_RIGHT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/r_leg(owner.loc) - else - organ= new /obj/item/weapon/organ/r_leg(owner.loc, owner) - if(LEG_LEFT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/l_leg(owner.loc) - else - organ= new /obj/item/weapon/organ/l_leg(owner.loc, owner) - if(HAND_RIGHT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/r_hand(owner.loc, owner) - dropped_items = list(owner.gloves) //should probably make it so that you can still wear gloves if you have one hand - if(HAND_LEFT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/l_hand(owner.loc, owner) - dropped_items = list(owner.gloves) - if(FOOT_RIGHT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/r_foot/(owner.loc, owner) - dropped_items = list(owner.shoes) - if(FOOT_LEFT) - if(!(status & ORGAN_ROBOT)) - organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner) - dropped_items = list(owner.shoes) - if(dropped_items) - for(var/obj/O in dropped_items) - owner.remove_from_mob(O) + spawn(1) + owner.update_body() + owner.updatehealth() + owner.UpdateDamageIcon() + dir = 2 - destspawn = 1 - //Robotic limbs explode if sabotaged. - if(status & ORGAN_ROBOT && !no_explode && sabotaged) - owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\ - "\red Your [display_name] explodes!",\ - "You hear an explosion!") - explosion(get_turf(owner),-1,-1,2,3) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, owner) - spark_system.attach(owner) - spark_system.start() - spawn(10) - del(spark_system) + switch(disintegrate) + if(DROPLIMB_EDGE) + compile_icon() + add_blood(owner) + var/matrix/M = matrix() + M.Turn(rand(180)) + src.transform = M + if(!clean) + // Throw limb around. + if(src && istype(loc,/turf)) + throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) + dir = 2 + return + if(DROPLIMB_BURN) + new /obj/effect/decal/cleanable/ash(get_turf(owner)) + if(DROPLIMB_BLUNT) + var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(owner)) + if(owner.species.flesh_color) + gore.fleshcolor = owner.species.flesh_color + if(owner.species.blood_color) + gore.basecolor = owner.species.blood_color + gore.update_icon() + gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\ - "Your [display_name] goes flying off!",\ - "You hear a terrible sound of ripping tendons and flesh.") + for(var/obj/item/organ/I in internal_organs) + I.removed() + if(istype(loc,/turf)) + I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - //Throw organs around - if(istype(owner.loc,/turf) && organ) - step(organ,pick(cardinal)) - - owner.update_body(1) - - // OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom! - release_restraints() - - if(vital) - owner.death() + del(src) /**************************************************** HELPERS ****************************************************/ -/datum/organ/external/proc/release_restraints() +/obj/item/organ/external/proc/is_stump() + return 0 + +/obj/item/organ/external/replaced() + get_icon() + icon = mob_icon + return ..() + +/obj/item/organ/external/proc/release_restraints() if (owner.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT)) owner.visible_message(\ "\The [owner.handcuffed.name] falls off of [owner.name].",\ @@ -691,7 +729,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.drop_from_inventory(owner.legcuffed) -/datum/organ/external/proc/bandage() +/obj/item/organ/external/proc/bandage() var/rval = 0 src.status &= ~ORGAN_BLEEDING for(var/datum/wound/W in wounds) @@ -700,7 +738,7 @@ Note that amputating the affected organ does in fact remove the infection from t W.bandaged = 1 return rval -/datum/organ/external/proc/disinfect() +/obj/item/organ/external/proc/disinfect() var/rval = 0 for(var/datum/wound/W in wounds) if(W.internal) continue @@ -709,7 +747,7 @@ Note that amputating the affected organ does in fact remove the infection from t W.germ_level = 0 return rval -/datum/organ/external/proc/clamp() +/obj/item/organ/external/proc/clamp() var/rval = 0 src.status &= ~ORGAN_BLEEDING for(var/datum/wound/W in wounds) @@ -718,21 +756,21 @@ Note that amputating the affected organ does in fact remove the infection from t W.clamped = 1 return rval -/datum/organ/external/proc/salve() +/obj/item/organ/external/proc/salve() var/rval = 0 for(var/datum/wound/W in wounds) rval |= !W.salved W.salved = 1 return rval -/datum/organ/external/proc/fracture() +/obj/item/organ/external/proc/fracture() - if(status & ORGAN_BROKEN) + if((status & ORGAN_BROKEN) || cannot_break) return owner.visible_message(\ "\red You hear a loud cracking sound coming from \the [owner].",\ - "\red Something feels like it shattered in your [display_name]!",\ + "\red Something feels like it shattered in your [name]!",\ "You hear a sickening crack.") if(owner.species && !(owner.species.flags & NO_PAIN)) @@ -760,12 +798,12 @@ Note that amputating the affected organ does in fact remove the infection from t if(isnull(suit.supporting_limbs)) return - owner << "You feel \the [suit] constrict about your [display_name], supporting it." + owner << "You feel \the [suit] constrict about your [name], supporting it." status |= ORGAN_SPLINTED suit.supporting_limbs |= src return -/datum/organ/external/proc/mend_fracture() +/obj/item/organ/external/proc/mend_fracture() if(status & ORGAN_ROBOT) return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs if(brute_dam > min_broken_damage * config.organ_health_multiplier) @@ -774,75 +812,50 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -/datum/organ/external/proc/robotize() - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_CUT_AWAY - src.status &= ~ORGAN_ATTACHABLE - src.status &= ~ORGAN_DESTROYED - src.status |= ORGAN_ROBOT - src.destspawn = 0 - for (var/datum/organ/external/T in children) +/obj/item/organ/external/robotize(var/company) + ..() + + if(company) + model = company + var/datum/robolimb/R = all_robolimbs[company] + if(R) + force_icon = R.icon + name = "[R.company] [initial(name)]" + desc = "[R.desc]" + + dislocated = -1 + cannot_break = 1 + get_icon() + for (var/obj/item/organ/external/T in children) if(T) T.robotize() -/datum/organ/external/proc/mutate() +/obj/item/organ/external/proc/mutate() src.status |= ORGAN_MUTATED owner.update_body() -/datum/organ/external/proc/unmutate() +/obj/item/organ/external/proc/unmutate() src.status &= ~ORGAN_MUTATED owner.update_body() -/datum/organ/external/proc/get_damage() //returns total damage +/obj/item/organ/external/proc/get_damage() //returns total damage return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? -/datum/organ/external/proc/has_infected_wound() +/obj/item/organ/external/proc/has_infected_wound() for(var/datum/wound/W in wounds) if(W.germ_level > INFECTION_LEVEL_ONE) return 1 return 0 -/datum/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon,gender="") - if (status & ORGAN_ROBOT && !(owner.species && owner.species.flags & IS_SYNTHETIC)) - return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]") - - if (status & ORGAN_MUTATED) - return new /icon(deform_icon, "[icon_name][gender ? "_[gender]" : ""]") - - return new /icon(race_icon, "[icon_name][gender ? "_[gender]" : ""]") - - -/datum/organ/external/proc/is_usable() +/obj/item/organ/external/proc/is_usable() return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) -/datum/organ/external/proc/is_broken() - return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)) +/obj/item/organ/external/proc/is_malfunctioning() + return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam)) -/datum/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam)) - -//for arms and hands -/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name) - if (!c_hand) +/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) + if(loc != owner) return - - if(is_broken()) - owner.u_equip(c_hand) - var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [hand_name]!") - if(is_malfunctioning()) - owner.u_equip(c_hand) - owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!") - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, owner) - spark_system.attach(owner) - spark_system.start() - spawn(10) - del(spark_system) - -/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) if(!silent) owner.visible_message("\The [W] sticks in the wound!") implants += W @@ -854,135 +867,211 @@ Note that amputating the affected organ does in fact remove the infection from t H.drop_item() W.loc = owner +/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children) + + var/is_robotic = status & ORGAN_ROBOT + ..() + + status |= ORGAN_DESTROYED + owner.bad_external_organs -= src + + for(var/implant in implants) //todo: check if this can be left alone + del(implant) + + // Attached organs also fly off. + if(!ignore_children) + for(var/obj/item/organ/external/O in children) + O.removed() + if(O) + O.loc = src + + // Grab all the internal giblets too. + for(var/obj/item/organ/organ in internal_organs) + organ.removed() + organ.loc = src + + release_restraints() + owner.organs -= src + owner.organs_by_name[limb_name] = null // Remove from owner's vars. + + //Robotic limbs explode if sabotaged. + if(is_robotic && sabotaged) + owner.visible_message( + "\The [owner]'s [src.name] explodes violently!",\ + "Your [src.name] explodes!",\ + "You hear an explosion!") + explosion(get_turf(owner),-1,-1,2,3) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, owner) + spark_system.attach(owner) + spark_system.start() + spawn(10) + del(spark_system) + del(src) + +/obj/item/organ/external/proc/disfigure(var/type = "brute") + if (disfigured) + return + if(type == "brute") + owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s [name].", \ + "\red Your [name] becomes a mangled mess!", \ + "\red You hear a sickening crack.") + else + owner.visible_message("\red \The [owner]'s [name] melts away, turning into mangled mess!", \ + "\red Your [name] melts away!", \ + "\red You hear a sickening sizzle.") + disfigured = 1 + /**************************************************** ORGAN DEFINES ****************************************************/ -/datum/organ/external/chest - name = "chest" +/obj/item/organ/external/chest + name = "upper body" + limb_name = "chest" icon_name = "torso" - display_name = "chest" - max_damage = 75 - min_broken_damage = 40 + health = 100 + min_broken_damage = 35 body_part = UPPER_TORSO vital = 1 - encased = "ribcage" + amputation_point = "spine" + joint = "neck" + dislocated = -1 + gendered_icon = 1 + cannot_amputate = 1 + parent_organ = null -/datum/organ/external/groin - name = "groin" +/obj/item/organ/external/groin + name = "lower body" + limb_name = "groin" icon_name = "groin" - display_name = "groin" - max_damage = 50 - min_broken_damage = 30 + health = 100 + min_broken_damage = 35 body_part = LOWER_TORSO vital = 1 + parent_organ = "chest" + amputation_point = "lumbar" + joint = "hip" + dislocated = -1 + gendered_icon = 1 -/datum/organ/external/l_arm - name = "l_arm" - display_name = "left arm" +/obj/item/organ/external/arm + limb_name = "l_arm" + name = "left arm" icon_name = "l_arm" - max_damage = 50 - min_broken_damage = 20 + health = 50 + min_broken_damage = 30 body_part = ARM_LEFT + parent_organ = "chest" + joint = "left elbow" + amputation_point = "left shoulder" + can_grasp = 1 - process() - ..() - process_grasp(owner.l_hand, "left hand") +/obj/item/organ/external/arm/right + limb_name = "r_arm" + name = "right arm" + icon_name = "r_arm" + body_part = ARM_RIGHT + joint = "right elbow" + amputation_point = "right shoulder" -/datum/organ/external/l_leg - name = "l_leg" - display_name = "left leg" +/obj/item/organ/external/leg + limb_name = "l_leg" + name = "left leg" icon_name = "l_leg" - max_damage = 50 - min_broken_damage = 20 + health = 50 + min_broken_damage = 30 body_part = LEG_LEFT icon_position = LEFT + parent_organ = "groin" + joint = "left knee" + amputation_point = "left hip" + can_stand = 1 -/datum/organ/external/r_arm - name = "r_arm" - display_name = "right arm" - icon_name = "r_arm" - max_damage = 50 - min_broken_damage = 20 - body_part = ARM_RIGHT - - process() - ..() - process_grasp(owner.r_hand, "right hand") - -/datum/organ/external/r_leg - name = "r_leg" - display_name = "right leg" +/obj/item/organ/external/leg/right + limb_name = "r_leg" + name = "right leg" icon_name = "r_leg" - max_damage = 50 - min_broken_damage = 20 body_part = LEG_RIGHT icon_position = RIGHT + joint = "right knee" + amputation_point = "right hip" -/datum/organ/external/l_foot - name = "l_foot" - display_name = "left foot" +/obj/item/organ/external/foot + limb_name = "l_foot" + name = "left foot" icon_name = "l_foot" - max_damage = 30 + health = 30 min_broken_damage = 15 body_part = FOOT_LEFT icon_position = LEFT + parent_organ = "l_leg" + joint = "left ankle" + amputation_point = "left ankle" + can_stand = 1 -/datum/organ/external/r_foot - name = "r_foot" - display_name = "right foot" +/obj/item/organ/external/foot/removed() + if(owner) owner.u_equip(owner.shoes) + ..() + +/obj/item/organ/external/foot/right + limb_name = "r_foot" + name = "right foot" icon_name = "r_foot" - max_damage = 30 - min_broken_damage = 15 body_part = FOOT_RIGHT icon_position = RIGHT + parent_organ = "r_leg" + joint = "right ankle" + amputation_point = "right ankle" -/datum/organ/external/r_hand - name = "r_hand" - display_name = "right hand" - icon_name = "r_hand" - max_damage = 30 - min_broken_damage = 15 - body_part = HAND_RIGHT - - process() - ..() - process_grasp(owner.r_hand, "right hand") - -/datum/organ/external/l_hand - name = "l_hand" - display_name = "left hand" +/obj/item/organ/external/hand + limb_name = "l_hand" + name = "left hand" icon_name = "l_hand" - max_damage = 30 + health = 30 min_broken_damage = 15 body_part = HAND_LEFT + parent_organ = "l_arm" + joint = "left wrist" + amputation_point = "left wrist" + can_grasp = 1 - process() - ..() - process_grasp(owner.l_hand, "left hand") +/obj/item/organ/external/hand/removed() + owner.u_equip(owner.gloves) + ..() -/datum/organ/external/head - name = "head" +/obj/item/organ/external/hand/right + limb_name = "r_hand" + name = "right hand" + icon_name = "r_hand" + body_part = HAND_RIGHT + parent_organ = "r_arm" + joint = "right wrist" + amputation_point = "right wrist" + +/obj/item/organ/external/head + limb_name = "head" icon_name = "head" - display_name = "head" - max_damage = 75 - min_broken_damage = 40 + name = "head" + health = 75 + min_broken_damage = 35 body_part = HEAD - var/disfigured = 0 vital = 1 - encased = "skull" + parent_organ = "chest" + joint = "jaw" + amputation_point = "neck" + gendered_icon = 1 -/datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon) - if (!owner) - return ..() - var/g = "m" - if(owner.gender == FEMALE) g = "f" - if (status & ORGAN_MUTATED) - . = new /icon(deform_icon, "[icon_name]_[g]") - else - . = new /icon(race_icon, "[icon_name]_[g]") +/obj/item/organ/external/head/removed() + if(owner) + owner.u_equip(owner.glasses) + owner.u_equip(owner.head) + owner.u_equip(owner.l_ear) + owner.u_equip(owner.r_ear) + owner.u_equip(owner.wear_mask) + ..() -/datum/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) +/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) ..(brute, burn, sharp, edge, used_weapon, forbidden_limbs) if (!disfigured) if (brute_dam > 40) @@ -990,156 +1079,3 @@ Note that amputating the affected organ does in fact remove the infection from t disfigure("brute") if (burn_dam > 40) disfigure("burn") - -/datum/organ/external/head/proc/disfigure(var/type = "brute") - if (disfigured) - return - if(type == "brute") - owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s face.", \ - "\red Your face becomes unrecognizible mangled mess!", \ - "\red You hear a sickening crack.") - else - owner.visible_message("\red [owner]'s face melts away, turning into mangled mess!", \ - "\red Your face melts off!", \ - "\red You hear a sickening sizzle.") - disfigured = 1 - -/**************************************************** - EXTERNAL ORGAN ITEMS -****************************************************/ - -obj/item/weapon/organ - icon = 'icons/mob/human_races/r_human.dmi' - var/op_stage = 0 - var/list/organs_internal = list() - -obj/item/weapon/organ/New(loc, mob/living/carbon/human/H) - ..(loc) - if(!istype(H)) - return - if(H.dna) - if(!blood_DNA) - blood_DNA = list() - blood_DNA[H.dna.unique_enzymes] = H.dna.b_type - - // Transferring over organs from the host. - for(var/datum/organ/internal/I in H.internal_organs) - if(I.parent_organ != name) - continue - var/obj/item/organ/current_organ = I.remove() - current_organ.removed(H) - current_organ.loc = src - if(current_organ.organ_data) - organs_internal |= current_organ.organ_data - - // Forming icon for the limb - // Setting base icon for this mob's race - var/icon/base - if(H.species && H.species.icobase) - base = icon(H.species.icobase) - else - base = icon('icons/mob/human_races/r_human.dmi') - - if(base) - //Changing limb's skin tone to match owner - if(!H.species || H.species.flags & HAS_SKIN_TONE) - if (H.s_tone >= 0) - base.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) - else - base.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) - - if(base) - //Changing limb's skin color to match owner - if(!H.species || H.species.flags & HAS_SKIN_COLOR) - base.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) - - icon = base - set_dir(SOUTH) - src.transform = turn(src.transform, rand(70,130)) - - -/**************************************************** - EXTERNAL ORGAN ITEMS DEFINES -****************************************************/ - -obj/item/weapon/organ/l_arm - name = "left arm" - icon_state = "l_arm" -obj/item/weapon/organ/l_foot - name = "left foot" - icon_state = "l_foot" -obj/item/weapon/organ/l_hand - name = "left hand" - icon_state = "l_hand" -obj/item/weapon/organ/l_leg - name = "left leg" - icon_state = "l_leg" -obj/item/weapon/organ/r_arm - name = "right arm" - icon_state = "r_arm" -obj/item/weapon/organ/r_foot - name = "right foot" - icon_state = "r_foot" -obj/item/weapon/organ/r_hand - name = "right hand" - icon_state = "r_hand" -obj/item/weapon/organ/r_leg - name = "right leg" - icon_state = "r_leg" -obj/item/weapon/organ/head - name = "head" - icon_state = "head_m" - -obj/item/weapon/organ/head/New(loc, mob/living/carbon/human/H) - if(istype(H)) - src.icon_state = H.gender == MALE? "head_m" : "head_f" - ..() - //Add (facial) hair. - if(H.f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] - if(facial_hair_style) - var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(facial_hair_style.do_colouration) - facial.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) - - overlays.Add(facial) // icon.Blend(facial, ICON_OVERLAY) - - if(H.h_style && !(H.head && (H.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] - if(hair_style) - var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(hair_style.do_colouration) - hair.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) - - overlays.Add(hair) //icon.Blend(hair, ICON_OVERLAY) - - name = "[H.real_name]'s head" - H.regenerate_icons() - -obj/item/weapon/organ/attackby(obj/item/weapon/W as obj, mob/user as mob) - switch(op_stage) - if(0) - if(istype(W,/obj/item/weapon/scalpel)) - user.visible_message("[user] cuts [src] open with [W]!") - op_stage++ - return - if(1) - if(istype(W,/obj/item/weapon/retractor)) - user.visible_message("[user] cracks [src] open like an egg with [W]!") - op_stage++ - return - if(2) - if(istype(W,/obj/item/weapon/hemostat)) - if(contents.len) - var/obj/item/removing = pick(contents) - removing.loc = get_turf(user.loc) - if(!(user.l_hand && user.r_hand)) - user.put_in_hands(removing) - if(istype(removing,/obj/item/organ)) - var/obj/item/organ/removed_organ = removing - organs_internal -= removed_organ.organ_data - user.visible_message("[user] extracts [removing] from [src] with [W]!") - else - user.visible_message("[user] fishes around fruitlessly in [src] with [W].") - return - ..() \ No newline at end of file diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm new file mode 100644 index 00000000000..d5b6bf2a4e1 --- /dev/null +++ b/code/modules/organs/organ_icon.dm @@ -0,0 +1,111 @@ +var/global/list/limb_icon_cache = list() + +/obj/item/organ/external/set_dir() + return + +/obj/item/organ/external/proc/compile_icon() + overlays.Cut() + get_icon() + // This is a kludge, only one icon has more than one generation of children though. + for(var/obj/item/organ/external/organ in contents) + if(organ.children && organ.children.len) + for(var/obj/item/organ/external/child in organ.children) + overlays += child.get_icon() + overlays += organ.get_icon() + +/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) + s_tone = null + s_col = null + if(human.s_tone && (human.species.flags & HAS_SKIN_TONE)) + s_tone = human.s_tone + if(human.species.flags & HAS_SKIN_COLOR) + s_col = list(human.r_skin, human.g_skin, human.b_skin) + +/obj/item/organ/external/proc/get_icon(var/skeletal) + + var/gender + if(force_icon) + mob_icon = new /icon(force_icon, "[icon_name]") + else + if(!owner) + mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]") + else + + if(gendered_icon) + if(owner.gender == FEMALE) + gender = "f" + else + gender = "m" + + if(skeletal) + mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]") + else if ((status & ORGAN_ROBOT) && !(owner.species && owner.species.flags & IS_SYNTHETIC)) + mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]") + else + if (status & ORGAN_MUTATED) + mob_icon = new /icon(owner.species.deform, "[icon_name][gender ? "_[gender]" : ""]") + else + mob_icon = new /icon(owner.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) + + dir = EAST + icon = mob_icon + + return mob_icon + +/obj/item/organ/external/head/get_icon(var/skeletal) + + if(skeletal || !owner) + return + + ..() + + if(owner.species.has_organ["eyes"]) + var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] + if(eyes && owner.species.eyes) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes) + eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) + mob_icon.Blend(eyes_icon, ICON_OVERLAY) + + if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS))) + mob_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s"), ICON_OVERLAY) + + if(owner.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] + if(facial_hair_style) + var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(facial_hair_style.do_colouration) + facial.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) + mob_icon.Blend(facial, ICON_OVERLAY) + + if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) + var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] + if(hair_style) + var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + if(hair_style.do_colouration) + hair.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD) + + mob_icon.Blend(hair, ICON_OVERLAY) + + icon = mob_icon + return mob_icon + +// 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() + var/n_is = damage_state_text() + if (n_is != damage_state) + damage_state = n_is + return 1 + return 0 diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index b6154242b9a..c552631abfd 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -1,296 +1,191 @@ #define PROCESS_ACCURACY 10 -/**************************************************** - INTERNAL ORGANS -****************************************************/ - -/mob/living/carbon/var/list/internal_organs = list() - -/datum/organ/internal - var/damage = 0 // amount of damage to the organ - var/min_bruised_damage = 10 - var/min_broken_damage = 30 - var/parent_organ = "chest" - var/robotic = 0 //For being a robot - var/removed_type //When removed, forms this object. - var/rejecting // Is this organ already being rejected? - var/obj/item/organ/organ_holder // If not in a body, held in this item. - var/list/transplant_data - -/datum/organ/internal/proc/rejuvenate() - damage=0 - -/datum/organ/internal/proc/is_bruised() - return damage >= min_bruised_damage - -/datum/organ/internal/proc/is_broken() - return damage >= min_broken_damage || status & ORGAN_CUT_AWAY - -/datum/organ/internal/New(mob/living/carbon/M) - ..() - if(M && istype(M)) - - M.internal_organs |= src - src.owner = M - - var/mob/living/carbon/human/H = M - if(istype(H)) - var/datum/organ/external/E = H.organs_by_name[src.parent_organ] - if(E.internal_organs == null) - E.internal_organs = list() - E.internal_organs |= src - -/datum/organ/internal/process() - - //Process infections - if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT)) //TODO make robotic internal and external organs separate types of organ instead of a flag - germ_level = 0 - return - - if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs - //** Handle antibiotics and curing infections - handle_antibiotics() - - //** Handle the effects of infections - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - - if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) - germ_level-- - - if (germ_level >= INFECTION_LEVEL_ONE/2) - //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes - if(antibiotics < 5 && prob(round(germ_level/6))) - germ_level++ - - if (germ_level >= INFECTION_LEVEL_TWO) - var/datum/organ/external/parent = owner.get_organ(parent_organ) - //spread germs - if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) - parent.germ_level++ - - if (prob(3)) //about once every 30 seconds - take_damage(1,silent=prob(30)) - - // Process unsuitable transplants. TODO: consider some kind of - // immunosuppressant that changes transplant data to make it match. - if(transplant_data) - if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"])) - rejecting = 1 - else - rejecting++ //Rejection severity increases over time. - if(rejecting % 10 == 0) //Only fire every ten rejection ticks. - switch(rejecting) - if(1 to 50) - take_damage(1) - if(51 to 200) - owner.reagents.add_reagent("toxin", 1) - take_damage(1) - if(201 to 500) - take_damage(rand(2,3)) - owner.reagents.add_reagent("toxin", 2) - if(501 to INFINITY) - take_damage(4) - owner.reagents.add_reagent("toxin", rand(3,5)) - -/datum/organ/internal/proc/take_damage(amount, var/silent=0) - if(src.robotic == 2) - src.damage += (amount * 0.8) - else - src.damage += amount - - var/datum/organ/external/parent = owner.get_organ(parent_organ) - if (!silent) - owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1) - -/datum/organ/internal/proc/emp_act(severity) - switch(robotic) - if(0) - return - if(1) - switch (severity) - if (1.0) - take_damage(20,0) - return - if (2.0) - take_damage(7,0) - return - if(3.0) - take_damage(3,0) - return - if(2) - switch (severity) - if (1.0) - take_damage(40,0) - return - if (2.0) - take_damage(15,0) - return - if(3.0) - take_damage(10,0) - return - -/datum/organ/internal/proc/mechanize() //Being used to make robutt hearts, etc - robotic = 2 - -/datum/organ/internal/proc/mechassist() //Used to add things like pacemakers, etc - robotic = 1 - min_bruised_damage = 15 - min_broken_damage = 35 - /**************************************************** INTERNAL ORGANS DEFINES ****************************************************/ -/datum/organ/internal/heart // This is not set to vital because death immediately occurs in blood.dm if it is removed. + +// Brain is defined in brain_item.dm. +/obj/item/organ/heart name = "heart" + icon_state = "heart-on" + organ_tag = "heart" parent_organ = "chest" - removed_type = /obj/item/organ/heart -/datum/organ/internal/lungs +/obj/item/organ/lungs name = "lungs" + icon_state = "lungs" + gender = PLURAL + organ_tag = "lungs" parent_organ = "chest" - removed_type = /obj/item/organ/lungs - process() - ..() - if (germ_level > INFECTION_LEVEL_ONE) - if(prob(5)) - owner.emote("cough") //respitory tract infection +/obj/item/organ/lungs/process() + ..() - if(is_bruised()) - if(prob(2)) - spawn owner.emote("me", 1, "coughs up blood!") - owner.drip(10) - if(prob(4)) - spawn owner.emote("me", 1, "gasps for air!") - owner.losebreath += 15 + if(!owner) + return -/datum/organ/internal/liver - name = "liver" - parent_organ = "chest" - removed_type = /obj/item/organ/liver + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(5)) + owner.emote("cough") //respitory tract infection - process() + if(is_bruised()) + if(prob(2)) + spawn owner.emote("me", 1, "coughs up blood!") + owner.drip(10) + if(prob(4)) + spawn owner.emote("me", 1, "gasps for air!") + owner.losebreath += 15 - ..() - - if (germ_level > INFECTION_LEVEL_ONE) - if(prob(1)) - owner << "\red Your skin itches." - if (germ_level > INFECTION_LEVEL_TWO) - if(prob(1)) - spawn owner.vomit() - - if(owner.life_tick % PROCESS_ACCURACY == 0) - - //High toxins levels are dangerous - if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin")) - //Healthy liver suffers on its own - if (src.damage < min_broken_damage) - src.damage += 0.2 * PROCESS_ACCURACY - //Damaged one shares the fun - else - var/datum/organ/internal/O = pick(owner.internal_organs) - if(O) - O.damage += 0.2 * PROCESS_ACCURACY - - //Detox can heal small amounts of damage - if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin")) - src.damage -= 0.2 * PROCESS_ACCURACY - - if(src.damage < 0) - src.damage = 0 - - // Get the effectiveness of the liver. - var/filter_effect = 3 - if(is_bruised()) - filter_effect -= 1 - if(is_broken()) - filter_effect -= 2 - - // Do some reagent filtering/processing. - for(var/datum/reagent/R in owner.reagents.reagent_list) - // Damaged liver means some chemicals are very dangerous - // The liver is also responsible for clearing out alcohol and toxins. - // Ethanol and all drinks are bad.K - if(istype(R, /datum/reagent/ethanol)) - if(filter_effect < 3) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect) - // Can't cope with toxins at all - else if(istype(R, /datum/reagent/toxin)) - if(filter_effect < 3) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) - owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect) - -/datum/organ/internal/kidney +/obj/item/organ/kidneys name = "kidneys" + icon_state = "kidneys" + gender = PLURAL + organ_tag = "kidneys" parent_organ = "groin" - removed_type = /obj/item/organ/kidneys - process() +/obj/item/organ/kidney/process() - ..() + ..() - // Coffee is really bad for you with busted kidneys. - // This should probably be expanded in some way, but fucked if I know - // what else kidneys can process in our reagent list. - var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list - if(coffee) - if(is_bruised()) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - else if(is_broken()) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + if(!owner) + return -/datum/organ/internal/brain - name = "brain" - parent_organ = "head" - removed_type = /obj/item/organ/brain - vital = 1 - -/datum/organ/internal/brain/xeno - removed_type = /obj/item/organ/brain/xeno - -/datum/organ/internal/brain/golem - name = "golem chem" - removed_type = /obj/item/organ/brain/golem - -/datum/organ/internal/brain/slime - name = "slime core" - removed_type = /obj/item/organ/brain/slime - -/datum/organ/internal/eyes - name = "eyes" - parent_organ = "head" - removed_type = /obj/item/organ/eyes - - process() //Eye damage replaces the old eye_stat var. - ..() + // Coffee is really bad for you with busted kidneys. + // This should probably be expanded in some way, but fucked if I know + // what else kidneys can process in our reagent list. + var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list + if(coffee) if(is_bruised()) - owner.eye_blurry = 20 + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + else if(is_broken()) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + + +/obj/item/organ/eyes + name = "eyeballs" + icon_state = "eyes" + gender = PLURAL + organ_tag = "eyes" + parent_organ = "head" + var/list/eye_colour = list(0,0,0) + +/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var. + ..() + if(!owner) + return + if(is_bruised()) + owner.eye_blurry = 20 + if(is_broken()) + owner.eye_blind = 20 + +/obj/item/organ/eyes/New() + ..() + if(owner) + eye_colour = list( + owner.r_eyes ? owner.r_eyes : 0, + owner.g_eyes ? owner.g_eyes : 0, + owner.b_eyes ? owner.b_eyes : 0 + ) + +/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user) + + if(!eye_colour) + eye_colour = list(0,0,0) + + ..() //Make sure target is set so we can steal their eye colour for later. + var/mob/living/carbon/human/H = target + if(istype(H)) + eye_colour = list( + H.r_eyes ? H.r_eyes : 0, + H.g_eyes ? H.g_eyes : 0, + H.b_eyes ? H.b_eyes : 0 + ) + + // Leave bloody red pits behind! + H.r_eyes = 128 + H.g_eyes = 0 + H.b_eyes = 0 + H.update_body() + + +/obj/item/organ/liver + name = "liver" + icon_state = "liver" + organ_tag = "liver" + parent_organ = "chest" + +/obj/item/organ/liver/process() + + ..() + + if(!owner) + return + + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(1)) + owner << "\red Your skin itches." + if (germ_level > INFECTION_LEVEL_TWO) + if(prob(1)) + spawn owner.vomit() + + if(owner.life_tick % PROCESS_ACCURACY == 0) + + //High toxins levels are dangerous + if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin")) + //Healthy liver suffers on its own + if (src.damage < min_broken_damage) + src.damage += 0.2 * PROCESS_ACCURACY + //Damaged one shares the fun + else + var/obj/item/organ/O = pick(owner.internal_organs) + if(O) + O.damage += 0.2 * PROCESS_ACCURACY + + //Detox can heal small amounts of damage + if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin")) + src.damage -= 0.2 * PROCESS_ACCURACY + + if(src.damage < 0) + src.damage = 0 + + // Get the effectiveness of the liver. + var/filter_effect = 3 + if(is_bruised()) + filter_effect -= 1 if(is_broken()) - owner.eye_blind = 20 + filter_effect -= 2 -/datum/organ/internal/appendix + // Do some reagent filtering/processing. + for(var/datum/reagent/R in owner.reagents.reagent_list) + // Damaged liver means some chemicals are very dangerous + // The liver is also responsible for clearing out alcohol and toxins. + // Ethanol and all drinks are bad.K + if(istype(R, /datum/reagent/ethanol)) + if(filter_effect < 3) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect) + // Can't cope with toxins at all + else if(istype(R, /datum/reagent/toxin)) + if(filter_effect < 3) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect) + +/obj/item/organ/appendix name = "appendix" + icon_state = "appendix" parent_organ = "groin" - removed_type = /obj/item/organ/appendix -/datum/organ/internal/proc/remove(var/mob/user) +/obj/item/organ/appendix/removed() - if(!removed_type) return 0 + ..() - var/turf/target_loc - if(user) - target_loc = get_turf(user) - else - target_loc = get_turf(owner) + var/inflamed = 0 + for(var/datum/disease/appendicitis/appendicitis in owner.viruses) + inflamed = 1 + appendicitis.cure() + owner.resistances += appendicitis - var/obj/item/organ/removed_organ = new removed_type(target_loc) - - if(istype(removed_organ)) - removed_organ.organ_data = src - removed_organ.update() - organ_holder = removed_organ - - return removed_organ \ No newline at end of file + if(inflamed) + icon_state = "appendixinflamed" + name = "inflamed appendix" \ No newline at end of file diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm deleted file mode 100644 index 51e657a6f92..00000000000 --- a/code/modules/organs/organ_objects.dm +++ /dev/null @@ -1,275 +0,0 @@ -/obj/item/organ - name = "organ" - desc = "It looks like it probably just plopped out." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - - health = 100 // Process() ticks before death. - - var/fresh = 3 // Squirts of blood left in it. - var/dead_icon // Icon used when the organ dies. - var/robotic // Is the limb prosthetic? - var/organ_tag // What slot does it go in? - var/organ_type = /datum/organ/internal // Used to spawn the relevant organ data when produced via a machine or spawn(). - var/datum/organ/internal/organ_data // Stores info when removed. - var/prosthetic_name = "prosthetic organ" // Flavour string for robotic organ. - var/prosthetic_icon // Icon for robotic organ. - -/obj/item/organ/attack_self(mob/user as mob) - - // Convert it to an edible form, yum yum. - if(!robotic && user.a_intent == I_HELP && user.zone_sel.selecting == "mouth") - bitten(user) - return - -/obj/item/organ/New() - ..() - create_reagents(5) - if(!robotic) - processing_objects += src - spawn(1) - update() - -/obj/item/organ/Del() - if(!robotic) processing_objects -= src - ..() - -/obj/item/organ/process() - - if(robotic) - processing_objects -= src - return - - // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? - if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) - return - - if(fresh && prob(40)) - fresh-- - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list - blood_splatter(src,B,1) - - health -= rand(1,3) - if(health <= 0) - die() - -/obj/item/organ/proc/die() - name = "dead [initial(name)]" - if(dead_icon) icon_state = dead_icon - health = 0 - processing_objects -= src - //TODO: Grey out the icon state. - //TODO: Inject an organ with peridaxon to make it alive again. - -/obj/item/organ/proc/roboticize() - - robotic = (organ_data && organ_data.robotic) ? organ_data.robotic : 1 - - if(prosthetic_name) - name = prosthetic_name - - if(prosthetic_icon) - icon_state = prosthetic_icon - else - //TODO: convert to greyscale. - -/obj/item/organ/proc/update() - - if(!organ_data) - organ_data = new organ_type() - - if(robotic) - organ_data.robotic = robotic - - if(organ_data.robotic >= 2) - roboticize() - -// Brain is defined in brain_item.dm. -/obj/item/organ/heart - name = "heart" - icon_state = "heart-on" - prosthetic_name = "circulatory pump" - prosthetic_icon = "heart-prosthetic" - organ_tag = "heart" - fresh = 6 // Juicy. - dead_icon = "heart-off" - organ_type = /datum/organ/internal/heart - -/obj/item/organ/lungs - name = "lungs" - icon_state = "lungs" - gender = PLURAL - prosthetic_name = "gas exchange system" - prosthetic_icon = "lungs-prosthetic" - organ_tag = "lungs" - organ_type = /datum/organ/internal/lungs - -/obj/item/organ/kidneys - name = "kidneys" - icon_state = "kidneys" - gender = PLURAL - prosthetic_name = "prosthetic kidneys" - prosthetic_icon = "kidneys-prosthetic" - organ_tag = "kidneys" - organ_type = /datum/organ/internal/kidney - -/obj/item/organ/eyes - name = "eyeballs" - icon_state = "eyes" - gender = PLURAL - prosthetic_name = "visual prosthesis" - prosthetic_icon = "eyes-prosthetic" - organ_tag = "eyes" - organ_type = /datum/organ/internal/eyes - var/eye_colour - -/obj/item/organ/liver - name = "liver" - icon_state = "liver" - prosthetic_name = "toxin filter" - prosthetic_icon = "liver-prosthetic" - organ_tag = "liver" - organ_type = /datum/organ/internal/liver - -/obj/item/organ/appendix - name = "appendix" - icon_state = "appendix" - organ_tag = "appendix" - organ_type = /datum/organ/internal/appendix - -//These are here so they can be printed out via the fabricator. -/obj/item/organ/heart/prosthetic - robotic = 2 - -/obj/item/organ/lungs/prosthetic - robotic = 2 - -/obj/item/organ/kidneys/prosthetic - robotic = 2 - -/obj/item/organ/eyes/prosthetic - robotic = 2 - -/obj/item/organ/liver/prosthetic - robotic = 2 - -/obj/item/organ/appendix - name = "appendix" - -/obj/item/organ/proc/removed(var/mob/living/carbon/human/target,var/mob/living/user) - - if(!istype(target) || !organ_data) - return - - target.internal_organs_by_name[organ_tag] = null - target.internal_organs_by_name -= organ_tag - target.internal_organs -= organ_data - - var/datum/organ/external/affected = target.get_organ(organ_data.parent_organ) - affected.internal_organs -= organ_data - - loc = target.loc - organ_data.rejecting = null - var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list - if(!organ_blood || !organ_blood.data["blood_DNA"]) - target.vessel.trans_to(src, 5, 1, 1) - - if(target && user && organ_data.vital) - user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)])" - target.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])" - msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (JMP)") - target.death() - -/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user) - - ..() - - var/inflamed = 0 - for(var/datum/disease/appendicitis/appendicitis in target.viruses) - inflamed = 1 - appendicitis.cure() - target.resistances += appendicitis - - if(inflamed) - icon_state = "appendixinflamed" - name = "inflamed appendix" - -/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user) - - if(!eye_colour) - eye_colour = list(0,0,0) - - ..() //Make sure target is set so we can steal their eye colour for later. - var/mob/living/carbon/human/H = target - if(istype(H)) - eye_colour = list( - H.r_eyes ? H.r_eyes : 0, - H.g_eyes ? H.g_eyes : 0, - H.b_eyes ? H.b_eyes : 0 - ) - - // Leave bloody red pits behind! - H.r_eyes = 128 - H.g_eyes = 0 - H.b_eyes = 0 - H.update_body() - -/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/datum/organ/external/affected) - - if(!istype(target)) return - - var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list - if(!transplant_blood) - organ_data.transplant_data = list() - organ_data.transplant_data["species"] = target.species.name - organ_data.transplant_data["blood_type"] = target.dna.b_type - organ_data.transplant_data["blood_DNA"] = target.dna.unique_enzymes - else - organ_data.transplant_data = list() - organ_data.transplant_data["species"] = transplant_blood.data["species"] - organ_data.transplant_data["blood_type"] = transplant_blood.data["blood_type"] - organ_data.transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"] - - organ_data.organ_holder = null - organ_data.owner = target - target.internal_organs |= organ_data - affected.internal_organs |= organ_data - target.internal_organs_by_name[organ_tag] = organ_data - organ_data.status |= ORGAN_CUT_AWAY - - del(src) - -/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) - - // Apply our eye colour to the target. - if(istype(target) && eye_colour) - target.r_eyes = eye_colour[1] - target.g_eyes = eye_colour[2] - target.b_eyes = eye_colour[3] - target.update_body() - ..() - -/obj/item/organ/proc/bitten(mob/user) - - if(robotic) - return - - user << "\blue You take an experimental bite out of \the [src]." - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list - blood_splatter(src,B,1) - - - user.drop_from_inventory(src) - var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src)) - O.name = name - O.icon_state = dead_icon ? dead_icon : icon_state - - // Pass over the blood. - reagents.trans_to(O, reagents.total_volume) - - if(fingerprints) O.fingerprints = fingerprints.Copy() - if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy() - if(fingerprintslast) O.fingerprintslast = fingerprintslast - - user.put_in_active_hand(O) - del(src) \ No newline at end of file diff --git a/code/modules/organs/organ_stump.dm b/code/modules/organs/organ_stump.dm new file mode 100644 index 00000000000..c08363e10bd --- /dev/null +++ b/code/modules/organs/organ_stump.dm @@ -0,0 +1,24 @@ +/obj/item/organ/external/stump + name = "limb stump" + icon_name = "" + dislocated = -1 + cannot_amputate = 1 + +/obj/item/organ/external/stump/New(var/mob/living/carbon/holder, var/internal, var/obj/item/organ/external/limb) + if(istype(limb)) + limb_name = limb.limb_name + body_part = limb.body_part + amputation_point = limb.amputation_point + joint = limb.joint + parent_organ = limb.parent_organ + wounds = limb.wounds + ..(holder, internal) + if(istype(limb)) + max_damage = limb.max_damage + +/obj/item/organ/external/stump/is_stump() + return 1 + +/obj/item/organ/external/stump/removed() + ..() + del(src) diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm index 49cc2073df0..31cb0c4e434 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/organs/pain.dm @@ -87,10 +87,8 @@ mob/living/carbon/human/proc/handle_pain() if(analgesic) return var/maxdam = 0 - var/datum/organ/external/damaged_organ = null - for(var/datum/organ/external/E in organs) - // amputated limbs don't cause pain - if(E.amputated) continue + var/obj/item/organ/external/damaged_organ = null + for(var/obj/item/organ/external/E in organs) if(E.status & ORGAN_DEAD) continue var/dam = E.get_damage() // make the choice of the organ depend on damage, @@ -99,13 +97,13 @@ mob/living/carbon/human/proc/handle_pain() damaged_organ = E maxdam = dam if(damaged_organ) - pain(damaged_organ.display_name, maxdam, 0) + pain(damaged_organ.name, maxdam, 0) // Damage to internal organs hurts a lot. - for(var/datum/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) if(I.damage > 2) if(prob(2)) - var/datum/organ/external/parent = get_organ(I.parent_organ) - src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1) + var/obj/item/organ/external/parent = get_organ(I.parent_organ) + src.custom_pain("You feel a sharp pain in your [parent.name]", 1) var/toxDamageMessage = null var/toxMessageProb = 1 diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm new file mode 100644 index 00000000000..8d19d60b491 --- /dev/null +++ b/code/modules/organs/robolimbs.dm @@ -0,0 +1,37 @@ +var/global/list/all_robolimbs = list() +var/global/list/chargen_robolimbs = list() +var/global/datum/robolimb/basic_robolimb + +/proc/populate_robolimb_list() + basic_robolimb = new() + for(var/limb_type in typesof(/datum/robolimb)) + var/datum/robolimb/R = new limb_type() + all_robolimbs[R.company] = R + if(!R.unavailable_at_chargen) + chargen_robolimbs[R.company] = R + +/datum/robolimb + var/company = "Unbranded" // Shown when selecting the limb. + var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb. + var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from. + var/unavailable_at_chargen // If set, not available at chargen. + +/datum/robolimb/bishop + company = "Bishop Cybernetics" + desc = "This limb has a white polymer casing with blue holo-displays." + icon = 'icons/mob/human_races/cyberlimbs/bishop.dmi' + +/datum/robolimb/hesphaistos + company = "Hesphiastos Industries" + desc = "This limb has a militaristic black and green casing with gold stripes." + icon = 'icons/mob/human_races/cyberlimbs/hesphaistos.dmi' + +/datum/robolimb/zenghu + company = "Zeng-Hu Pharmaceuticals" + desc = "This limb has a rubbery fleshtone covering with visible seams." + icon = 'icons/mob/human_races/cyberlimbs/zenghu.dmi' + +/datum/robolimb/xion + company = "Xion Manufacturing Group" + desc = "This limb has a minimalist black and red casing." + icon = 'icons/mob/human_races/cyberlimbs/xion.dmi' diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 43ed04b0d0c..a2219b262a7 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -22,12 +22,13 @@ return /obj/item/weapon/paper_bin/attack_hand(mob/user as mob) - if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] - if (user.hand) - temp = user:organs_by_name["l_hand"] + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + if (H.hand) + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return var/response = "" if(!papers.len > 0) diff --git a/code/modules/power/antimatter/computer.dm b/code/modules/power/antimatter/computer.dm index 3a47ec7abf2..d531ccfb540 100644 --- a/code/modules/power/antimatter/computer.dm +++ b/code/modules/power/antimatter/computer.dm @@ -45,7 +45,7 @@ src.state = STATE_DEFAULT if("login") var/mob/M = usr - var/obj/item/weapon/card/id/I = M.equipped() + var/obj/item/weapon/card/id/I = M.get_active_hand() if (I && istype(I)) if(src.check_access(I)) authenticated = 1 diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 23c5e0243a6..b9f1075fa1b 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -171,10 +171,8 @@ user << "\red There is already a [fueljar] inside!" return fueljar = W + user.remove_from_mob(W) W.loc = src - if(user.client) - user.client.screen -= W - user.u_equip(W) user.update_icons() user.visible_message("[user.name] loads an [W.name] into the [src.name].", \ "You load an [W.name].", \ diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 4ce3d4ba3e5..f652ebe9ec6 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -516,8 +516,8 @@ obj/structure/cable/proc/cableColor(var/colorC) /obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob) if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) + var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) + if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help") return ..() if(H.species.flags & IS_SYNTHETIC) @@ -527,7 +527,7 @@ obj/structure/cable/proc/cableColor(var/colorC) if(S.burn_dam > 0 && use(1)) S.heal_damage(0,15,0,1) - user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].") + user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].") return else user << "Nothing to fix!" diff --git a/code/modules/power/cable.dm.orig b/code/modules/power/cable.dm.orig new file mode 100644 index 00000000000..8a4d25ae20a --- /dev/null +++ b/code/modules/power/cable.dm.orig @@ -0,0 +1,934 @@ +/////////////////////////////// +//CABLE STRUCTURE +/////////////////////////////// + + +//////////////////////////////// +// Definitions +//////////////////////////////// + +/* Cable directions (d1 and d2) + + + 9 1 5 + \ | / + 8 - 0 - 4 + / | \ + 10 2 6 + +If d1 = 0 and d2 = 0, there's no cable +If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to dir (knot cable) +If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2 +By design, d1 is the smallest direction and d2 is the highest +*/ + +/obj/structure/cable + level = 1 + anchored =1 + var/datum/powernet/powernet + name = "power cable" + desc = "A flexible superconducting cable for heavy-duty power transfer" + icon = 'icons/obj/power_cond_white.dmi' + icon_state = "0-1" + var/d1 = 0 + var/d2 = 1 + layer = 2.44 //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4 + color = COLOR_RED + var/obj/machinery/power/breakerbox/breaker_box + +/obj/structure/cable/drain_power(var/drain_check, var/surge, var/amount = 0) + + if(drain_check) + return 1 + + var/datum/powernet/PN = get_powernet() + if(!PN) return 0 + + return PN.draw_power(amount) + +/obj/structure/cable/yellow + color = COLOR_YELLOW + +/obj/structure/cable/green + color = COLOR_GREEN + +/obj/structure/cable/blue + color = COLOR_BLUE + +/obj/structure/cable/pink + color = COLOR_PINK + +/obj/structure/cable/orange + color = COLOR_ORANGE + +/obj/structure/cable/cyan + color = COLOR_CYAN + +/obj/structure/cable/white + color = COLOR_WHITE + +/obj/structure/cable/New() + ..() + + + // ensure d1 & d2 reflect the icon_state for entering and exiting cable + + var/dash = findtext(icon_state, "-") + + d1 = text2num( copytext( icon_state, 1, dash ) ) + + d2 = text2num( copytext( icon_state, dash+1 ) ) + + var/turf/T = src.loc // hide if turf is not intact + + if(level==1) hide(T.intact) + cable_list += src //add it to the global cable list + + +/obj/structure/cable/Del() // called when a cable is deleted + if(powernet) + cut_cable_from_powernet() // update the powernets + cable_list -= src //remove it from global cable list + ..() // then go ahead and delete the cable + +/////////////////////////////////// +// General procedures +/////////////////////////////////// + +//If underfloor, hide the cable +/obj/structure/cable/hide(var/i) + + if(level == 1 && istype(loc, /turf)) + invisibility = i ? 101 : 0 + updateicon() + +/obj/structure/cable/proc/updateicon() + icon_state = "[d1]-[d2]" + alpha = invisibility ? 127 : 255 + +// returns the powernet this cable belongs to +/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete + return powernet + +//Telekinesis has no effect on a cable +/obj/structure/cable/attack_tk(mob/user) + return + +// Items usable on a cable : +// - Wirecutters : cut it duh ! +// - Cable coil : merge cables +// - Multitool : get the power currently passing through the cable +// +/obj/structure/cable/attackby(obj/item/W, mob/user) + + var/turf/T = src.loc + if(T.intact) + return + + if(istype(W, /obj/item/weapon/wirecutters)) +///// Z-Level Stuff + if(src.d1 == 12 || src.d2 == 12) + user << "You must cut this cable from above." + return +///// Z-Level Stuff + if(breaker_box) + user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it." + return + + if (shock(user, 50)) + 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) + else + new/obj/item/stack/cable_coil(T, 1, color) + + for(var/mob/O in viewers(src, null)) + O.show_message("[user] cuts the cable.", 1) + +///// Z-Level Stuff + if(src.d1 == 11 || src.d2 == 11) + var/turf/controllerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) + if(controller.down) + var/turf/below = locate(src.x, src.y, controller.down_target) + for(var/obj/structure/cable/c in below) + if(c.d1 == 12 || c.d2 == 12) + c.Del() +///// Z-Level Stuff + investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires") + + del(src) // qdel + return + + + else if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = W + if (coil.get_amount() < 1) + user << "Not enough cable" + return + coil.cable_join(src, user) + + else if(istype(W, /obj/item/device/multitool)) + + if(powernet && (powernet.avail > 0)) // is it powered? + user << "[powernet.avail]W in power network." + + else + user << "The cable is not powered." + + shock(user, 5, 0.2) + + else + if (W.flags & CONDUCT) + shock(user, 50, 0.7) + + src.add_fingerprint(user) + +// shock the user with probability prb +/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0) + if(!prob(prb)) + return 0 + if (electrocute_mob(user, powernet, src, siemens_coeff)) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + if(usr.stunned) + return 1 + return 0 + +//explosion handling +/obj/structure/cable/ex_act(severity) + switch(severity) + if(1.0) + del(src) // qdel + if(2.0) + if (prob(50)) + new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + del(src) // qdel + + if(3.0) + if (prob(25)) + new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + del(src) // qdel + return + +obj/structure/cable/proc/cableColor(var/colorC) + var/color_n = "#DD0000" + if(colorC) + color_n = colorC + color = color_n + +///////////////////////////////////////////////// +// Cable laying helpers +//////////////////////////////////////////////// + +//handles merging diagonally matching cables +//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically +/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction) + + //search for and merge diagonally matching cables from the first direction component (north/south) + var/turf/T = get_step(src, direction&3)//go north/south + + for(var/obj/structure/cable/C in T) + + if(!C) + continue + + if(src == C) + continue + + if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable + if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables) + var/datum/powernet/newPN = new() + newPN.add_cable(C) + + if(powernet) //if we already have a powernet, then merge the two powernets + merge_powernets(powernet,C.powernet) + else + C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet + + //the same from the second direction component (east/west) + T = get_step(src, direction&12)//go east/west + + for(var/obj/structure/cable/C in T) + + if(!C) + continue + + if(src == C) + continue + if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable + if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables) + var/datum/powernet/newPN = new() + newPN.add_cable(C) + + if(powernet) //if we already have a powernet, then merge the two powernets + merge_powernets(powernet,C.powernet) + else + C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet + +// merge with the powernets of power objects in the given direction +/obj/structure/cable/proc/mergeConnectedNetworks(var/direction) + + var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf + + if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing + return + + var/turf/TB = get_step(src, direction) + + for(var/obj/structure/cable/C in TB) + + if(!C) + continue + + if(src == C) + continue + + if(C.d1 == fdir || C.d2 == fdir) //we've got a matching cable in the neighbor turf + if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables) + var/datum/powernet/newPN = new() + newPN.add_cable(C) + + if(powernet) //if we already have a powernet, then merge the two powernets + merge_powernets(powernet,C.powernet) + else + C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet + +// merge with the powernets of power objects in the source turf +/obj/structure/cable/proc/mergeConnectedNetworksOnTurf() + var/list/to_connect = list() + + if(!powernet) //if we somehow have no powernet, make one (should not happen for cables) + var/datum/powernet/newPN = new() + newPN.add_cable(src) + + //first let's add turf cables to our powernet + //then we'll connect machines on turf with a node cable is present + for(var/AM in loc) + if(istype(AM,/obj/structure/cable)) + var/obj/structure/cable/C = AM + if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction + if(C.powernet == powernet) continue + if(C.powernet) + merge_powernets(powernet, C.powernet) + else + powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet + + else if(istype(AM,/obj/machinery/power/apc)) + var/obj/machinery/power/apc/N = AM + if(!N.terminal) continue // APC are connected through their terminal + + if(N.terminal.powernet == powernet) + continue + + to_connect += N.terminal //we'll connect the machines after all cables are merged + + else if(istype(AM,/obj/machinery/power)) //other power machines + var/obj/machinery/power/M = AM + + if(M.powernet == powernet) + continue + + to_connect += M //we'll connect the machines after all cables are merged + + //now that cables are done, let's connect found machines + for(var/obj/machinery/power/PM in to_connect) + if(!PM.connect_to_network()) + PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless + +////////////////////////////////////////////// +// Powernets handling helpers +////////////////////////////////////////////// + +//if powernetless_only = 1, will only get connections without powernet +/obj/structure/cable/proc/get_connections(var/powernetless_only = 0) + . = list() // this will be a list of all connected power objects + var/turf/T + +///// Z-Level Stuff + if (d1 == 11 || d1 == 12) + var/turf/controllerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) + if(controller.up && d1 == 12) + T = locate(src.x, src.y, controller.up_target) + if(T) + . += power_list(T, src, 11, 1) + if(controller.down && d1 == 11) + T = locate(src.x, src.y, controller.down_target) + if(T) + . += power_list(T, src, 12, 1) +///// Z-Level Stuff + //get matching cables from the first direction + else if(d1) //if not a node cable + T = get_step(src, d1) + if(T) + . += power_list(T, src, turn(d1, 180), powernetless_only) //get adjacents matching cables + + if(d1&(d1-1)) //diagonal direction, must check the 4 possibles adjacents tiles + T = get_step(src,d1&3) // go north/south + if(T) + . += power_list(T, src, d1 ^ 3, powernetless_only) //get diagonally matching cables + T = get_step(src,d1&12) // go east/west + if(T) + . += power_list(T, src, d1 ^ 12, powernetless_only) //get diagonally matching cables + + . += power_list(loc, src, d1, powernetless_only) //get on turf matching cables + +///// Z-Level Stuff + if(d2 == 11 || d2 == 12) + var/turf/controllerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) + if(controller.up && d2 == 12) + T = locate(src.x, src.y, controller.up_target) + if(T) + . += power_list(T, src, 11, 1) + if(controller.down && d2 == 11) + T = locate(src.x, src.y, controller.down_target) + if(T) + . += power_list(T, src, 12, 1) +///// Z-Level Stuff + else + //do the same on the second direction (which can't be 0) + T = get_step(src, d2) + if(T) + . += power_list(T, src, turn(d2, 180), powernetless_only) //get adjacents matching cables + + if(d2&(d2-1)) //diagonal direction, must check the 4 possibles adjacents tiles + T = get_step(src,d2&3) // go north/south + if(T) + . += power_list(T, src, d2 ^ 3, powernetless_only) //get diagonally matching cables + T = get_step(src,d2&12) // go east/west + if(T) + . += power_list(T, src, d2 ^ 12, powernetless_only) //get diagonally matching cables + . += power_list(loc, src, d2, powernetless_only) //get on turf matching cables + + return . + +//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf. +//needed as this can, unlike other placements, disconnect cables +/obj/structure/cable/proc/denode() + var/turf/T1 = loc + if(!T1) return + + var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet + if(powerlist.len>0) + var/datum/powernet/PN = new() + propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable + + if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables + del(PN) // qdel + +// cut the cable's powernet at this cable and updates the powergrid +/obj/structure/cable/proc/cut_cable_from_powernet() + var/turf/T1 = loc + var/list/P_list + if(!T1) return + if(d1) + T1 = get_step(T1, d1) + P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable... + + P_list += power_list(loc, src, d1, 0, cable_only = 1)//... and on turf + + + if(P_list.len == 0)//if nothing in both list, then the cable was a lone cable, just delete it and its powernet + powernet.remove_cable(src) + + for(var/obj/machinery/power/P in T1)//check if it was powering a machine + if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to + P.disconnect_from_network() //remove from current network (and delete powernet) + return + + // remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist + loc = null + powernet.remove_cable(src) //remove the cut cable from its powernet + + var/datum/powernet/newPN = new()// creates a new powernet... + propagate_network(P_list[1], newPN)//... and propagates it to the other side of the cable + + // Disconnect machines connected to nodes + if(d1 == 0) // if we cut a node (O-X) cable + for(var/obj/machinery/power/P in T1) + if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to + P.disconnect_from_network() //remove from current network + +/////////////////////////////////////////////// +// The cable coil object, used for laying cable +/////////////////////////////////////////////// + +//////////////////////////////// +// Definitions +//////////////////////////////// + +#define MAXCOIL 30 + +/obj/item/stack/cable_coil + name = "cable coil" + icon = 'icons/obj/power.dmi' + icon_state = "coil" + amount = MAXCOIL + max_amount = MAXCOIL + color = COLOR_RED + //item_color = COLOR_RED Use regular "color" var instead. No need to have it duplicate in two vars. Causes confusion. + desc = "A coil of power cable." + throwforce = 10 + w_class = 2.0 + throw_speed = 2 + throw_range = 5 + matter = list("metal" = 50, "glass" = 20) + flags = CONDUCT + slot_flags = SLOT_BELT + item_state = "coil" + attack_verb = list("whipped", "lashed", "disciplined", "flogged") + +/obj/item/stack/cable_coil/cyborg + name = "cable coil synthesizer" + desc = "A device that makes cable." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(1) + stacktype = /obj/item/stack/cable_coil + +/obj/item/stack/cable_coil/suicide_act(mob/user) + if(locate(/obj/item/weapon/stool) in user.loc) + user.visible_message("[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.") + else + user.visible_message("[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.") + return(OXYLOSS) + +/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null) + ..() + src.amount = length + if (param_color) // It should be red by default, so only recolor it if parameter was specified. + color = param_color + pixel_x = rand(-2,2) + pixel_y = rand(-2,2) + update_icon() + update_wclass() + +/////////////////////////////////// +// General procedures +/////////////////////////////////// + +//you can use wires to heal robotics +/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob) + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M +<<<<<<< HEAD + var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting) + if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) +======= + var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) + if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help") +>>>>>>> d77010221cbd08f6373edebee25d727b6409413b + return ..() + + if(H.species.flags & IS_SYNTHETIC) + if(M == user) + user << "\red You can't repair damage to your own body - it's against OH&S." + return + + if(S.burn_dam > 0 && use(1)) + S.heal_damage(0,15,0,1) + user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].") + return + else + user << "Nothing to fix!" + + else + return ..() + + +/obj/item/stack/cable_coil/update_icon() + if (!color) + color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) + if(amount == 1) + icon_state = "coil1" + name = "cable piece" + else if(amount == 2) + icon_state = "coil2" + name = "cable piece" + else + icon_state = "coil" + name = "cable coil" + +/obj/item/stack/cable_coil/proc/update_wclass() + if(amount == 1) + w_class = 1.0 + else + w_class = 2.0 + +/obj/item/stack/cable_coil/examine(mob/user) + if(get_dist(src, user) > 1) + return + + if(get_amount() == 1) + user << "A short piece of power cable." + else if(get_amount() == 2) + user << "A piece of power cable." + else + user << "A coil of power cable. There are [get_amount()] lengths of cable in the coil." + + +/obj/item/stack/cable_coil/verb/make_restraint() + set name = "Make Cable Restraints" + set category = "Object" + var/mob/M = usr + + if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned) + if(!istype(usr.loc,/turf)) return + if(src.amount <= 14) + usr << "\red You need at least 15 lengths to make restraints!" + return + var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc) + B.color = color + usr << "You wind some cable together to make some restraints." + src.use(15) + else + usr << "\blue You cannot do that." + ..() + +/obj/item/stack/cable_coil/cyborg/verb/set_colour() + set name = "Change Colour" + set category = "Object" + + var/list/possible_colours = list ("Yellow", "Green", "Pink", "Blue", "Orange", "Cyan", "Red") + var/selected_type = input("Pick new colour.", "Cable Colour", null, null) as null|anything in possible_colours + + if(selected_type) + switch(selected_type) + if("Yellow") + color = COLOR_YELLOW + if("Green") + color = COLOR_GREEN + if("Pink") + color = COLOR_PINK + if("Blue") + color = COLOR_BLUE + if("Orange") + color = COLOR_ORANGE + if("Cyan") + color = COLOR_CYAN + else + color = COLOR_RED + usr << "You change your cable coil's colour to [selected_type]" + +// Items usable on a cable coil : +// - Wirecutters : cut them duh ! +// - Cable coil : merge cables +/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user) + ..() + if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1) + src.use(1) + new/obj/item/stack/cable_coil(user.loc, 1,color) + user << "You cut a piece off the cable coil." + src.update_icon() + return + else if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(C.get_amount() >= get_max_amount()) + user << "The coil is too long, you cannot add any more cable to it." + return + + if( (C.get_amount() + src.get_amount() <= get_max_amount()) ) + user << "You join the cable coils together." + C.give(src.get_amount()) // give it cable + src.use(src.get_amount()) // make sure this one cleans up right + return + + else + var/amt = get_max_amount() - C.get_amount() + user << "You transfer [amt] length\s of cable from one coil to the other." + C.give(amt) + src.use(amt) + return + +//remove cables from the stack +/* This is probably reduntant +/obj/item/stack/cable_coil/use(var/used) + if(src.amount < used) + return 0 + else if (src.amount == used) + if(ismob(loc)) //handle mob icon update + var/mob/M = loc + M.unEquip(src) + qdel(src) + return 1 + else + amount -= used + update_icon() + return 1 +*/ +/obj/item/stack/cable_coil/use(var/used) + . = ..() + update_icon() + return + +//add cables to the stack +/obj/item/stack/cable_coil/proc/give(var/extra) + if(amount + extra > MAXCOIL) + amount = MAXCOIL + else + amount += extra + update_icon() + +/////////////////////////////////////////////// +// Cable laying procedures +////////////////////////////////////////////// + +// called when cable_coil is clicked on a turf/simulated/floor +/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user) + if(!isturf(user.loc)) + return + + if(get_amount() < 1) // Out of cable + user << "There is no cable left." + return + + if(get_dist(F,user) > 1) // Too far + user << "You can't lay cable at a place that far away." + return + + if(F.intact) // Ff floor is intact, complain + user << "You can't lay cable there unless the floor tiles are removed." + return + + else + var/dirn + + if(user.loc == F) + dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing + else + dirn = get_dir(F, user) + + for(var/obj/structure/cable/LC in F) + if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0)) + user << "There's already a cable at that position." + return +///// Z-Level Stuff + // check if the target is open space + if(istype(F, /turf/simulated/floor/open)) + for(var/obj/structure/cable/LC in F) + if((LC.d1 == dirn && LC.d2 == 11 ) || ( LC.d2 == dirn && LC.d1 == 11)) + user << "There's already a cable at that position." + return + + var/turf/simulated/floor/open/temp = F + var/obj/structure/cable/C = new(F) + var/obj/structure/cable/D = new(temp.floorbelow) + + C.cableColor(color) + + C.d1 = 11 + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() + + var/datum/powernet/PN = new() + PN.add_cable(C) + + C.mergeConnectedNetworks(C.d2) + C.mergeConnectedNetworksOnTurf() + + D.cableColor(color) + + D.d1 = 12 + D.d2 = 0 + D.add_fingerprint(user) + D.updateicon() + + PN.add_cable(D) + D.mergeConnectedNetworksOnTurf() + + // do the normal stuff + else +///// Z-Level Stuff + for(var/obj/structure/cable/LC in F) + if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0)) + user << "There's already a cable at that position." + return + + var/obj/structure/cable/C = new(F) + + C.cableColor(color) + + //set up the new cable + C.d1 = 0 //it's a O-X node cable + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() + + //create a new powernet with the cable, if needed it will be merged later + var/datum/powernet/PN = new() + PN.add_cable(C) + + C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets + C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + + if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d2) + + + use(1) + if (C.shock(user, 50)) + if (prob(50)) //fail + new/obj/item/stack/cable_coil(C.loc, 1, C.color) + del(C) // qdel + +// called when cable_coil is click on an installed obj/cable +// or click on a turf that already contains a "node" cable +/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user) + var/turf/U = user.loc + if(!isturf(U)) + return + + var/turf/T = C.loc + + if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable + return + + if(get_dist(C, user) > 1) // make sure it's close enough + user << "You can't lay cable at a place that far away." + return + + + if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing + turf_place(T,user) + return + + var/dirn = get_dir(C, user) + + // one end of the clicked cable is pointing towards us + if(C.d1 == dirn || C.d2 == dirn) + if(U.intact) // can't place a cable if the floor is complete + user << "You can't lay cable there unless the floor tiles are removed." + return + else + // cable is pointing at us, we're standing on an open tile + // so create a stub pointing at the clicked cable on our tile + + var/fdirn = turn(dirn, 180) // the opposite direction + + for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already + if(LC.d1 == fdirn || LC.d2 == fdirn) + user << "There's already a cable at that position." + return + + var/obj/structure/cable/NC = new(U) + NC.cableColor(color) + + NC.d1 = 0 + NC.d2 = fdirn + NC.add_fingerprint() + NC.updateicon() + + //create a new powernet with the cable, if needed it will be merged later + var/datum/powernet/newPN = new() + newPN.add_cable(NC) + + NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets + NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + + if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + NC.mergeDiagonalsNetworks(NC.d2) + + use(1) + + if (NC.shock(user, 50)) + if (prob(50)) //fail + new/obj/item/stack/cable_coil(NC.loc, 1, NC.color) + del(NC) // qdel + + return + + // exisiting cable doesn't point at our position, so see if it's a stub + else if(C.d1 == 0) + // if so, make it a full cable pointing from it's old direction to our dirn + var/nd1 = C.d2 // these will be the new directions + var/nd2 = dirn + + + if(nd1 > nd2) // swap directions to match icons/states + nd1 = dirn + nd2 = C.d2 + + + for(var/obj/structure/cable/LC in T) // check to make sure there's no matching cable + if(LC == C) // skip the cable we're interacting with + continue + if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction + user << "There's already a cable at that position." + return + + + C.cableColor(color) + + C.d1 = nd1 + C.d2 = nd2 + + C.add_fingerprint() + C.updateicon() + + + C.mergeConnectedNetworks(C.d1) //merge the powernets... + C.mergeConnectedNetworks(C.d2) //...in the two new cable directions + C.mergeConnectedNetworksOnTurf() + + if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d1) + + if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d2) + + use(1) + + if (C.shock(user, 50)) + if (prob(50)) //fail + new/obj/item/stack/cable_coil(C.loc, 2, C.color) + del(C) // qdel + return + + C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets. + return + +////////////////////////////// +// Misc. +///////////////////////////// + +/obj/item/stack/cable_coil/cut + item_state = "coil2" + +/obj/item/stack/cable_coil/cut/New(loc) + ..() + src.amount = rand(1,2) + pixel_x = rand(-2,2) + pixel_y = rand(-2,2) + update_icon() + update_wclass() + +/obj/item/stack/cable_coil/yellow + color = COLOR_YELLOW + +/obj/item/stack/cable_coil/blue + color = COLOR_BLUE + +/obj/item/stack/cable_coil/green + color = COLOR_GREEN + +/obj/item/stack/cable_coil/pink + color = COLOR_PINK + +/obj/item/stack/cable_coil/orange + color = COLOR_ORANGE + +/obj/item/stack/cable_coil/cyan + color = COLOR_CYAN + +/obj/item/stack/cable_coil/white + color = COLOR_WHITE + +/obj/item/stack/cable_coil/random/New() + color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) + ..() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 8df7969d8dd..871ac5395a4 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -3,6 +3,10 @@ name = "gun" desc = "Its a gun. It's pretty terrible, though." icon = 'icons/obj/gun.dmi' + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', + icon_r_hand = 'icons/mob/items/righthand_guns.dmi', + ) icon_state = "detective" item_state = "gun" flags = CONDUCT @@ -134,10 +138,7 @@ handle_post_fire(user, target, pointblank, reflex) update_icon() - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + update_held_icon() //obtains the next projectile to fire diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index db590d7b9f0..9f611e593df 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -40,7 +40,7 @@ /obj/item/weapon/gun/launcher/spikethrower/special_check(user) if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") + if(H.species && H.species.name != "Vox") user << "\The [src] does not respond to you!" return 0 return ..() @@ -52,56 +52,3 @@ if(spikes < 1) return null spikes-- return new /obj/item/weapon/spike(src) - -//This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. -/obj/item/weapon/gun/energy/noisecannon - name = "alien heavy cannon" - desc = "It's some kind of enormous alien weapon, as long as a man is tall." - - icon = 'icons/obj/gun.dmi' //Actual on-sprite is handled by icon_override. - icon_state = "noisecannon" - item_state = "noisecannon" - recoil = 1 - - force = 10 - projectile_type = /obj/item/projectile/energy/sonic - cell_type = /obj/item/weapon/cell/super - fire_delay = 40 - fire_sound = 'sound/effects/basscannon.ogg' - - var/mode = 1 - - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/held.dmi' - ) - -/obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob) - if(loc != user) - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.species.name == "Vox Armalis") - ..() - return - user << "\The [src] is far too large for you to pick up." - return - -/obj/item/weapon/gun/energy/noisecannon/update_icon() - return - -//Projectile. -/obj/item/projectile/energy/sonic - name = "distortion" - icon = 'icons/obj/machines/particle_accelerator2.dmi' - icon_state = "particle" - damage = 60 - damage_type = BRUTE - check_armour = "bullet" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - - embed = 0 - weaken = 5 - stun = 5 - -/obj/item/projectile/energy/sonic/proc/split() - //TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf. - return diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 19f11573718..994256b12a9 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -29,6 +29,7 @@ power_supply.give(power_supply.maxcharge) if(self_recharge) processing_objects.Add(src) + update_icon() /obj/item/weapon/gun/energy/Del() if(self_recharge) @@ -87,3 +88,4 @@ icon_state = "[modifystate][ratio]" else icon_state = "[initial(icon_state)][ratio]" + diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 2bc36508d81..dffc012998a 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -24,16 +24,18 @@ obj/item/weapon/gun/energy/retro name = "retro laser" icon_state = "retro" + item_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." fire_sound = 'sound/weapons/Laser.ogg' slot_flags = SLOT_BELT w_class = 3 projectile_type = /obj/item/projectile/beam - fire_delay = 10 + fire_delay = 10 //old technology /obj/item/weapon/gun/energy/captain name = "antique laser gun" icon_state = "caplaser" + item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 5 fire_sound = 'sound/weapons/Laser.ogg' @@ -48,7 +50,7 @@ obj/item/weapon/gun/energy/retro 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!" icon_state = "lasercannon" - item_state = "laser" + item_state = null fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" slot_flags = SLOT_BELT|SLOT_BACK @@ -57,6 +59,7 @@ obj/item/weapon/gun/energy/retro fire_delay = 20 /obj/item/weapon/gun/energy/lasercannon/mounted + name = "mounted laser cannon" self_recharge = 1 use_external_power = 1 recharge_time = 10 @@ -65,6 +68,7 @@ obj/item/weapon/gun/energy/retro name = "xray laser gun" desc = "A high-power laser gun capable of expelling concentrated xray blasts." icon_state = "xray" + item_state = "xray" fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" projectile_type = /obj/item/projectile/beam/xray @@ -116,10 +120,12 @@ obj/item/weapon/gun/energy/retro /obj/item/weapon/gun/energy/lasertag/blue icon_state = "bluetag" + item_state = "bluetag" projectile_type = /obj/item/projectile/beam/lastertag/blue required_vest = /obj/item/clothing/suit/bluetag /obj/item/weapon/gun/energy/lasertag/red icon_state = "redtag" + item_state = "redtag" projectile_type = /obj/item/projectile/beam/lastertag/red required_vest = /obj/item/clothing/suit/redtag diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index e2b97672c7f..6b9f6f0d514 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -29,12 +29,10 @@ projectile_type = /obj/item/projectile/beam/stun modifystate = "energystun" update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + update_held_icon() /obj/item/weapon/gun/energy/gun/mounted + name = "mounted energy gun" self_recharge = 1 use_external_power = 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 434156ad534..c7f74e1d958 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -26,6 +26,7 @@ name = "biological demolecularisor" desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" + item_state = "decloner" fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" charge_cost = 100 @@ -35,7 +36,7 @@ name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." icon_state = "floramut100" - item_state = "obj/item/gun.dmi" + item_state = "floramut" fire_sound = 'sound/effects/stealthoff.ogg' charge_cost = 100 projectile_type = /obj/item/projectile/energy/floramut @@ -59,7 +60,7 @@ projectile_type = /obj/item/projectile/energy/floramut modifystate = "floramut" update_icon() - return + update_held_icon() /obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag) //allow shooting into adjacent hydrotrays regardless of intent @@ -115,6 +116,7 @@ name = "staff of change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" icon = 'icons/obj/gun.dmi' + item_icons = null icon_state = "staffofchange" item_state = "staffofchange" fire_sound = 'sound/weapons/emitter.ogg' @@ -168,6 +170,7 @@ obj/item/weapon/gun/energy/staff/focus desc = "It's a cute rubber duck. With an evil gleam in it's eye." projectile_type = /obj/item/projectile/icarus/pointdefense icon = 'icons/obj/watercloset.dmi' + item_icons = null icon_state = "rubberducky" item_state = "rubberducky" charge_cost = 0 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index a99b71337ad..1d51f7957e7 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -9,10 +9,12 @@ cell_type = /obj/item/weapon/cell/crap /obj/item/weapon/gun/energy/taser/mounted + name = "mounted taser gun" self_recharge = 1 use_external_power = 1 /obj/item/weapon/gun/energy/taser/mounted/cyborg + name = "taser gun" cell_type = /obj/item/weapon/cell/secborg recharge_time = 10 //Time it takes for shots to recharge (in ticks) @@ -21,6 +23,7 @@ name = "stun revolver" desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger." icon_state = "stunrevolver" + item_state = "stunrevolver" fire_sound = 'sound/weapons/Gunshot.ogg' origin_tech = "combat=3;materials=3;powerstorage=2" charge_cost = 125 diff --git a/code/modules/projectiles/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm index 860169d7b27..917d3c338e3 100644 --- a/code/modules/projectiles/guns/launcher/crossbow.dm +++ b/code/modules/projectiles/guns/launcher/crossbow.dm @@ -105,14 +105,14 @@ current_user = user user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") tension = 1 - + while(bolt && tension && current_user == user) if(!do_after(user, 25)) //crossbow strings don't just magically pull back on their own. user.visible_message("[usr] stops drawing and relaxes the string of [src].","You stop drawing back and relax the string of [src].") tension = 0 icon_state = "crossbow" return - + tension++ icon_state = "crossbow-drawn" @@ -120,7 +120,7 @@ tension = max_tension usr << "[src] clunks as you draw the string to its maximum tension!" return - + user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") /obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob) diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index 9fac802bdaf..b1a0f563df8 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -66,7 +66,7 @@ for(var/obj/item/O in src.contents) total_stored += O.get_storage_cost() if(total_stored + W.get_storage_cost() <= max_storage_space) - user.drop_item(W) + user.remove_from_mob(W) W.loc = src user << "You shove [W] into the hopper." else diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index 75c015d579e..099f8687a33 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -133,4 +133,5 @@ name = "syringe gun revolver" desc = "A modification of the syringe gun design, using a rotating cylinder to store up to five syringes. The spring still needs to be drawn between shots." icon_state = "rapidsyringegun" + item_state = "rapidsyringegun" max_darts = 5 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 5778b3febe9..75bbf810a80 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -51,7 +51,7 @@ name = "\improper STS-35 automatic rifle" desc = "A durable, rugged looking automatic weapon of a make popular on the frontier worlds. Uses 7.62mm rounds. It is unmarked." icon_state = "arifle" - item_state = "l6closednomag" //placeholder + item_state = null w_class = 4 force = 10 caliber = "a762" @@ -63,12 +63,13 @@ /obj/item/weapon/gun/projectile/automatic/sts35/update_icon() ..() icon_state = (ammo_magazine)? "arifle-0" : "arifle" + update_held_icon() /obj/item/weapon/gun/projectile/automatic/wt550 name = "\improper W-T 550 Saber" desc = "A cheap, mass produced Ward-Takahashi PDW. Uses 9mm rounds." icon_state = "wt550" - item_state = "c20r" //placeholder + item_state = "wt550" w_class = 3 caliber = "9mm" origin_tech = "combat=5;materials=2" @@ -90,7 +91,7 @@ name = "\improper Z8 Bulldog" desc = "An older model bullpup carbine, made by the now defunct Zendai Foundries. Uses armor piercing 5.56mm rounds. Makes you feel like a space marine when you hold it." icon_state = "carbine" - item_state = "l6closednomag" //placeholder + item_state = "z8carbine" w_class = 4 force = 10 caliber = "a556" diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index a8f93b8d253..cf05a005eda 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -45,6 +45,7 @@ name = "dart gun" desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." icon_state = "dartgun-empty" + item_state = null caliber = "dart" fire_sound = 'sound/weapons/empty.ogg' diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index adbf30922db..b29f2f3e420 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -63,6 +63,7 @@ name = "desert eagle" desc = "A robust handgun that uses .50 AE ammo" icon_state = "deagle" + item_state = "deagle" force = 14.0 caliber = ".50" load_method = MAGAZINE @@ -107,6 +108,7 @@ name = "\improper Stechtkin pistol" desc = "A small, easily concealable gun. Uses 9mm rounds." icon_state = "pistol" + item_state = null w_class = 2 caliber = "9mm" silenced = 0 diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index fb5895aad90..f0291de0f87 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -2,6 +2,7 @@ name = "revolver" desc = "A classic revolver. Uses .357 ammo" icon_state = "revolver" + item_state = "revolver" caliber = "357" origin_tech = "combat=2;materials=2" handle_casings = CYCLE_CASINGS diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index fd85bc28be9..fa29d7e8ba3 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -42,6 +42,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" icon_state = "cshotgun" + item_state = "cshotgun" origin_tech = "combat=5;materials=2" max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8. ammo_type = /obj/item/ammo_casing/shotgun @@ -51,7 +52,7 @@ name = "double-barreled shotgun" desc = "A true classic." icon_state = "dshotgun" - item_state = "shotgun" + item_state = "dshotgun" //SPEEDLOADER because rapid unloading. //In principle someone could make a speedloader for it, so it makes sense. load_method = SINGLE_CASING|SPEEDLOADER diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm index bd5c1c8d97a..388b53a2566 100644 --- a/code/modules/projectiles/targeting.dm +++ b/code/modules/projectiles/targeting.dm @@ -80,7 +80,7 @@ var/mob/living/M = loc if(M == T) return if(!istype(M)) return - if(src != M.equipped()) + if(src != M.get_active_hand()) stop_aim() return diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index bef45fbb166..4c857a51c3c 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -655,7 +655,7 @@ user << "\The [O] is not suitable for blending." return 1 - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src holdingitems += O src.updateUsrDialog() @@ -794,4 +794,4 @@ if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break -#undef REAGENTS_PER_SHEET \ No newline at end of file +#undef REAGENTS_PER_SHEET diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 1399fdd14ad..1b710dbfc61 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -670,7 +670,7 @@ datum if(prob(50)) M.radiation += 50 // curing it that way may kill you instead var/absorbed - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in C.internal_organs + var/obj/item/organ/diona/nutrients/rad_organ = locate() in C.internal_organs if(rad_organ && !rad_organ.is_broken()) absorbed = 1 if(!absorbed) @@ -1284,7 +1284,7 @@ datum M.eye_blind = max(M.eye_blind-5 , 0) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] if(E && istype(E)) if(E.damage > 0) E.damage = max(E.damage - 1, 0) @@ -1306,7 +1306,7 @@ datum var/mob/living/carbon/human/H = M //Peridaxon heals only non-robotic organs - for(var/datum/organ/internal/I in H.internal_organs) + for(var/obj/item/organ/I in H.internal_organs) if((I.damage > 0) && (I.robotic != 2)) I.damage = max(I.damage - 0.20, 0) ..() @@ -2057,7 +2057,7 @@ datum if(!M.unacidable) if(istype(M, /mob/living/carbon/human) && volume >= 10) var/mob/living/carbon/human/H = M - var/datum/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ("head") if(affecting) if(affecting.take_damage(4*toxpwr, 2*toxpwr)) H.UpdateDamageIcon() @@ -3332,7 +3332,7 @@ datum M:drowsyness = max(M:drowsyness, 30) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/liver/L = H.internal_organs_by_name["liver"] + var/obj/item/organ/liver/L = H.internal_organs_by_name["liver"] if (!L) H.adjustToxLoss(5) else if(istype(L)) @@ -3654,13 +3654,13 @@ datum if(prob(30)) M.adjustToxLoss(2) if(prob(5)) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"] + var/obj/item/organ/heart/L = H.internal_organs_by_name["heart"] if (L && istype(L)) L.take_damage(5, 0) if (300 to INFINITY) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"] + var/obj/item/organ/heart/L = H.internal_organs_by_name["heart"] if (L && istype(L)) L.take_damage(100, 0) holder.remove_reagent(src.id, FOOD_METABOLISM) diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 22c0bf6da82..bc36317521d 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -43,7 +43,7 @@ force = 15 //Smashing bottles over someoen's head hurts. - var/datum/organ/external/affecting = user.zone_sel.selecting //Find what the player is aiming at + var/obj/item/organ/external/affecting = user.zone_sel.selecting //Find what the player is aiming at var/armor_block = 0 //Get the target's armour values for normal attack damage. var/armor_duration = 0 //The more force the bottle has, the longer the duration. diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 68db3b98c8a..229b4b04e59 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -165,9 +165,7 @@ return user << "\red You slip [W] inside [src]." - user.u_equip(W) - if ((user.client && user.s_active != src)) - user.client.screen -= W + user.remove_from_mob(W) W.dropped(user) add_fingerprint(user) contents += W @@ -1576,9 +1574,9 @@ surprise.transform *= 0.6 surprise.add_blood(M) var/mob/living/carbon/human/H = M - var/datum/organ/external/E = H.get_organ("chest") + var/obj/item/organ/external/E = H.get_organ("chest") E.fracture() - for (var/datum/organ/internal/I in E.internal_organs) + for (var/obj/item/organ/I in E.internal_organs) I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1)) if (!E.hidden && prob(60)) //set it snuggly diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index cbae0f8f402..4d23bb30ed2 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -249,8 +249,8 @@ reagents.add_reagent("synaptizine", 5) reagents.add_reagent("hyperzine", 5) - /obj/item/weapon/reagent_containers/pill/spaceacillin - name = "Spaceacillin" +/obj/item/weapon/reagent_containers/pill/spaceacillin + name = "Spaceacillin pill" desc = "Contains antiviral agents." icon_state = "pill19" New() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 01bddd04312..a1c2fc4415d 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -235,14 +235,13 @@ if(istype(target, /mob/living/carbon/human)) var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target)) - var/datum/organ/external/affecting = target:get_organ(target_zone) + var/obj/item/organ/external/affecting = target:get_organ(target_zone) - if (!affecting) + if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump()) + user << "They are missing that limb!" return - if(affecting.status & ORGAN_DESTROYED) - user << "What [affecting.display_name]?" - return - var/hit_area = affecting.display_name + + var/hit_area = affecting.name var/mob/living/carbon/human/H = target if((user != target) && H.check_shields(7, "the [src.name]")) @@ -251,7 +250,7 @@ if (target != user && target.getarmor(target_zone, "melee") > 5 && prob(50)) for(var/mob/O in viewers(world.view, user)) O.show_message(text("\red [user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!"), 1) - user.u_equip(src) + user.remove_from_mob(src) del(src) return @@ -270,7 +269,7 @@ var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand src.reagents.trans_to(target, syringestab_amount_transferred) src.break_syringe(target, user) - + proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user) src.desc += " It is broken." src.mode = SYRINGE_BROKEN diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm index d1d3937c972..5a6e8a46dbd 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm @@ -13,7 +13,7 @@ if(ishuman(toucher)) var/mob/living/carbon/human/H = toucher - for(var/datum/organ/external/affecting in H.organs) + for(var/obj/item/organ/external/affecting in H.organs) if(affecting && istype(affecting)) affecting.heal_damage(25 * weakness, 25 * weakness) //H:heal_organ_damage(25, 25) diff --git a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm index 2437eeb0672..5a74061a239 100644 --- a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm +++ b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm @@ -14,9 +14,8 @@ if(held_container) user << "\red You must remove the [held_container] first." else - user.drop_item(src) held_container = W - held_container.loc = src + user.drop_from_inventory(held_container, src) user << "\blue You put the [held_container] onto the [src]." var/image/I = image("icon"=W, "layer"=FLOAT_LAYER) underlays += I diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 66ba38726e1..6236f8c35af 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -26,18 +26,18 @@ dat += "
    " dat += "Memorize which spell:
    " dat += "The number after the spell name is the cooldown time.
    " - dat += "Magic Missile (10)
    " + dat += "Magic Missile (15)
    " dat += "Fireball (10)
    " //dat += "Disintegrate (60)
    " - dat += "Disable Technology (60)
    " - dat += "Smoke (10)
    " + dat += "Disable Technology (40)
    " + dat += "Smoke (12)
    " dat += "Blind (30)
    " dat += "Mind Transfer (60)
    " dat += "Forcewall (10)
    " dat += "Blink (2)
    " dat += "Teleport (60)
    " - dat += "Mutate (60)
    " - dat += "Ethereal Jaunt (60)
    " + dat += "Mutate (40)
    " + dat += "Ethereal Jaunt (30)
    " dat += "Knock (10)
    " dat += "Curse of the Horseman (15)
    " // if(op) @@ -105,7 +105,7 @@ if("magicmissile") feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H) - temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage." + temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If a projectile hits a target, the target is stunned for some time." if("fireball") feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H) @@ -117,11 +117,11 @@ if("disabletech") feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H) - temp = "This spell disables all weapons, cameras and most other technology in range." + temp = "This spell releases an EMP from your person disabling most technology within range; computers, doors, prosthetics, etc." if("smoke") feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H) - temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." + temp = "This spell spawns a cloud of vision obscuring smoke at your location and does not require wizard garb." if("blind") feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H) @@ -141,11 +141,11 @@ if("teleport") feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H) - temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable." + temp = "This spell teleports you to an area of your selection, and creates a cloud of smoke around you upon arrival. Very useful if you are in danger.." if("mutate") feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H) - temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while." + temp = "This spell causes you to turn into a hulk, gaining super strength and the ability to punch down walls! You also gain the ability to fire lasers from your eyes!" if("etherealjaunt") feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 605b1503d56..b2ccbb10032 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -17,27 +17,27 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open >= 2 && affected.stage == 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open >= 2 && affected.stage == 0 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected.stage == 0) - user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.display_name] with \the [tool]." , \ - "You start applying medication to the damaged bones in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Something in your [affected.display_name] is causing you a lot of pain!",1) + user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ + "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] applies some [tool] to [target]'s bone in [affected.display_name]", \ - "\blue You apply some [tool] to [target]'s bone in [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] applies some [tool] to [target]'s bone in [affected.name]", \ + "\blue You apply some [tool] to [target]'s bone in [affected.name] with \the [tool].") affected.stage = 1 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") /datum/surgery_step/set_bone allowed_tools = list( @@ -51,31 +51,31 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.name != "head" && affected.open >= 2 && affected.stage == 1 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.name != "head" && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to set the bone in [target]'s [affected.display_name] in place with \the [tool]." , \ - "You are beginning to set the bone in [target]'s [affected.display_name] in place with \the [tool].") - target.custom_pain("The pain in your [affected.display_name] is going to make you pass out!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \ + "You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].") + target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected.status & ORGAN_BROKEN) - user.visible_message("\blue [user] sets the bone in [target]'s [affected.display_name] in place with \the [tool].", \ - "\blue You set the bone in [target]'s [affected.display_name] in place with \the [tool].") + user.visible_message("\blue [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ + "\blue You set the bone in [target]'s [affected.name] in place with \the [tool].") affected.stage = 2 else - user.visible_message("\blue [user] sets the bone in [target]'s [affected.display_name]\red in the WRONG place with \the [tool].", \ - "\blue You set the bone in [target]'s [affected.display_name]\red in the WRONG place with \the [tool].") + user.visible_message("\blue [user] sets the bone in [target]'s [affected.name]\red in the WRONG place with \the [tool].", \ + "\blue You set the bone in [target]'s [affected.name]\red in the WRONG place with \the [tool].") affected.fracture() fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the bone in [target]'s [affected.display_name] with \the [tool]!" , \ - "\red Your hand slips, damaging the bone in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!" , \ + "\red Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!") affected.createwound(BRUISE, 5) /datum/surgery_step/mend_skull @@ -90,8 +90,8 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.name == "head" && affected.open >= 2 && affected.stage == 1 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.name == "head" && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \ @@ -99,16 +99,16 @@ ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\blue [user] sets [target]'s skull with \the [tool]." , \ "\blue You set [target]'s skull with \the [tool].") affected.stage = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \ "\red Your hand slips, damaging [target]'s face with \the [tool]!") - var/datum/organ/external/head/h = affected + var/obj/item/organ/external/head/h = affected h.createwound(BRUISE, 10) h.disfigured = 1 @@ -126,25 +126,25 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open >= 2 && affected.stage == 2 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open >= 2 && affected.stage == 2 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.display_name] with \the [tool].", \ - "You start to finish mending the damaged bones in [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].", \ + "You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].") ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.display_name] with \the [tool]." , \ - "\blue You have mended the damaged bones in [target]'s [affected.display_name] with \the [tool]." ) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ + "\blue You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) affected.status &= ~ORGAN_BROKEN affected.status &= ~ORGAN_SPLINTED affected.stage = 0 affected.perma_injury = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!") \ No newline at end of file + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") \ No newline at end of file diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm index 85b5dd8dd3e..60fdffe31d2 100644 --- a/code/modules/surgery/brainrepair.dm +++ b/code/modules/surgery/brainrepair.dm @@ -14,8 +14,9 @@ max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return + var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] return (sponge && sponge.damage > 0 && sponge.damage <= 20) && affected.open == 3 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -26,7 +27,7 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("\blue [user] takes out all the bone chips in [target]'s brain with \the [tool].", \ "\blue You take out all the bone chips in [target]'s brain with \the [tool].") - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] if (sponge) sponge.damage = 0 @@ -46,8 +47,9 @@ max_duration = 110 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return + var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] return (sponge && sponge.damage > 20) && affected.open == 3 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -58,7 +60,7 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \ "\blue You mend hematoma in [target]'s brain with \the [tool].") - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] if (sponge) sponge.damage = 20 diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index 72cff7ab3dd..fedf5bbc1c0 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -11,8 +11,8 @@ if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.encased && affected.open >= 2 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.encased && affected.open >= 2 /datum/surgery_step/open_encased/saw @@ -27,25 +27,25 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open == 2 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ "You begin to cut through [target]'s [affected.encased] with \the [tool].") - target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\blue [user] has cut [target]'s [affected.encased] open with \the [tool].", \ "\blue You have cut [target]'s [affected.encased] open with \the [tool].") @@ -55,7 +55,7 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!" , \ "\red Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" ) @@ -76,26 +76,26 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open == 2.5 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2.5 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.display_name] with \the [tool]." - var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.display_name] with \the [tool]." + var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." + var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\blue [user] forces open [target]'s [affected.encased] with \the [tool]." var/self_msg = "\blue You force open [target]'s [affected.encased] with \the [tool]." @@ -111,7 +111,7 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\red [user]'s hand slips, cracking [target]'s [affected.encased]!" var/self_msg = "\red Your hand slips, cracking [target]'s [affected.encased]!" @@ -133,26 +133,26 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open == 3 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 3 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\blue [user] bends [target]'s [affected.encased] back into place with \the [tool]." var/self_msg = "\blue You bend [target]'s [affected.encased] back into place with \the [tool]." @@ -164,7 +164,7 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\red [user]'s hand slips, bending [target]'s [affected.encased] the wrong way!" var/self_msg = "\red Your hand slips, bending [target]'s [affected.encased] the wrong way!" @@ -190,26 +190,26 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open == 2.5 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2.5 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]." var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\blue [user] applied \the [tool] to [target]'s [affected.encased]." var/self_msg = "\blue You applied \the [tool] to [target]'s [affected.encased]." diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm index 81170afc39d..edc1c54c679 100644 --- a/code/modules/surgery/eye.dm +++ b/code/modules/surgery/eye.dm @@ -9,11 +9,11 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (!affected) return 0 - var/datum/organ/internal/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes = target.internal_organs_by_name["eyes"] return target_zone == "eyes" && eyes @@ -42,8 +42,8 @@ target.blinded += 1.5 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/eyes/eyes = target.internal_organs_by_name["eyes"] - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, slicing [target]'s eyes wth \the [tool]!" , \ "\red Your hand slips, slicing [target]'s eyes wth \the [tool]!" ) affected.createwound(CUT, 10) @@ -72,8 +72,8 @@ target.op_stage.eyes = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/eyes/eyes = target.internal_organs_by_name["eyes"] - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, damaging [target]'s eyes with \the [tool]!", \ "\red Your hand slips, damaging [target]'s eyes with \the [tool]!") target.apply_damage(10, BRUTE, affected) @@ -103,8 +103,8 @@ target.op_stage.eyes = 3 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/eyes/eyes = target.internal_organs_by_name["eyes"] - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, stabbing \the [tool] into [target]'s eye!", \ "\red Your hand slips, stabbing \the [tool] into [target]'s eye!") target.apply_damage(10, BRUTE, affected, sharp=1) @@ -129,7 +129,7 @@ "You are beginning to cauterize the incision around [target]'s eyes with \the [tool].") end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] user.visible_message("\blue [user] cauterizes the incision around [target]'s eyes with \the [tool].", \ "\blue You cauterize the incision around [target]'s eyes with \the [tool].") if (target.op_stage.eyes == 3) @@ -139,8 +139,8 @@ target.op_stage.eyes = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/eyes/eyes = target.internal_organs_by_name["eyes"] - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, searing [target]'s eyes with \the [tool]!", \ "\red Your hand slips, searing [target]'s eyes with \the [tool]!") target.apply_damage(5, BURN, affected) diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index b5b22659f46..e25291eba54 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -9,7 +9,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (!affected) return 0 return target_zone == "mouth" @@ -38,7 +38,7 @@ target.op_stage.face = 1 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \ "\red Your hand slips, slicing [target]'s throat wth \the [tool]!" ) affected.createwound(CUT, 60) @@ -95,7 +95,7 @@ target.op_stage.face = 3 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \ "\red Your hand slips, tearing skin on [target]'s face with \the [tool]!") target.apply_damage(10, BRUTE, affected, sharp=1, sharp=1) @@ -120,18 +120,18 @@ ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\blue [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \ "\blue You cauterize the incision on [target]'s face and neck with \the [tool].") affected.open = 0 affected.status &= ~ORGAN_BLEEDING if (target.op_stage.face == 3) - var/datum/organ/external/head/h = affected + var/obj/item/organ/external/head/h = affected h.disfigured = 0 target.op_stage.face = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \ "\red Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") target.apply_damage(4, BURN, affected) \ No newline at end of file diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index b7a4bfa61c7..f6352f6b742 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -12,7 +12,7 @@ return 0 if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected == null) return 0 if (affected.status & ORGAN_DESTROYED) @@ -36,20 +36,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts the bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start the bloodless incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.display_name]!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts the bloodless incision on [target]'s [affected.name] with \the [tool].", \ + "You start the bloodless incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have made a bloodless incision on [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You have made a bloodless incision on [target]'s [affected.name] with \the [tool].",) //Could be cleaner ... affected.open = 1 @@ -61,9 +61,9 @@ spread_germs_to_organ(affected, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 7.5) affected.createwound(BURN, 12.5) @@ -77,20 +77,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ - "You start to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.display_name] as it is pushed apart!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ + "You start to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.name] as it is pushed apart!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ + "\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",) affected.open = 1 if(istype(target) && !(target.species.flags & NO_BLOOD)) @@ -101,9 +101,9 @@ affected.open = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) affected.createwound(BURN, 15) @@ -119,20 +119,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts the incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start the incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.display_name]!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts the incision on [target]'s [affected.name] with \the [tool].", \ + "You start the incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made an incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have made an incision on [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has made an incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You have made an incision on [target]'s [affected.name] with \the [tool].",) affected.open = 1 if(istype(target) && !(target.species.flags & NO_BLOOD)) @@ -141,9 +141,9 @@ affected.createwound(CUT, 1) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!", \ - "\red Your hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!", \ + "\red Your hand slips, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!") affected.createwound(CUT, 10) /datum/surgery_step/generic/clamp_bleeders @@ -158,27 +158,27 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open && (affected.status & ORGAN_BLEEDING) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && (affected.status & ORGAN_BLEEDING) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts clamping bleeders in [target]'s [affected.display_name] with \the [tool].", \ - "You start clamping bleeders in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("The pain in your [affected.display_name] is maddening!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \ + "You start clamping bleeders in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in your [affected.name] is maddening!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.display_name] with \the [tool].", \ - "\blue You clamp bleeders in [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.name] with \the [tool].", \ + "\blue You clamp bleeders in [target]'s [affected.name] with \the [tool].") affected.clamp() spread_germs_to_organ(affected, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) affected.createwound(CUT, 10) /datum/surgery_step/generic/retract_skin @@ -193,13 +193,13 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts to pry open the incision on [target]'s [affected.display_name] with \the [tool]." - var/self_msg = "You start to pry open the incision on [target]'s [affected.display_name] with \the [tool]." + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." + var/self_msg = "You start to pry open the incision on [target]'s [affected.name] with \the [tool]." if (target_zone == "chest") msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." @@ -207,13 +207,13 @@ msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("It feels like the skin on your [affected.display_name] is on fire!",1) + target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] keeps the incision open on [target]'s [affected.display_name] with \the [tool]." - var/self_msg = "\blue You keep the incision open on [target]'s [affected.display_name] with \the [tool]." + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "\blue [user] keeps the incision open on [target]'s [affected.name] with \the [tool]." + var/self_msg = "\blue You keep the incision open on [target]'s [affected.name] with \the [tool]." if (target_zone == "chest") msg = "\blue [user] keeps the ribcage open on [target]'s torso with \the [tool]." self_msg = "\blue You keep the ribcage open on [target]'s torso with \the [tool]." @@ -224,9 +224,9 @@ affected.open = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "\red [user]'s hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!" - var/self_msg = "\red Your hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "\red [user]'s hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" + var/self_msg = "\red Your hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" if (target_zone == "chest") msg = "\red [user]'s hand slips, damaging several organs in [target]'s torso with \the [tool]!" self_msg = "\red Your hand slips, damaging several organs in [target]'s torso with \the [tool]!" @@ -249,31 +249,31 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool]." , \ - "You are beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Your [affected.display_name] is being burned!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("Your [affected.name] is being burned!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You cauterize the incision on [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You cauterize the incision on [target]'s [affected.name] with \the [tool].") affected.open = 0 affected.germ_level = 0 affected.status &= ~ORGAN_BLEEDING fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!") target.apply_damage(3, BURN, affected) -/datum/surgery_step/generic/cut_limb +/datum/surgery_step/generic/amputate allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ /obj/item/weapon/hatchet = 75 @@ -287,29 +287,29 @@ return 0 if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected == null) return 0 if (affected.status & ORGAN_DESTROYED) return 0 - return target_zone != "chest" && target_zone != "groin" && target_zone != "head" + return !affected.cannot_amputate begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to cut off [target]'s [affected.display_name] with \the [tool]." , \ - "You are beginning to cut off [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Your [affected.display_name] is being ripped apart!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") + target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cuts off [target]'s [affected.display_name] with \the [tool].", \ - "\blue You cut off [target]'s [affected.display_name] with \the [tool].") - affected.droplimb(1,1,1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] amputates [target]'s [affected.name] at the [affected.amputation_point] with \the [tool].", \ + "\blue You amputate [target]'s [affected.name] with \the [tool].") + affected.droplimb(1,DROPLIMB_EDGE) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 30) affected.fracture() diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index 85a56a754e9..9957ee8b78a 100644 --- a/code/modules/surgery/headreattach.dm +++ b/code/modules/surgery/headreattach.dm @@ -1,162 +1,6 @@ //This is an uguu head restoration surgery TOTALLY not yoinked from chinsky's limb reattacher - - -/datum/surgery_step/head/ - can_infect = 0 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - if (!affected) - return 0 - if (!(affected.status & ORGAN_DESTROYED)) - return 0 - if (affected.parent) - if (affected.parent.status & ORGAN_DESTROYED) - return 0 - return affected.name == "head" - - -/datum/surgery_step/head/peel - allowed_tools = list( - /obj/item/weapon/retractor = 100, \ - /obj/item/weapon/crowbar = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 50, \ - ) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return !(affected.status & ORGAN_CUT_AWAY) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts peeling back tattered flesh where [target]'s head used to be with \the [tool].", \ - "You start peeling back tattered flesh where [target]'s head used to be with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] peels back tattered flesh where [target]'s head used to be with \the [tool].", \ - "\blue You peel back tattered flesh where [target]'s head used to be with \the [tool].") - affected.status |= ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, ripping [target]'s [affected.display_name] open!", \ - "\red Your hand slips, ripping [target]'s [affected.display_name] open!") - affected.createwound(CUT, 10) - - -/datum/surgery_step/head/shape - allowed_tools = list( - /obj/item/weapon/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 10) //ok chinsky - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.status & ORGAN_CUT_AWAY && target.op_stage.head_reattach == 0 && !(affected.status & ORGAN_ATTACHABLE) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to reshape [target]'s esophagal and vocal region with \the [tool].", \ - "You start to reshape [target]'s [affected.display_name] esophagal and vocal region with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has finished repositioning flesh and tissue to something anatomically recognizable where [target]'s head used to be with \the [tool].", \ - "\blue You have finished repositioning flesh and tissue to something anatomically recognizable where [target]'s head used to be with \the [tool].") - target.op_stage.head_reattach = 1 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, further rending flesh on [target]'s neck!", \ - "\red Your hand slips, further rending flesh on [target]'s neck!") - target.apply_damage(10, BRUTE, affected) - -/datum/surgery_step/head/suture - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/stack/cable_coil = 60, \ - /obj/item/weapon/FixOVein = 80) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - return target.op_stage.head_reattach == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] is stapling and suturing flesh into place in [target]'s esophagal and vocal region with \the [tool].", \ - "You start to staple and suture flesh into place in [target]'s esophagal and vocal region with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has finished stapling [target]'s neck into place with \the [tool].", \ - "\blue You have finished stapling [target]'s neck into place with \the [tool].") - target.op_stage.head_reattach = 2 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, ripping apart flesh on [target]'s neck!", \ - "\red Your hand slips, ripping apart flesh on [target]'s neck!") - target.apply_damage(10, BRUTE, affected) - -/datum/surgery_step/head/prepare - allowed_tools = list( - /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/weapon/flame/lighter = 50, \ - /obj/item/weapon/weldingtool = 25 - ) - - min_duration = 60 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - return target.op_stage.head_reattach == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts adjusting area around [target]'s neck with \the [tool].", \ - "You start adjusting area around [target]'s neck with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has finished adjusting the area around [target]'s neck with \the [tool].", \ - "\blue You have finished adjusting the area around [target]'s neck with \the [tool].") - target.op_stage.head_reattach = 0 - affected.status |= ORGAN_ATTACHABLE - affected.amputated = 1 - affected.setAmputatedTree() - affected.open = 0 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, searing [target]'s neck!", \ - "\red Your hand slips, searing [target]'s [affected.display_name]!") - target.apply_damage(10, BURN, affected) - - -/datum/surgery_step/head/attach - allowed_tools = list(/obj/item/weapon/organ/head = 100) +/datum/surgery_step/attach_head/ + allowed_tools = list(/obj/item/organ/external/head = 100) can_infect = 0 min_duration = 80 @@ -164,31 +8,25 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/head = target.get_organ(target_zone) - return head.status & ORGAN_ATTACHABLE + var/obj/item/organ/external/head = target.get_organ(target_zone) + return !head && target_zone == "head" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts attaching [tool] to [target]'s reshaped neck.", \ "You start attaching [tool] to [target]'s reshaped neck.") end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) user.visible_message("\blue [user] has attached [target]'s head to the body.", \ "\blue You have attached [target]'s head to the body.") - affected.status = 0 - affected.amputated = 0 - affected.destspawn = 0 + var/obj/item/organ/external/head = tool + head.loc = target + head.replaced(target) + head.status = 0 target.update_body() target.updatehealth() target.UpdateDamageIcon() - for(var/obj/item/organ/replacing_organ in tool) - replacing_organ.loc = get_turf(tool) - replacing_organ.replaced(target,affected) - del(replacing_organ) //Just in case. - del(tool) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging connectors on [target]'s neck!", \ - "\red Your hand slips, damaging connectors on [target]'s neck!") - target.apply_damage(10, BRUTE, affected, sharp=1) + user.visible_message("\red [user]'s hand slips, damaging [target]'s neck!", \ + "\red Your hand slips, damaging [target]'s neck!") + target.apply_damage(10, BRUTE, null, sharp=1) diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 9a8c77e4805..df394fcd433 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -9,10 +9,10 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) - proc/get_max_wclass(datum/organ/external/affected) + proc/get_max_wclass(var/obj/item/organ/external/affected) switch (affected.name) if ("head") return 1 @@ -22,7 +22,7 @@ return 2 return 0 - proc/get_cavity(datum/organ/external/affected) + proc/get_cavity(var/obj/item/organ/external/affected) switch (affected.name) if ("head") return "cranial" @@ -44,11 +44,11 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return !affected.cavity && !affected.hidden + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !affected.cavity && !affected.hidden begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) @@ -56,14 +56,14 @@ ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) user.visible_message("\blue [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ "\blue You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) /datum/surgery_step/cavity/close_space @@ -80,11 +80,11 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.cavity + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.cavity begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \ "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) @@ -92,14 +92,14 @@ ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) user.visible_message("\blue [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \ "\blue You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." ) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) /datum/surgery_step/cavity/place_item @@ -111,18 +111,18 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return !istype(user,/mob/living/silicon/robot) && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !istype(user,/mob/living/silicon/robot) && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ "You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) target.custom_pain("The pain in your chest is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) user.visible_message("\blue [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ "\blue You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) @@ -130,16 +130,16 @@ user << "\red You tear some blood vessels trying to fit such a big object in this cavity." var/datum/wound/internal_bleeding/I = new (10) affected.wounds += I - affected.owner.custom_pain("You feel something rip in your [affected.display_name]!", 1) + affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1) user.drop_item() affected.hidden = tool tool.loc = target affected.cavity = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) ////////////////////////////////////////////////////////////////// @@ -157,18 +157,18 @@ max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] return ..() && (!sponge || !sponge.damage) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start poking around inside the incision on [target]'s [affected.display_name] with \the [tool]" ) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.name] with \the [tool].", \ + "You start poking around inside the incision on [target]'s [affected.name] with \the [tool]" ) target.custom_pain("The pain in your chest is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) var/find_prob = 0 @@ -186,8 +186,8 @@ find_prob +=50 if (prob(find_prob)) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You take [obj] out of incision on [target]'s [affected.display_name]s with \the [tool]." ) + user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You take [obj] out of incision on [target]'s [affected.name]s with \the [tool]." ) affected.implants -= obj BITSET(target.hud_updateflag, IMPLOYAL_HUD) @@ -206,11 +206,11 @@ imp.imp_in = null imp.implanted = 0 else - user.visible_message("\blue [user] removes \the [tool] from [target]'s [affected.display_name].", \ - "\blue There's something inside [target]'s [affected.display_name], but you just missed it this time." ) + user.visible_message("\blue [user] removes \the [tool] from [target]'s [affected.name].", \ + "\blue There's something inside [target]'s [affected.name], but you just missed it this time." ) else if (affected.hidden) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." ) + user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You take something out of incision on [target]'s [affected.name]s with \the [tool]." ) affected.hidden.loc = get_turf(target) if(!affected.hidden.blood_DNA) affected.hidden.blood_DNA = list() @@ -219,20 +219,20 @@ affected.hidden = null else - user.visible_message("\blue [user] could not find anything inside [target]'s [affected.display_name], and pulls \the [tool] out.", \ - "\blue You could not find anything inside [target]'s [affected.display_name]." ) + user.visible_message("\blue [user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ + "\blue You could not find anything inside [target]'s [affected.name]." ) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) if (affected.implants.len) var/fail_prob = 10 fail_prob += 100 - tool_quality(tool) if (prob(fail_prob)) var/obj/item/weapon/implant/imp = affected.implants[1] - user.visible_message("\red Something beeps inside [target]'s [affected.display_name]!") + user.visible_message("\red Something beeps inside [target]'s [affected.name]!") playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) spawn(25) imp.activate() diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 146cf3eda61..bb0a6314c83 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -9,8 +9,8 @@ if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == (affected.encased ? 3 : 2) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == (affected.encased ? 3 : 2) ////////////////////////////////////////////////////////////////// // ALIEN EMBRYO SURGERY // @@ -34,8 +34,8 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && embryo && affected.open == 3 && target_zone == "chest" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && embryo && affected.open == 3 && target_zone == "chest" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." @@ -68,10 +68,11 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) + return var/is_organ_damaged = 0 - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I.damage > 0) is_organ_damaged = 1 break @@ -86,15 +87,15 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic < 2) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) - target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -106,9 +107,9 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic < 2) user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ @@ -119,10 +120,10 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, getting mess and tearing the inside of [target]'s [affected.display_name] with \the [tool]!") + user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!") var/dam_amt = 2 if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) @@ -133,7 +134,7 @@ target.adjustToxLoss(10) affected.createwound(CUT, 5) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) I.take_damage(dam_amt,0) @@ -151,10 +152,10 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) - + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return var/is_organ_damaged = 0 - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I.damage > 0 && I.robotic >= 2) is_organ_damaged = 1 break @@ -164,24 +165,24 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ "You start mending the damage to [target]'s [I.name]'s mechanisms." ) - target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) @@ -193,15 +194,15 @@ if (!hasorgans(target)) return - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.display_name] with \the [tool]!") + user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") target.adjustToxLoss(5) affected.createwound(CUT, 5) - for(var/datum/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I) I.take_damage(rand(3,5),0) @@ -226,7 +227,7 @@ var/list/attached_organs = list() for(var/organ in target.internal_organs_by_name) - var/datum/organ/internal/I = target.internal_organs_by_name[organ] + var/obj/item/organ/I = target.internal_organs_by_name[organ] if(!I.status && I.parent_organ == target_zone) attached_organs |= organ @@ -240,25 +241,25 @@ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts to separate [target]'s [target.op_stage.current_organ] with \the [tool].", \ "You start to separate [target]'s [target.op_stage.current_organ] with \the [tool]." ) - target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("\blue [user] has separated [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have separated [target]'s [target.op_stage.current_organ] with \the [tool].") - var/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status |= ORGAN_CUT_AWAY fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, rand(30,50), 1) /datum/surgery_step/internal/remove_organ @@ -281,7 +282,7 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) - var/datum/organ/internal/I = target.internal_organs_by_name[organ] + var/obj/item/organ/I = target.internal_organs_by_name[organ] if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) removable_organs |= organ @@ -304,18 +305,15 @@ // Extract the organ! if(target.op_stage.current_organ) - var/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] - var/obj/item/organ/O - if(I && istype(I)) - O = I.remove(user) - if(O && istype(O)) - O.removed(target,user) + var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] + if(O && istype(O)) + O.removed(user) target.op_stage.current_organ = null fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!") affected.createwound(BRUISE, 20) /datum/surgery_step/internal/replace_organ @@ -329,8 +327,8 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/O = tool - var/datum/organ/external/affected = target.get_organ(target_zone) - + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return var/organ_compatible var/organ_missing @@ -357,10 +355,10 @@ user << "\red \The [target] already has [o_a][O.organ_tag]." return 2 - if(O.organ_data && affected.name == O.organ_data.parent_organ) + if(O && affected.name == O.parent_organ) organ_compatible = 1 else - user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.display_name]." + user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.name]." return 2 else user << "\red You're pretty sure [target.species.name_plural] don't normally have [o_a][O.organ_tag]." @@ -369,19 +367,19 @@ return ..() && organ_missing && organ_compatible begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.display_name].", \ - "You start transplanting \the [tool] into [target]'s [affected.display_name].") - target.custom_pain("Someone's rooting around in your [affected.display_name]!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.name].", \ + "You start transplanting \the [tool] into [target]'s [affected.name].") + target.custom_pain("Someone's rooting around in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.display_name].", \ - "\blue You have transplanted \the [tool] into [target]'s [affected.display_name].") - user.drop_item(tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.name].", \ + "\blue You have transplanted \the [tool] into [target]'s [affected.name].") var/obj/item/organ/O = tool if(istype(O)) + user.remove_from_mob(O) O.replaced(target,affected) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -389,7 +387,7 @@ "\red Your hand slips, damaging \the [tool]!") var/obj/item/organ/I = tool if(istype(I)) - I.organ_data.take_damage(rand(3,5),0) + I.take_damage(rand(3,5),0) /datum/surgery_step/internal/attach_organ allowed_tools = list( @@ -409,7 +407,7 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) - var/datum/organ/internal/I = target.internal_organs_by_name[organ] + var/obj/item/organ/I = target.internal_organs_by_name[organ] if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) removable_organs |= organ @@ -430,14 +428,14 @@ user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - var/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!") affected.createwound(BRUISE, 20) ////////////////////////////////////////////////////////////////// diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index c954c16de6c..56418b70c8e 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -20,8 +20,8 @@ if(!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return var/internal_bleeding = 0 for(var/datum/wound/W in affected.wounds) if(W.internal) internal_bleeding = 1 @@ -30,16 +30,16 @@ return affected.open >= 2 && internal_bleeding begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.display_name] with \the [tool]." , \ - "You start patching the damaged vein in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("The pain in [affected.display_name] is unbearable!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.name] with \the [tool]." , \ + "You start patching the damaged vein in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in [affected.name] is unbearable!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has patched the damaged vein in [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have patched the damaged vein in [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has patched the damaged vein in [target]'s [affected.name] with \the [tool].", \ + "\blue You have patched the damaged vein in [target]'s [affected.name] with \the [tool].") for(var/datum/wound/W in affected.wounds) if(W.internal) affected.wounds -= W @@ -47,9 +47,9 @@ if (ishuman(user) && prob(40)) user:bloody_hands(target, 0) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") affected.take_damage(5, 0) /datum/surgery_step/fix_dead_tissue //Debridement @@ -73,27 +73,27 @@ if (target_zone == "mouth" || target_zone == "eyes") return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected.open >= 2 && (affected.status & ORGAN_DEAD) + return affected && affected.open >= 2 && (affected.status & ORGAN_DEAD) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.display_name] with \the [tool]." , \ - "You start cutting away necrotic tissue in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("The pain in [affected.display_name] is unbearable!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]." , \ + "You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in [affected.name] is unbearable!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has cut away necrotic tissue in [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have cut away necrotic tissue in [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has cut away necrotic tissue in [target]'s [affected.name] with \the [tool].", \ + "\blue You have cut away necrotic tissue in [target]'s [affected.name] with \the [tool].") affected.open = 3 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20, 1) /datum/surgery_step/treat_necrosis @@ -126,18 +126,18 @@ if (target_zone == "mouth" || target_zone == "eyes") return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 3 && (affected.status & ORGAN_DEAD) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 3 && (affected.status & ORGAN_DEAD) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.display_name] with \the [tool]." , \ - "You start applying medication to the affected tissue in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Something in your [affected.display_name] is causing you a lot of pain!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]." , \ + "You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].") + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (!istype(tool, /obj/item/weapon/reagent_containers)) return @@ -151,11 +151,11 @@ if(container.reagents.has_reagent("peridaxon")) affected.status &= ~ORGAN_DEAD - user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.display_name]", \ - "\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.display_name] with \the [tool].") + user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", \ + "\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool].") fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (!istype(tool, /obj/item/weapon/reagent_containers)) return @@ -165,8 +165,8 @@ var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue - user.visible_message("\red [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.display_name] with the [tool]!" , \ - "\red Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.display_name] with the [tool]!") + user.visible_message("\red [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!" , \ + "\red Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!") //no damage or anything, just wastes medicine diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm index 7e768bfa06f..5b524288f9c 100644 --- a/code/modules/surgery/robolimbs.dm +++ b/code/modules/surgery/robolimbs.dm @@ -8,127 +8,11 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - if (!affected) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected) return 0 - if (!(affected.status & ORGAN_DESTROYED)) - return 0 - if (affected.parent) - if (affected.parent.status & ORGAN_DESTROYED) - return 0 - return affected.name != "head" - - -/datum/surgery_step/limb/cut - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/kitchenknife = 75, \ - /obj/item/weapon/shard = 50, \ - ) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return !(affected.status & ORGAN_CUT_AWAY) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].", \ - "You start cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cuts away flesh where [target]'s [affected.display_name] used to be with \the [tool].", \ - "\blue You cut away flesh where [target]'s [affected.display_name] used to be with \the [tool].") - affected.status |= ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, cutting [target]'s [affected.display_name] open!", \ - "\red Your hand slips, cutting [target]'s [affected.display_name] open!") - affected.createwound(CUT, 10) - - -/datum/surgery_step/limb/mend - allowed_tools = list( - /obj/item/weapon/retractor = 100, \ - /obj/item/weapon/crowbar = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 50) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to reposition flesh and nerve endings where where [target]'s [affected.display_name] used to be with [tool].", \ - "You start repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].", \ - "\blue You have finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].") - affected.open = 3 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, tearing flesh on [target]'s [affected.display_name]!", \ - "\red Your hand slips, tearing flesh on [target]'s [affected.display_name]!") - target.apply_damage(10, BRUTE, affected, sharp=1) - - -/datum/surgery_step/limb/prepare - allowed_tools = list( - /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/weapon/flame/lighter = 50, \ - /obj/item/weapon/weldingtool = 25 - ) - - min_duration = 60 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 3 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts adjusting the area around [target]'s [affected.display_name] with \the [tool].", \ - "You start adjusting the area around [target]'s [affected.display_name] with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has finished adjusting the area around [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have finished adjusting the area around [target]'s [affected.display_name] with \the [tool].") - affected.status |= ORGAN_ATTACHABLE - affected.amputated = 1 - affected.setAmputatedTree() - affected.open = 0 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.parent) - affected = affected.parent - user.visible_message("\red [user]'s hand slips, searing [target]'s [affected.display_name]!", \ - "\red Your hand slips, searing [target]'s [affected.display_name]!") - target.apply_damage(10, BURN, affected) - + var/list/organ_data = target.species.has_limbs["[target_zone]"] + return !isnull(organ_data) && !(target_zone in list("head","groin","chest")) /datum/surgery_step/limb/attach allowed_tools = list(/obj/item/robot_parts = 100) @@ -142,32 +26,34 @@ if (p.part) if (!(target_zone in p.part)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.status & ORGAN_ATTACHABLE + return isnull(target.get_organ(target_zone)) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts attaching \the [tool] where [target]'s [affected.display_name] used to be.", \ - "You start attaching \the [tool] where [target]'s [affected.display_name] used to be.") + user.visible_message("[user] starts attaching \the [tool] to [target].", \ + "You start attaching \the [tool] to [target].") end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/robot_parts/L = tool - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has attached \the [tool] where [target]'s [affected.display_name] used to be.", \ - "\blue You have attached \the [tool] where [target]'s [affected.display_name] used to be.") - affected.germ_level = 0 - affected.robotize() - if(L.sabotaged) - affected.sabotaged = 1 - else - affected.sabotaged = 0 + user.visible_message("\blue [user] has attached \the [tool] to [target].", \ + "\blue You have attached \the [tool] to [target].") + + if(L.part) + for(var/part_name in L.part) + if(!isnull(target.get_organ(part_name))) continue + var/list/organ_data = target.species.has_limbs["[target_zone]"] + var/new_limb_type = organ_data["path"] + var/obj/item/organ/external/new_limb = new new_limb_type(target) + new_limb.robotize(L.model_info) + if(L.sabotaged) + new_limb.sabotaged = 1 + target.update_body() target.updatehealth() target.UpdateDamageIcon() + del(tool) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging connectors on [target]'s [affected.display_name]!", \ - "\red Your hand slips, damaging connectors on [target]'s [affected.display_name]!") - target.apply_damage(10, BRUTE, affected, sharp=1) + user.visible_message("\red [user]'s hand slips, damaging [target]'s flesh!", \ + "\red Your hand slips, damaging [target]'s flesh!") + target.apply_damage(10, BRUTE, null, sharp=1) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index b0626cdc778..2fdf26e04e3 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -49,7 +49,7 @@ // does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (can_infect && affected) spread_germs_to_organ(affected, user) if (ishuman(user) && prob(60)) @@ -68,7 +68,7 @@ proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) return null -proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user) +proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/human/user) if(!istype(user) || !istype(E)) return var/germ_level = user.germ_level diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 8b6d9f30e8b..878f8c24be1 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -79,13 +79,13 @@ mob.adjustBruteLoss(10*multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/datum/organ/external/O = pick(H.organs) + var/obj/item/organ/external/O = pick(H.organs) if(prob(25)) - mob << "Your [O.display_name] feels as if it might fall off!" + mob << "Your [O.name] feels as if it might burst!" if(prob(10)) spawn(50) if(O) - O.droplimb(1) + O.droplimb(0,DROPLIMB_BLUNT) else if(prob(75)) mob << "Your whole body feels like it might fall apart!" @@ -153,11 +153,11 @@ if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob var/organ = pick(list("r_arm","l_arm","r_leg","r_leg")) - var/datum/organ/external/E = H.organs_by_name[organ] + var/obj/item/organ/external/E = H.organs_by_name[organ] if (!(E.status & ORGAN_DEAD)) E.status |= ORGAN_DEAD - H << "You can't feel your [E.display_name] anymore..." - for (var/datum/organ/external/C in E.children) + H << "You can't feel your [E.name] anymore..." + for (var/obj/item/organ/external/C in E.children) C.status |= ORGAN_DEAD H.update_body(1) mob.adjustToxLoss(15*multiplier) @@ -165,9 +165,9 @@ deactivate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.status &= ~ORGAN_DEAD - for (var/datum/organ/external/C in E.children) + for (var/obj/item/organ/external/C in E.children) C.status &= ~ORGAN_DEAD H.update_body(1) @@ -178,7 +178,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) if (E.status & ORGAN_BROKEN && prob(30)) E.status ^= ORGAN_BROKEN var/heal_amt = -5*multiplier @@ -199,13 +199,13 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.min_broken_damage = max(5, E.min_broken_damage - 30) deactivate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.min_broken_damage = initial(E.min_broken_damage) ////////////////////////STAGE 3///////////////////////////////// @@ -237,7 +237,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/datum/organ/internal/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] if (B && B.damage < B.min_broken_damage) B.take_damage(5) else diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index feb7aec6a63..2cac2551044 100644 --- a/code/modules/virus2/helpers.dm +++ b/code/modules/virus2/helpers.dm @@ -110,14 +110,14 @@ proc/airborne_can_reach(turf/source, turf/target) //Infects mob M with random lesser disease, if he doesn't have one /proc/infect_mob_random_lesser(var/mob/living/carbon/M) var/datum/disease2/disease/D = new /datum/disease2/disease - + D.makerandom(1) infect_mob(M, D) //Infects mob M with random greated disease, if he doesn't have one /proc/infect_mob_random_greater(var/mob/living/carbon/M) var/datum/disease2/disease/D = new /datum/disease2/disease - + D.makerandom(2) infect_mob(M, D) @@ -158,7 +158,7 @@ proc/airborne_can_reach(turf/source, turf/target) if (ishuman(victim)) var/mob/living/carbon/human/H = victim - var/datum/organ/external/select_area = H.get_organ(src.zone_sel.selecting) + var/obj/item/organ/external/select_area = H.get_organ(src.zone_sel.selecting) var/list/clothes = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform, H.gloves, H.shoes) for(var/obj/item/clothing/C in clothes) if(C && istype(C)) diff --git a/code/setup.dm b/code/setup.dm index 8e18caf8ec8..28a0f1bf843 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -255,6 +255,11 @@ #define slot_legs 21 #define slot_tie 22 +// Mob sprite sheets. These need to be strings as numbers +// cannot be used as associative list keys. +#define icon_l_hand "slot_l_hand" +#define icon_r_hand "slot_r_hand" + // Bitflags for clothing parts. #define HEAD 1 #define FACE 2 @@ -498,6 +503,7 @@ #define SALVED 512 #define ORGAN_DEAD 1024 #define ORGAN_MUTATED 2048 +#define ORGAN_ASSISTED 4096 // Admin permissions. Please don't edit these values without speaking to Errorage first. ~Carn #define R_BUILDMODE 1 @@ -613,22 +619,23 @@ var/list/be_special_flags = list( #define GETPULSE_TOOL 1 // More accurate. (med scanner, sleeper, etc.) // Species flags. -#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out. -#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss. -#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen. -#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator. -#define NO_SLIP 16 // Cannot fall over. -#define NO_POISON 32 // Cannot not suffer toxloss. -#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen. (0-255) -#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen. (RGB) -#define HAS_LIPS 256 // Lips are drawn onto the mob icon. (lipstick) -#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon. -#define IS_PLANT 1024 // Is a treeperson. -#define IS_WHITELISTED 2048 // Must be whitelisted to play. -#define IS_SYNTHETIC 4096 // Is a machine race. -#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen. (RGB) -#define CAN_JOIN 16384 // Species is selectable in chargen. -#define IS_RESTRICTED 32768 // Is not a core/normally playable species. (castes, mutantraces) +#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out. +#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss. +#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen. +#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator. +#define NO_SLIP 16 // Cannot fall over. +#define NO_POISON 32 // Cannot not suffer toxloss. +#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen. (0-255) +#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen. (RGB) +#define HAS_LIPS 256 // Lips are drawn onto the mob icon. (lipstick) +#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon. +#define IS_PLANT 1024 // Is a treeperson. +#define IS_WHITELISTED 2048 // Must be whitelisted to play. +#define IS_SYNTHETIC 4096 // Is a machine race. +#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen. (RGB) +#define CAN_JOIN 16384 // Species is selectable in chargen. +#define IS_RESTRICTED 32768 // Is not a core/normally playable species. (castes, mutantraces) +#define REGENERATES_LIMBS 65536 // Attempts to regenerate unamputated limbs. // Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. @@ -853,6 +860,10 @@ var/list/be_special_flags = list( #define NEXT_MOVE_DELAY 8 +#define DROPLIMB_EDGE 0 +#define DROPLIMB_BLUNT 1 +#define DROPLIMB_BURN 2 + // Custom layer definitions, supplementing the default TURF_LAYER, MOB_LAYER, etc. #define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 #define DOOR_CLOSED_LAYER 3.1 //Above most items if closed diff --git a/code/world.dm b/code/world.dm index ae63acadb2d..01c6b0d1c5e 100644 --- a/code/world.dm +++ b/code/world.dm @@ -52,9 +52,7 @@ var/global/datum/global_init/init = new () sleep_offline = 1 - // Set up roundstart seed list. This is here because vendors were - // bugging out and not populating with the correct packet names - // due to this list not being instantiated. + // Set up roundstart seed list. plant_controller = new() //Create the asteroid Z-level. @@ -64,17 +62,16 @@ var/global/datum/global_init/init = new () // Create autolathe recipes, as above. populate_lathe_recipes() + // Create robolimbs for chargen. + populate_robolimb_list() + processScheduler = new master_controller = new /datum/controller/game_controller() spawn(1) - processScheduler.deferSetupFor(/datum/controller/process/ticker) processScheduler.setup() - master_controller.setup() - - spawn(3000) //so we aren't adding to the round-start lag if(config.ToRban) ToRban_autoupdate() @@ -85,17 +82,6 @@ var/global/datum/global_init/init = new () return -//world/Topic(href, href_list[]) -// world << "Received a Topic() call!" -// world << "[href]" -// for(var/a in href_list) -// world << "[a]" -// if(href_list["hello"]) -// world << "Hello world!" -// return "Hello world!" -// world << "End of Topic() call." -// ..() - var/world_topic_spam_protect_ip = "0.0.0.0" var/world_topic_spam_protect_time = world.timeofday diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index afeb796a299..0c99056632e 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi new file mode 100644 index 00000000000..045c3a57249 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/bishop.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/hesphaistos.dmi b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi new file mode 100644 index 00000000000..5fbcd158619 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/xion.dmi b/icons/mob/human_races/cyberlimbs/xion.dmi new file mode 100644 index 00000000000..daf10298c21 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/xion.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/zenghu.dmi b/icons/mob/human_races/cyberlimbs/zenghu.dmi new file mode 100644 index 00000000000..ca0cff0efa8 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/zenghu.dmi differ diff --git a/icons/mob/human_races/r_diona.dmi b/icons/mob/human_races/r_diona.dmi index 91757faf7ca..3215ea8908b 100644 Binary files a/icons/mob/human_races/r_diona.dmi and b/icons/mob/human_races/r_diona.dmi differ diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi new file mode 100644 index 00000000000..fca687513ab Binary files /dev/null and b/icons/mob/items/lefthand.dmi differ diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi new file mode 100644 index 00000000000..d564d9bafe3 Binary files /dev/null and b/icons/mob/items/lefthand_guns.dmi differ diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi new file mode 100644 index 00000000000..87b3eea46b0 Binary files /dev/null and b/icons/mob/items/righthand.dmi differ diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi new file mode 100644 index 00000000000..63c5c0ae01b Binary files /dev/null and b/icons/mob/items/righthand_guns.dmi differ diff --git a/icons/mob/species/armalis/feet.dmi b/icons/mob/species/armalis/feet.dmi deleted file mode 100644 index cbd83be7027..00000000000 Binary files a/icons/mob/species/armalis/feet.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/gloves.dmi b/icons/mob/species/armalis/gloves.dmi deleted file mode 100644 index 7d3eed317af..00000000000 Binary files a/icons/mob/species/armalis/gloves.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/head.dmi b/icons/mob/species/armalis/head.dmi deleted file mode 100644 index ddb8859fd0d..00000000000 Binary files a/icons/mob/species/armalis/head.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/held.dmi b/icons/mob/species/armalis/held.dmi deleted file mode 100644 index 517709f33c4..00000000000 Binary files a/icons/mob/species/armalis/held.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/mask.dmi b/icons/mob/species/armalis/mask.dmi deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/icons/mob/species/armalis/suit.dmi b/icons/mob/species/armalis/suit.dmi deleted file mode 100644 index 05f9b082cf0..00000000000 Binary files a/icons/mob/species/armalis/suit.dmi and /dev/null differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index ce8762d6e1e..7c823421d3f 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index 2a579370d10..1f0a960d34f 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -4865,7 +4865,7 @@ "bPC" = (/obj/machinery/camera{c_tag = "Medbay Port Corridor"; dir = 8; network = list("SS13")},/obj/structure/disposalpipe/segment,/obj/machinery/light_switch{pixel_x = 22; pixel_y = -9},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bPD" = (/obj/machinery/camera{c_tag = "Medbay CMO Office"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = -9},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Medical Officer's Desk"; departmentType = 5; name = "Chief Medical Officer RC"; pixel_x = -34; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bPE" = (/obj/structure/table,/obj/machinery/computer/skills{pixel_y = 4},/obj/item/device/megaphone,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bPF" = (/obj/structure/table,/obj/item/weapon/paper{desc = "A few notes scratched out by the last CMO before they departed the station."; info = "
    To the incoming CMO of Exodus:


    I wish you and your crew well. Do take note:


    The Medical Emergency Red Phone system has proven itself well. Take care to keep the phones in their designated places as they have been optimised for broadcast. The two handheld green radios (I have left one in this office, and one near the Emergency Entrance) are free to be used. The system has proven effective at alerting Medbay of important details, especially during power outages.

    I think I may have left the toilet cubicle doors shut. It might be a good idea to open them so the staff and patients know they are not engaged.

    The new syringe gun has been stored in secondary storage. I tend to prefer it stored in my office, but 'guidelines' are 'guidelines'.

    Also in secondary storage is the grenade equipment crate. I've just realised I've left it open - you may wish to shut it.

    There were a few problems with their installation, but the Medbay Quarantine shutters should now be working again - they lock down the Emergency and Main entrances to prevent travel in and out. Pray you shan't have to use them.

    The new version of the Medical Diagnostics Manual arrived. I distributed them to the shelf in the staff break room, and one on the table in the corner of this room.

    The exam/triage room has the walking canes in it. I'm not sure why we'd need them - but there you have it.

    Emergency Cryo bags are beside the emergency entrance, along with a kit.

    Spare paper cups for the reception are on the left side of the reception desk.

    I've fed Runtime. She should be fine.


    That should be all. Good luck!
    "; name = "Outgoing CMO's Notes"},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bPF" = (/obj/structure/table,/obj/item/weapon/paper{desc = "A few notes scratched out by the last CMO before they departed the station."; info = "\[i]\[center]To the incoming CMO of Exodus:\[/i]\[/center]\[br]\[br]I wish you and your crew well. Do take note:\[br]\[br]\[br]The Medical Emergency Red Phone system has proven itself well. Take care to keep the phones in their designated places as they have been optimised for broadcast. The two handheld green radios (I have left one in this office, and one near the Emergency Entrance) are free to be used. The system has proven effective at alerting Medbay of important details, especially during power outages.\[br]\[br]I think I may have left the toilet cubicle doors shut. It might be a good idea to open them so the staff and patients know they are not engaged.\[br]\[br]The new syringe gun has been stored in secondary storage. I tend to prefer it stored in my office, but 'guidelines' are 'guidelines'.\[br]\[br]Also in secondary storage is the grenade equipment crate. I've just realised I've left it open - you may wish to shut it.\[br]\[br]There were a few problems with their installation, but the Medbay Quarantine shutters should now be working again - they lock down the Emergency and Main entrances to prevent travel in and out. Pray you shan't have to use them.\[br]\[br]The new version of the Medical Diagnostics Manual arrived. I distributed them to the shelf in the staff break room, and one on the table in the corner of this room.\[br]\[br]The exam/triage room has the walking canes in it. I'm not sure why we'd need them - but there you have it.\[br]\[br]Emergency Cryo bags are beside the emergency entrance, along with a kit.\[br]\[br]Spare paper cups for the reception are on the left side of the reception desk.\[br]\[br]I've fed Runtime. She should be fine.\[br]\[br]\[br]\[center]That should be all. Good luck!\[/center]"; name = "Outgoing CMO's Notes"},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bPG" = (/obj/structure/table,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/computer/med_data/laptop{pixel_x = 3; pixel_y = 4},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/crew_quarters/heads/cmo) "bPH" = (/obj/machinery/camera{c_tag = "Medbay Starboard Corridor"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bPI" = (/obj/structure/disposalpipe/segment,/obj/machinery/newscaster{pixel_x = 30},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm index 517ce91d674..4a6468a5a00 100644 --- a/maps/exodus-2.dmm +++ b/maps/exodus-2.dmm @@ -1215,7 +1215,7 @@ "xs" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "xt" = (/obj/structure/table/rack,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/grenade_launcher,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/rcd,/obj/item/rig_module/device/rcd,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/mounted/egun,/obj/item/rig_module/mounted/egun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "xu" = (/obj/machinery/door/airlock/centcom{name = "Armory Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"xv" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/wall,/area/centcom/specops) +"xv" = (/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "xw" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/specops) "xx" = (/obj/machinery/door/airlock/centcom{name = "Bridge"; opacity = 1; req_access = list(109)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xy" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT0"; name = "Launch Bay #0"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) @@ -1773,7 +1773,7 @@ "Ie" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "If" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/nuclear,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Ig" = (/obj/structure/table/woodentable,/obj/effect/landmark{name = "Teleport-Scroll"},/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/wizard_station) -"Ih" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "

    LIST OF SPELLS AVAILABLE

    Magic Missile:
    This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.

    Fireball:
    This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you.

    Disintegrate:
    This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.

    Disable Technology:
    This spell disables all weapons, cameras and most other technology in range.

    Smoke:
    This spell spawns a cloud of choking smoke at your location and does not require wizard garb.

    Blind:
    This spell temporarly blinds a single person and does not require wizard garb.

    Forcewall:
    This spell creates an unbreakable wall that lasts for 30 seconds and does not require wizard garb.

    Blink:
    This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience.

    Teleport:
    This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable.

    Mutate:
    This spell causes you to turn into a hulk, and gain telekinesis for a short while.

    Ethereal Jaunt:
    This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.

    Knock:
    This spell opens nearby doors and does not require wizard garb.

    "; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) +"Ih" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "\[center]\[b]LIST OF SPELLS AVAILABLE\[/b]\[/center]\[br]\[br]Magic Missile:\[br]This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.\[br]\[br]Fireball:\[br]This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you.\[br]\[br]Disintegrate:\[br]This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.\[br]\[br]Disable Technology:\[br]This spell disables all weapons, cameras and most other technology in range.\[br]\[br]Smoke:\[br]This spell spawns a cloud of choking smoke at your location and does not require wizard garb.\[br]\[br]Blind:\[br]This spell temporarly blinds a single person and does not require wizard garb.\[br]Forcewall:\[br]This spell creates an unbreakable wall that lasts for 30 seconds and does not require wizard garb.\[br]\[br]Blink:\[br]This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience.\[br]\[br]Teleport:\[br]This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable.\[br]\[br]Mutate:\[br]This spell causes you to turn into a hulk, and gain telekinesis for a short while.\[br]\[br]Ethereal Jaunt:\[br]This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.\[br]\[br]Knock:\[br]This spell opens nearby doors and does not require wizard garb.\[br]"; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) "Ii" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/satchel/withwallet,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/wizard_station) "Ij" = (/obj/structure/toilet{pixel_y = 8},/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) "Ik" = (/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) @@ -2128,6 +2128,7 @@ "OV" = (/turf/space,/area/shuttle/skipjack/station) "OW" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "OX" = (/mob/living/carbon/human/monkey{name = "Murphey"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) +"OY" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) (1,1,1) = {" aaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoalahajeEapaqarasatauavawaxayazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtwtwtwtwtwtwtwtwtwtwtwtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaNaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaQ @@ -2258,20 +2259,20 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVqRpepepepepepepepepepeqHoVoVoVoVpFpFtctdpFpFpFtctetdpFqvqvqvpFtftgtgtgtgtgthpFpZqztitjqYqYqYtktlqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVpFtptptptptptptptptppFpFsNpFpFtptptptptptptppFpZqztrtstttttttstuqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvyhyhyhyhyhyhyhxOxOBdtxtxtxtxtxtxpFtytztypFtxtxtxtxtxtxtxtxpZqzqztAtBtBtBtCqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtqtvtDtFtEtHtGtNtvtYuhtZtZuiuaujujululyhzdyIyIyIyIumwGwHwGuntOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvAgtvuyuhuhuhuhuhtvuzuhuhuhuhuhuhuhuhuhyhyByIuAyIyIvexQxQxQvfueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuvbuvuwvguhuhuhuhuhuhuhvbtvvkuhuhuhuhuhuhuhuhuhyhyHvpzqyIyIumwGwHwGunueufufufufpFpFsNpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvbvctvvyuhuhuhuhuhuhuhtvvzuhuhuhuhujvEvAvKvKyhzrzpzEyIyIyhvMvMvMtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtqtvtDtFtEuytNtGtvtYuhtZtZuiuaujujululyhzdyIyIyIyIumwGxvwGuntOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvAgtvuhuhuhuhuhuhtvuzuhuhuhuhuhuhuhuhuhyhyByIuAyIyIvexQxQxQvfueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuvbuvuwvguhuhuhuhuhuhuhvytvvkuhuhuhuhuhuhuhuhuhyhyHvpzqyIyIumwGxvwGunueufufufufpFpFsNpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvbvctvtHuhuhuhuhuhuhuhtvvzuhuhuhuhujvEvAvKvKyhzrzpzEyIyIyhvMvMvMtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvgtvtvtvuhuhuhuhuhuhuhuhtvuhuhuhuhvNtvtvtvtvtvyhyhyhyhyhyhyhxQxQxQtxvOtxvlvmvntxufufuftxvlvmvotxvPtxvqvrvqvrvqugtxtxtxtxurururtxvsvtuPvuvsvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutvIvbvbvJtvvxvQukxovRvSuhuhtvuhuhuhuhvTtvwlwhwhwlwownwqwpxQxQxQxQxQwztxufufvBvCvCvCvCvCvCvCvCvCvDufufwAvqvqvqvqvqugvFuNuotxurururtxvGvGvHvGvGvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVwWuXuVuVuVuYwWwivavbvbwjtvwFwGwGwGwItvuhuhtvuhuhuhuhwBtvuhxQxQwmwEwmwmwmwmwmxQxQxQwPtxufufvVvWvXvXvXvXvXvXvXvYueufufugvZwawbwcwdugweuNuptxurururtxwfwfuNwfwfvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbvbwywowVwYwXxawZwouhuhwouhuhuhuhxbwouhxQxQuwxcxQxQxQwqwqtvtvtvtvtvufufvVwrwsufwtwuwvufwswrueufufugugugugugugugweuNuptxurururtxwwwwuNwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxduXuVuVuVuYxdxevavbvbxgxkxhuhuhuhxlxkuhuhxkuhuhxnxmxpxkxqxQxQxQtvwFwGwHwGwItvwJwJwJtvufufwKwLwMwNwOxrwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutxsvbvbvbtvxtuhuhuhuhtvxuxutvxvxvtvtvtvtvxqxQxQuwuWxfxfxfxfxfxwxfxfxfxwufufufxxufufxiufxiufufxxufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutxsvbvbxMtvxtuhuhuhuhtvxuxutvOYOYtvtvtvtvxqxQxQuwuWxfxfxfxfxfxwxfxfxfxwufufufxxufufxiufxiufufxxufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxyuXuVuVuVuYxyxzxAvbvbuwxHuhuhuhuhuhxHuhuhxIuhuhxKxJxLxLuhxQxQvdtvwFwGwHwGwItvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvbxNxMxHuhuhuhuhuhxHuhuhxRuhuhxQyayayaxQxQxQzcycybydxQyfyetvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvwFwGwGwGwItvygygtvyiuhxQyjylykxQxQxQyRymydxQxQxQxQxcxQxnyztvufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywObtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMdCyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvbvbuwxHuhuhuhuhuhxHuhuhxRuhuhxQyayayaxQxQxQzcycybydxQyfyetvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvvbvbxNtvwFwGwGwGwItvygygtvyiuhxQyjylykxQxQxQyRymydxQxQxQxQxcxQxnyztvufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywObtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhxkzeuhxQzgzgzgxQxQxQxQxcxQxQxQyYyXxkyJyEyFtvufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhtvwCuhuhzhuhuhuhxQxQwCymxQxQxQyYyXtvtvtvtvtvtxtxzitxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvzkzkzlznzmzCzxwDtvzOzDvMtvAbAbtvvMzDzOycAexQxQyYyXtvzsztztzszuzvufzwtxtxtxAhtxtxtxaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt