diff --git a/baystation12.dme b/baystation12.dme index 9d2be5ed2b..9ad0f589c3 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1117,6 +1117,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" @@ -1273,9 +1274,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 6cd983732b..391f5b719a 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/item_attack.dm b/code/_onclick/item_attack.dm index a81c6f30fa..1d68fb54e8 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 2e3d2cc544..5fc86c420a 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 8daad7bfc1..2e8e4bfd3f 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 0000000000..fd8c7f4590 --- /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 8ab0f1b491..37a2adecb6 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 1d6d703c16..f6fbbc110c 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 2b45d1f778..9fe4226e5b 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 4ffa5ea512..9bfdf9f0b6 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 08a479963b..1362aa6888 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 0000000000..00810f50e1 --- /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 530a009b67..7126bbc7f6 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() diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 51f77c2cc0..f2f5f96de7 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 30ce1206e5..3c9e684c5f 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) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index ba53c38525..27236dd8fb 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/job_controller.dm b/code/game/jobs/job_controller.dm index f6ec2ad87d..360245ccf1 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 98ebc5a626..51e1ec7510 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/bioprinter.dm b/code/game/machinery/bioprinter.dm index 207da09a04..48c0edb984 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/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0040ac0e92..40c137e77b 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 4f310de8b9..1a47ae81fd 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 74e7de9934..1283e7e52c 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/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 534e59c0c6..940ec0f104 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 1499af4996..176b6dea6c 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 87b8375bbb..f000499ffd 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 cdc7b26bbf..840d779510 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 db86bf36a1..c6b3137806 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 b52c5930f9..9077398fbb 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -119,11 +119,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 +497,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 +527,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/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 2746c70a74..87f7b0fd8a 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 e0731443d5..1a646d3fe1 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 8deb8d7a50..ee1021116b 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 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 27e3eea6f7..e59220c848 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 798c6c0511..f85bc336be 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/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index d78c7d4093..dc6787a73b 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/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index bda28f83b1..03d8ccdffc 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 73c14edc88..85bec3a8ea 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 ea3b7d5752..3969ddd1ef 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() 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() 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 6d6e5ad4cb..b274c9aeb5 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 diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 1b1d5b04f3..f04be5d33a 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 a4fc0081c2..6b48653a6a 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/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 822b986488..626ed7aba2 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/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index bd34960a35..8747bbfacf 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/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index d8c811d2f6..20d96676ed 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 5b23e90a01..8384d118f3 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -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 8a1e35ca98..bce7eabe9d 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 a23bb65cf8..900baea3f3 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/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 40ba963efd..4ee9b728a6 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -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 47d9f7289b..8ce25ddb67 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 489e81a739..fad0c3d0bd 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/watercloset.dm b/code/game/objects/structures/watercloset.dm index e77f1e602c..62f3ef60c1 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/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1702fc4dbc..d83d4da747 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 5ffd58353e..39ec298775 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1835,7 +1835,7 @@ 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) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 7f7c3fe8e9..676ee17cd1 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 493b681be3..5a5e09a5ac 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 f3d46739f2..a67efd084c 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/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 7bf622b539..15c4a68308 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/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index e82bb3457f..f516b609ff 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/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 043e44db9d..6734510a5b 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/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 67d630119a..10f5961da7 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 a3b601ebce..698815d0a9 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/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index cd12ead385..1f89c16ff9 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 2369cb9fe5..548eee230b 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 6ec6b4fce4..d2aa61e635 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 26ad526e95..ed18254deb 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) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 4976cba4fb..311942ca02 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 6b40a64198..65fa5c522e 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,0,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 73f8fc90ee..965870f97e 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 b6f1a67597..9c3057c52d 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 82c03a181f..a8e645eeb3 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 561659a27a..e96e526077 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 ff02684de8..300b7ce184 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 @@ -70,10 +72,10 @@ emp_act u_equip(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 155492a36b..749903dc2a 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 0000000000..3c0f9e011c --- /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) + u_equip(l_hand) + else + u_equip(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) + u_equip(l_hand) + else + u_equip(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/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index d1f8b21f05..67d17c2560 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) ) @@ -407,7 +407,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 +695,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 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 9881ca1311..847bebe7f0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -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 bf007450e3..e3f10cf92e 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -42,13 +42,13 @@ ) 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) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index ea03c44e45..09f3360d45 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 bb922b905b..c3312b9a7a 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 f04a8cb367..ce106c4191 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 0e148b0236..0f4f8364ee 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 8cf07fc8d5..62907752aa 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 4bdddc2ca6..093025189b 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 c7c7fcc903..6fbdfa8ddb 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 2fc44af935..caea1ae7a8 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 4265f1b39a..913e3e71ad 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 d033e70610..148baf6618 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 dadebe8c57..71a87099a2 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 @@ -925,48 +856,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/shock.dm b/code/modules/mob/living/carbon/shock.dm index b76b7a49b7..a83e76ef76 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 d040c03e55..848ffe6e47 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 diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index 0f84806a1f..cb86e52302 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 0ca5e36828..333ea3540d 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 af2a923c96..b0fd2a5121 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 5bc3d41afc..73de95acee 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 5895c42d71..747cde86ce 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.")) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4379db6c17..3ee11cc9f6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -589,8 +589,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 +1101,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 +1116,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 +1137,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 4f83216e81..4121517589 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -125,7 +125,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 +140,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 bd00faf953..63974f1c25 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -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 d25b66210e..ea87e5984b 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)) diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 5f045736dc..1eab38904c 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 495ce2762c..5d307fffcf 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 4a36d23659..d326e2ade4 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 4dcc006df6..28cc8c741d 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)) + dropped = 1 + droplimb(0,1) + 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() + else + droplimb(0,2) 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() 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 = 0 - // 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(0) + 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(1) + 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(2) + 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(0) + 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(1) + new /obj/effect/decal/cleanable/ash(get_turf(owner)) + if(2) + 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 0000000000..d5b6bf2a4e --- /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 b6154242b9..c552631abf 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 51e657a6f9..0000000000 --- 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 0000000000..c08363e10b --- /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 49cc2073df..31cb0c4e43 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 0000000000..8d19d60b49 --- /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 43ed04b0d0..a2219b262a 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/cable.dm b/code/modules/power/cable.dm index 4ce3d4ba3e..f652ebe9ec 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 0000000000..8a4d25ae20 --- /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/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm index 860169d7b2..917d3c338e 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/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 1399fdd14a..1b710dbfc6 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 22c0bf6da8..bc36317521 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 68db3b98c8..45ee8b95f2 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -1576,9 +1576,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/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 01bddd0431..9a9dc18c60 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]")) @@ -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 d1d3937c97..5a6e8a46db 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/surgery/bones.dm b/code/modules/surgery/bones.dm index 605b1503d5..b2ccbb1003 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 85b5dd8dd3..60fdffe31d 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 72cff7ab3d..fedf5bbc1c 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 81170afc39..edc1c54c67 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 b5b22659f4..e25291eba5 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 b7a4bfa61c..ca4a7dafe4 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) 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 85a56a754e..9957ee8b78 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 9a8c77e480..df394fcd43 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 146cf3eda6..cbfea6912e 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,16 +367,16 @@ 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].") + 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].") user.drop_item(tool) var/obj/item/organ/O = tool if(istype(O)) @@ -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 c954c16de6..56418b70c8 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 7e768bfa06..5b524288f9 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 b0626cdc77..2fdf26e04e 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 8b6d9f30e8..3153bd4f9b 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 fall off!" if(prob(10)) spawn(50) if(O) - O.droplimb(1) + O.droplimb() 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 feb7aec6a6..2cac255104 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 ad9dc8a5fe..7d8e678a54 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -498,6 +498,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 +614,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. diff --git a/code/world.dm b/code/world.dm index ae63acadb2..01c6b0d1c5 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/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi new file mode 100644 index 0000000000..045c3a5724 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 0000000000..5fbcd15861 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 0000000000..daf10298c2 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 0000000000..ca0cff0efa 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 91757faf7c..3215ea8908 100644 Binary files a/icons/mob/human_races/r_diona.dmi and b/icons/mob/human_races/r_diona.dmi differ