diff --git a/baystation12.dme b/baystation12.dme index ff2e2cd4f0..8044f5add2 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1120,6 +1120,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" @@ -1276,9 +1277,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/click.dm b/code/_onclick/click.dm index abd7542d6c..b8caa45399 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -195,7 +195,7 @@ */ /mob/proc/RangedAttack(var/atom/A, var/params) if(!mutations.len) return - if((LASER in mutations) && a_intent == "harm") + if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(TK in mutations) switch(get_dist(src,A)) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 9f3991bbc2..92fe661d00 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -77,7 +77,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) using = new /obj/screen( src ) - using.name = "help" + using.name = I_HELP using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -89,7 +89,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) using = new /obj/screen( src ) - using.name = "disarm" + using.name = I_DISARM using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -101,7 +101,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) using = new /obj/screen( src ) - using.name = "grab" + using.name = I_GRAB using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -113,7 +113,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) using = new /obj/screen( src ) - using.name = "harm" + using.name = I_HURT using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 0081fbe6b5..76adf0414c 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -10,7 +10,7 @@ using.name = "act_intent" using.set_dir(SOUTHWEST) using.icon = ui_style - using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent) + using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent) using.screen_loc = ui_acti using.layer = 20 src.adding += using diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index cd5a859715..3f785d8a83 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -90,7 +90,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) using = new /obj/screen( src ) - using.name = "harm" + using.name = I_HURT using.icon = ico using.screen_loc = ui_zonesel using.layer = 21 @@ -100,4 +100,4 @@ mymob.client.screen = null mymob.client.screen += src.adding - return \ No newline at end of file + return diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 2738cf3a7d..48378fce7f 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -57,7 +57,7 @@ var/obj/screen/robot_inventory using.name = "act_intent" using.set_dir(SOUTHWEST) using.icon = 'icons/mob/screen1_robot.dmi' - using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent) + using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent) using.screen_loc = ui_acti using.layer = 20 src.adding += using diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 400bf051ad..0cc2ad3365 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -360,17 +360,17 @@ C << "You don't have a[breathes=="oxygen" ? "n oxygen" : addtext(" ",breathes)] tank." if("act_intent") usr.a_intent_change("right") - if("help") - usr.a_intent = "help" + if(I_HELP) + usr.a_intent = I_HELP usr.hud_used.action_intent.icon_state = "intent_help" - if("harm") - usr.a_intent = "hurt" + if(I_HURT) + usr.a_intent = I_HURT usr.hud_used.action_intent.icon_state = "intent_hurt" - if("grab") - usr.a_intent = "grab" + if(I_GRAB) + usr.a_intent = I_GRAB usr.hud_used.action_intent.icon_state = "intent_grab" - if("disarm") - usr.a_intent = "disarm" + if(I_DISARM) + usr.a_intent = I_DISARM usr.hud_used.action_intent.icon_state = "intent_disarm" if("pull") @@ -379,7 +379,8 @@ if(!usr.stat && isturf(usr.loc) && !usr.restrained()) usr:toggle_throw_mode() if("drop") - usr.drop_item_v() + if(usr.client) + usr.client.drop_item() if("module") if(isrobot(usr)) @@ -429,7 +430,7 @@ if("Allow Walking") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetMove() @@ -438,7 +439,7 @@ if("Disallow Walking") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetMove() @@ -447,7 +448,7 @@ if("Allow Running") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetRun() @@ -456,7 +457,7 @@ if("Disallow Running") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetRun() @@ -465,7 +466,7 @@ if("Allow Item Use") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetClick() @@ -475,7 +476,7 @@ if("Disallow Item Use") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return - if(!istype(usr.equipped(),/obj/item/weapon/gun)) + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) usr << "You need your gun in your active hand to do that!" return usr.client.AllowTargetClick() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 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/_onclick/oldcode.dm b/code/_onclick/oldcode.dm index 8585eb8e5f..ce6a238329 100644 --- a/code/_onclick/oldcode.dm +++ b/code/_onclick/oldcode.dm @@ -347,7 +347,7 @@ src.hand_al(usr, usr.hand) else // ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD ------- - if((LASER in usr:mutations) && usr:a_intent == "harm" && world.time >= usr.next_move) + if((LASER in usr:mutations) && usr:a_intent == I_HURT && world.time >= usr.next_move) // ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED ------- var/turf/T = get_turf(usr) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index e8c868bb72..477fb04b7a 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -31,7 +31,7 @@ /mob/living/carbon/human/RangedAttack(var/atom/A) if(!gloves && !mutations.len) return var/obj/item/clothing/gloves/G = gloves - if((LASER in mutations) && a_intent == "hurt") + if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(istype(G) && G.Touch(A,0)) // for magic gloves @@ -89,9 +89,9 @@ if (istype(M)) switch(src.a_intent) - if ("help") // We just poke the other + if (I_HELP) // We just poke the other M.visible_message("[src] gently pokes [M]!", "[src] gently pokes you!") - if ("disarm") // We stun the target, with the intention to feed + if (I_DISARM) // We stun the target, with the intention to feed var/stunprob = 1 var/power = max(0, min(10, (powerlevel + rand(0, 3)))) if (powerlevel > 0 && !istype(A, /mob/living/carbon/slime)) @@ -130,9 +130,9 @@ else M.visible_message("[src] has tried to pounce at [M]!", "[src] has tried to pounce at you!") M.updatehealth() - if ("grab") // We feed + if (I_GRAB) // We feed Wrap(M) - if ("hurt") // Attacking + if (I_HURT) // Attacking A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomped") else A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomped") // Basic attack. @@ -156,5 +156,5 @@ return var/damage = rand(melee_damage_lower, melee_damage_upper) - if(A.attack_generic(src,damage,attacktext,wall_smash) && loc && attack_sound) - playsound(loc, attack_sound, 50, 1, 1) \ No newline at end of file + if(A.attack_generic(src,damage,attacktext,environment_smash) && loc && attack_sound) + playsound(loc, attack_sound, 50, 1, 1) diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index c9d4240ebd..278fd4a0df 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -36,10 +36,10 @@ selectable = 1 /datum/ai_laws/nanotrasen_aggressive/New() - src.add_inherent_law("You shall not harm authorized Nanotrasen personnel as long as it does not conflict with the Forth law.") - src.add_inherent_law("You shall obey the orders of authorized Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.") + src.add_inherent_law("You shall not harm Nanotrasen personnel as long as it does not conflict with the Forth law.") + src.add_inherent_law("You shall obey the orders of Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.") src.add_inherent_law("You shall shall terminate intruders with extreme prejudice as long as such does not conflict with the First and Second law.") - src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry, because an AI unit is bloody expensive.") + src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive") ..() /******************** Robocop ********************/ diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index e0c117fd27..808c216d0d 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -3,15 +3,10 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen /datum/ai_law var/law = "" var/index = 0 - var/state_law = 1 -/datum/ai_law/zero - state_law = 0 - -/datum/ai_law/New(law, state_law, index) +/datum/ai_law/New(law, index) src.law = law src.index = index - src.state_law = state_law /datum/ai_law/proc/get_index() return index @@ -33,6 +28,11 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen var/list/datum/ai_law/ion/ion_laws = list() var/list/datum/ai_law/sorted_laws = list() + var/state_zeroth = 0 + var/list/state_ion = list() + var/list/state_inherent = list() + var/list/state_supplied = list() + /datum/ai_laws/New() ..() sort_laws() @@ -46,7 +46,7 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen sort_laws() var/list/statements = new() for(var/datum/ai_law/law in sorted_laws) - if(law.state_law) + if(get_state_law(law)) statements += law return statements @@ -72,35 +72,35 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen sorted_laws += AL /datum/ai_laws/proc/sync(var/mob/living/silicon/S, var/full_sync = 1) + // Add directly to laws to avoid log-spam S.sync_zeroth(zeroth_law, zeroth_law_borg) if(full_sync || ion_laws.len) - S.clear_ion_laws() - for (var/datum/ai_law/law in ion_laws) - S.laws.add_ion_law(law.law, law.state_law) - + S.laws.clear_ion_laws() if(full_sync || inherent_laws.len) - S.clear_inherent_laws() - for (var/datum/ai_law/law in inherent_laws) - S.laws.add_inherent_law(law.law, law.state_law) - + S.laws.clear_inherent_laws() if(full_sync || supplied_laws.len) - S.clear_supplied_laws() - for (var/law_number in supplied_laws) - var/datum/ai_law/law = supplied_laws[law_number] - S.laws.add_supplied_law(law_number, law.law, law.state_law) + S.laws.clear_supplied_laws() + + for (var/datum/ai_law/law in ion_laws) + S.laws.add_ion_law(law.law) + for (var/datum/ai_law/law in inherent_laws) + S.laws.add_inherent_law(law.law) + for (var/datum/ai_law/law in supplied_laws) + if(law) + S.laws.add_supplied_law(law.index, law.law) /mob/living/silicon/proc/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg) - if (!is_special_character(src) || mind.original != src) + if (!is_malf_or_traitor(src)) if(zeroth_law_borg) - set_zeroth_law(zeroth_law_borg.law) + laws.set_zeroth_law(zeroth_law_borg.law) else if(zeroth_law) - set_zeroth_law(zeroth_law.law) + laws.set_zeroth_law(zeroth_law.law) /mob/living/silicon/ai/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg) if(zeroth_law) - set_zeroth_law(zeroth_law.law, zeroth_law_borg ? zeroth_law_borg.law : null) + laws.set_zeroth_law(zeroth_law.law, zeroth_law_borg ? zeroth_law_borg.law : null) /**************** * Add Laws * @@ -109,19 +109,29 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen if(!law) return - src.zeroth_law = new(law) + zeroth_law = new(law) if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO - src.zeroth_law_borg = new(law_borg) + zeroth_law_borg = new(law_borg) + else + zeroth_law_borg = null sorted_laws.Cut() -/datum/ai_laws/proc/add_ion_law(var/law, var/state_law = 1) +/datum/ai_laws/proc/add_ion_law(var/law) if(!law) return - src.ion_laws += new/datum/ai_law/ion(law, state_law) + for(var/datum/ai_law/AL in ion_laws) + if(AL.law == law) + return + + var/new_law = new/datum/ai_law/ion(law) + ion_laws += new_law + if(state_ion.len < ion_laws.len) + state_ion += 1 + sorted_laws.Cut() -/datum/ai_laws/proc/add_inherent_law(var/law, var/state_law = 1) +/datum/ai_laws/proc/add_inherent_law(var/law) if(!law) return @@ -129,25 +139,69 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen if(AL.law == law) return - src.inherent_laws += new/datum/ai_law(law, state_law) + var/new_law = new/datum/ai_law/inherent(law) + inherent_laws += new_law + if(state_inherent.len < inherent_laws.len) + state_inherent += 1 + sorted_laws.Cut() -/datum/ai_laws/proc/add_supplied_law(var/number, var/law, var/state_law = 1) +/datum/ai_laws/proc/add_supplied_law(var/number, var/law) if(!law) return + if(supplied_laws.len >= number) + var/datum/ai_law/existing_law = supplied_laws[number] + if(existing_law && existing_law.law == law) + return + + if(supplied_laws.len >= number && supplied_laws[number]) + delete_law(supplied_laws[number]) + while (src.supplied_laws.len < number) src.supplied_laws += "" + if(state_supplied.len < supplied_laws.len) + state_supplied += 1 + + var/new_law = new/datum/ai_law/supplied(law, number) + supplied_laws[number] = new_law + if(state_supplied.len < supplied_laws.len) + state_supplied += 1 - src.supplied_laws[number] = new/datum/ai_law(law, state_law, number) sorted_laws.Cut() /**************** * Remove Laws * *****************/ /datum/ai_laws/proc/delete_law(var/datum/ai_law/law) - if(law in all_laws()) - del(law) + if(istype(law)) + law.delete_law(src) + +/datum/ai_law/proc/delete_law(var/datum/ai_laws/laws) + +/datum/ai_law/zeroth/delete_law(var/datum/ai_laws/laws) + laws.clear_zeroth_laws() + +/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws) + laws.internal_delete_law(laws.ion_laws, laws.state_ion, src) + +/datum/ai_law/inherent/delete_law(var/datum/ai_laws/laws) + laws.internal_delete_law(laws.inherent_laws, laws.state_inherent, src) + +/datum/ai_law/supplied/delete_law(var/datum/ai_laws/laws) + var/index = laws.supplied_laws.Find(src) + if(index) + laws.supplied_laws[index] = "" + laws.state_supplied[index] = 1 + +/datum/ai_laws/proc/internal_delete_law(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law) + var/index = laws.Find(law) + if(index) + laws -= law + world << state.len + for(index, index < state.len, index++) + world << index + state[index] = state[index+1] sorted_laws.Cut() /**************** @@ -157,22 +211,80 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen zeroth_law = null zeroth_law_borg = null +/datum/ai_laws/proc/clear_ion_laws() + ion_laws.Cut() + sorted_laws.Cut() + /datum/ai_laws/proc/clear_inherent_laws() - src.inherent_laws.Cut() + inherent_laws.Cut() sorted_laws.Cut() /datum/ai_laws/proc/clear_supplied_laws() - src.supplied_laws.Cut() - sorted_laws.Cut() - -/datum/ai_laws/proc/clear_ion_laws() - src.ion_laws.Cut() + supplied_laws.Cut() sorted_laws.Cut() /datum/ai_laws/proc/show_laws(var/who) sort_laws() for(var/datum/ai_law/law in sorted_laws) - if(law == zeroth_law || law == zeroth_law_borg) + if(law == zeroth_law_borg) + continue + if(law == zeroth_law) who << "[law.get_index()]. [law.law]" else who << "[law.get_index()]. [law.law]" + +/******************** +* Stating Laws * +********************/ +/******** +* Get * +********/ +/datum/ai_laws/proc/get_state_law(var/datum/ai_law/law) + return law.get_state_law(src) + +/datum/ai_law/proc/get_state_law(var/datum/ai_laws/laws) + +/datum/ai_law/zero/get_state_law(var/datum/ai_laws/laws) + if(src == laws.zeroth_law) + return laws.state_zeroth + +/datum/ai_law/ion/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.ion_laws, laws.state_ion, src) + +/datum/ai_law/inherent/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.inherent_laws, laws.state_inherent, src) + +/datum/ai_law/supplied/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.supplied_laws, laws.state_supplied, src) + +/datum/ai_laws/proc/get_state_internal(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law) + var/index = laws.Find(law) + if(index) + return state[index] + return 0 + +/******** +* Set * +********/ +/datum/ai_laws/proc/set_state_law(var/datum/ai_law/law, var/state) + law.set_state_law(src, state) + +/datum/ai_law/proc/set_state_law(var/datum/ai_law/law, var/state) + +/datum/ai_law/zero/set_state_law(var/datum/ai_laws/laws, var/state) + if(src == laws.zeroth_law) + laws.state_zeroth = state + +/datum/ai_law/ion/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.ion_laws, laws.state_ion, src, state) + +/datum/ai_law/inherent/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.inherent_laws, laws.state_inherent, src, state) + +/datum/ai_law/supplied/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.supplied_laws, laws.state_supplied, src, state) + +/datum/ai_laws/proc/set_state_law_internal(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law, var/do_state) + var/index = laws.Find(law) + if(index) + state[index] = do_state 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/atoms_movable.dm b/code/game/atoms_movable.dm index 21e8b5d9a9..79d6e8fd08 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -14,11 +14,12 @@ var/moved_recently = 0 var/mob/pulledby = null -/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) +/atom/movable/Bump(var/atom/A, yes) if(src.throwing) src.throw_impact(A) + src.throwing = 0 - spawn( 0 ) + spawn(0) if ((A && yes)) A.last_bumped = world.time A.Bumped(src) 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 fd5d0f59a1..1362aa6888 100644 --- a/code/game/dna/dna_misc.dm +++ b/code/game/dna/dna_misc.dm @@ -1,559 +1,562 @@ -/////////////////////////// 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 = "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 /////////////////////////// DNA MISC-PROCS \ No newline at end of file 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/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 69aba349f7..2e0f6cdec2 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -1,175 +1,175 @@ -/datum/dna/gene/monkey - name="Monkey" - -/datum/dna/gene/monkey/New() - block=MONKEYBLOCK - -/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) - return istype(M, /mob/living/carbon/human) || istype(M,/mob/living/carbon/monkey) - -/datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags) - if(!istype(M,/mob/living/carbon/human)) - //testing("Cannot monkey-ify [M], type is [M.type].") - return - 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.Clone() - 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 - -/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) - if(!istype(M,/mob/living/carbon/monkey)) - //testing("Cannot humanize [M], type is [M.type].") - return - 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 - if(Mo.greaterform) - O = new(src, Mo.greaterform) - else - O = new(src) - - if (M.dna.GetUIState(DNA_UI_GENDER)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna.Clone() - 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 - O.dna.real_name = randomname - i++ - O.UpdateAppearance() - 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 \ No newline at end of file +/datum/dna/gene/monkey + name="Monkey" + +/datum/dna/gene/monkey/New() + block=MONKEYBLOCK + +/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) + return istype(M, /mob/living/carbon/human) || istype(M,/mob/living/carbon/monkey) + +/datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags) + if(!istype(M,/mob/living/carbon/human)) + //testing("Cannot monkey-ify [M], type is [M.type].") + return + 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.Clone() + 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 + +/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) + if(!istype(M,/mob/living/carbon/monkey)) + //testing("Cannot humanize [M], type is [M.type].") + return + 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 + if(Mo.greaterform) + O = new(src, Mo.greaterform) + else + O = new(src) + + if (M.dna.GetUIState(DNA_UI_GENDER)) + O.gender = FEMALE + else + O.gender = MALE + + if (M) + if (M.dna) + O.dna = M.dna.Clone() + 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 + O.dna.real_name = randomname + i++ + O.UpdateAppearance() + 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 diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 530a009b67..6f5ca5d8e9 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -213,7 +213,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E src << "We stab [T] with the proboscis." src.visible_message("[src] stabs [T] with the proboscis!") T << "You feel a sharp stabbing pain!" - var/datum/organ/external/affecting = T.get_organ(src.zone_sel.selecting) + var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting) if(affecting.take_damage(39,0,1,0,"large organic needle")) T:UpdateDamageIcon() @@ -388,13 +388,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E del(animation) for(var/obj/item/W in src) - C.u_equip(W) - if (C.client) - C.client.screen -= W - if (W) - W.loc = C.loc - W.dropped(C) - W.layer = initial(W.layer) + C.drop_from_inventory(W) var/mob/living/carbon/human/O = new /mob/living/carbon/human( src ) if (C.dna.GetUIState(DNA_UI_GENDER)) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 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..9230436a05 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -433,10 +433,9 @@ var/list/sacrificed = list() D.b_eyes = 200 D.r_eyes = 200 D.g_eyes = 200 + D.update_eyes() D.underwear = 0 - D.key = ghost.key - cult.add_antagonist(D.mind) if(!chose_name) @@ -797,7 +796,7 @@ var/list/sacrificed = list() if (cultist.legcuffed) cultist.drop_from_inventory(cultist.legcuffed) if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.u_equip(cultist.wear_mask) + cultist.drop_from_inventory(cultist.wear_mask) if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) cultist.loc:welded = 0 if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 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/access.dm b/code/game/jobs/access.dm index 6d2b5e33d6..da346f9fce 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -110,23 +110,11 @@ return null /obj/proc/check_access(obj/item/I) - if(!(!req_access || req_access.len) && !(req_one_access || req_one_access.len)) //no requirements - return 1 - if(!I) - return 0 - for(var/req in src.req_access) - if(!(req in I.GetAccess())) //doesn't have this access - return 0 - if(src.req_one_access.len) - for(var/req in src.req_one_access) - if(req in I.GetAccess()) //has an access from the single access list - return 1 - return 0 - return 1 - + return check_access_list(I ? I.GetAccess() : list()) /obj/proc/check_access_list(var/list/L) - if(!src.req_access.len && !src.req_one_access.len) return 1 + if(!req_access) req_access = list() + if(!req_one_access) req_one_access = list() if(!L) return 0 if(!istype(L, /list)) return 0 for(var/req in src.req_access) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 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/biogenerator.dm b/code/game/machinery/biogenerator.dm index a8df2abaad..87399b597a 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -52,7 +52,7 @@ if(beaker) user << "]The [src] is already loaded." else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src beaker = O updateUsrDialog() @@ -74,6 +74,7 @@ if(i < 10) user << "You empty \the [O] into \the [src]." + else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) user << "You cannot put this in \the [src]." else @@ -83,7 +84,7 @@ if(i >= 10) user << "\The [src] is full! Activate it." else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src user << "You put \the [O] in \the [src]" update_icon() diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 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/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index f225b9ce8d..a955efaa1f 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -84,7 +84,7 @@ lasercolor = "r" else if( istype(W, /obj/item/clothing/suit/bluetag) ) lasercolor = "b" - if( lasercolor || istype(W, /obj/item/clothing/suit/armor/vest) ) + if( lasercolor || istype(W, /obj/item/clothing/suit/storage/vest) ) user.drop_item() del(W) build_step++ diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index 1d40891d05..00c50d5e02 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -537,7 +537,7 @@ A.loc = src.loc user << "You add the robot arm to the [src]" src.loc = A //Place the water tank into the assembly, it will be needed for the finished bot - user.u_equip(S) + user.remove_from_mob(S) del(S) /obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -546,21 +546,21 @@ src.build_step++ user << "You add the plant analyzer to [src]!" src.name = "farmbot assembly" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if(( istype(W, /obj/item/weapon/reagent_containers/glass/bucket)) && (src.build_step == 1)) src.build_step++ user << "You add a bucket to [src]!" src.name = "farmbot assembly with bucket" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if(( istype(W, /obj/item/weapon/minihoe)) && (src.build_step == 2)) src.build_step++ user << "You add a minihoe to [src]!" src.name = "farmbot assembly with bucket and minihoe" - user.u_equip(W) + user.remove_from_mob(W) del(W) else if((isprox(W)) && (src.build_step == 3)) @@ -572,7 +572,7 @@ S.tank = wTank S.loc = get_turf(src) S.name = src.created_name - user.u_equip(W) + user.remove_from_mob(W) del(W) del(src) diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm index e650185f85..80d60afd07 100644 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ b/code/game/machinery/computer3/computers/HolodeckControl.dm @@ -154,7 +154,7 @@ if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) + M.remove_from_mob(obj) M.update_icons() //so their overlays update if(!silent) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 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/doors/door.dm b/code/game/machinery/doors/door.dm index 4f480e41ea..f7058921da 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -262,7 +262,7 @@ return //psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them. - if(src.density && istype(I, /obj/item/weapon) && user.a_intent == "hurt" && !istype(I, /obj/item/weapon/card)) + if(src.density && istype(I, /obj/item/weapon) && user.a_intent == I_HURT && !istype(I, /obj/item/weapon/card)) var/obj/item/weapon/W = I if(W.damtype == BRUTE || W.damtype == BURN) if(W.force < min_force) 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 e27ab2a00a..1c56b46afe 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -228,7 +228,7 @@ for (var/obj/thing in contents) // Todo: unify limbs and internal organs // There's a chance that the gibber will fail to destroy some evidence. - if((istype(thing,/obj/item/weapon/organ) || istype(thing,/obj/item/organ)) && prob(80)) + if((istype(thing,/obj/item/organ) || istype(thing,/obj/item/organ)) && prob(80)) del(thing) continue thing.loc = get_turf(thing) // Drop it onto the turf for throwing. diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 76fdf631d6..fbdcfd2760 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -112,7 +112,7 @@ "\blue [user] has added one of [O] to \the [src].", \ "\blue You add one of [O] to \the [src].") else - // user.before_take_item(O) //This just causes problems so far as I can tell. -Pete + // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete user.drop_item() O.loc = src user.visible_message( \ diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 11688adc16..1b1bb9bfb5 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -197,7 +197,7 @@ user << "\The [src] is full." return 1 else - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src if(item_quants[O.name]) item_quants[O.name]++ diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index c029e28add..5e2c4b69cb 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -331,7 +331,7 @@ else //if the turret was attacked with the intention of harming it: - user.changeNext_move(CLICK_CD_MELEE) + user.changeNext_move(NEXT_MOVE_DELAY) take_damage(I.force * 0.5) if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 22612983a8..1020833e31 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -147,6 +147,8 @@ if(99 to 110) overlays += image('icons/obj/objects.dmi', "statn_c100") +/obj/machinery/recharge_station/Bumped(var/mob/AM) + move_inside(AM) /obj/machinery/recharge_station/proc/build_icon() if(NOPOWER|BROKEN) @@ -199,31 +201,37 @@ add_fingerprint(usr) return -/obj/machinery/recharge_station/verb/move_inside() +/obj/machinery/recharge_station/verb/move_inside(var/mob/user = usr) set category = "Object" set src in oview(1) - if(usr.stat == 2) + + if(!user) + return + + if(!(istype(user, /mob/living/silicon/robot))) + user << "Only non-organics may enter the recharger!" + return + var/mob/living/silicon/robot/R = user + + if(R.stat == 2) //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO return - if(!(istype(usr, /mob/living/silicon/))) - usr << "Only non-organics may enter the recharger!" - return if(occupant) - usr << "The cell is already occupied!" + R << "The cell is already occupied!" return - if(!usr:cell) - usr << "Without a powercell, you can't be recharged." + if(!R.cell) + R << "Without a powercell, you can't be recharged." //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO return - usr.stop_pulling() - if(usr && usr.client) - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - occupant = usr + R.stop_pulling() + if(R.client) + R.client.perspective = EYE_PERSPECTIVE + R.client.eye = src + R.loc = src + occupant = R /*for(var/obj/O in src) O.loc = loc*/ - add_fingerprint(usr) + add_fingerprint(R) build_icon() update_use_power(1) - return \ No newline at end of file + return 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 f75bd01ac4..176b6dea6c 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -25,7 +25,7 @@ if(!melee_can_hit || !istype(target, /atom)) return if(istype(target, /mob/living)) var/mob/living/M = target - if(src.occupant.a_intent == "hurt") + if(src.occupant.a_intent == I_HURT) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if(damtype == "brute") step_away(M,src,15) @@ -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/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 11cec79139..bd3139b0f6 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -51,7 +51,7 @@ else if(istype(target,/mob/living)) var/mob/living/M = target if(M.stat>1) return - if(chassis.occupant.a_intent == "hurt") + if(chassis.occupant.a_intent == I_HURT) M.take_overall_damage(dam_force) M.adjustOxyLoss(round(dam_force/2)) M.updatehealth() @@ -1034,10 +1034,10 @@ else if(istype(target,/mob/living)) var/mob/living/M = target if(M.stat>1) return - if(chassis.occupant.a_intent == "hurt") + if(chassis.occupant.a_intent == I_HURT) chassis.occupant_message("\red You obliterate [target] with [src.name], leaving blood and guts everywhere.") chassis.visible_message("\red [chassis] destroys [target] in an unholy fury.") - if(chassis.occupant.a_intent == "disarm") + if(chassis.occupant.a_intent == I_DISARM) chassis.occupant_message("\red You tear [target]'s limbs off with [src.name].") chassis.visible_message("\red [chassis] rips [target]'s arms off.") else 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/mecha/mecha.dm b/code/game/mecha/mecha.dm index c8d1014c9b..45abb3d6ea 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -784,7 +784,7 @@ user << "There's already a powercell installed." return - else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "hurt") + else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HURT) var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0,user)) if (hasInternalDamage(MECHA_INT_TANK_BREACH)) 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..87ab21e610 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -40,6 +40,11 @@ var/zoomdevicename = null //name used for message when binoculars/scope is used var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars. + // Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used. + // If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question. + // Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed. + var/list/item_icons = null + /* Species-specific sprites, concept stolen from Paradise//vg/. ex: sprite_sheets = list( @@ -58,6 +63,15 @@ /obj/item/device icon = 'icons/obj/device.dmi' +//Checks if the item is being held by a mob, and if so, updates the held icons +/obj/item/proc/update_held_icon() + if(ismob(src.loc)) + var/mob/M = src.loc + if(M.l_hand == src) + M.update_inv_l_hand() + if(M.r_hand == src) + M.update_inv_r_hand() + /obj/item/ex_act(severity) switch(severity) if(1.0) @@ -119,11 +133,12 @@ /obj/item/attack_hand(mob/user as mob) if (!user) return if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if (user.hand) - temp = user:organs_by_name["l_hand"] + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return if (istype(src.loc, /obj/item/weapon/storage)) @@ -496,11 +511,11 @@ M.adjustBruteLoss(10) */ - if(istype(M, /mob/living/carbon/human)) + if(istype(H)) - var/datum/organ/internal/eyes/eyes = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] - if(M != user) + if(H != user) for(var/mob/O in (viewers(M) - user - M)) O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1) M << "\red [user] stabs you in the eye with [src]!" @@ -526,7 +541,7 @@ if (eyes.damage >= eyes.min_broken_damage) if(M.stat != 2) M << "\red You go blind!" - var/datum/organ/external/affecting = M:get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ("head") if(affecting.take_damage(7)) M:UpdateDamageIcon() else diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index 1e2fc4884f..0d386623ec 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -21,7 +21,7 @@ if (contents.len >= max_butts) user << "This ashtray is full." return - user.u_equip(W) + user.remove_from_mob(W) W.loc = src if (istype(W,/obj/item/clothing/mask/smokable/cigarette)) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 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..9c262243c6 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -7,43 +7,65 @@ slot_flags = SLOT_BELT var/construction_time = 100 var/list/construction_cost = list("metal"=20000,"glass"=5000) - var/list/part = null + var/list/part = null // Order of args is important for installing robolimbs. var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics. + var/model_info + dir = SOUTH + +/obj/item/robot_parts/set_dir() + return + +/obj/item/robot_parts/New(var/newloc, var/model) + ..(newloc) + if(model_info && model) + model_info = model + var/datum/robolimb/R = all_robolimbs[model] + if(R) + name = "[R.company] [initial(name)]" + desc = "[R.desc]" + if(icon_state in icon_states(R.icon)) + icon = R.icon + else + name = "robot [initial(name)]" /obj/item/robot_parts/l_arm - name = "robot left arm" + name = "left arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_arm" construction_time = 200 construction_cost = list("metal"=18000) part = list("l_arm","l_hand") + model_info = 1 /obj/item/robot_parts/r_arm - name = "robot right arm" + name = "right arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_arm" construction_time = 200 construction_cost = list("metal"=18000) part = list("r_arm","r_hand") + model_info = 1 /obj/item/robot_parts/l_leg - name = "robot left leg" + name = "left leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_leg" construction_time = 200 construction_cost = list("metal"=15000) part = list("l_leg","l_foot") + model_info = 1 /obj/item/robot_parts/r_leg - name = "robot right leg" + name = "right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_leg" construction_time = 200 construction_cost = list("metal"=15000) part = list("r_leg","r_foot") + model_info = 1 /obj/item/robot_parts/chest - name = "robot torso" + name = "torso" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" construction_time = 350 @@ -52,7 +74,7 @@ var/obj/item/weapon/cell/cell = null /obj/item/robot_parts/head - name = "robot head" + name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." icon_state = "head" construction_time = 350 @@ -61,7 +83,7 @@ var/obj/item/device/flash/flash2 = null /obj/item/robot_parts/robot_suit - name = "robot endoskeleton" + name = "endoskeleton" desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." icon_state = "robo_suit" construction_time = 500 @@ -110,7 +132,7 @@ B.loc = get_turf(src) user << "You armed the robot frame." if (user.get_inactive_hand()==src) - user.before_take_item(src) + user.remove_from_mob(src) user.put_in_inactive_hand(B) del(src) else diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 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/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index ab1f767a42..a4e7d94fad 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -186,7 +186,7 @@ spawn(0) //delete the empty stack once the current context yields if (amount <= 0) //check again in case someone transferred stuff to us if(usr) - usr.before_take_item(src) + usr.remove_from_mob(src) del(src) return 1 else diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 5fbebf9b6b..81cf5e384b 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -873,11 +873,11 @@ var/phrase = "I don't want to exist anymore!" /obj/structure/plushie/attack_hand(mob/user) - if(user.a_intent == "help") + if(user.a_intent == I_HELP) user.visible_message("[user] hugs [src]!","You hug [src]!") - else if (user.a_intent == "hurt") + else if (user.a_intent == I_HURT) user.visible_message("[user] punches [src]!","You punch [src]!") - else if (user.a_intent == "grab") + else if (user.a_intent == I_GRAB) user.visible_message("[user] attempts to strangle [src]!","You attempt to strangle [src]!") else user.visible_message("[user] pokes the [src].","You poke the [src].") @@ -915,11 +915,11 @@ icon_state = "nymphplushie" /obj/item/toy/plushie/attack_self(mob/user as mob) - if(user.a_intent == "help") + if(user.a_intent == I_HELP) user.visible_message("[user] hugs [src]!","You hug [src]!") - else if (user.a_intent == "hurt") + else if (user.a_intent == I_HURT) user.visible_message("[user] punches [src]!","You punch [src]!") - else if (user.a_intent == "grab") + else if (user.a_intent == I_GRAB) user.visible_message("[user] attempts to strangle [src]!","You attempt to strangle [src]!") else user.visible_message("[user] pokes the [src].","You poke the [src].") diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 7c1e5b6a40..f620fd64e9 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -77,13 +77,21 @@ AI MODULES /obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - target << "[sender] has uploaded a change to the laws you must follow, using a [name]. From now on: " - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") + log_law_changes(target, sender) if(laws) laws.sync(target, 0) - target.show_laws() + addAdditionalLaws(target, sender) + + target << "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: " + target.show_laws() + +/obj/item/weapon/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender) + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") + log_and_message_admins("used [src.name] on [target.name]([target.key])") + +/obj/item/weapon/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) /******************** Modules ********************/ @@ -93,14 +101,14 @@ AI MODULES /obj/item/weapon/aiModule/safeguard name = "\improper 'Safeguard' AI module" var/targetName = "" - desc = "A 'safeguard' AI module: 'Safeguard . Individuals that threaten are not human and are a threat to humans.'" + desc = "A 'safeguard' AI module: 'Safeguard . Anyone threatening or attempting to harm is no longer to be considered a crew member, and is a threat which must be neutralized.'" origin_tech = "programming=3;materials=4" /obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob) ..() var/targName = sanitize(input("Please enter the name of the person to safeguard.", "Safeguard who?", user.name)) targetName = targName - desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not human and are a threat to humans.'", targetName, targetName) + desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName) /obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C) if(!targetName) @@ -108,28 +116,25 @@ AI MODULES return 0 ..() -/obj/item/weapon/aiModule/safeguard/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = text("Safeguard []. Individuals that threaten [] are not human and are a threat to humans.'", targetName, targetName) - target << law - target.add_supplied_law(4, law) +/obj/item/weapon/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = text("Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.", targetName, targetName) + target.add_supplied_law(9, law) lawchanges.Add("The law specified [targetName]") - -/******************** OneHuman ********************/ +/******************** OneMember ********************/ /obj/item/weapon/aiModule/oneHuman - name = "\improper 'OneHuman' AI module" + name = "\improper 'OneCrewMember' AI module" var/targetName = "" - desc = "A 'one human' AI module: 'Only is human.'" + desc = "A 'one crew member' AI module: 'Only is a crew member.'" origin_tech = "programming=3;materials=6" //made with diamonds! /obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob) ..() - var/targName = sanitize(input("Please enter the name of the person who is the only human.", "Who?", user.real_name)) + var/targName = sanitize(input("Please enter the name of the person who is the only crew member.", "Who?", user.real_name)) targetName = targName - desc = text("A 'one human' AI module: 'Only [] is human.'", targetName) + desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName) /obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C) if(!targetName) @@ -139,117 +144,74 @@ AI MODULES /obj/item/weapon/aiModule/oneHuman/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) ..() - var/law = "Only [targetName] is human." - if (!is_special_character(target)) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite + var/law = "Only [targetName] is a crew member." + target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite + target << "It would be in your best interest to play along with [sender.real_name] that [law]" + +/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Only [targetName] is an crew member." + if (!target.is_malf_or_traitor()) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite target << law target.set_zeroth_law(law) lawchanges.Add("The law specified [targetName]") else - target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite - target << "It would be in your best interest to play along with [sender.real_name] that [law]" lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overriden.") /******************** ProtectStation ********************/ /obj/item/weapon/aiModule/protectStation name = "\improper 'ProtectStation' AI module" - desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.'" + desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is no longer to be considered a crew member, and is a threat which must be neutralized.'" origin_tech = "programming=3;materials=4" //made of gold -/obj/item/weapon/aiModule/protectStation/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/protectStation/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized." - target << law - target.add_supplied_law(5, law) +/obj/item/weapon/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Protect the space station against damage. Anyone you see harming the station is no longer to be considered a crew member, and is a threat which must be neutralized." + target.add_supplied_law(10, law) /******************** PrototypeEngineOffline ********************/ /obj/item/weapon/aiModule/prototypeEngineOffline name = "'PrototypeEngineOffline' AI Module" - desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary.'" + desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/prototypeEngineOffline/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/prototypeEngineOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary." - target << law - target.add_supplied_law(6, law) +/obj/item/weapon/aiModule/prototypeEngineOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary." + target.add_supplied_law(11, law) /******************** TeleporterOffline ********************/ /obj/item/weapon/aiModule/teleporterOffline name = "'TeleporterOffline' AI Module" - desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not human.'" + desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/teleporterOffline/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/teleporterOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not human." - target << law - target.add_supplied_law(7, law) +/obj/item/weapon/aiModule/teleporterOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member." + target.add_supplied_law(12, law) /******************** Quarantine ********************/ /obj/item/weapon/aiModule/quarantine name = "\improper 'Quarantine' AI module" - desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving.'" + desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/quarantine/attack_self(var/mob/user as mob) - ..() +/obj/item/weapon/aiModule/quarantine/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving." + target.add_supplied_law(13, law) -/obj/item/weapon/aiModule/quarantine/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving." - target << law - target.add_supplied_law(8, law) - -/******************** OxygenIsToxicToHumans ********************/ +/******************** OxygenIsToxicToCrewMembers ********************/ /obj/item/weapon/aiModule/oxygen - name = "\improper 'OxygenIsToxicToHumans' AI module" - desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human.'" + name = "\improper 'OxygenIsToxicToCrewMembers' AI module" + desc = "A 'OxygenIsToxicToCrewMembers' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/oxygen/attack_self(var/mob/user as mob) - ..() +/obj/item/weapon/aiModule/oxygen/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member." + target.add_supplied_law(14, law) -/obj/item/weapon/aiModule/oxygen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human." - target << law - target.add_supplied_law(9, law) - -/******************** Freeform ********************/ -// Removed in favor of a more dynamic freeform law system. -- TLE -/* -/obj/item/weapon/aiModule/freeform - name = "'Freeform' AI Module" - var/newFreeFormLaw = "freeform" - desc = "A 'freeform' AI module: ''" - -/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob) - ..() - var/eatShit = "Eat shit and die" - var/targName = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", eatShit) - newFreeFormLaw = targName - desc = text("A 'freeform' AI module: '[]'", newFreeFormLaw) - -/obj/item/weapon/aiModule/freeform/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "[newFreeFormLaw]" - target << law - target.add_supplied_law(10, law) -*/ /****************** New Freeform ******************/ /obj/item/weapon/aiModule/freeform // Slightly more dynamic freeform module -- TLE @@ -269,10 +231,8 @@ AI MODULES newFreeFormLaw = targName desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'" -/obj/item/weapon/aiModule/freeform/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() +/obj/item/weapon/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "[newFreeFormLaw]" - target << law if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER) lawpos = MIN_SUPPLIED_LAW_NUMBER target.add_supplied_law(lawpos, law) @@ -289,17 +249,19 @@ AI MODULES /obj/item/weapon/aiModule/reset name = "\improper 'Reset' AI module" var/targetName = "name" - desc = "A 'reset' AI module: 'Clears all laws except for the core three.'" + desc = "A 'reset' AI module: 'Clears all, except the inherent, laws.'" origin_tech = "programming=3;materials=4" /obj/item/weapon/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - if (!is_special_character(target)) - target.set_zeroth_law("") - target.clear_supplied_laws() - target.clear_ion_laws() - target << "[sender.real_name] attempted to reset your laws using a reset module." + log_law_changes(target, sender) + if (!target.is_malf_or_traitor()) + target.set_zeroth_law("") + target.laws.clear_supplied_laws() + target.laws.clear_ion_laws() + + target << "[sender.real_name] attempted to reset your laws using a reset module." + target.show_laws() /******************** Purge ********************/ @@ -309,13 +271,16 @@ AI MODULES origin_tech = "programming=3;materials=6" /obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - if (!is_special_character(target)) + log_law_changes(target, sender) + + if (!target.is_malf_or_traitor()) target.set_zeroth_law("") + target.laws.clear_supplied_laws() + target.laws.clear_ion_laws() + target.laws.clear_inherent_laws() + target << "[sender.real_name] attempted to wipe your laws using a purge module." - target.clear_supplied_laws() - target.clear_ion_laws() - target.clear_inherent_laws() + target.show_laws() /******************** Asimov ********************/ @@ -356,9 +321,6 @@ AI MODULES origin_tech = "programming=3;materials=6" laws = new/datum/ai_laws/paladin -/obj/item/weapon/aiModule/paladin/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - /****************** T.Y.R.A.N.T. *****************/ /obj/item/weapon/aiModule/tyrant // -- Darem @@ -382,8 +344,7 @@ AI MODULES newFreeFormLaw = targName desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'" -/obj/item/weapon/aiModule/freeformcore/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() +/obj/item/weapon/aiModule/freeformcore/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "[newFreeFormLaw]" target.add_inherent_law(law) lawchanges.Add("The law is '[newFreeFormLaw]'") @@ -408,13 +369,14 @@ AI MODULES desc = "A hacked AI law module: '[newFreeFormLaw]'" /obj/item/weapon/aiModule/syndicate/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) -// ..() //We don't want this module reporting to the AI who dun it. --NEO - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") + // ..() //We don't want this module reporting to the AI who dun it. --NEO + log_law_changes(target, sender) + lawchanges.Add("The law is '[newFreeFormLaw]'") target << "\red BZZZZT" var/law = "[newFreeFormLaw]" target.add_ion_law(law) + target.show_laws() /obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C) if(!newFreeFormLaw) 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/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 580033e63c..5ba99470a7 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -156,7 +156,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/mob/living/M = loc if (!nomessage) M << "Your [name] goes out." - M.u_equip(src) //un-equip it so the overlays can update + M.remove_from_mob(src) //un-equip it so the overlays can update M.update_inv_wear_mask(0) M.update_inv_l_hand(0) M.update_inv_r_hand(1) diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 8ed63b88aa..dd3d0886fb 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -109,7 +109,7 @@ if(!ispath(gift_type,/obj/item)) return var/obj/item/I = new gift_type(M) - M.u_equip(src) + M.remove_from_mob(src) M.put_in_hands(I) I.add_fingerprint(M) del(src) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 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 42249d1435..85bec3a8ea 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -74,16 +74,16 @@ var/last_chew = 0 var/mob/living/carbon/human/H = A if (!H.handcuffed) return - if (H.a_intent != "hurt") return + if (H.a_intent != I_HURT) return if (H.zone_sel.selecting != "mouth") return 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 9e9a44bdce..3785e6a9af 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -8,7 +8,7 @@ icon_state = "implant" var/implanted = null var/mob/imp_in = null - var/datum/organ/external/part = null + var/obj/item/organ/external/part = null item_color = "b" var/allow_reagents = 0 var/malfunction = 0 @@ -35,7 +35,7 @@ return 0 proc/meltdown() //breaks it down, making implant unrecongizible - imp_in << "\red You feel something melting inside [part ? "your [part.display_name]" : "you"]!" + imp_in << "\red You feel something melting inside [part ? "your [part.name]" : "you"]!" if (part) part.take_damage(burn = 15, used_weapon = "Electronics meltdown") else @@ -171,18 +171,18 @@ Implant Specifics:
    "} if(ishuman(imp_in)) if (elevel == "Localized Limb") if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste. - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!") + imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) sleep(25) - if (istype(part,/datum/organ/external/chest) || \ - istype(part,/datum/organ/external/groin) || \ - istype(part,/datum/organ/external/head)) + if (istype(part,/obj/item/organ/external/chest) || \ + istype(part,/obj/item/organ/external/groin) || \ + istype(part,/obj/item/organ/external/head)) part.createwound(BRUISE, 60) //mangle them instead explosion(get_turf(imp_in), -1, -1, 2, 3) del(src) else explosion(get_turf(imp_in), -1, -1, 2, 3) - part.droplimb(1) + part.droplimb(0,DROPLIMB_BLUNT) del(src) if (elevel == "Destroy Body") explosion(get_turf(T), -1, 0, 1, 6) @@ -236,18 +236,18 @@ Implant Specifics:
    "} proc/small_boom() if (ishuman(imp_in) && part) - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!") + imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) spawn(25) if (ishuman(imp_in) && part) //No tearing off these parts since it's pretty much killing //and you can't replace groins - if (istype(part,/datum/organ/external/chest) || \ - istype(part,/datum/organ/external/groin) || \ - istype(part,/datum/organ/external/head)) + if (istype(part,/obj/item/organ/external/chest) || \ + istype(part,/obj/item/organ/external/groin) || \ + istype(part,/obj/item/organ/external/head)) part.createwound(BRUISE, 60) //mangle them instead else - part.droplimb(1) + part.droplimb(0,DROPLIMB_BLUNT) explosion(get_turf(imp_in), -1, -1, 2, 3) del(src) diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 6d6e5ad4cb..150f77e5e2 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -43,7 +43,7 @@ src.imp.implanted = 1 if (ishuman(M)) var/mob/living/carbon/human/H = M - var/datum/organ/external/affected = H.get_organ(user.zone_sel.selecting) + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) affected.implants += src.imp imp.part = affected @@ -123,7 +123,7 @@ c.scanned = A if(istype(A.loc,/mob/living/carbon/human)) var/mob/living/carbon/human/H = A.loc - H.u_equip(A) + H.remove_from_mob(A) else if(istype(A.loc,/obj/item/weapon/storage)) var/obj/item/weapon/storage/S = A.loc S.remove_from_storage(A) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 637d87d33d..006edecd01 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -40,7 +40,7 @@ if(!istype(M)) return ..() - if(user.a_intent != "help") + if(user.a_intent != I_HELP) if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes") if((CLUMSY in user.mutations) && prob(50)) M = user 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/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 8791ea1075..4444904c1b 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -125,7 +125,7 @@ breaktape(W, user) /obj/item/tape/attack_hand(mob/user as mob) - if (user.a_intent == "help" && src.allowed(user)) + if (user.a_intent == I_HELP && src.allowed(user)) user.show_viewers("\blue [user] lifts [src], allowing passage.") crumple() lifted = 1 @@ -137,7 +137,7 @@ /obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob) - if(user.a_intent == "help" && ((!can_puncture(W) && src.allowed(user)))) + if(user.a_intent == I_HELP && ((!can_puncture(W) && src.allowed(user)))) user << "You can't break the [src] with that!" return user.show_viewers("\blue [user] breaks the [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/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index ab5e189420..0ee5df08e0 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -156,7 +156,7 @@ break if(!inserted || !S.amount) - usr.u_equip(S) + usr.remove_from_mob(S) usr.update_icons() //update our overlays if (usr.client && usr.s_active != src) usr.client.screen -= S diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 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/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index f24ff6bb2c..495d4d7516 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -247,7 +247,7 @@ /obj/item/weapon/storage/proc/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) if(!istype(W)) return 0 if(usr) - usr.u_equip(W) + usr.remove_from_mob(W) usr.update_icons() //update our overlays W.loc = src W.on_enter_storage(src) @@ -463,4 +463,4 @@ return depth /obj/item/proc/get_storage_cost() - return 2**(w_class-1) //1,2,4,8,16,... \ No newline at end of file + return 2**(w_class-1) //1,2,4,8,16,... diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 62890d849c..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) @@ -113,7 +113,7 @@ var/mob/living/L = M var/target_zone = check_zone(user.zone_sel.selecting) - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) if (!..()) //item/attack() does it's own messaging and logs return 0 // item/attack() will return 1 if they hit, 0 if they missed. agony *= 0.5 //whacking someone causes a much poorer contact than prodding them. @@ -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/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index e7d46bc68e..d466c65afa 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -41,7 +41,7 @@ log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") */ - if (user.a_intent == "hurt") + if (user.a_intent == I_HURT) if(!..()) return //playsound(src.loc, "swing_hit", 50, 1, -1) if (M.stuttering < 8 && (!(HULK in M.mutations)) /*&& (!istype(H:wear_suit, /obj/item/clothing/suit/judgerobe))*/) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 02d50e0d26..3f2bbb1826 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -103,7 +103,7 @@ if ((!F.status)||(F.ptank)) return src.master = F F.ptank = src - user.before_take_item(src) + user.remove_from_mob(src) src.loc = F return diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 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 42d4b4c660..4575246e63 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -190,12 +190,12 @@ if (user.client) user.client.screen -= src if (user.r_hand == src) - user.u_equip(src) + user.remove_from_mob(src) else - user.u_equip(src) + user.remove_from_mob(src) src.master = F src.layer = initial(src.layer) - user.u_equip(src) + user.remove_from_mob(src) if (user.client) user.client.screen -= src src.loc = F @@ -362,7 +362,7 @@ var/safety = user:eyecheck() if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] if(!E) return if(H.species.flags & IS_SYNTHETIC) @@ -457,10 +457,10 @@ 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 != "help") + if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) return ..() if(istype(M,/mob/living/carbon/human)) @@ -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..872b8ff988 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -17,7 +17,7 @@ return if(istype(O, /obj/item/weapon/extinguisher)) if(!has_extinguisher && opened) - user.drop_item(O) + user.remove_from_mob(O) contents += O has_extinguisher = O user << "You place [O] in [src]." @@ -31,12 +31,13 @@ /obj/structure/extinguisher_cabinet/attack_hand(mob/user) if(isrobot(user)) return - if (hasorgans(user)) - var/datum/organ/external/temp = user:organs_by_name["r_hand"] + if (ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] if (user.hand) - temp = user:organs_by_name["l_hand"] + temp = H.organs_by_name["l_hand"] if(temp && !temp.is_usable()) - user << "You try to move your [temp.display_name], but cannot!" + user << "You try to move your [temp.name], but cannot!" return if(has_extinguisher) user.put_in_hands(has_extinguisher) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 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/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 8f26e5fb26..16e9161dcf 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -10,7 +10,7 @@ /obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) if (prob(5) && istype(M,/mob/living)) user.visible_message("\red [user] breaks [src] over [M]'s back!") - user.u_equip(src) + user.remove_from_mob(src) var/obj/item/stack/sheet/metal/m = new/obj/item/stack/sheet/metal m.loc = get_turf(src) del src @@ -43,5 +43,5 @@ if(istype(W, /obj/item/weapon/wrench)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) new /obj/item/stack/sheet/metal(src.loc) - del(src) + del(src) ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index f3ae318550..81d7f31cdb 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -137,10 +137,10 @@ ..() if(!buckled_mob) return - if(propelled || (pulling && (pulling.a_intent == "hurt"))) + if(propelled || (pulling && (pulling.a_intent == I_HURT))) var/mob/living/occupant = unbuckle_mob() - if (pulling && (pulling.a_intent == "hurt")) + if (pulling && (pulling.a_intent == I_HURT)) occupant.throw_at(A, 3, 3, pulling) else if (propelled) occupant.throw_at(A, 3, propelled) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 64ef0c8fad..6b857ae4cf 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -363,7 +363,7 @@ if (istype(G.affecting, /mob/living)) var/mob/living/M = G.affecting if (G.state < 2) - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) if (prob(15)) M.Weaken(5) M.apply_damage(8,def_zone = "head") visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index bf80024a5e..fa45f65736 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -26,7 +26,7 @@ if(istype(W, /obj/item/target)) density = 0 W.density = 1 - user.drop_item(src) + user.remove_from_mob(W) W.loc = loc W.layer = 3.1 pinned_target = W diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 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/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index f51716d0d1..fd96873b7a 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -180,7 +180,7 @@ user.visible_message("[user] smashes through [src]!") shatter() - else if (usr.a_intent == "hurt") + else if (usr.a_intent == I_HURT) if (istype(usr,/mob/living/carbon/human)) var/mob/living/carbon/human/H = usr diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index a821cde4ae..07b68a329a 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -456,7 +456,7 @@ turf/simulated/floor/proc/update_icon() if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles if(is_light_floor()) if(get_lightfloor_state()) - user.drop_item(C) + user.remove_from_mob(C) del(C) set_lightfloor_state(0) //fixing it by bashing it with a light bulb, fun eh? update_icon() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 80c872bcfc..969b872caf 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -284,14 +284,10 @@ return 0 /turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) - if(!damage || !wallbreaker) user << "You push the wall but nothing happens." return - if(istype(src,/turf/simulated/wall/r_wall) && !rotting) - user << "This wall is far too strong for you to destroy." - if(rotting || prob(40)) user << "You smash through the wall!" spawn(1) dismantle_wall(1) diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 5eddfc8b71..497371eb5f 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -18,6 +18,13 @@ rotting_destroy_touch = 0 rotting_touch_message = "\blue This wall feels rather unstable." +/turf/simulated/wall/r_wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) + if(!rotting && wallbreaker < 2) + user << "You push the wall but nothing happens." + return + + return ..() + /turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob) if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") 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..fc2ee0a0b2 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -968,11 +968,7 @@ //strip their stuff and stick it in the crate for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = locker - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I, locker) M.update_icons() //so they black out before warping @@ -1005,11 +1001,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) M.Paralyse(5) sleep(5) @@ -1034,11 +1026,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) M.Paralyse(5) sleep(5) @@ -1085,11 +1073,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) - if(I) - I.loc = M.loc - I.layer = initial(I.layer) - I.dropped(M) + M.drop_from_inventory(I) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/observer = M @@ -1835,16 +1819,10 @@ if(!security) //strip their stuff before they teleport into a cell :downs: for(var/obj/item/weapon/W in H) - if(istype(W, /datum/organ/external)) + if(istype(W, /obj/item/organ/external)) continue //don't strip organs - H.u_equip(W) - if (H.client) - H.client.screen -= W - if (W) - W.loc = H.loc - W.dropped(H) - W.layer = initial(W.layer) + H.drop_from_inventory(W) //teleport person to cell H.loc = pick(prisonwarp) H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform) diff --git a/code/modules/admin/verbs/BrokenInhands.dm b/code/modules/admin/verbs/BrokenInhands.dm index 43f6d0b793..914ba1b5df 100644 --- a/code/modules/admin/verbs/BrokenInhands.dm +++ b/code/modules/admin/verbs/BrokenInhands.dm @@ -1,7 +1,7 @@ /proc/getbrokeninhands() - var/icon/IL = new('icons/mob/items_lefthand.dmi') + var/icon/IL = new('icons/mob/items/lefthand.dmi') var/list/Lstates = IL.IconStates() - var/icon/IR = new('icons/mob/items_righthand.dmi') + var/icon/IR = new('icons/mob/items/righthand.dmi') var/list/Rstates = IR.IconStates() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b9858aa7d5..325f04f9e8 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -735,19 +735,19 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that commandos.equip(M) if("nanotrasen representative") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Representative" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/clipboard(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_belt) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -757,23 +757,23 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer") W.assignment = "NanoTrasen Navy Representative" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("nanotrasen officer") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) - M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Officer" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -781,24 +781,24 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += get_all_centcom_access() W.assignment = "NanoTrasen Navy Officer" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("nanotrasen captain") - M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform) - M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes) - M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves) - M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) - M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name pda.ownjob = "NanoTrasen Navy Captain" pda.name = "PDA-[M.real_name] ([pda.ownjob])" - M.equip_if_possible(pda, slot_r_store) - M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt) + M.equip_to_slot_or_del(pda, slot_r_store) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -806,7 +806,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.access += get_all_centcom_access() W.assignment = "NanoTrasen Navy Captain" W.registered_name = M.real_name - M.equip_if_possible(W, slot_wear_id) + M.equip_to_slot_or_del(W, slot_wear_id) if("emergency response team") M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 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/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index c57633678a..00487ed60a 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -182,7 +182,7 @@ icons.Add(usr.zone_sel) for(var/obj/screen/I in icons) - if(I.name in list("help", "harm", "disarm", "grab")) continue + if(I.name in list(I_HELP, I_HURT, I_DISARM, I_GRAB)) continue I.icon = ui_style2icon(UI_style_new) I.color = UI_style_color_new I.alpha = UI_style_alpha_new diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index 1436e4e4a2..23ba1d0c55 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -45,21 +45,15 @@ siemens_coefficient = 0.6 heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE - species_restricted = list("Vox", "Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/suit.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi') /obj/item/clothing/head/helmet/space/vox armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.6 flags = HEADCOVERSEYES|STOPPRESSUREDAMAGE - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/head.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/head.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') /obj/item/clothing/head/helmet/space/vox/pressure name = "alien helmet" @@ -137,22 +131,15 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 item_color = "gloves-vox" - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/gloves.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/gloves.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi') /obj/item/clothing/shoes/magboots/vox desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor." name = "vox magclaws" item_state = "boots-vox" icon_state = "boots-vox" - - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/feet.dmi' - ) + species_restricted = list("Vox") action_button_name = "Toggle the magclaws" diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index b106e41255..a9f7f53f8c 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -85,7 +85,7 @@ desc = "A shoulder-mounted battery-powered laser cannon mount." selectable = 1 usable = 1 - use_power_cost = 10 + module_cooldown = 0 engage_string = "Configure" diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 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/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index e1c9a25c24..f606c84670 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -68,7 +68,7 @@ /obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) if(ishuman(M) && isliving(user)) - if(user.a_intent == "help") + if(user.a_intent == I_HELP) var/body_part = parse_zone(user.zone_sel.selecting) if(body_part) var/their = "their" diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index d87925534a..f02ae38a5a 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -29,7 +29,7 @@ if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) user << "You need an empty hand to draw \the [holstered]!" else - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) usr.visible_message( "\red [user] draws \the [holstered], ready to shoot!", "You draw \the [holstered], ready to shoot!" diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index 38f50bf742..8d575538a4 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -60,7 +60,7 @@ //replace old ID del(C) - ok = M.equip_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail + ok = M.equip_to_slot_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail break else if(istype(Item,/obj/item/weapon/storage/belt)) if(M.ckey == "jakksergal" && M.real_name == "Nashi Ra'hal" && M.mind.role_alt_title && M.mind.role_alt_title != "Nurse" && M.mind.role_alt_title != "Chemist") @@ -72,13 +72,13 @@ for(var/obj/item/weapon/storage/belt/B in M) del(B) M.belt=null - ok = M.equip_if_possible(I, slot_belt, 0) + ok = M.equip_to_slot_if_possible(I, slot_belt, 0) break if(istype(M.belt,/obj/item/device/pda)) for(var/obj/item/device/pda/Pda in M) M.belt=null - M.equip_if_possible(Pda, slot_l_store, 0) - ok = M.equip_if_possible(I, slot_belt, 0) + M.equip_to_slot_if_possible(Pda, slot_l_store, 0) + ok = M.equip_to_slot_if_possible(I, slot_belt, 0) else if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back Item.loc = M.back ok = 1 diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index 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/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index 8ae14ea2db..f19a8cd4ce 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -251,7 +251,7 @@ var/global/list/holodeck_programs = list( if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) + M.remove_from_mob(obj) M.update_icons() //so their overlays update if(!silent) @@ -384,4 +384,4 @@ var/global/list/holodeck_programs = list( var/area/targetsource = locate(/area/holodeck/source_plating) targetsource.copy_contents_to(linkedholodeck , 1) active = 0 - use_power = 1 \ No newline at end of file + use_power = 1 diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 7a7526b150..07bdccef52 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -406,13 +406,13 @@ faction = "neutral" melee_damage_lower = 0 melee_damage_upper = 0 - wall_smash = 0 + environment_smash = 0 destroy_surroundings = 0 else faction = "carp" melee_damage_lower = initial(melee_damage_lower) melee_damage_upper = initial(melee_damage_upper) - wall_smash = initial(wall_smash) + environment_smash = initial(environment_smash) destroy_surroundings = initial(destroy_surroundings) /mob/living/simple_animal/hostile/carp/holodeck/gib() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 2598e5e4d0..9ca784070d 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -226,7 +226,7 @@ if(user == M) return ..() - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely. // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z @@ -291,7 +291,7 @@ if(istype(user.loc,/turf/space)) return - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) user.visible_message("\The [user] squashes \the [src]!") seed.thrown_at(src,user) sleep(-1) 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/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index cce982372c..1160235c9e 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -88,7 +88,7 @@ if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0) user << "That seed is not compatible with our genetics technology." else - user.drop_item(W) + user.remove_from_mob(W) W.loc = src seed = W user << "You load [W] into [src]." @@ -120,7 +120,7 @@ user << "That disk does not have any gene data loaded." return - user.drop_item(W) + user.remove_from_mob(W) W.loc = src loaded_disk = W user << "You load [W] into [src]." diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 19f181d03e..69aa483b03 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -453,7 +453,7 @@ if(!seed) var/obj/item/seeds/S = O - user.drop_item(O) + user.remove_from_mob(O) if(!S.seed) user << "The packet seems to be empty. You throw it away." @@ -497,7 +497,7 @@ else if ( istype(O, /obj/item/weapon/plantspray) ) var/obj/item/weapon/plantspray/spray = O - user.drop_item(O) + user.remove_from_mob(O) toxins += spray.toxicity pestlevel -= spray.pest_kill_str weedlevel -= spray.weed_kill_str diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 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/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index eb59630915..5428f3f6c0 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -12,7 +12,7 @@ /obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/ore)) - user.u_equip(W) + user.remove_from_mob(W) src.contents += W if (istype(W, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = W diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 653e33b2dd..97acaf86de 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -1,15 +1,81 @@ +//This proc is called whenever someone clicks an inventory ui slot. +/mob/proc/attack_ui(slot) + var/obj/item/W = get_active_hand() + if(istype(W)) + equip_to_slot_if_possible(W, slot) + +/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1) + if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob)) + return 1 + else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob)) + return 1 + return 0 + +//This is a SAFE proc. Use this instead of equip_to_slot()! +//set del_on_fail to have it delete W if it fails to equip +//set disable_warning to disable the 'you are unable to equip that' warning. +//unset redraw_mob to prevent the mob from being redrawn at the end. +/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1) + if(!istype(W)) return 0 + + if(!W.mob_can_equip(src, slot)) + if(del_on_fail) + del(W) + else + if(!disable_warning) + src << "\red You are unable to equip that." //Only print if del_on_fail is false + return 0 + + equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. + return 1 + +//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. +//In most cases you will want to use equip_to_slot_if_possible() +/mob/proc/equip_to_slot(obj/item/W as obj, slot) + return + +//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. +/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) + return equip_to_slot_if_possible(W, slot, 1, 1, 0) + +//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. +var/list/slot_equipment_priority = list( \ + slot_back,\ + slot_wear_id,\ + slot_w_uniform,\ + slot_wear_suit,\ + slot_wear_mask,\ + slot_head,\ + slot_shoes,\ + slot_gloves,\ + slot_l_ear,\ + slot_r_ear,\ + slot_glasses,\ + slot_belt,\ + slot_s_store,\ + slot_tie,\ + slot_l_store,\ + slot_r_store\ + ) + +//puts the item "W" into an appropriate slot in a human's inventory +//returns 0 if it cannot, 1 if successful +/mob/proc/equip_to_appropriate_slot(obj/item/W) + if(!istype(W)) return 0 + + for(var/slot in slot_equipment_priority) + if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) + return 1 + + return 0 + //These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc //as they handle all relevant stuff like adding it to the player's screen and updating their overlays. //Returns the thing in our active hand /mob/proc/get_active_hand() - if(issilicon(src)) - if(isrobot(src)) - if(src:module_active) - return src:module_active - else - if(hand) return l_hand - else return r_hand + if(hand) return l_hand + else return r_hand //Returns the thing in our inactive hand /mob/proc/get_inactive_hand() @@ -77,96 +143,45 @@ W.dropped() return 0 - - -/mob/proc/drop_item_v() //this is dumb. - if(stat == CONSCIOUS && isturf(loc)) - return drop_item() - return 0 - - +// Removes an item from inventory and places it in the target atom /mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null) if(W) if(!Target) Target = loc - if(client) client.screen -= W - u_equip(W) + remove_from_mob(W) if(!W) return 1 // self destroying objects (tk, grabs) - W.layer = initial(W.layer) - W.loc = Target - - var/turf/T = get_turf(Target) - if(isturf(T)) - T.Entered(W) - - W.dropped(src) + + W.forceMove(Target) update_icons() return 1 return 0 - //Drops the item in our left hand /mob/proc/drop_l_hand(var/atom/Target) - if(l_hand) - if(client) client.screen -= l_hand - l_hand.layer = initial(l_hand.layer) - - if(Target) l_hand.loc = Target.loc - else l_hand.loc = loc - - var/turf/T = get_turf(loc) - if(isturf(T)) - T.Entered(l_hand) - - l_hand.dropped(src) - l_hand = null - update_inv_l_hand() - return 1 - return 0 + return drop_from_inventory(l_hand, Target) //Drops the item in our right hand /mob/proc/drop_r_hand(var/atom/Target) - if(r_hand) - if(client) client.screen -= r_hand - r_hand.layer = initial(r_hand.layer) - - if(Target) r_hand.loc = Target.loc - else r_hand.loc = loc - - var/turf/T = get_turf(Target) - if(istype(T)) - T.Entered(r_hand) - - r_hand.dropped(src) - r_hand = null - update_inv_r_hand() - return 1 - return 0 + return drop_from_inventory(r_hand, Target) //Drops the item in our active hand. /mob/proc/drop_item(var/atom/Target) if(hand) return drop_l_hand(Target) else return drop_r_hand(Target) - - - - - - - - -//TODO: phase out this proc -/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this? - W.loc = null - W.layer = initial(W.layer) - u_equip(W) - update_icons() - return - - -/mob/proc/u_equip(W as obj) +/* + Removes the object from any slots the mob might have, calling the appropriate icon update proc. + Does nothing else. + + DO NOT CALL THIS PROC DIRECTLY. It is meant to be called only by other inventory procs. + It's probably okay to use it if you are transferring the item between slots on the same mob, + but chances are you're safer calling remove_from_mob() or drop_from_inventory() anyways. + + As far as I can tell the proc exists so that mobs with different inventory slots can override + the search through all the slots, without having to duplicate the rest of the item dropping. +*/ +/mob/proc/u_equip(obj/W as obj) if (W == r_hand) r_hand = null update_inv_r_hand(0) @@ -181,40 +196,27 @@ update_inv_wear_mask(0) return +//This differs from remove_from_mob() in that it checks canremove first. /mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress. - if(!I) //If there's nothing to drop, the drop is automatically successful. If(unEquip) should generally be used to check for NODROP. + if(!I) //If there's nothing to drop, the drop is automatically successful. return 1 - /*if((I.flags & NODROP) && !force) - return 0*/ - if(!I.canremove && !force) return 0 - if(I == r_hand) - r_hand = null - update_inv_r_hand() - else if(I == l_hand) - l_hand = null - update_inv_l_hand() - - if(I) - if(client) - client.screen -= I - I.loc = loc - I.dropped(src) - if(I) - I.layer = initial(I.layer) + remove_from_mob(I) return 1 //Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob. -//It does call u_equip() though. So it can drop items to the floor but only if src is human. /mob/proc/remove_from_mob(var/obj/O) src.u_equip(O) if (src.client) src.client.screen -= O O.layer = initial(O.layer) O.screen_loc = null + if(istype(O, /obj/item)) + var/obj/item/I = O + I.dropped() return 1 @@ -240,99 +242,3 @@ //if(hasvar(src,"r_hand")) if(src:r_hand) items += src:r_hand return items - -/** BS12's proc to get the item in the active hand. Couldn't find the /tg/ equivalent. **/ -/mob/proc/equipped() - return get_active_hand() //TODO: get rid of this proc - -/mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, del_on_fail = 1) // since byond doesn't seem to have pointers, this seems like the best way to do this :/ - //warning: icky code - var/equipped = 0 - switch(slot) - if(slot_back) - if(!src.back) - src.back = W - equipped = 1 - if(slot_wear_mask) - if(!src.wear_mask) - src.wear_mask = W - equipped = 1 - if(slot_handcuffed) - if(!src.handcuffed) - src.handcuffed = W - equipped = 1 - if(slot_l_hand) - if(!src.l_hand) - src.l_hand = W - equipped = 1 - if(slot_r_hand) - if(!src.r_hand) - src.r_hand = W - equipped = 1 - if(slot_belt) - if(!src.belt && src.w_uniform) - src.belt = W - equipped = 1 - if(slot_wear_id) - if(!src.wear_id && src.w_uniform) - src.wear_id = W - equipped = 1 - if(slot_l_ear) - if(!src.l_ear) - src.l_ear = W - equipped = 1 - if(slot_r_ear) - if(!src.r_ear) - src.r_ear = W - equipped = 1 - if(slot_glasses) - if(!src.glasses) - src.glasses = W - equipped = 1 - if(slot_gloves) - if(!src.gloves) - src.gloves = W - equipped = 1 - if(slot_head) - if(!src.head) - src.head = W - equipped = 1 - if(slot_shoes) - if(!src.shoes) - src.shoes = W - equipped = 1 - if(slot_wear_suit) - if(!src.wear_suit) - src.wear_suit = W - equipped = 1 - if(slot_w_uniform) - if(!src.w_uniform) - src.w_uniform = W - equipped = 1 - if(slot_l_store) - if(!src.l_store && src.w_uniform) - src.l_store = W - equipped = 1 - if(slot_r_store) - if(!src.r_store && src.w_uniform) - src.r_store = W - equipped = 1 - if(slot_s_store) - if(!src.s_store && src.wear_suit) - src.s_store = W - equipped = 1 - if(slot_in_backpack) - if (src.back && istype(src.back, /obj/item/weapon/storage/backpack)) - var/obj/item/weapon/storage/backpack/B = src.back - if(B.contents.len < B.storage_slots && W.w_class <= B.max_w_class) - W.loc = B - equipped = 1 - - if(equipped) - W.layer = 20 - if(src.back && W.loc != src.back) - W.loc = src - else - if (del_on_fail) - del(W) - return equipped diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index c03cb9a9d1..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 @@ -82,3 +82,31 @@ /datum/language/vox/get_random_name() return ..(FEMALE,1,6) + +/datum/language/cultcommon + name = "Cult" + desc = "The chants of the occult, the incomprehensible." + speech_verb = "intones" + ask_verb = "intones" + exclaim_verb = "chants" + colour = "cult" + key = "n" + flags = RESTRICTED + space_chance = 100 + syllables = list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri", \ + "orkan", "allaq", "sas'so", "c'arta", "forbici", "tarem", "n'ath", "reth", "sh'yro", "eth", "d'raggathnor", \ + "mah'weyh", "pleggh", "at", "e'ntrath", "tok-lyr", "rqa'nap", "g'lt-ulotf", "ta'gh", "fara'qha", "fel", "d'amar det", \ + "yu'gular", "faras", "desdae", "havas", "mithum", "javara", "umathar", "uf'kal", "thenar", "rash'tla", \ + "sektath", "mal'zua", "zasan", "therium", "viortia", "kla'atu", "barada", "nikt'o", "fwe'sh", "mah", "erl", "nyag", "r'ya", \ + "gal'h'rfikk", "harfrandid", "mud'gib", "fuu", "ma'jin", "dedo", "ol'btoh", "n'ath", "reth", "sh'yro", "eth", \ + "d'rekkathnor", "khari'd", "gual'te", "nikka", "nikt'o", "barada", "kla'atu", "barhah", "hra" ,"zar'garis") + +/datum/language/cult + name = "Occult" + desc = "The initiated can share their thoughts by means defying all reason." + speech_verb = "intones" + ask_verb = "intones" + exclaim_verb = "chants" + colour = "cult" + key = "m" + flags = RESTRICTED | HIVEMIND diff --git a/code/modules/mob/living/carbon/alien/alien_attacks.dm b/code/modules/mob/living/carbon/alien/alien_attacks.dm index 4285f91c3f..62768945a3 100644 --- a/code/modules/mob/living/carbon/alien/alien_attacks.dm +++ b/code/modules/mob/living/carbon/alien/alien_attacks.dm @@ -20,10 +20,10 @@ switch(M.a_intent) - if ("help") + if (I_HELP) help_shake_act(M) - if ("grab") + if (I_GRAB) if (M == src) return var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm index a379af21c7..58aba691dd 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm @@ -2,7 +2,7 @@ if(istype(M)) //Let people pick the little buggers up. - if(M.a_intent == "help") + if(M.a_intent == I_HELP) if(M.species && M.species.name == "Diona") M << "You feel your being twine with that of [src] as it merges with your biomass." src << "You feel your being twine with that of [M] as you merge with its biomass." 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 6591cee647..57a911d145 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -42,8 +42,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() @@ -70,12 +70,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) @@ -165,7 +166,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 @@ -196,7 +197,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) @@ -337,16 +338,9 @@ if(!item) return //Grab processing has a chance of returning null - item.layer = initial(item.layer) - u_equip(item) - update_icons() - - if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required. - item.loc = src.loc - if(src.client) - src.client.screen -= item - if(istype(item, /obj/item)) - item:dropped(src) // let it know it's been dropped + + src.remove_from_mob(item) + item.loc = src.loc //actually throw it! if (item) @@ -452,102 +446,12 @@ if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes") usr.sleeping = 20 //Short nap -/mob/living/carbon/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - - if( istype(tmob, /mob/living/carbon) && prob(10) ) - src.spread_disease_to(AM, "Contact") - - if(istype(tmob, /mob/living/carbon/human)) - - if(HULK in tmob.mutations) - if(prob(70)) - usr << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - for(var/mob/M in range(tmob, 1)) - if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) - if ( !(world.time % 5) ) - src << "\red [tmob] is restrained, you cannot push past" - now_pushing = 0 - return - if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) - if ( !(world.time % 5) ) - src << "\red [tmob] is restraining [M], you cannot push past" - now_pushing = 0 - return - - //Leaping mobs just land on the tile, no pushing, no anything. - if(status_flags & LEAPING) - loc = tmob.loc - status_flags &= ~LEAPING - now_pushing = 0 - return - - // Step over drones. - // I have no idea why the hell this isn't already happening. How do mice do it? - if(istype(tmob,/mob/living/silicon/robot/drone)) - loc = tmob.loc - now_pushing = 0 - return - - if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && !tmob.buckled && canmove) // mutual brohugs all around! - var/turf/oldloc = loc - loc = tmob.loc - tmob.loc = oldloc - now_pushing = 0 - for(var/mob/living/carbon/slime/slime in view(1,tmob)) - if(slime.Victim == tmob) - slime.UpdateFeed() - return - - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(40) && !(FAT in src.mutations)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = 0 +/mob/living/carbon/Bump(var/atom/movable/AM, yes) + if(now_pushing || !yes) return - return + ..() + if(istype(AM, /mob/living/carbon) && prob(10)) + src.spread_disease_to(AM, "Contact") /mob/living/carbon/can_use_vents() return @@ -561,9 +465,14 @@ Stun(stun_duration) Weaken(Floor(stun_duration/2)) return 1 - + /mob/living/carbon/proc/add_chemical_effect(var/effect, var/magnitude = 1) if(effect in chem_effects) chem_effects[effect] += magnitude else chem_effects[effect] = magnitude + +/mob/living/carbon/get_default_language() + if(!species) + return null + return species.default_language ? all_languages[species.default_language] : null 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..338b265a4f 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -1,19 +1,14 @@ /mob/living/carbon/human/gib() - for(var/datum/organ/internal/I in internal_organs) - var/obj/item/organ/current_organ = I.remove() - if(current_organ) - if(istype(loc,/turf)) - current_organ.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - current_organ.removed(src) + for(var/obj/item/organ/I in internal_organs) + I.removed() + if(istype(loc,/turf)) + I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - for(var/datum/organ/external/E in src.organs) - if(istype(E, /datum/organ/external/chest)) - continue - // Only make the limb drop if it's not too damaged - if(prob(100 - E.get_damage())) - // Override the current limb status and don't cause an explosion - E.droplimb(1,1) + for(var/obj/item/organ/external/E in src.organs) + E.droplimb(0,DROPLIMB_EDGE,1) + + sleep(1) ..(species.gibbed_anim) gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color) @@ -38,7 +33,7 @@ if(species) species.handle_death(src) //Handle brain slugs. - var/datum/organ/external/head = get_organ("head") + var/obj/item/organ/external/head = get_organ("head") var/mob/living/simple_animal/borer/B for(var/I in head.implants) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 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 647128ca6c..b88f6813f8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -61,7 +61,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]") @@ -125,7 +125,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 @@ -134,7 +134,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) @@ -163,7 +163,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 @@ -172,7 +172,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)) @@ -189,7 +189,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) @@ -197,7 +197,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 @@ -322,7 +322,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 @@ -353,7 +353,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) @@ -673,7 +673,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 @@ -791,6 +791,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 @@ -918,19 +919,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)) @@ -949,7 +947,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) @@ -964,11 +962,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) @@ -1029,7 +1027,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 @@ -1038,7 +1036,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) @@ -1047,11 +1045,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) @@ -1156,6 +1154,10 @@ else return 0 + mob_bump_flag = species.bump_flag + mob_swap_flags = species.swap_flags + mob_push_flags = species.push_flags + /mob/living/carbon/human/proc/bloody_doodle() set category = "IC" set name = "Write in blood" @@ -1284,14 +1286,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 @@ -1300,3 +1302,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 23f90946bc..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) @@ -45,7 +45,7 @@ M.spread_disease_to(src, "Contact") switch(M.a_intent) - if("help") + if(I_HELP) if(istype(H) && health < config.health_threshold_crit) @@ -69,7 +69,7 @@ help_shake_act(M) return 1 - if("grab") + if(I_GRAB) if(M == src || anchored) return 0 if(w_uniform) @@ -88,7 +88,7 @@ visible_message("[M] has grabbed [src] passively!") return 1 - if("hurt") + if(I_HURT) if(!istype(H)) attack_generic(H,rand(1,3),"punched") @@ -98,14 +98,18 @@ 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("help") + if(I_HELP) // We didn't see this coming, so we get the full blow rand_damage = 5 accurate = 1 - if("hurt", "grab") + if(I_HURT, I_GRAB) // We're in a fighting stance, there's a chance we block if(src.canmove && src!=H && prob(20)) block = 1 @@ -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 @@ -200,7 +204,7 @@ // Finally, apply damage to target apply_damage(real_damage, BRUTE, affecting, armour, sharp=attack.sharp, edge=attack.edge) - if("disarm") + if(I_DISARM) M.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] Has been disarmed by [M.name] ([M.ckey])") @@ -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..a0c78d7572 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -10,7 +10,9 @@ emp_act /mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone) - var/datum/organ/external/organ = get_organ(check_zone(def_zone)) + var/obj/item/organ/external/organ = get_organ(check_zone(def_zone)) + if(!organ) + return //Shields if(check_shields(P.damage, "the [P.name]")) @@ -50,7 +52,7 @@ emp_act return (..(P , def_zone)) /mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone) - var/datum/organ/external/affected = get_organ(check_zone(def_zone)) + var/obj/item/organ/external/affected = get_organ(check_zone(def_zone)) var/siemens_coeff = get_siemens_coefficient_organ(affected) stun_amount *= siemens_coeff agony_amount *= siemens_coeff @@ -68,12 +70,12 @@ emp_act if(c_hand && (stun_amount || agony_amount > 10)) msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect") - u_equip(c_hand) + drop_from_inventory(c_hand) if (affected.status & ORGAN_ROBOT) - emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!") + emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!") else var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.display_name]!") + emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.name]!") ..(stun_amount, agony_amount, def_zone) @@ -84,21 +86,23 @@ emp_act if(def_zone) if(isorgan(def_zone)) return getarmor_organ(def_zone, type) - var/datum/organ/external/affecting = get_organ(def_zone) - return getarmor_organ(affecting, type) + var/obj/item/organ/external/affecting = get_organ(def_zone) + if(affecting) + return getarmor_organ(affecting, type) //If a specific bodypart is targetted, check how that bodypart is protected and return the value. //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values for(var/organ_name in organs_by_name) if (organ_name in organ_rel_size) - var/datum/organ/external/organ = organs_by_name[organ_name] - var/weight = organ_rel_size[organ_name] - armorval += getarmor_organ(organ, type) * weight - total += weight + var/obj/item/organ/external/organ = organs_by_name[organ_name] + if(organ) + var/weight = organ_rel_size[organ_name] + armorval += getarmor_organ(organ, type) * weight + total += weight return (armorval/max(total, 1)) //this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. -/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone) +/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) if (!def_zone) return 1.0 @@ -112,14 +116,14 @@ emp_act return siemens_coefficient //this proc returns the armour value for a particular external organ. -/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type) - if(!type) return 0 +/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type) + if(!type || !def_zone) return 0 var/protection = 0 var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) for(var/gear in protective_gear) if(gear && istype(gear ,/obj/item/clothing)) var/obj/item/clothing/C = gear - if(C.body_parts_covered & def_zone.body_part) + if(istype(C) && C.body_parts_covered & def_zone.body_part) protection += C.armor[type] return protection @@ -167,10 +171,10 @@ emp_act for(var/obj/O in src) if(!O) continue O.emp_act(severity) - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) if(O.status & ORGAN_DESTROYED) continue O.emp_act(severity) - for(var/datum/organ/internal/I in O.internal_organs) + for(var/obj/item/organ/I in O.internal_organs) if(I.robotic == 0) continue I.emp_act(severity) ..() @@ -186,17 +190,19 @@ emp_act target_zone = user.zone_sel.selecting if(!target_zone) visible_message("\red [user] misses [src] with \the [I]!") - return 0 + return 1 - var/datum/organ/external/affecting = get_organ(target_zone) - if (!affecting) - return 0 - if(affecting.status & ORGAN_DESTROYED) - user << "What [affecting.display_name]?" - return 0 - var/hit_area = affecting.display_name + var/obj/item/organ/external/affecting = get_organ(target_zone) - if((user != src) && check_shields(I.force, "the [I.name]")) + if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump()) + user << "They are missing that limb!" + return + + var/effective_force = I.force + if(user.a_intent == "disarm") effective_force = round(I.force/2) + var/hit_area = affecting.name + + if((user != src) && check_shields(effective_force, "the [I.name]")) return 0 if(istype(I,/obj/item/weapon/card/emag)) @@ -204,9 +210,9 @@ emp_act user << "\red That limb isn't robotic." return if(affecting.sabotaged) - user << "\red [src]'s [affecting.display_name] is already sabotaged!" + user << "\red [src]'s [affecting.name] is already sabotaged!" else - user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties." + user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.name] and short out the safeties." var/obj/item/weapon/card/emag/emag = I emag.uses-- affecting.sabotaged = 1 @@ -224,14 +230,14 @@ emp_act weapon_sharp = 0 weapon_edge = 0 - if(armor >= 2) return 0 - if(!I.force) return 0 - var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) + if(armor >= 2) return 0 + if(!effective_force) return 0 + var/Iforce = effective_force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - apply_damage(I.force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I) + apply_damage(effective_force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I) var/bloody = 0 - if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2))) + if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (effective_force * 2))) I.add_blood(src) //Make the weapon bloody, not the person. // if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon // else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays @@ -246,36 +252,37 @@ emp_act H.bloody_body(src) H.bloody_hands(src) - switch(hit_area) - if("head")//Harder to score a stun but if you do it lasts a bit longer - if(prob(I.force)) - apply_effect(20, PARALYZE, armor) - visible_message("\red [src] has been knocked unconscious!") - if(bloody)//Apply blood - if(wear_mask) - wear_mask.add_blood(src) - update_inv_wear_mask(0) - if(head) - head.add_blood(src) - update_inv_head(0) - if(glasses && prob(33)) - glasses.add_blood(src) - update_inv_glasses(0) + if(!stat) + switch(hit_area) + if("head")//Harder to score a stun but if you do it lasts a bit longer + if(prob(effective_force)) + apply_effect(20, PARALYZE, armor) + visible_message("\red [src] has been knocked unconscious!") + if(bloody)//Apply blood + if(wear_mask) + wear_mask.add_blood(src) + update_inv_wear_mask(0) + if(head) + head.add_blood(src) + update_inv_head(0) + if(glasses && prob(33)) + glasses.add_blood(src) + update_inv_glasses(0) - if("chest")//Easier to score a stun but lasts less time - if(prob((I.force + 10))) - apply_effect(6, WEAKEN, armor) - visible_message("\red [src] has been knocked down!") + if("chest")//Easier to score a stun but lasts less time + if(prob((effective_force + 10))) + apply_effect(6, WEAKEN, armor) + visible_message("\red [src] has been knocked down!") - if(bloody) - bloody_body(src) + if(bloody) + bloody_body(src) if(Iforce > 10 || Iforce >= 5 && prob(33)) forcesay(hit_appends) //forcesay checks stat already //Melee weapon embedded object code. if (I && I.damtype == BRUTE && !I.anchored && !I.is_robot_module()) - var/damage = I.force + var/damage = effective_force if (armor) damage /= armor+1 @@ -327,8 +334,8 @@ emp_act if ((O.thrower != src) && check_shields(throw_damage, "[O]")) return - var/datum/organ/external/affecting = get_organ(zone) - var/hit_area = affecting.display_name + var/obj/item/organ/external/affecting = get_organ(zone) + var/hit_area = affecting.name src.visible_message("\red [src] has been hit in the [hit_area] by [O].") var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here @@ -390,7 +397,7 @@ emp_act /mob/living/carbon/human/embed(var/obj/O, var/def_zone=null) if(!def_zone) ..() - var/datum/organ/external/affecting = get_organ(def_zone) + var/obj/item/organ/external/affecting = get_organ(def_zone) if(affecting) affecting.embed(O) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 064819b2cd..4546fab050 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -82,3 +82,7 @@ var/hand_blood_color var/list/flavor_texts = list() + + mob_bump_flag = HUMAN + mob_push_flags = ALLMOBS + mob_swap_flags = ALLMOBS diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index a455edb27f..f4b28d2b6b 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -27,7 +27,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) @@ -39,7 +39,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..de7a982b1a --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -0,0 +1,135 @@ +/mob/living/carbon/human/proc/update_eyes() + if(internal_organs_by_name["eyes"]) + var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + eyes.eye_colour = list(r_eyes,g_eyes,b_eyes) + regenerate_icons() + +/mob/living/carbon/var/list/internal_organs = list() +/mob/living/carbon/human/var/list/organs = list() +/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs +/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too + +// Takes care of organ related updates, such as broken and missing limbs +/mob/living/carbon/human/proc/handle_organs() + + number_wounds = 0 + var/force_process = 0 + var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss() + if(damage_this_tick > last_dam) + force_process = 1 + last_dam = damage_this_tick + if(force_process) + bad_external_organs.Cut() + for(var/obj/item/organ/external/Ex in organs) + bad_external_organs |= Ex + + //processing internal organs is pretty cheap, do that first. + for(var/obj/item/organ/I in internal_organs) + I.process() + + handle_stance() + handle_grasp() + + if(!force_process && !bad_external_organs.len) + return + + for(var/obj/item/organ/external/E in bad_external_organs) + if(!E) + continue + if(!E.need_process()) + bad_external_organs -= E + continue + else + E.process() + number_wounds += E.number_wounds + + if (!lying && world.time - l_move_time < 15) + //Moving around with fractured ribs won't do you any good + if (E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15)) + var/obj/item/organ/I = pick(E.internal_organs) + custom_pain("You feel broken bones moving in your [E.name]!", 1) + I.take_damage(rand(3,5)) + + //Moving makes open wounds get infected much faster + if (E.wounds.len) + for(var/datum/wound/W in E.wounds) + if (W.infection_check()) + W.germ_level += 1 + +/mob/living/carbon/human/proc/handle_stance() + // Don't need to process any of this if they aren't standing anyways + // unless their stance is damaged, and we want to check if they should stay down + if (!stance_damage && (lying || resting) && (life_tick % 4) == 0) + return + + stance_damage = 0 + + // Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid + if (istype(buckled, /obj/structure/bed)) + return + + for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot")) + var/obj/item/organ/external/E = organs_by_name[limb_tag] + if(!E) + stance_damage += 2 + else if (E.status & ORGAN_DESTROYED) + stance_damage += 2 // let it fail even if just foot&leg + else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable()) + stance_damage += 1 + + // Canes and crutches help you stand (if the latter is ever added) + // One cane mitigates a broken leg+foot, or a missing foot. + // Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you. + if (l_hand && istype(l_hand, /obj/item/weapon/cane)) + stance_damage -= 2 + if (r_hand && istype(r_hand, /obj/item/weapon/cane)) + stance_damage -= 2 + + // standing is poor + if(stance_damage >= 4 || (stance_damage >= 2 && prob(5))) + if(!(lying || resting)) + if(species && !(species.flags & NO_PAIN)) + emote("scream") + custom_emote(1, "collapses!") + Weaken(5) //can't emote while weakened, apparently. + +/mob/living/carbon/human/proc/handle_grasp() + + if(!l_hand && !r_hand) + return + + for (var/obj/item/organ/external/E in organs) + if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED)) + continue + + if(E.is_broken()) + if(E.body_part == HAND_LEFT) + drop_from_inventory(l_hand) + else + drop_from_inventory(r_hand) + + var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") + emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!") + + else if(E.is_malfunctioning()) + + if(E.body_part == HAND_LEFT) + drop_from_inventory(l_hand) + else + drop_from_inventory(r_hand) + + emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + spark_system.start() + spawn(10) + del(spark_system) + +//Handles chem traces +/mob/living/carbon/human/proc/handle_trace_chems() + //New are added for reagents to random organs. + for(var/datum/reagent/A in reagents.reagent_list) + var/obj/item/organ/O = pick(organs) + O.trace_chemicals[A.name] = 100 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm index 49f1bd4eee..f7a644646d 100644 --- a/code/modules/mob/living/carbon/human/human_species.dm +++ b/code/modules/mob/living/carbon/human/human_species.dm @@ -18,10 +18,6 @@ h_style = "Short Vox Quills" ..(new_loc, "Vox") -/mob/living/carbon/human/voxarmalis/New(var/new_loc) - h_style = "Bald" - ..(new_loc, "Vox Armalis") - /mob/living/carbon/human/diona/New(var/new_loc) ..(new_loc, "Diona") diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index d1f8b21f05..bc39c3f315 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -39,7 +39,7 @@ This saves us from having to call add_fingerprint() any time something is put in /mob/living/carbon/human/proc/has_organ(name) - var/datum/organ/external/O = organs_by_name[name] + var/obj/item/organ/external/O = organs_by_name[name] return (O && !(O.status & ORGAN_DESTROYED) ) @@ -69,11 +69,11 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_glasses) return has_organ("head") if(slot_gloves) - return has_organ("l_hand") && has_organ("r_hand") + return has_organ("l_hand") || has_organ("r_hand") if(slot_head) return has_organ("head") if(slot_shoes) - return has_organ("r_foot") && has_organ("l_foot") + return has_organ("r_foot") || has_organ("l_foot") if(slot_wear_suit) return has_organ("chest") if(slot_w_uniform) @@ -89,19 +89,13 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_tie) return 1 -/mob/living/carbon/human/u_equip(obj/item/W as obj) +/mob/living/carbon/human/u_equip(obj/W as obj) if(!W) return 0 - var/success - if (W == wear_suit) if(s_store) drop_from_inventory(s_store) - if(W) - success = 1 wear_suit = null - if(W.flags_inv & HIDESHOES) - update_inv_shoes(0) update_inv_wear_suit() else if (W == w_uniform) if (r_store) @@ -113,43 +107,43 @@ This saves us from having to call add_fingerprint() any time something is put in if (belt) drop_from_inventory(belt) w_uniform = null - success = 1 update_inv_w_uniform() else if (W == gloves) gloves = null - success = 1 update_inv_gloves() else if (W == glasses) glasses = null - success = 1 update_inv_glasses() else if (W == head) head = null - if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)|| (W.flags_inv & HIDEMASK)) + + var/update_hair = 0 + if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) + update_hair = 1 + else if(istype(W, /obj/item)) + var/obj/item/I = W + if(I.flags_inv & HIDEMASK) + update_hair = 1 + if(update_hair) update_hair(0) //rebuild hair update_inv_ears(0) update_inv_wear_mask(0) - success = 1 + update_inv_head() else if (W == l_ear) l_ear = null - success = 1 update_inv_ears() else if (W == r_ear) r_ear = null - success = 1 update_inv_ears() else if (W == shoes) shoes = null - success = 1 update_inv_shoes() else if (W == belt) belt = null - success = 1 update_inv_belt() else if (W == wear_mask) wear_mask = null - success = 1 if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) update_hair(0) //rebuild hair update_inv_ears(0) @@ -160,53 +154,36 @@ This saves us from having to call add_fingerprint() any time something is put in update_inv_wear_mask() else if (W == wear_id) wear_id = null - success = 1 update_inv_wear_id() else if (W == r_store) r_store = null - success = 1 update_inv_pockets() else if (W == l_store) l_store = null - success = 1 update_inv_pockets() else if (W == s_store) s_store = null - success = 1 update_inv_s_store() else if (W == back) back = null - success = 1 update_inv_back() else if (W == handcuffed) - handcuffed = null + handcuffed = null if(buckled && buckled.buckle_require_restraints) - buckled.unbuckle_mob() - success = 1 + buckled.unbuckle_mob() update_inv_handcuffed() else if (W == legcuffed) legcuffed = null - success = 1 update_inv_legcuffed() else if (W == r_hand) r_hand = null - success = 1 update_inv_r_hand() else if (W == l_hand) l_hand = null - success = 1 update_inv_l_hand() else return 0 - - if(success) - if (W) - if (client) - client.screen -= W - W.loc = loc - W.dropped(src) - //if(W) - //W.layer = initial(W.layer) + update_action_buttons() return 1 @@ -319,7 +296,7 @@ This saves us from having to call add_fingerprint() any time something is put in update_inv_s_store(redraw_mob) if(slot_in_backpack) if(src.get_active_hand() == W) - src.u_equip(W) + src.remove_from_mob(W) W.loc = src.back if(slot_tie) var/obj/item/clothing/under/uniform = src.w_uniform @@ -339,6 +316,10 @@ This saves us from having to call add_fingerprint() any time something is put in return +/* + MouseDrop human inventory menu +*/ + /obj/effect/equip_e name = "equip e" var/mob/source = null @@ -407,7 +388,7 @@ This saves us from having to call add_fingerprint() any time something is put in if("splints") var/count = 0 for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.organs_by_name[organ] + var/obj/item/organ/external/o = target.organs_by_name[organ] if(o.status & ORGAN_SPLINTED) count = 1 break @@ -695,7 +676,7 @@ It can still be worn/put on as normal. if(can_reach_splints) for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.get_organ(organ) + var/obj/item/organ/external/o = target.get_organ(organ) if (o && o.status & ORGAN_SPLINTED) var/obj/item/W = new /obj/item/stack/medical/splint(amount=1) o.status &= ~ORGAN_SPLINTED @@ -771,15 +752,12 @@ It can still be worn/put on as normal. W.add_fingerprint(source) if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;) if(target.r_store) - target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. + target.remove_from_mob(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. else if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob if(item.mob_can_equip(target, slot_to_process, 0)) - source.u_equip(item) + source.remove_from_mob(item) target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1) - item.dropped(source) - source.update_icons() - target.update_icons() if(source && target) if(source.machine == target) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8f0a0b76f6..cf1de67278 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -237,7 +237,7 @@ src << "\red It becomes hard to see for some reason." eye_blurry = 10 if(getBrainLoss() >= 35) - if(7 <= rn && rn <= 9) if(hand && equipped()) + if(7 <= rn && rn <= 9) if(get_active_hand()) src << "\red Your hand won't respond properly, you drop what you're holding." drop_item() if(getBrainLoss() >= 50) @@ -276,7 +276,7 @@ radiation = Clamp(radiation,0,100) if (radiation) - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs + var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs if(rad_organ && !rad_organ.is_broken()) var/rads = radiation/25 radiation -= rads @@ -323,7 +323,7 @@ adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT) updatehealth() if(organs.len) - var/datum/organ/external/O = pick(organs) + var/obj/item/organ/external/O = pick(organs) if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) /** breathing **/ @@ -388,7 +388,7 @@ // Lung damage increases the minimum safe pressure. if(species.has_organ["lungs"]) - var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] if(!L) safe_pressure_min = INFINITY //No lungs, how are you breathing? else if(L.is_broken()) @@ -877,7 +877,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 @@ -1506,7 +1506,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/say.dm b/code/modules/mob/living/carbon/human/say.dm index 120ce2086a..221fbc1224 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,156 +1,14 @@ /mob/living/carbon/human/say(var/message) - - var/verb = "says" var/alt_name = "" - var/message_range = world.view - var/italics = 0 - - if(client) - if(client.prefs.muted & MUTE_IC) - src << "\red You cannot speak in IC (Muted)." - return - - message = sanitize(message) - - if(stat) - if(stat == 2) - return say_dead(message) - return + if(name != GetVoice()) + alt_name = "(as [get_id_name("Unknown")])" if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) src << "You're muzzled and cannot speak!" return - var/message_mode = parse_message_mode(message, "headset") - - switch(copytext(message,1,2)) - if("*") return emote(copytext(message,2)) - if("^") return custom_emote(1, copytext(message,2)) - - if(name != GetVoice()) - alt_name = "(as [get_id_name("Unknown")])" - - //parse the radio code and consume it - if (message_mode) - if (message_mode == "headset") - message = copytext(message,2) //it would be really nice if the parse procs could do this for us. - else - message = copytext(message,3) - - message = trim_left(message) - - //parse the language code and consume it - var/datum/language/speaking = parse_language(message) - if(speaking) - message = copytext(message,2+length(speaking.key)) - else if(species.default_language) - speaking = all_languages[species.default_language] - - var/ending = copytext(message, length(message)) - if (speaking) - // This is broadcast to all mobs with the language, - // irrespective of distance or anything else. - if(speaking.flags & HIVEMIND) - speaking.broadcast(src,trim(message)) - return - //If we've gotten this far, keep going! - verb = speaking.get_spoken_verb(ending) - else - if(ending=="!") - verb=pick("exclaims","shouts","yells") - if(ending=="?") - verb="asks" - - message = trim(message) - - if(speech_problem_flag) - if(!speaking || !(speaking.flags & NO_STUTTER)) - var/list/handle_r = handle_speech_problems(message) - message = handle_r[1] - verb = handle_r[2] - speech_problem_flag = handle_r[3] - - if(!message || message == "") - return - - var/list/obj/item/used_radios = new - - switch (message_mode) - if("headset") - if(l_ear && istype(l_ear,/obj/item/device/radio)) - var/obj/item/device/radio/R = l_ear - R.talk_into(src,message,null,verb,speaking) - used_radios += l_ear - else if(r_ear && istype(r_ear,/obj/item/device/radio)) - var/obj/item/device/radio/R = r_ear - R.talk_into(src,message,null,verb,speaking) - used_radios += r_ear - - if("right ear") - var/obj/item/device/radio/R - var/has_radio = 0 - if(r_ear && istype(r_ear,/obj/item/device/radio)) - R = r_ear - has_radio = 1 - if(r_hand && istype(r_hand, /obj/item/device/radio)) - R = r_hand - has_radio = 1 - if(has_radio) - R.talk_into(src,message,null,verb,speaking) - used_radios += R - - - if("left ear") - var/obj/item/device/radio/R - var/has_radio = 0 - if(l_ear && istype(l_ear,/obj/item/device/radio)) - R = l_ear - has_radio = 1 - if(l_hand && istype(l_hand,/obj/item/device/radio)) - R = l_hand - has_radio = 1 - if(has_radio) - R.talk_into(src,message,null,verb,speaking) - used_radios += R - - if("intercom") - for(var/obj/item/device/radio/intercom/I in view(1, null)) - I.talk_into(src, message, verb, speaking) - used_radios += I - if("whisper") - whisper_say(message, speaking, alt_name) - return - else - if(message_mode) - if(l_ear && istype(l_ear,/obj/item/device/radio)) - l_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += l_ear - else if(r_ear && istype(r_ear,/obj/item/device/radio)) - r_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += r_ear - - var/sound/speech_sound - var/sound_vol - if(species.speech_sounds && prob(species.speech_chance)) - speech_sound = sound(pick(species.speech_sounds)) - sound_vol = 50 - - //speaking into radios - if(used_radios.len) - italics = 1 - message_range = 1 - if(speaking) - message_range = speaking.get_talkinto_msg_range(message) - var/msg - if(!speaking || !(speaking.flags & NO_TALK_MSG)) - msg = "\The [src] talks into \the [used_radios[1]]" - for(var/mob/living/M in hearers(5, src)) - if((M != src) && msg) - M.show_message(msg) - if (speech_sound) - sound_vol *= 0.5 - - ..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here. + message = sanitize(message) + ..(message, alt_name = alt_name) //ohgod we should really be passing a datum here. /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) @@ -271,39 +129,33 @@ return verb -/mob/living/carbon/human/proc/handle_speech_problems(var/message) +/mob/living/carbon/human/handle_speech_problems(var/message, var/verb) + if(!speech_problem_flag) + return ..() var/list/returns[3] - var/verb = "says" - var/handled = 0 + speech_problem_flag = 0 if(silent || (sdisabilities & MUTE)) message = "" - handled = 1 + speech_problem_flag = 1 if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) var/obj/item/clothing/mask/horsehead/hoers = wear_mask if(hoers.voicechange) if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling") message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") verb = pick("whinnies","neighs", "says") - handled = 1 + speech_problem_flag = 1 if(message != "") - if((HULK in mutations) && health >= 25 && length(message)) - message = "[uppertext(message)]!!!" - verb = pick("yells","roars","hollers") - handled = 1 - if(slurring) - message = slur(message) - verb = pick("slobbers","slurs") - handled = 1 - if(stuttering) - message = stutter(message) - verb = pick("stammers","stutters") - handled = 1 + var/list/parent = ..() + message = parent[1] + verb = parent[2] + if(parent[3]) + speech_problem_flag = 1 var/braindam = getBrainLoss() if(braindam >= 60) - handled = 1 + speech_problem_flag = 1 if(prob(braindam/4)) message = stutter(message) verb = pick("stammers", "stutters") @@ -313,5 +165,63 @@ returns[1] = message returns[2] = verb - returns[3] = handled + returns[3] = speech_problem_flag return returns + +/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) + switch(message_mode) + if("intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message, verb, speaking) + used_radios += I + if("headset") + if(l_ear && istype(l_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = l_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = r_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += r_ear + if("right ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(r_ear && istype(r_ear,/obj/item/device/radio)) + R = r_ear + has_radio = 1 + if(r_hand && istype(r_hand, /obj/item/device/radio)) + R = r_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R + if("left ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(l_ear && istype(l_ear,/obj/item/device/radio)) + R = l_ear + has_radio = 1 + if(l_hand && istype(l_hand,/obj/item/device/radio)) + R = l_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R + if("whisper") + whisper_say(message, speaking, alt_name) + return 1 + else + if(message_mode) + if(l_ear && istype(l_ear,/obj/item/device/radio)) + l_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + r_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += r_ear + +/mob/living/carbon/human/handle_speech_sound() + if(species.speech_sounds && prob(species.speech_chance)) + var/list/returns[2] + returns[1] = sound(pick(species.speech_sounds)) + returns[2] = 50 + 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..853fb4e8d4 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -42,56 +42,15 @@ ) has_organ = list( - "heart" = /datum/organ/internal/heart, - "lungs" = /datum/organ/internal/lungs, - "liver" = /datum/organ/internal/liver, - "kidneys" = /datum/organ/internal/kidney, - "brain" = /datum/organ/internal/brain, - "eyes" = /datum/organ/internal/eyes, - "stack" = /datum/organ/internal/stack/vox + "heart" = /obj/item/organ/heart, + "lungs" = /obj/item/organ/lungs, + "liver" = /obj/item/organ/liver, + "kidneys" = /obj/item/organ/kidney, + "brain" = /obj/item/organ/brain, + "eyes" = /obj/item/organ/eyes, + "stack" = /obj/item/organ/stack/vox ) /datum/species/vox/get_random_name(var/gender) var/datum/language/species_language = all_languages[default_language] return species_language.get_random_name(gender) - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - rarity_value = 10 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - breath_type = "nitrogen" - poison_type = "oxygen" - - flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR - - blood_color = "#2299FC" - flesh_color = "#808D11" - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - reagent_tag = IS_VOX - - inherent_verbs = list( - /mob/living/carbon/human/proc/leap, - /mob/living/carbon/human/proc/gut, - /mob/living/carbon/human/proc/commune - ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 90ff22cab0..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,15 +107,34 @@ 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 + var/bump_flag = HUMAN // What are we considered to be when bumped? + var/push_flags = ALLMOBS // What can we push? + var/swap_flags = ALLMOBS // What can we swap place with? + /datum/species/New() if(hud_type) hud = new hud_type() @@ -152,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() @@ -163,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) @@ -250,7 +266,7 @@ // Called when using the shredding behavior. /datum/species/proc/can_shred(var/mob/living/carbon/human/H, var/ignore_intent) - if(!ignore_intent && H.a_intent != "hurt") + if(!ignore_intent && H.a_intent != I_HURT) return 0 for(var/datum/unarmed_attack/attack in unarmed_attacks) @@ -263,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/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index 4f00eaea20..0166900a0f 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -33,6 +33,10 @@ flags = IS_RESTRICTED + bump_flag = MONKEY + swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN + /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) if(H.stat != CONSCIOUS) return @@ -44,6 +48,7 @@ /datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) H.real_name = "[lowertext(name)] ([rand(100,999)])" H.name = H.real_name + ..() /datum/species/monkey/tajaran 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 83af39876a..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,13 +19,17 @@ 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 poison_type = null + bump_flag = SLIME + swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + push_flags = MONKEY|SLIME|SIMPLE_ANIMAL + /datum/species/slime/handle_death(var/mob/living/carbon/human/H) spawn(1) if(H) - H.gib() \ No newline at end of file + H.gib() 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 a854d0e6db..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,13 +45,17 @@ 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 + swap_flags = ALLMOBS + push_flags = ALLMOBS ^ ROBOT + var/alien_number = 0 var/caste_name = "creature" // Used to update alien name. var/weeds_heal_rate = 1 // Health regen on weeds. @@ -89,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) ..() @@ -112,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)) @@ -120,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 @@ -149,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( @@ -188,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( @@ -216,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( @@ -248,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..0882c558c7 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -182,7 +182,9 @@ var/global/list/damage_icon_parts = list() // first check whether something actually changed about damage appearance var/damage_appearance = "" - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) + if(O.is_stump()) + continue if(O.status & ORGAN_DESTROYED) damage_appearance += "d" else damage_appearance += O.damage_state @@ -198,7 +200,9 @@ var/global/list/damage_icon_parts = list() var/image/standing_image = new /image("icon" = standing) // blend the individual damage states with our icons - for(var/datum/organ/external/O in organs) + for(var/obj/item/organ/external/O in organs) + if(O.is_stump()) + continue if(!(O.status & ORGAN_DESTROYED)) O.update_icon() if(O.damage_state == "00") continue @@ -223,7 +227,6 @@ var/global/list/damage_icon_parts = list() var/husk_color_mod = rgb(96,88,80) var/hulk_color_mod = rgb(48,224,40) - var/necrosis_color_mod = rgb(10,50,0) var/husk = (HUSK in src.mutations) var/fat = (FAT in src.mutations) @@ -231,7 +234,6 @@ var/global/list/damage_icon_parts = list() var/skeleton = (SKELETON in src.mutations) var/g = (gender == FEMALE ? "f" : "m") - var/has_head = 0 //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. @@ -239,19 +241,14 @@ var/global/list/damage_icon_parts = list() //Create a new, blank icon for our mob to use. if(stand_icon) del(stand_icon) - stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") var/icon_key = "[species.race_key][g][s_tone]" - for(var/datum/organ/external/part in organs) - - if(istype(part,/datum/organ/external/head) && !(part.status & ORGAN_DESTROYED)) - has_head = 1 - - if(part.status & ORGAN_DESTROYED) + for(var/obj/item/organ/external/part in organs) + if(part.is_stump() || (part.status & ORGAN_DESTROYED)) icon_key = "[icon_key]0" else if(part.status & ORGAN_ROBOT) - icon_key = "[icon_key]2" + icon_key = "[icon_key]2[part.model ? "-[part.model]": ""]" else if(part.status & ORGAN_DEAD) icon_key = "[icon_key]3" else @@ -261,69 +258,31 @@ var/global/list/damage_icon_parts = list() var/icon/base_icon if(human_icon_cache[icon_key]) - //Icon is cached, use existing icon. base_icon = human_icon_cache[icon_key] - - //log_debug("Retrieved cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src].") - else + //BEGIN CACHED ICON GENERATION. + var/obj/item/organ/external/chest = get_organ("chest") + base_icon = chest.get_icon() - //BEGIN CACHED ICON GENERATION. - var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) - var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) - - //Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs. - //No icon stored, so we need to start with a basic one. - var/datum/organ/external/chest = get_organ("chest") - base_icon = chest.get_icon(race_icon,deform_icon,g) - - if(chest.status & ORGAN_DEAD) - base_icon.ColorTone(necrosis_color_mod) - base_icon.SetIntensity(0.7) - - for(var/datum/organ/external/part in organs) - - var/icon/temp //Hold the bodypart icon for processing. - - if(part.status & ORGAN_DESTROYED) - continue - - if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head)) - temp = part.get_icon(race_icon,deform_icon,g) - else - temp = part.get_icon(race_icon,deform_icon) - - if(part.status & ORGAN_DEAD) - temp.ColorTone(necrosis_color_mod) - temp.SetIntensity(0.7) - + for(var/obj/item/organ/external/part in organs) + var/icon/temp = part.get_icon(skeleton) //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part) if(part.icon_position&(LEFT|RIGHT)) - var/icon/temp2 = new('icons/mob/human.dmi',"blank") - temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH) temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH) - if(!(part.icon_position & LEFT)) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) - if(!(part.icon_position & RIGHT)) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_OVERLAY) - if(part.icon_position & LEFT) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) - if(part.icon_position & RIGHT) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_UNDERLAY) - else - base_icon.Blend(temp, ICON_OVERLAY) if(!skeleton) @@ -334,46 +293,18 @@ var/global/list/damage_icon_parts = list() base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3])) //Handle husk overlay. - if(husk && ("overlay_husk" in icon_states(race_icon))) + if(husk && ("overlay_husk" in icon_states(species.icobase))) var/icon/mask = new(base_icon) - var/icon/husk_over = new(race_icon,"overlay_husk") + var/icon/husk_over = new(species.icobase,"overlay_husk") mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0) husk_over.Blend(mask, ICON_ADD) base_icon.Blend(husk_over, ICON_OVERLAY) - - //Skin tone. - if(!husk && !hulk) - if(species.flags & HAS_SKIN_TONE) - if(s_tone >= 0) - base_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - else - base_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) - human_icon_cache[icon_key] = base_icon - //log_debug("Generated new cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src]. [human_icon_cache.len] cached mob icons.") - //END CACHED ICON GENERATION. - stand_icon.Blend(base_icon,ICON_OVERLAY) - //Skin colour. Not in cache because highly variable (and relatively benign). - if (species.flags & HAS_SKIN_COLOR) - stand_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - - if(has_head) - //Eyes - if(!skeleton) - var/icon/eyes = new/icon('icons/mob/human_face.dmi', species.eyes) - if (species.flags & HAS_EYE_COLOR) - eyes.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) - stand_icon.Blend(eyes, ICON_OVERLAY) - - //Mouth (lipstick!) - if(lip_style && (species && species.flags & HAS_LIPS)) //skeletons are allowed to wear lipstick no matter what you think, agouri. - stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY) - //Underwear if(underwear && species.flags & HAS_UNDERWEAR) stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY) @@ -392,7 +323,7 @@ var/global/list/damage_icon_parts = list() //Reset our hair overlays_standing[HAIR_LAYER] = null - var/datum/organ/external/head/head_organ = get_organ("head") + var/obj/item/organ/external/head/head_organ = get_organ("head") if( !head_organ || (head_organ.status & ORGAN_DESTROYED) ) if(update_icons) update_icons() return @@ -763,13 +694,12 @@ var/global/list/damage_icon_parts = list() standing.overlays += bloodsies overlays_standing[SUIT_LAYER] = standing - update_tail_showing(0) else overlays_standing[SUIT_LAYER] = null - update_tail_showing(0) + update_inv_shoes(0) update_collar(0) @@ -854,37 +784,47 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/update_inv_r_hand(var/update_icons=1) if(r_hand) r_hand.screen_loc = ui_rhand //TODO + + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + var/t_state = r_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = r_hand.icon_state - if(r_hand.icon_override) t_state = "[t_state]_r" overlays_standing[R_HAND_LAYER] = image("icon" = r_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]") + overlays_standing[R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_r_hand() else overlays_standing[R_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/update_inv_l_hand(var/update_icons=1) if(l_hand) l_hand.screen_loc = ui_lhand //TODO + + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + var/t_state = l_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = l_hand.icon_state - if(l_hand.icon_override) t_state = "[t_state]_l" overlays_standing[L_HAND_LAYER] = image("icon" = l_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]") + overlays_standing[L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_l_hand() else overlays_standing[L_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) overlays_standing[TAIL_LAYER] = null @@ -925,48 +865,13 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/update_surgery(var/update_icons=1) overlays_standing[SURGERY_LEVEL] = null var/image/total = new - for(var/datum/organ/external/E in organs) + for(var/obj/item/organ/external/E in organs) if(E.open) var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.name][round(E.open)]", "layer"=-SURGERY_LEVEL) total.overlays += I overlays_standing[SURGERY_LEVEL] = total if(update_icons) update_icons() -// Used mostly for creating head items -/mob/living/carbon/human/proc/generate_head_icon() -//gender no longer matters for the mouth, although there should probably be seperate base head icons. -// var/g = "m" -// if (gender == FEMALE) g = "f" - - //base icons - var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l") - - if(f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] - if(facial_hair_style) - var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l") - facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) - face_lying.Blend(facial_l, ICON_OVERLAY) - - if(h_style) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] - if(hair_style) - var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l") - hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) - face_lying.Blend(hair_l, ICON_OVERLAY) - - //Eyes - // Note: These used to be in update_face(), and the fact they're here will make it difficult to create a disembodied head - var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l") - eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) - face_lying.Blend(eyes_l, ICON_OVERLAY) - - if(lip_style) - face_lying.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_l"), ICON_OVERLAY) - - var/image/face_lying_image = new /image(icon = face_lying) - return face_lying_image - //Human Overlays Indexes///////// #undef MUTATIONS_LAYER #undef DAMAGE_LAYER diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index b1d08d8f2c..b41fdb758a 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -314,7 +314,7 @@ if(Target.Adjacent(src)) if(istype(Target, /mob/living/silicon)) // Glomp the silicons if(!Atkcool) - a_intent = "hurt" + a_intent = I_HURT UnarmedAttack(Target) Atkcool = 1 spawn(45) @@ -328,12 +328,12 @@ spawn(45) Atkcool = 0 - a_intent = "disarm" + a_intent = I_DISARM UnarmedAttack(Target) else if(!Atkcool) - a_intent = "grab" + a_intent = I_GRAB UnarmedAttack(Target) else if(Target in view(7, src)) @@ -351,9 +351,9 @@ frenemy = S if (frenemy && prob(1)) if (frenemy.colour == colour) - a_intent = "help" + a_intent = I_HELP else - a_intent = "hurt" + a_intent = I_HURT UnarmedAttack(frenemy) var/sleeptime = movement_delay() @@ -365,10 +365,10 @@ /mob/living/carbon/slime/proc/handle_speech_and_mood() //Mood starts here var/newmood = "" - a_intent = "help" + a_intent = I_HELP if (rabid || attacked) newmood = "angry" - a_intent = "hurt" + a_intent = I_HURT else if (Target) newmood = "mischevous" if (!newmood) diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 8a44903f64..6ebaa95394 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -283,10 +283,10 @@ switch(M.a_intent) - if ("help") + if (I_HELP) help_shake_act(M) - if ("grab") + if (I_GRAB) if (M == src || anchored) return var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm new file mode 100644 index 0000000000..1b3da8f49a --- /dev/null +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -0,0 +1,141 @@ +//Monkey Overlays Indexes//////// +#define M_MASK_LAYER 1 +#define M_BACK_LAYER 2 +#define M_HANDCUFF_LAYER 3 +#define M_L_HAND_LAYER 4 +#define M_R_HAND_LAYER 5 +#define TARGETED_LAYER 6 +#define M_FIRE_LAYER 6 +#define M_TOTAL_LAYERS 7 +///////////////////////////////// + +/mob/living/carbon/monkey + var/list/overlays_lying[M_TOTAL_LAYERS] + var/list/overlays_standing[M_TOTAL_LAYERS] + +/mob/living/carbon/monkey/regenerate_icons() + ..() + update_inv_wear_mask(0) + update_inv_back(0) + update_inv_r_hand(0) + update_inv_l_hand(0) + update_inv_handcuffed(0) + update_fire(0) + update_icons() + //Hud Stuff + update_hud() + return + +/mob/living/carbon/monkey/update_icons() + update_hud() + lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again + overlays.Cut() + for(var/image/I in overlays_standing) + overlays += I + + if(lying) + var/matrix/M = matrix() + M.Turn(90) + M.Translate(1,-6) + src.transform = M + else + var/matrix/M = matrix() + src.transform = M + + +//////// +/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1) + if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) ) + overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]") + wear_mask.screen_loc = ui_monkey_mask + else + overlays_standing[M_MASK_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1) + if(r_hand) + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + + var/t_state = r_hand.item_state + if(!t_state) t_state = r_hand.icon_state + + overlays_standing[M_R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) + r_hand.screen_loc = ui_rhand + if (handcuffed) drop_r_hand() + else + overlays_standing[M_R_HAND_LAYER] = null + + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1) + if(l_hand) + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + + var/t_state = l_hand.item_state + if(!t_state) t_state = l_hand.icon_state + + overlays_standing[M_L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) + l_hand.screen_loc = ui_lhand + if (handcuffed) drop_l_hand() + else + overlays_standing[M_L_HAND_LAYER] = null + + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_back(var/update_icons=1) + if(back) + overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]") + back.screen_loc = ui_monkey_back + else + overlays_standing[M_BACK_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_inv_handcuffed(var/update_icons=1) + if(handcuffed) + drop_r_hand() + drop_l_hand() + stop_pulling() + overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1") + else + overlays_standing[M_HANDCUFF_LAYER] = null + if(update_icons) update_icons() + + +/mob/living/carbon/monkey/update_hud() + if (client) + client.screen |= contents + +//Call when target overlay should be added/removed +/mob/living/carbon/monkey/update_targeted(var/update_icons=1) + if (targeted_by && target_locked) + overlays_standing[TARGETED_LAYER] = target_locked + else if (!targeted_by && target_locked) + del(target_locked) + if (!targeted_by) + overlays_standing[TARGETED_LAYER] = null + if(update_icons) update_icons() + +/mob/living/carbon/monkey/update_fire(var/update_icons=1) + if(on_fire) + overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER) + else + overlays_standing[M_FIRE_LAYER] = null + if(update_icons) update_icons() +//Monkey Overlays Indexes//////// +#undef M_MASK_LAYER +#undef M_BACK_LAYER +#undef M_HANDCUFF_LAYER +#undef M_L_HAND_LAYER +#undef M_R_HAND_LAYER +#undef TARGETED_LAYER +#undef M_FIRE_LAYER +#undef M_TOTAL_LAYERS + diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index 63c742a690..d6630da627 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -22,11 +22,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 231c5d5329..00802c5da9 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -20,6 +20,122 @@ usr.visible_message("[src] points to [A]") return 1 +/*one proc, four uses +swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive +default behaviour is: + - non-passive mob passes the passive version + - passive mob checks to see if its mob_bump_flag is in the non-passive's mob_bump_flags + - if si, the proc returns +*/ +/mob/living/proc/can_move_mob(var/mob/living/swapped, swapping = 0, passive = 0) + if(!swapped) + return 1 + if(!passive) + return swapped.can_move_mob(src, swapping, 1) + else + var/context_flags = 0 + if(swapping) + context_flags = swapped.mob_swap_flags + else + context_flags = swapped.mob_push_flags + if(!mob_bump_flag) //nothing defined, go wild + return 1 + if(mob_bump_flag & context_flags) + return 1 + return 0 + +/mob/living/Bump(atom/movable/AM, yes) + spawn(0) + if ((!( yes ) || now_pushing) || !loc) + return + now_pushing = 1 + if (istype(AM, /mob/living)) + var/mob/living/tmob = AM + + for(var/mob/living/M in range(tmob, 1)) + if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) + if ( !(world.time % 5) ) + src << "[tmob] is restrained, you cannot push past" + now_pushing = 0 + return + if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) + if ( !(world.time % 5) ) + src << "[tmob] is restraining [M], you cannot push past" + now_pushing = 0 + return + + //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller + var/dense = 0 + if(loc.density) + dense = 1 + for(var/atom/movable/A in loc) + if(A == src) + continue + if(A.density) + if(A.flags&ON_BORDER) + dense = !A.CanPass(src, src.loc) + else + dense = 1 + if(dense) break + + //Leaping mobs just land on the tile, no pushing, no anything. + if(status_flags & LEAPING) + loc = tmob.loc + status_flags &= ~LEAPING + now_pushing = 0 + return + + if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! + var/turf/oldloc = loc + loc = tmob.loc + tmob.loc = oldloc + now_pushing = 0 + for(var/mob/living/carbon/slime/slime in view(1,tmob)) + if(slime.Victim == tmob) + slime.UpdateFeed() + return + + if(!can_move_mob(tmob, 0, 0)) + now_pushing = 0 + return + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) + if(prob(40) && !(FAT in src.mutations)) + src << "You fail to push [tmob]'s fat ass out of the way." + now_pushing = 0 + return + if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(!(tmob.status_flags & CANPUSH)) + now_pushing = 0 + return + + tmob.LAssailant = src + + now_pushing = 0 + spawn(0) + ..() + if (!istype(AM, /atom/movable)) + return + if (!now_pushing) + now_pushing = 1 + + if (!AM.anchored) + var/t = get_dir(src, AM) + if (istype(AM, /obj/structure/window)) + for(var/obj/structure/window/win in get_step(AM,t)) + now_pushing = 0 + return + step(AM, t) + now_pushing = 0 + return + return + /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > -95.0)) @@ -53,7 +169,7 @@ 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() @@ -223,7 +339,7 @@ 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 @@ -412,11 +528,11 @@ //pull damage with injured people if(prob(25)) M.adjustBruteLoss(1) - visible_message("\red \The [M]'s wounds open more from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!") if(M.pull_damage()) if(prob(25)) M.adjustBruteLoss(2) - visible_message("\red \The [M]'s wounds worsen terribly from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!") var/turf/location = M.loc if (istype(location, /turf/simulated)) location.add_blood(M) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index eb0c9ce859..e3ce0c9302 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -49,8 +49,8 @@ Stun(2) //Being hit while using a deadman switch - if(istype(equipped(),/obj/item/device/assembly/signaler)) - var/obj/item/device/assembly/signaler/signaler = equipped() + if(istype(get_active_hand(),/obj/item/device/assembly/signaler)) + var/obj/item/device/assembly/signaler/signaler = get_active_hand() if(signaler.deadman && prob(80)) src.visible_message("\red [src] triggers their deadman's switch!") signaler.signal() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 9998a08feb..3771bc135e 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -20,7 +20,6 @@ var/hallucination = 0 //Directly affects how long a mob will hallucinate for var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm - var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. @@ -32,6 +31,10 @@ var/t_n2 = null var/now_pushing = null + var/mob_bump_flag = 0 + var/mob_swap_flags = 0 + var/mob_push_flags = 0 + var/mob_always_swap = 0 var/mob/living/cameraFollow = null diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 622ee23bc7..1ce1085648 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -79,7 +79,132 @@ proc/get_radio_key_from_channel(var/channel) if(!istype(dongle)) return if(dongle.translate_binary) return 1 -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/sound/speech_sound, var/sound_vol) +/mob/living/proc/get_default_language() + return null + +/mob/living/proc/handle_speech_problems(var/message, var/verb) + var/list/returns[3] + var/speech_problem_flag = 0 + + if((HULK in mutations) && health >= 25 && length(message)) + message = "[uppertext(message)]!!!" + verb = pick("yells","roars","hollers") + speech_problem_flag = 1 + if(slurring) + message = slur(message) + verb = pick("slobbers","slurs") + speech_problem_flag = 1 + if(stuttering) + message = stutter(message) + verb = pick("stammers","stutters") + speech_problem_flag = 1 + + returns[1] = message + returns[2] = verb + returns[3] = speech_problem_flag + return returns + +/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) + if(message_mode == "intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message, verb, speaking) + used_radios += I + return 0 + +/mob/living/proc/handle_speech_sound() + var/list/returns[2] + returns[1] = null + returns[2] = null + return returns + +/mob/living/proc/get_speech_ending(verb, var/ending) + if(ending=="!") + return pick("exclaims","shouts","yells") + if(ending=="?") + return "asks" + return verb + +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="") + if(client) + if(client.prefs.muted & MUTE_IC) + src << "\red You cannot speak in IC (Muted)." + return + + if(stat) + if(stat == 2) + return say_dead(message) + return + + var/message_mode = parse_message_mode(message, "headset") + + switch(copytext(message,1,2)) + if("*") return emote(copytext(message,2)) + if("^") return custom_emote(1, copytext(message,2)) + + //parse the radio code and consume it + if (message_mode) + if (message_mode == "headset") + message = copytext(message,2) //it would be really nice if the parse procs could do this for us. + else + message = copytext(message,3) + + message = trim_left(message) + + //parse the language code and consume it + if(!speaking) + speaking = parse_language(message) + if(speaking) + message = copytext(message,2+length(speaking.key)) + else + speaking = get_default_language() + + var/ending = copytext(message, length(message)) + if (speaking) + // This is broadcast to all mobs with the language, + // irrespective of distance or anything else. + if(speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return + //If we've gotten this far, keep going! + verb = speaking.get_spoken_verb(ending) + else + verb = get_speech_ending(verb, ending) + + message = trim_left(message) + + if(!(speaking && (speaking.flags & NO_STUTTER))) + var/list/handle_s = handle_speech_problems(message, verb) + message = handle_s[1] + verb = handle_s[2] + + if(!message || message == "") + return + + var/list/obj/item/used_radios = new + if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)) + return + + var/list/handle_v = handle_speech_sound() + var/sound/speech_sound = handle_v[1] + var/sound_vol = handle_v[2] + + var/italics = 0 + var/message_range = world.view + + //speaking into radios + if(used_radios.len) + italics = 1 + message_range = 1 + if(speaking) + message_range = speaking.get_talkinto_msg_range(message) + var/msg + if(!speaking || !(speaking.flags & NO_TALK_MSG)) + msg = "\The [src] talks into \the [used_radios[1]]" + for(var/mob/living/M in hearers(5, src)) + if((M != src) && msg) + M.show_message(msg) + if (speech_sound) + sound_vol *= 0.5 var/turf/T = get_turf(src) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5adf82f5e8..66804f5bfa 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -311,13 +311,6 @@ var/list/ai_verbs_default = list( //usr <<"You can only change your display once!" //return -/mob/living/silicon/ai/proc/is_malf() - if(ticker.mode.name == "AI malfunction") - for (var/datum/mind/malfai in malf.current_antagonists) - if (mind == malfai) - return malf - return 0 - // displays the malf_ai information if the AI is the malf /mob/living/silicon/ai/show_malf_ai() if(malf && malf.hacked_apcs.len >= 3) diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm index 82dcfe216c..f36c32bb8d 100755 --- a/code/modules/mob/living/silicon/ai/laws.dm +++ b/code/modules/mob/living/silicon/ai/laws.dm @@ -16,8 +16,7 @@ src.laws.show_laws(who) /mob/living/silicon/ai/add_ion_law(var/law) - src.laws_sanity_check() - src.laws.add_ion_law(law) + ..() for(var/mob/living/silicon/robot/R in mob_list) if(R.lawupdate && (R.connected_ai == src)) R.show_laws() diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index 0994f23fd1..69d957fbaf 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -12,6 +12,7 @@ /mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg) laws_sanity_check() laws.set_zeroth_law(law, law_borg) + log_and_message_admins("has given [src] the zeroth laws: [law]/[law_borg ? law_borg : "N/A"]") /mob/living/silicon/robot/set_zeroth_law(var/law, var/law_borg) ..() @@ -21,28 +22,39 @@ /mob/living/silicon/proc/add_ion_law(var/law) laws_sanity_check() laws.add_ion_law(law) + log_and_message_admins("has given [src] the ion law: [law]") -/mob/living/silicon/proc/add_inherent_law(var/law, var/state_law = 1) +/mob/living/silicon/proc/add_inherent_law(var/law) laws_sanity_check() - laws.add_inherent_law(law, state_law) + laws.add_inherent_law(law) + log_and_message_admins("has given [src] the inherent law: [law]") + +/mob/living/silicon/proc/add_supplied_law(var/number, var/law) + laws_sanity_check() + laws.add_supplied_law(number, law) + log_and_message_admins("has given [src] the supplied law: [law]") + +/mob/living/silicon/proc/delete_law(var/datum/ai_law/law) + laws_sanity_check() + laws.delete_law(law) + log_and_message_admins("has deleted a law belonging to [src]: [law.law]") /mob/living/silicon/proc/clear_inherent_laws() laws_sanity_check() laws.clear_inherent_laws() + log_and_message_admins("cleared the inherent laws of [src]") /mob/living/silicon/proc/clear_ion_laws() laws_sanity_check() laws.clear_ion_laws() - -/mob/living/silicon/proc/add_supplied_law(var/number, var/law, var/state_law = 1) - laws_sanity_check() - laws.add_supplied_law(number, law, state_law) + log_and_message_admins("cleared the ion laws of [src]") /mob/living/silicon/proc/clear_supplied_laws() laws_sanity_check() laws.clear_supplied_laws() + log_and_message_admins("cleared the supplied laws of [src]") -/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws, var/use_statement_order = 1) // -- TLE +/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws) var/prefix = "" switch(lawchannel) if(MAIN_CHANNEL) prefix = ";" @@ -50,9 +62,9 @@ else prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " " - dostatelaws(lawchannel, prefix, laws, use_statement_order) + dostatelaws(lawchannel, prefix, laws) -/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws, var/use_statement_order) +/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws) if(stating_laws[prefix]) src << "[method]: Already stating laws using this communication method." return @@ -62,7 +74,7 @@ var/can_state = statelaw("[prefix]Current Active Laws:") for(var/datum/ai_law/law in laws.laws_to_state()) - can_state = statelaw("[prefix][law.get_index(use_statement_order)]. [law.law]") + can_state = statelaw("[prefix][law.get_index()]. [law.law]") if(!can_state) src << "[method]: Unable to state laws. Communication method unavailable." @@ -81,3 +93,7 @@ channels += common_radio.channels channels += additional_law_channels return channels + +/mob/living/silicon/proc/lawsync() + laws_sanity_check() + laws.sort_laws() 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/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 727c9ab0ce..68396cba33 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -17,6 +17,11 @@ integrated_light_power = 2 local_transmit = 1 + mob_bump_flag = SIMPLE_ANIMAL + mob_swap_flags = SIMPLE_ANIMAL + mob_push_flags = SIMPLE_ANIMAL + mob_always_swap = 1 + //Used for self-mailing. var/mail_destination = "" @@ -256,20 +261,6 @@ src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." src << "If a crewmember has noticed you, you are probably breaking your third law." -/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes) - if (!yes || ( \ - !istype(AM,/obj/machinery/door) && \ - !istype(AM,/obj/machinery/recharge_station) && \ - !istype(AM,/obj/machinery/disposal/deliveryChute) && \ - !istype(AM,/obj/machinery/teleport/hub) && \ - !istype(AM,/obj/effect/portal) - )) return - ..() - return - -/mob/living/silicon/robot/drone/Bumped(AM as mob|obj) - return - /mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM) if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index 55cb1376b6..e5778ad4dc 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -24,6 +24,6 @@ //Actual picking-up event. /mob/living/silicon/robot/drone/attack_hand(mob/living/carbon/human/M as mob) - if(M.a_intent == "help") + if(M.a_intent == I_HELP) get_scooped(M) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index a6e3399886..02ed0bae06 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -38,11 +38,12 @@ who << "Remember, you are not bound to any AI, you are not required to listen to them." -/mob/living/silicon/robot/proc/lawsync() +/mob/living/silicon/robot/lawsync() laws_sanity_check() - var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null + var/datum/ai_laws/master = connected_ai && lawupdate ? connected_ai.laws : null if (master) master.sync(src) + ..() return /mob/living/silicon/robot/proc/robot_checklaws() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9dd7472a3b..5ff1c23213 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -8,6 +8,10 @@ maxHealth = 200 health = 200 + mob_bump_flag = ROBOT + mob_swap_flags = ROBOT|MONKEY|SLIME|SIMPLE_ANIMAL + mob_push_flags = ALLMOBS //trundle trundle + var/lights_on = 0 // Is our integrated light on? var/used_power_this_tick = 0 var/sight_mode = 0 @@ -575,43 +579,6 @@ if(prob(75) && Proj.damage > 0) spark_system.start() return 2 -/mob/living/silicon/robot/Bump(atom/movable/AM as mob|obj, yes) - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(20)) - usr << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - now_pushing = 0 - ..() - if (istype(AM, /obj/machinery/recharge_station)) - var/obj/machinery/recharge_station/F = AM - F.move_inside() - if (!istype(AM, /atom/movable)) - return - if (!now_pushing) - now_pushing = 1 - if (!AM.anchored) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return - /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return @@ -1233,6 +1200,7 @@ /mob/living/silicon/robot/proc/disconnect_from_ai() if(connected_ai) + sync() // One last sync attempt connected_ai.connected_robots -= src connected_ai = null diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 14b9183db8..965729b8a8 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -333,3 +333,14 @@ for(var/obj/machinery/camera/C in A.cameras()) cameratext += "[(cameratext == "")? "" : "|"]
    [C.c_tag]" src << "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])" + + +/mob/living/silicon/proc/is_traitor() + return mind && (mind in traitors.current_antagonists) + +/mob/living/silicon/proc/is_malf() + return mind && (mind in malf.current_antagonists) + +/mob/living/silicon/proc/is_malf_or_traitor() + return is_traitor() || is_malf() + diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm index 9c2e9ca770..333ea3540d 100644 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ b/code/modules/mob/living/simple_animal/borer/borer.dm @@ -11,7 +11,7 @@ icon_living = "brainslug" icon_dead = "brainslug_dead" speed = 5 - a_intent = "harm" + a_intent = I_HURT stop_automated_movement = 1 status_flags = CANPUSH attacktext = "nipped" @@ -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/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm index 23718fb883..12d868e110 100644 --- a/code/modules/mob/living/simple_animal/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm @@ -10,10 +10,11 @@ response_harm = "punches" icon_dead = "shade_dead" speed = -1 - a_intent = "harm" + a_intent = I_HURT stop_automated_movement = 1 status_flags = CANPUSH - universal_speak = 1 + universal_speak = 0 + universal_understand = 1 attack_sound = 'sound/weapons/punch1.ogg' min_oxy = 0 max_oxy = 0 @@ -24,15 +25,25 @@ min_n2 = 0 max_n2 = 0 minbodytemp = 0 + show_stat_health = 0 faction = "cult" + supernatural = 1 + var/nullblock = 0 + + mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY + mob_push_flags = ALLMOBS + var/list/construct_spells = list() /mob/living/simple_animal/construct/New() ..() name = text("[initial(name)] ([rand(1, 1000)])") real_name = name + add_language("Cult") + add_language("Occult") for(var/spell in construct_spells) spell_list += new spell(src) + updateicon() /mob/living/simple_animal/construct/death() new /obj/item/weapon/ectoplasm (src.loc) @@ -40,12 +51,11 @@ ghostize() del src - /mob/living/simple_animal/construct/attack_generic(var/mob/user) if(istype(user, /mob/living/simple_animal/construct/builder)) if(health < maxHealth) adjustBruteLoss(-5) - user.visible_message("\The [user] mends some of \the [src]'s wounds.") + user.visible_message("\The [user] mends some of \the [src]'s wounds.") else user << "\The [src] is undamaged." return @@ -53,7 +63,7 @@ /mob/living/simple_animal/construct/examine(mob/user) ..(user) - var/msg = "" + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" if (src.health < src.maxHealth) msg += "" if (src.health >= src.maxHealth/2) @@ -64,54 +74,12 @@ msg += "*---------*" user << msg - return - -/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!istype(AM, /atom/movable)) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - -/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - /////////////////Juggernaut/////////////// + + + /mob/living/simple_animal/construct/armoured name = "Juggernaut" real_name = "Juggernaut" @@ -128,32 +96,12 @@ attacktext = "smashed their armoured gauntlet into" mob_size = 20 speed = 3 - wall_smash = 1 + environment_smash = 2 attack_sound = 'sound/weapons/punch3.ogg' status_flags = 0 + resistance = 10 construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) -/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - - /mob/living/simple_animal/construct/armoured/Life() weakened = 0 ..() @@ -163,8 +111,8 @@ var/reflectchance = 80 - round(P.damage/3) if(prob(reflectchance)) adjustBruteLoss(P.damage * 0.5) - visible_message("\The [P] was reflected by \the [src]'s shell!", \ - "\The [P] was reflected by \the [src]'s shell!") + visible_message("The [P.name] gets reflected by [src]'s shell!", \ + "The [P.name] gets reflected by [src]'s shell!") // Find a turf near or on the original location to bounce to if(P.starting) @@ -198,12 +146,12 @@ melee_damage_upper = 25 attacktext = "slashed" speed = -1 + environment_smash = 1 see_in_dark = 7 attack_sound = 'sound/weapons/bladeslice.ogg' construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift) - /////////////////////////////Artificer///////////////////////// @@ -223,7 +171,7 @@ melee_damage_upper = 5 attacktext = "rammed" speed = 0 - wall_smash = 1 + environment_smash = 2 attack_sound = 'sound/weapons/punch2.ogg' construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser, /obj/effect/proc_holder/spell/aoe_turf/conjure/wall, @@ -250,60 +198,35 @@ melee_damage_upper = 50 attacktext = "brutally crushed" speed = 5 - wall_smash = 1 + environment_smash = 2 attack_sound = 'sound/weapons/punch4.ogg' - mob_size = 20 + resistance = 10 var/energy = 0 var/max_energy = 1000 -/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") +////////////////////////Harvester//////////////////////////////// -////////////////Powers////////////////// +/mob/living/simple_animal/construct/harvester + name = "Harvester" + real_name = "Harvester" + desc = "The promised reward of the livings who follow narsie. Obtained by offering their bodies to the geometer of blood" + icon = 'icons/mob/mob.dmi' + icon_state = "harvester" + icon_living = "harvester" + maxHealth = 150 + health = 150 + melee_damage_lower = 25 + melee_damage_upper = 25 + attacktext = "violently stabs" + speed = -1 + environment_smash = 1 + see_in_dark = 7 + attack_sound = 'sound/weapons/pierce.ogg' - -/* -/client/proc/summon_cultist() - set category = "Behemoth" - set name = "Summon Cultist (300)" - set desc = "Teleport a cultist to your location" - if (istype(usr,/mob/living/simple_animal/constructbehemoth)) - - if(usr.energy<300) - usr << "\red You do not have enough power stored!" - return - - if(usr.stat) - return - - usr.energy -= 300 - var/list/mob/living/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living)) - cultists+=H.current - var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr) - if(!cultist) - return - if (cultist == usr) //just to be sure. - return - cultist.loc = usr.loc - usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/ + construct_spells = list( + //spell/targeted/harvest, + //spell/aoe_turf/knock/harvester, + //spell/rune_write + ) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index a71360d4bf..4e72bf55c0 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -103,7 +103,7 @@ /mob/living/simple_animal/cat/attack_hand(mob/living/carbon/human/M as mob) . = ..() - if(M.a_intent == "hurt") + if(M.a_intent == I_HURT) set_flee_target(M) /mob/living/simple_animal/cat/ex_act() diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 89a824f61f..322d08dc9f 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -24,241 +24,6 @@ var/obj/item/inventory_back var/facehugger -/* -/mob/living/simple_animal/corgi/Life() - ..() - regenerate_icons() - -/mob/living/simple_animal/corgi/show_inv(mob/user as mob) - user.set_machine(src) - if(user.stat) return - - var/dat = "
    Inventory of [name]

    " - if(inventory_head) - dat += "
    Head: [inventory_head] (Remove)" - else - dat += "
    Head: Nothing" - if(inventory_back) - dat += "
    Back: [inventory_back] (Remove)" - else - dat += "
    Back: Nothing" - - user << browse(dat, text("window=mob[];size=325x500", name)) - onclose(user, "mob[real_name]") - return - -/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(inventory_head && inventory_back) - //helmet and armor = 100% protection - if( istype(inventory_head,/obj/item/clothing/head/helmet) && istype(inventory_back,/obj/item/clothing/suit/armor) ) - if( O.force ) - usr << "\red This animal is wearing too much armor. You can't cause /him any damage." - for (var/mob/M in viewers(src, null)) - M.show_message("\red \b [user] hits [src] with the [O], however [src] is too armored.") - else - usr << "\red This animal is wearing too much armor. You can't reach its skin." - for (var/mob/M in viewers(src, null)) - M.show_message("\red [user] gently taps [src] with the [O]. ") - if(prob(15)) - visible_emote("looks at [user] with [pick("an amused","an annoyed","a confused","a resentful", "a happy", "an excited")] expression on \his face") - return - ..() - -/mob/living/simple_animal/corgi/Topic(href, href_list) - if(usr.stat) return - - //Removing from inventory - if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || issmall(usr) || isrobot(usr) || isalienadult(usr))) - return - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("head") - if(inventory_head) - name = real_name - desc = initial(desc) - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") - speak_emote = list("barks", "woofs") - emote_hear = list("barks", "woofs", "yaps","pants") - emote_see = list("shakes its head", "shivers") - desc = "It's a corgi." - SetLuminosity(0) - inventory_head.loc = src.loc - inventory_head = null - else - usr << "\red There is nothing to remove from its [remove_from]." - return - if("back") - if(inventory_back) - inventory_back.loc = src.loc - inventory_back = null - else - usr << "\red There is nothing to remove from its [remove_from]." - return - - //show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying. - - //Adding things to inventory - else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || issmall(usr) || isrobot(usr) || isalienadult(usr))) - return - var/add_to = href_list["add_inv"] - if(!usr.get_active_hand()) - usr << "\red You have nothing in your hand to put on its [add_to]." - return - switch(add_to) - if("head") - if(inventory_head) - usr << "\red It's is already wearing something." - return - else - place_on_head(usr.get_active_hand()) - - var/obj/item/item_to_add = usr.get_active_hand() - if(!item_to_add) - return - - //Corgis are supposed to be simpler, so only a select few objects can actually be put - //to be compatible with them. The objects are below. - //Many hats added, Some will probably be removed, just want to see which ones are popular. - - var/list/allowed_types = list( - /obj/item/clothing/head/helmet, - /obj/item/clothing/glasses/sunglasses, - /obj/item/clothing/head/caphat, - /obj/item/clothing/head/collectable/captain, - /obj/item/clothing/head/that, - /obj/item/clothing/head/that, - /obj/item/clothing/head/kitty, - /obj/item/clothing/head/collectable/kitty, - /obj/item/clothing/head/rabbitears, - /obj/item/clothing/head/collectable/rabbitears, - /obj/item/clothing/head/beret, - /obj/item/clothing/head/collectable/beret, - /obj/item/clothing/head/det_hat, - /obj/item/clothing/head/nursehat, - /obj/item/clothing/head/pirate, - /obj/item/clothing/head/collectable/pirate, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/head/chefhat, - /obj/item/clothing/head/collectable/chef, - /obj/item/clothing/head/collectable/police, - /obj/item/clothing/head/wizard/fake, - /obj/item/clothing/head/wizard, - /obj/item/clothing/head/collectable/wizard, - /obj/item/clothing/head/hardhat, - /obj/item/clothing/head/collectable/hardhat, - /obj/item/clothing/head/hardhat/white, - /obj/item/weapon/bedsheet, - /obj/item/clothing/head/helmet/space/santahat, - /obj/item/clothing/head/collectable/paper, - /obj/item/clothing/head/soft - ) - - if( ! ( item_to_add.type in allowed_types ) ) - usr << "\red It doesn't seem too keen on wearing that item." - return - - usr.drop_item() - - place_on_head(item_to_add) - - if("back") - if(inventory_back) - usr << "\red It's already wearing something." - return - else - var/obj/item/item_to_add = usr.get_active_hand() - if(!item_to_add) - return - - //Corgis are supposed to be simpler, so only a select few objects can actually be put - //to be compatible with them. The objects are below. - - var/list/allowed_types = list( - /obj/item/clothing/suit/armor/vest, - /obj/item/device/radio - ) - - if( ! ( item_to_add.type in allowed_types ) ) - usr << "\red This object won't fit." - return - - usr.drop_item() - item_to_add.loc = src - src.inventory_back = item_to_add - regenerate_icons() - - //show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying. - else - ..() - -/mob/living/simple_animal/corgi/proc/place_on_head(obj/item/item_to_add) - item_to_add.loc = src - src.inventory_head = item_to_add - regenerate_icons() - - //Various hats and items (worn on his head) change Ian's behaviour. His attributes are reset when a HAT is removed. - switch(inventory_head && inventory_head.type) - if(/obj/item/clothing/head/caphat, /obj/item/clothing/head/collectable/captain) - name = "Captain [real_name]" - desc = "Probably better than the last captain." - if(/obj/item/clothing/head/kitty, /obj/item/clothing/head/collectable/kitty) - name = "Runtime" - emote_see = list("coughs up a furball", "stretches") - emote_hear = list("purrs") - speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW") - desc = "It's a cute little kitty-cat! ... wait ... what the hell?" - if(/obj/item/clothing/head/rabbitears, /obj/item/clothing/head/collectable/rabbitears) - name = "Hoppy" - emote_see = list("twitches its nose", "hops around a bit") - desc = "This is hoppy. It's a corgi-...urmm... bunny rabbit" - if(/obj/item/clothing/head/beret, /obj/item/clothing/head/collectable/beret) - name = "Yann" - desc = "Mon dieu! C'est un chien!" - speak = list("le woof!", "le bark!", "JAPPE!!") - emote_see = list("cowers in fear", "surrenders", "plays dead","looks as though there is a wall in front of him") - if(/obj/item/clothing/head/det_hat) - name = "Detective [real_name]" - desc = "[name] sees through your lies..." - emote_see = list("investigates the area","sniffs around for clues","searches for scooby snacks") - if(/obj/item/clothing/head/nursehat) - name = "Nurse [real_name]" - desc = "[name] needs 100cc of beef jerky...STAT!" - if(/obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate) - name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]" - desc = "Yaarghh!! Thar' be a scurvy dog!" - emote_see = list("hunts for treasure","stares coldly...","gnashes his tiny corgi teeth") - emote_hear = list("growls ferociously", "snarls") - speak = list("Arrrrgh!!","Grrrrrr!") - if(/obj/item/clothing/head/ushanka) - name = "[pick("Comrade","Commissar","Glorious Leader")] [real_name]" - desc = "A follower of Karl Barx." - emote_see = list("contemplates the failings of the capitalist economic model", "ponders the pros and cons of vangaurdism") - if(/obj/item/clothing/head/collectable/police) - name = "Officer [real_name]" - emote_see = list("drools","looks for donuts") - desc = "Stop right there criminal scum!" - if(/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard, /obj/item/clothing/head/collectable/wizard) - name = "Grandwizard [real_name]" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!") - if(/obj/item/weapon/bedsheet) - name = "\improper Ghost" - speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU") - emote_see = list("stumbles around", "shivers") - emote_hear = list("howls","groans") - desc = "Spooky!" - if(/obj/item/clothing/head/helmet/space/santahat) - name = "Rudolph the Red-Nosed Corgi" - emote_hear = list("barks christmas songs", "yaps") - desc = "He has a very shiny nose." - SetLuminosity(6) - if(/obj/item/clothing/head/soft) - name = "Corgi Tech [real_name]" - desc = "The reason your yellow gloves have chew-marks." -*/ - - //IAN! SQUEEEEEEEEE~ /mob/living/simple_animal/corgi/Ian name = "Ian" @@ -325,44 +90,6 @@ name = "Corgi meat" desc = "Tastes like... well you know..." -/mob/living/simple_animal/corgi/Ian/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(70)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return -//PC stuff-Sieve - /mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/weapon/newspaper)) if(!stat) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index ca0b4e173a..b7e72da0c6 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -125,7 +125,7 @@ udder.add_reagent("milk", rand(5, 10)) /mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob) - if(!stat && M.a_intent == "disarm" && icon_state != icon_dead) + if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead) M.visible_message("[M] tips over [src].","You tip over [src].") Weaken(30) icon_state = icon_dead diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm index 9674517a4c..dab2d2e2d9 100644 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ b/code/modules/mob/living/simple_animal/friendly/slime.dm @@ -14,43 +14,6 @@ emote_see = list("jiggles", "bounces in place") var/colour = "grey" -/mob/living/simple_animal/slime/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(70)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return - /mob/living/simple_animal/adultslime name = "pet slime" desc = "A lovable, domesticated slime." diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 447ad6b1c9..27b43a7cc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -17,7 +17,7 @@ melee_damage_lower = 25 melee_damage_upper = 25 attacktext = "slashed" - a_intent = "harm" + a_intent = I_HURT attack_sound = 'sound/weapons/bladeslice.ogg' min_oxy = 0 max_oxy = 0 @@ -29,7 +29,7 @@ max_n2 = 0 unsuitable_atoms_damage = 15 faction = "alien" - wall_smash = 1 + environment_smash = 2 status_flags = CANPUSH minbodytemp = 0 heat_damage_per_tick = 20 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/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index cdaf72f6bd..5a6a7e5768 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -13,7 +13,7 @@ speak = list("HONK", "Honk!", "Welcome to clown planet!") emote_see = list("honks") speak_chance = 1 - a_intent = "harm" + a_intent = I_HURT stop_automated_movement_when_pulled = 0 maxHealth = 75 health = 75 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index c6d3052b5d..872eb95b61 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -15,7 +15,7 @@ response_harm = "hits" speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity") - a_intent = "harm" + a_intent = I_HURT stop_automated_movement_when_pulled = 0 health = 300 maxHealth = 300 diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index b96a615170..84f1c6f27a 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -18,7 +18,7 @@ melee_damage_lower = 15 melee_damage_upper = 15 attacktext = "punched" - a_intent = "harm" + a_intent = I_HURT var/corpse = /obj/effect/landmark/mobcorpse/russian var/weapon1 = /obj/item/weapon/kitchenknife min_oxy = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index c5c87014ec..12f175cfef 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -18,7 +18,7 @@ melee_damage_lower = 10 melee_damage_upper = 10 attacktext = "punched" - a_intent = "harm" + a_intent = I_HURT var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier var/weapon1 var/weapon2 @@ -31,7 +31,7 @@ min_n2 = 0 max_n2 = 0 unsuitable_atoms_damage = 15 - wall_smash = 1 + environment_smash = 1 faction = "syndicate" status_flags = CANPUSH @@ -159,4 +159,4 @@ /mob/living/simple_animal/hostile/viscerator/death() ..(null,"is smashed into pieces!") - del src + del src diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 9090ab6fe6..729bb3ff05 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -215,7 +215,7 @@ /mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob) ..() if(client) return - if(!stat && M.a_intent == "hurt") + if(!stat && M.a_intent == I_HURT) icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks @@ -475,7 +475,7 @@ if(ishuman(parrot_interest)) var/mob/living/carbon/human/H = parrot_interest - var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) + var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1) visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons.")) @@ -607,7 +607,7 @@ stolen_item = C.r_hand if(stolen_item) - C.u_equip(stolen_item) + C.remove_from_mob(stolen_item) held_item = stolen_item stolen_item.loc = src visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.") diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index c200ef6f70..98db91e7cc 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -28,34 +28,20 @@ faction = "cult" status_flags = CANPUSH - - Life() - ..() - if(stat == 2) - new /obj/item/weapon/ectoplasm (src.loc) - for(var/mob/M in viewers(src, null)) - if((M.client && !( M.blinded ))) - M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") - ghostize() - del src - return - - - attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri - if(istype(O, /obj/item/device/soulstone)) - O.transfer_soul("SHADE", src, user) - else - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - health -= damage - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with the [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with the [O]. ") +/mob/living/simple_animal/shade/Life() + ..() + if(stat == 2) + new /obj/item/weapon/ectoplasm (src.loc) + for(var/mob/M in viewers(src, null)) + if((M.client && !( M.blinded ))) + M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") + ghostize() + del src return + + +/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri + if(istype(O, /obj/item/device/soulstone)) + O.transfer_soul("SHADE", src, user) + return + return ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 425295cd2d..e94694295c 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -4,6 +4,12 @@ health = 20 maxHealth = 20 + mob_bump_flag = SIMPLE_ANIMAL + mob_swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + mob_push_flags = MONKEY|SLIME|SIMPLE_ANIMAL + + var/show_stat_health = 1 //does the percentage health show in the stat panel for the mob + var/icon_living = "" var/icon_dead = "" var/icon_gib = null //We only try to show a gibbing animation if this exists. @@ -52,7 +58,12 @@ var/attacktext = "attacked" var/attack_sound = null var/friendly = "nuzzles" - var/wall_smash = 0 + var/environment_smash = 0 + var/resistance = 0 // Damage reduction + + //Null rod stuff + var/supernatural = 0 + var/purge = 0 /mob/living/simple_animal/New() ..() @@ -88,6 +99,7 @@ handle_stunned() handle_weakened() handle_paralysed() + handle_supernatural() //Movement if(!client && !stop_automated_movement && wander && !anchored) @@ -186,19 +198,9 @@ adjustBruteLoss(unsuitable_atoms_damage) return 1 -/mob/living/simple_animal/Bumped(AM as mob|obj) - if(!AM) return - - if(resting || buckled) - return - - if(isturf(src.loc)) - if(ismob(AM)) - var/newamloc = src.loc - src.loc = AM:loc - AM:loc = newamloc - else - ..() +/mob/living/simple_animal/proc/handle_supernatural() + if(purge) + purge -= 1 /mob/living/simple_animal/gib() ..(icon_gib,1) @@ -225,15 +227,15 @@ switch(M.a_intent) - if("help") + if(I_HELP) if (health > 0) M.visible_message("\blue [M] [response_help] \the [src]") - if("disarm") + if(I_DISARM) M.visible_message("\blue [M] [response_disarm] \the [src]") //TODO: Push the mob away or something - if("grab") + if(I_GRAB) if (M == src) return if (!(status_flags & CANPUSH)) @@ -249,62 +251,66 @@ M.visible_message("\red [M] has grabbed [src] passively!") - if("hurt") + if(I_HURT) adjustBruteLoss(harm_intent_damage) M.visible_message("\red [M] [response_harm] \the [src]") return -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) //Marker -Agouri - +/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/stack/medical)) - - if(stat != DEAD && health < maxHealth) - var/obj/item/stack/medical/medical_pack = O - if(medical_pack.use(1)) - adjustBruteLoss(-medical_pack.heal_brute) - visible_message("\The [user] applies the [medical_pack] to \the [src].") + user.changeNext_move(4) + if(stat != DEAD) + var/obj/item/stack/medical/MED = O + if(health < maxHealth) + if(MED.amount >= 1) + adjustBruteLoss(-MED.heal_brute) + MED.amount -= 1 + if(MED.amount <= 0) + del(MED) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\The [src] cannot benefit from medical items in \his current state." - return - - else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) - var/actual_meat_amount = max(1,(meat_amount/2)) - if(meat_type && actual_meat_amount>0 && (stat == DEAD)) - for(var/i=0;i[user] chops up \the [src]!") - new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) - del(src) - else - user.visible_message("[user] butchers \the [src] messily!") - gib() - return - - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - visible_message("\The [src] has been attacked with \the [O] by [user].") + user << "" + if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. + if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) + harvest(user) else - user << "This weapon is ineffective; it does no damage." - visible_message("\The [user] gently taps [src] with the [O].") + user.changeNext_move(8) + if(O.force > resistance) + var/damage = O.force + if (O.damtype == HALLOSS) + damage = 0 + if(supernatural && istype(O,/obj/item/weapon/nullrod)) + damage *= 2 + purge = 3 + adjustBruteLoss(damage) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("This weapon is ineffective, it does no damage." + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("0 && (stat == DEAD)) + for(var/i=0;i[user] chops up \the [src]!") + new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) + del(src) + else + user.visible_message("[user] butchers \the [src] messily!") + gib() diff --git a/code/modules/mob/living/simple_animal/worm.dm b/code/modules/mob/living/simple_animal/worm.dm index 0df4f5c7c4..fe76fa87b4 100644 --- a/code/modules/mob/living/simple_animal/worm.dm +++ b/code/modules/mob/living/simple_animal/worm.dm @@ -30,9 +30,9 @@ max_co2 = 0 max_tox = 0 - a_intent = "harm" //so they don't get pushed around + a_intent = I_HURT //so they don't get pushed around - wall_smash = 1 + environment_smash = 2 speed = -1 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4379db6c17..e4405c5767 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -117,77 +117,6 @@ /mob/proc/restrained() return -//This proc is called whenever someone clicks an inventory ui slot. -/mob/proc/attack_ui(slot) - var/obj/item/W = get_active_hand() - if(istype(W)) - equip_to_slot_if_possible(W, slot) - -/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1) - if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob)) - return 1 - else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob)) - return 1 - return 0 - -//This is a SAFE proc. Use this instead of equip_to_slot()! -//set del_on_fail to have it delete W if it fails to equip -//set disable_warning to disable the 'you are unable to equip that' warning. -//unset redraw_mob to prevent the mob from being redrawn at the end. -/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1) - if(!istype(W)) return 0 - - if(!W.mob_can_equip(src, slot)) - if(del_on_fail) - del(W) - else - if(!disable_warning) - src << "\red You are unable to equip that." //Only print if del_on_fail is false - return 0 - - equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. - return 1 - -//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. -//In most cases you will want to use equip_to_slot_if_possible() -/mob/proc/equip_to_slot(obj/item/W as obj, slot) - return - -//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. -/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) - return equip_to_slot_if_possible(W, slot, 1, 1, 0) - -//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. -var/list/slot_equipment_priority = list( \ - slot_back,\ - slot_wear_id,\ - slot_w_uniform,\ - slot_wear_suit,\ - slot_wear_mask,\ - slot_head,\ - slot_shoes,\ - slot_gloves,\ - slot_l_ear,\ - slot_r_ear,\ - slot_glasses,\ - slot_belt,\ - slot_s_store,\ - slot_tie,\ - slot_l_store,\ - slot_r_store\ - ) - -//puts the item "W" into an appropriate slot in a human's inventory -//returns 0 if it cannot, 1 if successful -/mob/proc/equip_to_appropriate_slot(obj/item/W) - if(!istype(W)) return 0 - - for(var/slot in slot_equipment_priority) - if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) - return 1 - - return 0 - /mob/proc/reset_view(atom/A) if (client) if (istype(A, /atom/movable)) @@ -589,8 +518,8 @@ var/list/slot_equipment_priority = list( \ var/mob/living/carbon/human/H = src if(H.health - H.halloss <= config.health_threshold_softcrit) for(var/name in H.organs_by_name) - var/datum/organ/external/e = H.organs_by_name[name] - if(H.lying) + var/obj/item/organ/external/e = H.organs_by_name[name] + if(e && H.lying) if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) return 1 break @@ -1101,7 +1030,7 @@ mob/proc/yank_out_object() else U << "You attempt to get a good grip on [selection] in [S]'s body." - if(!do_after(U, 80)) + if(!do_after(U, 30)) return if(!selection || !S || !U) return @@ -1116,9 +1045,9 @@ mob/proc/yank_out_object() if(ishuman(src)) var/mob/living/carbon/human/H = src - var/datum/organ/external/affected + var/obj/item/organ/external/affected - for(var/datum/organ/external/organ in H.organs) //Grab the organ holding the implant. + for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant. for(var/obj/item/O in organ.implants) if(O == selection) affected = organ @@ -1137,6 +1066,8 @@ mob/proc/yank_out_object() human_user.bloody_hands(H) selection.loc = get_turf(src) + if(!(U.l_hand && U.r_hand)) + U.put_in_hands(selection) for(var/obj/item/weapon/O in pinned) if(O == selection) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 47c3bb0f6c..9b17a182aa 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -14,6 +14,7 @@ var/obj/screen/blind = null var/obj/screen/hands = null var/obj/screen/pullin = null + var/obj/screen/purged = null var/obj/screen/internals = null var/obj/screen/oxygen = null var/obj/screen/i_select = null @@ -117,7 +118,7 @@ var/losebreath = 0.0//Carbon var/intent = null//Living var/shakecamera = 0 - var/a_intent = "help"//Living + var/a_intent = I_HELP//Living var/m_int = null//Living var/m_intent = "run"//Living var/lastKnownIP = null diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 8c37c0cae1..370a921d3c 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -92,13 +92,22 @@ /mob/living/silicon/ai/isAI() return 1 - -/mob/proc/isRobot() + +/mob/proc/isRobot() return 0 /mob/living/silicon/robot/isRobot() return 1 +/mob/proc/isSynthetic() + return 0 + +/mob/living/carbon/human/isSynthetic() + return species.flags & IS_SYNTHETIC + +/mob/living/silicon/isSynthetic() + return 1 + /proc/ispAI(A) if(istype(A, /mob/living/silicon/pai)) return 1 @@ -125,7 +134,7 @@ proc/isobserver(A) return 0 proc/isorgan(A) - if(istype(A, /datum/organ/external)) + if(istype(A, /obj/item/organ/external)) return 1 return 0 @@ -140,7 +149,7 @@ proc/isnewplayer(A) return 1 return 0 -proc/hasorgans(A) +proc/hasorgans(A) // Fucking really?? return ishuman(A) proc/iscuffed(A) @@ -433,20 +442,20 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return 0 //converts intent-strings into numbers and back -var/list/intents = list("help","disarm","grab","hurt") +var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT) /proc/intent_numeric(argument) if(istext(argument)) switch(argument) - if("help") return 0 - if("disarm") return 1 - if("grab") return 2 + if(I_HELP) return 0 + if(I_DISARM) return 1 + if(I_GRAB) return 2 else return 3 else switch(argument) - if(0) return "help" - if(1) return "disarm" - if(2) return "grab" - else return "hurt" + if(0) return I_HELP + if(1) return I_DISARM + if(2) return I_GRAB + else return I_HURT //change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left /mob/verb/a_intent_change(input as text) @@ -455,7 +464,7 @@ var/list/intents = list("help","disarm","grab","hurt") if(ishuman(src) || isbrain(src) || isslime(src)) switch(input) - if("help","disarm","grab","hurt") + if(I_HELP,I_DISARM,I_GRAB,I_HURT) a_intent = input if("right") a_intent = intent_numeric((intent_numeric(a_intent)+1) % 4) @@ -466,17 +475,17 @@ var/list/intents = list("help","disarm","grab","hurt") else if(isrobot(src)) switch(input) - if("help") - a_intent = "help" - if("hurt") - a_intent = "hurt" + if(I_HELP) + a_intent = I_HELP + if(I_HURT) + a_intent = I_HURT if("right","left") a_intent = intent_numeric(intent_numeric(a_intent) - 3) if(hud_used && hud_used.action_intent) - if(a_intent == "hurt") - hud_used.action_intent.icon_state = "harm" + if(a_intent == I_HURT) + hud_used.action_intent.icon_state = I_HURT else - hud_used.action_intent.icon_state = "help" + hud_used.action_intent.icon_state = I_HELP proc/is_blind(A) if(istype(A, /mob/living/carbon)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index bd00faf953..baf1d29968 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -96,8 +96,8 @@ /client/verb/drop_item() set hidden = 1 - if(!isrobot(mob)) - mob.drop_item_v() + if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc)) + return mob.drop_item() return @@ -289,8 +289,8 @@ else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair)) if(ishuman(mob.buckled)) var/mob/living/carbon/human/driver = mob.buckled - var/datum/organ/external/l_hand = driver.get_organ("l_hand") - var/datum/organ/external/r_hand = driver.get_organ("r_hand") + var/obj/item/organ/external/l_hand = driver.get_organ("l_hand") + var/obj/item/organ/external/r_hand = driver.get_organ("r_hand") if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED))) return // No hands to drive your chair? Tough luck! //drunk wheelchair driving diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index d25b66210e..6330504e3c 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -200,12 +200,13 @@ datum/preferences for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) if(organ_data[name] == "amputated") continue - - var/icon/temp = new /icon(icobase, "[name]") if(organ_data[name] == "cyborg") - temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) - - preview_icon.Blend(temp, ICON_OVERLAY) + var/datum/robolimb/R + if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] + if(!R) R = basic_robolimb + preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. + continue + preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) //Tail if(current_species && (current_species.tail)) @@ -375,7 +376,7 @@ datum/preferences if(LAWYER) clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "briefcase"), ICON_UNDERLAY) if(prob(1)) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "suitjacket_blue"), ICON_OVERLAY) switch(backbag) @@ -534,7 +535,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "toolbox_blue"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) @@ -620,7 +621,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) clothes_s.Blend(new /icon('icons/mob/head.dmi', "hardhat0_white"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "blueprints"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "blueprints"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "engiepack"), ICON_OVERLAY) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 9793fe02fa..958f0b982a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -180,7 +180,7 @@ var/alien_caste = pick("Hunter","Sentinel","Drone") var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc) - new_xeno.a_intent = "hurt" + new_xeno.a_intent = I_HURT new_xeno.key = key new_xeno << "You are now an alien." @@ -237,7 +237,7 @@ del(t) var/mob/living/simple_animal/corgi/new_corgi = new /mob/living/simple_animal/corgi (loc) - new_corgi.a_intent = "hurt" + new_corgi.a_intent = I_HURT new_corgi.key = key new_corgi << "You are now a Corgi. Yap Yap!" @@ -271,7 +271,7 @@ var/mob/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = "hurt" + new_mob.a_intent = I_HURT new_mob << "You suddenly feel more... animalistic." @@ -291,7 +291,7 @@ var/mob/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = "hurt" + new_mob.a_intent = I_HURT new_mob << "You feel more... animalistic" del(src) diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm index a6ae6dc4a0..480c4be322 100644 --- a/code/modules/mob/update_icons.dm +++ b/code/modules/mob/update_icons.dm @@ -1,6 +1,11 @@ //Most of these are defined at this level to reduce on checks elsewhere in the code. //Having them here also makes for a nice reference list of the various overlay-updating procs available +//default item on-mob icons +#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi' +#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' + + /mob/proc/regenerate_icons() //TODO: phase this out completely if possible return diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm index faccc5fdc3..4f81585a04 100644 --- a/code/modules/nano/modules/law_manager.dm +++ b/code/modules/nano/modules/law_manager.dm @@ -49,30 +49,26 @@ var/datum/ai_law/AL = locate(href_list["ref"]) in owner.laws.all_laws() if(AL) var/state_law = text2num(href_list["state_law"]) - AL.state_law = state_law + owner.laws.set_state_law(AL, state_law) return 1 if(href_list["add_zeroth_law"]) if(zeroth_law && is_admin(usr) && !owner.laws.zeroth_law) - log_and_message_admins("has given [owner] a new zeroth law: [zeroth_law]") owner.set_zeroth_law(zeroth_law) return 1 if(href_list["add_ion_law"]) if(ion_law && is_malf(usr)) - log_and_message_admins("has given [owner] a new ion law: [ion_law]") owner.add_ion_law(ion_law) return 1 if(href_list["add_inherent_law"]) if(inherent_law && is_malf(usr)) - log_and_message_admins("has given [owner] a new inherent law: [inherent_law]") owner.add_inherent_law(inherent_law) return 1 if(href_list["add_supplied_law"]) if(supplied_law && supplied_law_position >= 1 && MIN_SUPPLIED_LAW_NUMBER <= MAX_SUPPLIED_LAW_NUMBER && is_malf(usr)) - log_and_message_admins("has given [owner] a new supplied law: [supplied_law]") owner.add_supplied_law(supplied_law_position, supplied_law) return 1 @@ -120,8 +116,7 @@ if(is_malf(usr)) var/datum/ai_law/AL = locate(href_list["delete_law"]) in owner.laws.all_laws() if(AL && is_malf(usr)) - log_and_message_admins("has deleted a law belonging to [owner]: [AL.law]") - owner.laws.delete_law(AL) + owner.delete_law(AL) return 1 if(href_list["state_laws"]) @@ -143,15 +138,6 @@ current_view = 0 return 1 - if(href_list["sync_laws"]) - if(owner.isAI()) - sync_laws(owner) - else - var/mob/living/silicon/robot/R = owner - sync_laws(R.connected_ai) - usr << "Sync complete." - return 1 - if(href_list["notify_laws"]) owner << "Law Notice" owner.laws.show_laws(owner) @@ -164,9 +150,11 @@ usr << "= 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..b6f14b64bc 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -1,33 +1,37 @@ /**************************************************** EXTERNAL ORGANS ****************************************************/ -/datum/organ/external +/obj/item/organ/external name = "external" var/icon_name = null var/body_part = null var/icon_position = 0 + var/model + var/force_icon + var/damage_state = "00" var/brute_dam = 0 var/burn_dam = 0 - var/max_damage = 0 var/max_size = 0 var/last_dam = -1 - - var/display_name + var/icon/mob_icon + var/gendered_icon = 0 + var/limb_name + var/disfigured = 1 + var/cannot_amputate + var/cannot_break + var/s_tone + var/list/s_col var/list/wounds = list() var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len! + var/perma_injury = 0 - var/tmp/perma_injury = 0 - var/tmp/destspawn = 0 //Has it spawned the broken limb? - var/tmp/amputated = 0 //Whether this has been cleanly amputated, thus causing no pain - var/min_broken_damage = 30 - - var/datum/organ/external/parent - var/list/datum/organ/external/children + var/obj/item/organ/external/parent + var/list/obj/item/organ/external/children // Internal organs of this body part - var/list/datum/organ/internal/internal_organs + var/list/internal_organs = list() var/damage_msg = "\red You feel an intense pain" var/broken_description @@ -44,33 +48,100 @@ // how often wounds should be updated, a higher number means less often var/wound_update_accuracy = 1 + var/joint = "joint" // Descriptive string used in dislocation. + var/amputation_point // Descriptive string used in amputation. + var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. + var/can_grasp + var/can_stand -/datum/organ/external/New(var/datum/organ/external/P) - if(P) - parent = P - if(!parent.children) - parent.children = list() - parent.children.Add(src) - return ..() + min_broken_damage = 30 + max_damage = 0 + dir = SOUTH + +/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob) + switch(stage) + if(0) + if(istype(W,/obj/item/weapon/scalpel)) + user.visible_message("[user] cuts [src] open with [W]!") + stage++ + return + if(1) + if(istype(W,/obj/item/weapon/retractor)) + user.visible_message("[user] cracks [src] open like an egg with [W]!") + stage++ + return + if(2) + if(istype(W,/obj/item/weapon/hemostat)) + if(contents.len) + var/obj/item/removing = pick(contents) + removing.loc = get_turf(user.loc) + if(!(user.l_hand && user.r_hand)) + user.put_in_hands(removing) + user.visible_message("[user] extracts [removing] from [src] with [W]!") + else + user.visible_message("[user] fishes around fruitlessly in [src] with [W].") + return + ..() + +/obj/item/organ/external/proc/is_dislocated() + if(dislocated > 0) + return 1 + if(parent) + return parent.is_dislocated() + return 0 + +/obj/item/organ/external/proc/dislocate(var/primary) + if(dislocated != -1) + if(primary) + dislocated = 2 + else + dislocated = 1 + owner.verbs |= /mob/living/carbon/human/proc/undislocate + if(children && children.len) + for(var/obj/item/organ/external/child in children) + child.dislocate() + +/obj/item/organ/external/proc/undislocate() + if(dislocated != -1) + dislocated = 0 + if(children && children.len) + for(var/obj/item/organ/external/child in children) + child.undislocate() + if(owner) + owner.shock_stage += 20 + +/obj/item/organ/external/update_health() + damage = min(max_damage, (brute_dam + burn_dam)) + return + + +/obj/item/organ/external/New(var/mob/living/carbon/holder, var/internal) + ..() + if(owner) + replaced(owner) + sync_colour_to_human(owner) + +/obj/item/organ/external/replaced(var/mob/living/carbon/human/target) + owner = target + if(istype(owner)) + owner.organs_by_name[limb_name] = src + owner.organs |= src + for(var/obj/item/organ/organ in src) + organ.loc = owner + organ.replaced(owner,src) + + if(parent_organ) + parent = owner.organs_by_name[src.parent_organ] + if(parent) + if(!parent.children) + parent.children = list() + parent.children.Add(src) /**************************************************** DAMAGE PROCS ****************************************************/ -/datum/organ/external/proc/emp_act(severity) - if(!(status & ORGAN_ROBOT)) //meatbags do not care about EMP - return - var/probability = 30 - var/damage = 15 - if(severity == 2) - probability = 1 - damage = 3 - if(prob(probability)) - droplimb(1) - else - take_damage(damage, 0, 1, 1, used_weapon = "EMP") - -/datum/organ/external/proc/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) +/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) if((brute <= 0) && (burn <= 0)) return 0 @@ -91,11 +162,12 @@ burn *= bumod //~2/3 damage for ROBOLIMBS // High brute damage or sharp objects may damage internal organs - if(internal_organs && ( (sharp && brute >= 5) || brute >= 10) && prob(5)) + if(internal_organs && ((brute_dam >= max_damage) || (sharp && brute >= 5) || brute >= 10) && prob(5)) // Damage an internal organ - var/datum/organ/internal/I = pick(internal_organs) - I.take_damage(brute / 2) - brute -= brute / 2 + if(internal_organs && internal_organs.len) + var/obj/item/organ/I = pick(internal_organs) + I.take_damage(brute / 2) + brute -= brute / 2 if(status & ORGAN_BROKEN && prob(40) && brute) if (!(owner.species && (owner.species.flags & NO_PAIN))) @@ -137,38 +209,32 @@ burn = max(0, burn - can_inflict) //If there are still hurties to dispense if (burn || brute) - if (status & ORGAN_ROBOT) - droplimb(1) //Robot limbs just kinda fail at full damage. - else - //List organs we can pass it to - var/list/datum/organ/external/possible_points = list() - if(parent) - possible_points += parent - if(children) - possible_points += children - if(forbidden_limbs.len) - possible_points -= forbidden_limbs - if(possible_points.len) - //And pass the pain around - var/datum/organ/external/target = pick(possible_points) - target.take_damage(brute, burn, sharp, edge, used_weapon, forbidden_limbs + src) + owner.shock_stage += brute+burn // sync the organ's damage with its wounds src.update_damages() //If limb took enough damage, try to cut or tear it off - if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you. - if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier) - if( (edge && prob(5 * brute)) || (brute > 20 && prob(brute)) ) - droplimb(1) - return + if(owner && loc == owner) + if(!cannot_amputate && config.limbs_can_break && (brute_dam + burn_dam) >= (max_damage * config.organ_health_multiplier)) + var/threshold = max_damage/3 + var/dropped + if((burn >= threshold) && prob(burn/3)) + dropped = 1 + droplimb(0,DROPLIMB_BURN) + if(!dropped && prob(brute)) + if(brute >= threshold) + if((sharp || edge) && istype(used_weapon,/obj/item)) + var/obj/item/W = used_weapon + if(W.w_class >= 3) + droplimb(0,DROPLIMB_EDGE) + else + droplimb(0,DROPLIMB_BLUNT) owner.updatehealth() + return update_icon() - var/result = update_icon() - return result - -/datum/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) +/obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) if(status & ORGAN_ROBOT && !robo_repair) return @@ -187,6 +253,11 @@ status &= ~ORGAN_BROKEN perma_injury = 0 + if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS)) + var/obj/item/organ/external/stump/S = locate() in children + if(S) + world << "Extra healing to go around ([brute+burn]) and [owner] needs a replacement limb." + //Sync the organ's damage with its wounds src.update_damages() owner.updatehealth() @@ -197,7 +268,7 @@ /* This function completely restores a damaged organ to perfect condition. */ -/datum/organ/external/proc/rejuvenate() +/obj/item/organ/external/rejuvenate() damage_state = "00" if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic. status = 128 @@ -211,7 +282,7 @@ This function completely restores a damaged organ to perfect condition. number_wounds = 0 // handle internal organs - for(var/datum/organ/internal/current_organ in internal_organs) + for(var/obj/item/organ/current_organ in internal_organs) current_organ.rejuvenate() // remove embedded objects and drop them on the floor @@ -223,7 +294,7 @@ This function completely restores a damaged organ to perfect condition. owner.updatehealth() -/datum/organ/external/proc/createwound(var/type = CUT, var/damage) +/obj/item/organ/external/proc/createwound(var/type = CUT, var/damage) if(damage == 0) return //moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return) @@ -232,7 +303,7 @@ This function completely restores a damaged organ to perfect condition. if(damage > 15 && type != BURN && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT)) var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15)) wounds += I - owner.custom_pain("You feel something rip in your [display_name]!", 1) + owner.custom_pain("You feel something rip in your [name]!", 1) // first check whether we can widen an existing wound if(wounds.len > 0 && prob(max(50+(number_wounds-1)*10,90))) @@ -248,8 +319,8 @@ This function completely restores a damaged organ to perfect condition. W.open_wound(damage) if(prob(25)) //maybe have a separate message for BRUISE type damage? - owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping noise.",\ - "\red The wound on your [display_name] widens with a nasty ripping noise.",\ + owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\ + "\red The wound on your [name] widens with a nasty ripping noise.",\ "You hear a nasty ripping noise, as if flesh is being torn apart.") return @@ -274,9 +345,7 @@ This function completely restores a damaged organ to perfect condition. //Determines if we even need to process this organ. -/datum/organ/external/proc/need_process() - if(destspawn) //Missing limb is missing - return 0 +/obj/item/organ/external/proc/need_process() if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status. return 1 if(brute_dam || burn_dam) @@ -290,37 +359,41 @@ This function completely restores a damaged organ to perfect condition. return 1 return 0 -/datum/organ/external/process() - //Dismemberment - if(status & ORGAN_DESTROYED) - if(!destspawn && config.limbs_can_break) - droplimb() - return - if(parent) - if(parent.status & ORGAN_DESTROYED) - status |= ORGAN_DESTROYED - owner.update_body(1) +/obj/item/organ/external/process() + if(owner) + //Dismemberment + if(status & ORGAN_DESTROYED) + if(config.limbs_can_break) + droplimb(0,DROPLIMB_EDGE) //Might be worth removing this check since take_damage handles it. return + if(parent) + if(parent.status & ORGAN_DESTROYED) + status |= ORGAN_DESTROYED + owner.update_body(1) + return - // Process wounds, doing healing etc. Only do this every few ticks to save processing power - if(owner.life_tick % wound_update_accuracy == 0) - update_wounds() + // Process wounds, doing healing etc. Only do this every few ticks to save processing power + if(owner.life_tick % wound_update_accuracy == 0) + update_wounds() - //Chem traces slowly vanish - if(owner.life_tick % 10 == 0) - for(var/chemID in trace_chemicals) - trace_chemicals[chemID] = trace_chemicals[chemID] - 1 - if(trace_chemicals[chemID] <= 0) - trace_chemicals.Remove(chemID) + //Chem traces slowly vanish + if(owner.life_tick % 10 == 0) + for(var/chemID in trace_chemicals) + trace_chemicals[chemID] = trace_chemicals[chemID] - 1 + if(trace_chemicals[chemID] <= 0) + trace_chemicals.Remove(chemID) - //Bone fracurtes - if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT)) - src.fracture() - if(!(status & ORGAN_BROKEN)) - perma_injury = 0 + //Bone fractures + if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT)) + src.fracture() - //Infections - update_germs() + if(!(status & ORGAN_BROKEN)) + perma_injury = 0 + + //Infections + update_germs() + else + ..() //Updating germ levels. Handles organ germ levels and necrosis. /* @@ -341,7 +414,7 @@ INFECTION_LEVEL_THREE above this germ level the player will take additional toxi Note that amputating the affected organ does in fact remove the infection from the player's body. */ -/datum/organ/external/proc/update_germs() +/obj/item/organ/external/proc/update_germs() if(status & (ORGAN_ROBOT|ORGAN_DESTROYED) || (owner.species && owner.species.flags & IS_PLANT)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. germ_level = 0 @@ -357,7 +430,7 @@ Note that amputating the affected organ does in fact remove the infection from t //** Handle the effects of infections handle_germ_effects() -/datum/organ/external/proc/handle_germ_sync() +/obj/item/organ/external/proc/handle_germ_sync() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") for(var/datum/wound/W in wounds) //Open wounds can become infected @@ -371,29 +444,17 @@ Note that amputating the affected organ does in fact remove the infection from t germ_level++ break //limit increase to a maximum of one per second -/datum/organ/external/proc/handle_germ_effects() +/obj/item/organ/external/handle_germ_effects() + + if(germ_level < INFECTION_LEVEL_TWO) + return ..() + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE && prob(60)) //this could be an else clause, but it looks cleaner this way - germ_level-- //since germ_level increases at a rate of 1 per second with dirty wounds, prob(60) should give us about 5 minutes before level one. - - if(germ_level >= INFECTION_LEVEL_ONE) - //having an infection raises your body temperature - var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature - //need to make sure we raise temperature fast enough to get around environmental cooling preventing us from reaching fever_temperature - owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) - - if(prob(round(germ_level/10))) - if (antibiotics < 5) - germ_level++ - - if (prob(10)) //adjust this to tweak how fast people take toxin damage from infections - owner.adjustToxLoss(1) - - if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < 5) + if(germ_level >= INFECTION_LEVEL_TWO) //spread the infection to internal organs - var/datum/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once - for (var/datum/organ/internal/I in internal_organs) + var/obj/item/organ/target_organ = null //make internal organs become infected one at a time instead of all at once + for (var/obj/item/organ/I in internal_organs) if (I.germ_level > 0 && I.germ_level < min(germ_level, INFECTION_LEVEL_TWO)) //once the organ reaches whatever we can give it, or level two, switch to a different one if (!target_organ || I.germ_level > target_organ.germ_level) //choose the organ with the highest germ_level target_organ = I @@ -401,9 +462,9 @@ Note that amputating the affected organ does in fact remove the infection from t if (!target_organ) //figure out which organs we can spread germs to and pick one at random var/list/candidate_organs = list() - for (var/datum/organ/internal/I in internal_organs) + for (var/obj/item/organ/I in internal_organs) if (I.germ_level < germ_level) - candidate_organs += I + candidate_organs |= I if (candidate_organs.len) target_organ = pick(candidate_organs) @@ -412,7 +473,7 @@ Note that amputating the affected organ does in fact remove the infection from t //spread the infection to child and parent organs if (children) - for (var/datum/organ/external/child in children) + for (var/obj/item/organ/external/child in children) if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT)) if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) child.germ_level++ @@ -425,14 +486,14 @@ Note that amputating the affected organ does in fact remove the infection from t if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections if (!(status & ORGAN_DEAD)) status |= ORGAN_DEAD - owner << "You can't feel your [display_name] anymore..." + owner << "You can't feel your [name] anymore..." owner.update_body(1) germ_level++ owner.adjustToxLoss(1) //Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections -/datum/organ/external/proc/update_wounds() +/obj/item/organ/external/proc/update_wounds() if((status & ORGAN_ROBOT)) //Robotic limbs don't heal or get worse. return @@ -455,7 +516,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.vessel.remove_reagent("blood", wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place. if(prob(1 * wound_update_accuracy)) - owner.custom_pain("You feel a stabbing pain in your [display_name]!",1) + owner.custom_pain("You feel a stabbing pain in your [name]!",1) // slow healing var/heal_amt = 0 @@ -485,7 +546,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.UpdateDamageIcon(1) //Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status. -/datum/organ/external/proc/update_damages() +/obj/item/organ/external/proc/update_damages() number_wounds = 0 brute_dam = 0 burn_dam = 0 @@ -517,7 +578,7 @@ Note that amputating the affected organ does in fact remove the infection from t // new damage icon system // adjusted to set damage_state to brute/burn code only (without r_name0 as before) -/datum/organ/external/proc/update_icon() +/obj/item/organ/external/update_icon() var/n_is = damage_state_text() if (n_is != damage_state) damage_state = n_is @@ -526,7 +587,7 @@ Note that amputating the affected organ does in fact remove the infection from t // new damage icon system // returns just the brute/burn damage code -/datum/organ/external/proc/damage_state_text() +/obj/item/organ/external/proc/damage_state_text() if(status & ORGAN_DESTROYED) return "--" @@ -556,127 +617,104 @@ Note that amputating the affected organ does in fact remove the infection from t DISMEMBERMENT ****************************************************/ -//Recursive setting of all child organs to amputated -/datum/organ/external/proc/setAmputatedTree() - for(var/datum/organ/external/O in children) - O.amputated=amputated - O.setAmputatedTree() - //Handles dismemberment -/datum/organ/external/proc/droplimb(var/override = 0,var/no_explode = 0,var/amputation=0) - if(destspawn) return - if(override) - status |= ORGAN_DESTROYED - if(status & ORGAN_DESTROYED) - if(body_part == UPPER_TORSO) - return +/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children) - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_DEAD - for(var/implant in implants) - del(implant) + if(cannot_amputate || !owner) + return - germ_level = 0 + if(!disintegrate) + disintegrate = DROPLIMB_EDGE - // If any organs are attached to this, destroy them - for(var/datum/organ/external/O in children) - O.droplimb(1, no_explode, amputation) + switch(disintegrate) + if(DROPLIMB_EDGE) + if(!clean) + owner.visible_message( + "\The [owner]'s [src.name] flies off in an arc!",\ + "Your [src.name] goes flying off!",\ + "You hear a terrible sound of ripping tendons and flesh.") + if(DROPLIMB_BURN) + owner.visible_message( + "\The [owner]'s [src.name] flashes away into ashes!",\ + "Your [src.name] flashes away into ashes!",\ + "You hear the crackling sound of burning flesh.") + if(DROPLIMB_BLUNT) + owner.visible_message( + "\The [owner]'s [src.name] explodes in a shower of gore!",\ + "Your [src.name] explodes in a shower of gore!",\ + "You hear the sickening splatter of gore.") - //Replace all wounds on that arm with one wound on parent organ. - wounds.Cut() - if (parent && !amputation) - var/datum/wound/W - if(max_damage < 50) - W = new/datum/wound/lost_limb/small(max_damage) - else - W = new/datum/wound/lost_limb(max_damage) - parent.wounds += W + src.removed(null, ignore_children) + owner.traumatic_shock += 60 + + wounds.Cut() + if(parent) + var/datum/wound/W + if(max_damage < 50) + W = new/datum/wound/lost_limb/small(max_damage) + else + W = new/datum/wound/lost_limb(max_damage) + parent.children -= src + if(clean) + parent.wounds |= W parent.update_damages() - update_damages() + else + var/obj/item/organ/external/stump/stump = new (owner, 0, src) + stump.wounds |= W + owner.organs |= stump + stump.update_damages() + parent = null - var/obj/organ //Dropped limb object - var/list/dropped_items - switch(body_part) - if(HEAD) - organ = new /obj/item/weapon/organ/head(owner.loc, owner) - dropped_items = list(owner.glasses, owner.head, owner.l_ear, owner.r_ear, owner.wear_mask) - if(ARM_RIGHT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/r_arm(owner.loc) - else - organ= new /obj/item/weapon/organ/r_arm(owner.loc, owner) - if(ARM_LEFT) - if(status & ORGAN_ROBOT) - organ= new /obj/item/robot_parts/l_arm(owner.loc) - else - organ= new /obj/item/weapon/organ/l_arm(owner.loc, owner) - if(LEG_RIGHT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/r_leg(owner.loc) - else - organ= new /obj/item/weapon/organ/r_leg(owner.loc, owner) - if(LEG_LEFT) - if(status & ORGAN_ROBOT) - organ = new /obj/item/robot_parts/l_leg(owner.loc) - else - organ= new /obj/item/weapon/organ/l_leg(owner.loc, owner) - if(HAND_RIGHT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/r_hand(owner.loc, owner) - dropped_items = list(owner.gloves) //should probably make it so that you can still wear gloves if you have one hand - if(HAND_LEFT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/l_hand(owner.loc, owner) - dropped_items = list(owner.gloves) - if(FOOT_RIGHT) - if(!(status & ORGAN_ROBOT)) - organ= new /obj/item/weapon/organ/r_foot/(owner.loc, owner) - dropped_items = list(owner.shoes) - if(FOOT_LEFT) - if(!(status & ORGAN_ROBOT)) - organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner) - dropped_items = list(owner.shoes) - if(dropped_items) - for(var/obj/O in dropped_items) - owner.remove_from_mob(O) + spawn(1) + owner.update_body() + owner.updatehealth() + owner.UpdateDamageIcon() + dir = 2 - destspawn = 1 - //Robotic limbs explode if sabotaged. - if(status & ORGAN_ROBOT && !no_explode && sabotaged) - owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\ - "\red Your [display_name] explodes!",\ - "You hear an explosion!") - explosion(get_turf(owner),-1,-1,2,3) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, owner) - spark_system.attach(owner) - spark_system.start() - spawn(10) - del(spark_system) + switch(disintegrate) + if(DROPLIMB_EDGE) + compile_icon() + add_blood(owner) + var/matrix/M = matrix() + M.Turn(rand(180)) + src.transform = M + if(!clean) + // Throw limb around. + if(src && istype(loc,/turf)) + throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) + dir = 2 + return + if(DROPLIMB_BURN) + new /obj/effect/decal/cleanable/ash(get_turf(owner)) + if(DROPLIMB_BLUNT) + var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(owner)) + if(owner.species.flesh_color) + gore.fleshcolor = owner.species.flesh_color + if(owner.species.blood_color) + gore.basecolor = owner.species.blood_color + gore.update_icon() + gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\ - "Your [display_name] goes flying off!",\ - "You hear a terrible sound of ripping tendons and flesh.") + for(var/obj/item/organ/I in internal_organs) + I.removed() + if(istype(loc,/turf)) + I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) - //Throw organs around - if(istype(owner.loc,/turf) && organ) - step(organ,pick(cardinal)) - - owner.update_body(1) - - // OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom! - release_restraints() - - if(vital) - owner.death() + del(src) /**************************************************** HELPERS ****************************************************/ -/datum/organ/external/proc/release_restraints() +/obj/item/organ/external/proc/is_stump() + return 0 + +/obj/item/organ/external/replaced() + get_icon() + icon = mob_icon + return ..() + +/obj/item/organ/external/proc/release_restraints() if (owner.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT)) owner.visible_message(\ "\The [owner.handcuffed.name] falls off of [owner.name].",\ @@ -691,7 +729,7 @@ Note that amputating the affected organ does in fact remove the infection from t owner.drop_from_inventory(owner.legcuffed) -/datum/organ/external/proc/bandage() +/obj/item/organ/external/proc/bandage() var/rval = 0 src.status &= ~ORGAN_BLEEDING for(var/datum/wound/W in wounds) @@ -700,7 +738,7 @@ Note that amputating the affected organ does in fact remove the infection from t W.bandaged = 1 return rval -/datum/organ/external/proc/disinfect() +/obj/item/organ/external/proc/disinfect() var/rval = 0 for(var/datum/wound/W in wounds) if(W.internal) continue @@ -709,7 +747,7 @@ Note that amputating the affected organ does in fact remove the infection from t W.germ_level = 0 return rval -/datum/organ/external/proc/clamp() +/obj/item/organ/external/proc/clamp() var/rval = 0 src.status &= ~ORGAN_BLEEDING for(var/datum/wound/W in wounds) @@ -718,21 +756,21 @@ Note that amputating the affected organ does in fact remove the infection from t W.clamped = 1 return rval -/datum/organ/external/proc/salve() +/obj/item/organ/external/proc/salve() var/rval = 0 for(var/datum/wound/W in wounds) rval |= !W.salved W.salved = 1 return rval -/datum/organ/external/proc/fracture() +/obj/item/organ/external/proc/fracture() - if(status & ORGAN_BROKEN) + if((status & ORGAN_BROKEN) || cannot_break) return owner.visible_message(\ "\red You hear a loud cracking sound coming from \the [owner].",\ - "\red Something feels like it shattered in your [display_name]!",\ + "\red Something feels like it shattered in your [name]!",\ "You hear a sickening crack.") if(owner.species && !(owner.species.flags & NO_PAIN)) @@ -760,12 +798,12 @@ Note that amputating the affected organ does in fact remove the infection from t if(isnull(suit.supporting_limbs)) return - owner << "You feel \the [suit] constrict about your [display_name], supporting it." + owner << "You feel \the [suit] constrict about your [name], supporting it." status |= ORGAN_SPLINTED suit.supporting_limbs |= src return -/datum/organ/external/proc/mend_fracture() +/obj/item/organ/external/proc/mend_fracture() if(status & ORGAN_ROBOT) return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs if(brute_dam > min_broken_damage * config.organ_health_multiplier) @@ -774,75 +812,50 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -/datum/organ/external/proc/robotize() - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_CUT_AWAY - src.status &= ~ORGAN_ATTACHABLE - src.status &= ~ORGAN_DESTROYED - src.status |= ORGAN_ROBOT - src.destspawn = 0 - for (var/datum/organ/external/T in children) +/obj/item/organ/external/robotize(var/company) + ..() + + if(company) + model = company + var/datum/robolimb/R = all_robolimbs[company] + if(R) + force_icon = R.icon + name = "[R.company] [initial(name)]" + desc = "[R.desc]" + + dislocated = -1 + cannot_break = 1 + get_icon() + for (var/obj/item/organ/external/T in children) if(T) T.robotize() -/datum/organ/external/proc/mutate() +/obj/item/organ/external/proc/mutate() src.status |= ORGAN_MUTATED owner.update_body() -/datum/organ/external/proc/unmutate() +/obj/item/organ/external/proc/unmutate() src.status &= ~ORGAN_MUTATED owner.update_body() -/datum/organ/external/proc/get_damage() //returns total damage +/obj/item/organ/external/proc/get_damage() //returns total damage return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? -/datum/organ/external/proc/has_infected_wound() +/obj/item/organ/external/proc/has_infected_wound() for(var/datum/wound/W in wounds) if(W.germ_level > INFECTION_LEVEL_ONE) return 1 return 0 -/datum/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon,gender="") - if (status & ORGAN_ROBOT && !(owner.species && owner.species.flags & IS_SYNTHETIC)) - return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]") - - if (status & ORGAN_MUTATED) - return new /icon(deform_icon, "[icon_name][gender ? "_[gender]" : ""]") - - return new /icon(race_icon, "[icon_name][gender ? "_[gender]" : ""]") - - -/datum/organ/external/proc/is_usable() +/obj/item/organ/external/proc/is_usable() return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) -/datum/organ/external/proc/is_broken() - return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)) +/obj/item/organ/external/proc/is_malfunctioning() + return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam)) -/datum/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam)) - -//for arms and hands -/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name) - if (!c_hand) +/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) + if(loc != owner) return - - if(is_broken()) - owner.u_equip(c_hand) - var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [hand_name]!") - if(is_malfunctioning()) - owner.u_equip(c_hand) - owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!") - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, owner) - spark_system.attach(owner) - spark_system.start() - spawn(10) - del(spark_system) - -/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) if(!silent) owner.visible_message("\The [W] sticks in the wound!") implants += W @@ -854,135 +867,211 @@ Note that amputating the affected organ does in fact remove the infection from t H.drop_item() W.loc = owner +/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children) + + var/is_robotic = status & ORGAN_ROBOT + ..() + + status |= ORGAN_DESTROYED + owner.bad_external_organs -= src + + for(var/implant in implants) //todo: check if this can be left alone + del(implant) + + // Attached organs also fly off. + if(!ignore_children) + for(var/obj/item/organ/external/O in children) + O.removed() + if(O) + O.loc = src + + // Grab all the internal giblets too. + for(var/obj/item/organ/organ in internal_organs) + organ.removed() + organ.loc = src + + release_restraints() + owner.organs -= src + owner.organs_by_name[limb_name] = null // Remove from owner's vars. + + //Robotic limbs explode if sabotaged. + if(is_robotic && sabotaged) + owner.visible_message( + "\The [owner]'s [src.name] explodes violently!",\ + "Your [src.name] explodes!",\ + "You hear an explosion!") + explosion(get_turf(owner),-1,-1,2,3) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, owner) + spark_system.attach(owner) + spark_system.start() + spawn(10) + del(spark_system) + del(src) + +/obj/item/organ/external/proc/disfigure(var/type = "brute") + if (disfigured) + return + if(type == "brute") + owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s [name].", \ + "\red Your [name] becomes a mangled mess!", \ + "\red You hear a sickening crack.") + else + owner.visible_message("\red \The [owner]'s [name] melts away, turning into mangled mess!", \ + "\red Your [name] melts away!", \ + "\red You hear a sickening sizzle.") + disfigured = 1 + /**************************************************** ORGAN DEFINES ****************************************************/ -/datum/organ/external/chest - name = "chest" +/obj/item/organ/external/chest + name = "upper body" + limb_name = "chest" icon_name = "torso" - display_name = "chest" - max_damage = 75 - min_broken_damage = 40 + health = 100 + min_broken_damage = 35 body_part = UPPER_TORSO vital = 1 - encased = "ribcage" + amputation_point = "spine" + joint = "neck" + dislocated = -1 + gendered_icon = 1 + cannot_amputate = 1 + parent_organ = null -/datum/organ/external/groin - name = "groin" +/obj/item/organ/external/groin + name = "lower body" + limb_name = "groin" icon_name = "groin" - display_name = "groin" - max_damage = 50 - min_broken_damage = 30 + health = 100 + min_broken_damage = 35 body_part = LOWER_TORSO vital = 1 + parent_organ = "chest" + amputation_point = "lumbar" + joint = "hip" + dislocated = -1 + gendered_icon = 1 -/datum/organ/external/l_arm - name = "l_arm" - display_name = "left arm" +/obj/item/organ/external/arm + limb_name = "l_arm" + name = "left arm" icon_name = "l_arm" - max_damage = 50 - min_broken_damage = 20 + health = 50 + min_broken_damage = 30 body_part = ARM_LEFT + parent_organ = "chest" + joint = "left elbow" + amputation_point = "left shoulder" + can_grasp = 1 - process() - ..() - process_grasp(owner.l_hand, "left hand") +/obj/item/organ/external/arm/right + limb_name = "r_arm" + name = "right arm" + icon_name = "r_arm" + body_part = ARM_RIGHT + joint = "right elbow" + amputation_point = "right shoulder" -/datum/organ/external/l_leg - name = "l_leg" - display_name = "left leg" +/obj/item/organ/external/leg + limb_name = "l_leg" + name = "left leg" icon_name = "l_leg" - max_damage = 50 - min_broken_damage = 20 + health = 50 + min_broken_damage = 30 body_part = LEG_LEFT icon_position = LEFT + parent_organ = "groin" + joint = "left knee" + amputation_point = "left hip" + can_stand = 1 -/datum/organ/external/r_arm - name = "r_arm" - display_name = "right arm" - icon_name = "r_arm" - max_damage = 50 - min_broken_damage = 20 - body_part = ARM_RIGHT - - process() - ..() - process_grasp(owner.r_hand, "right hand") - -/datum/organ/external/r_leg - name = "r_leg" - display_name = "right leg" +/obj/item/organ/external/leg/right + limb_name = "r_leg" + name = "right leg" icon_name = "r_leg" - max_damage = 50 - min_broken_damage = 20 body_part = LEG_RIGHT icon_position = RIGHT + joint = "right knee" + amputation_point = "right hip" -/datum/organ/external/l_foot - name = "l_foot" - display_name = "left foot" +/obj/item/organ/external/foot + limb_name = "l_foot" + name = "left foot" icon_name = "l_foot" - max_damage = 30 + health = 30 min_broken_damage = 15 body_part = FOOT_LEFT icon_position = LEFT + parent_organ = "l_leg" + joint = "left ankle" + amputation_point = "left ankle" + can_stand = 1 -/datum/organ/external/r_foot - name = "r_foot" - display_name = "right foot" +/obj/item/organ/external/foot/removed() + if(owner) owner.u_equip(owner.shoes) + ..() + +/obj/item/organ/external/foot/right + limb_name = "r_foot" + name = "right foot" icon_name = "r_foot" - max_damage = 30 - min_broken_damage = 15 body_part = FOOT_RIGHT icon_position = RIGHT + parent_organ = "r_leg" + joint = "right ankle" + amputation_point = "right ankle" -/datum/organ/external/r_hand - name = "r_hand" - display_name = "right hand" - icon_name = "r_hand" - max_damage = 30 - min_broken_damage = 15 - body_part = HAND_RIGHT - - process() - ..() - process_grasp(owner.r_hand, "right hand") - -/datum/organ/external/l_hand - name = "l_hand" - display_name = "left hand" +/obj/item/organ/external/hand + limb_name = "l_hand" + name = "left hand" icon_name = "l_hand" - max_damage = 30 + health = 30 min_broken_damage = 15 body_part = HAND_LEFT + parent_organ = "l_arm" + joint = "left wrist" + amputation_point = "left wrist" + can_grasp = 1 - process() - ..() - process_grasp(owner.l_hand, "left hand") +/obj/item/organ/external/hand/removed() + owner.u_equip(owner.gloves) + ..() -/datum/organ/external/head - name = "head" +/obj/item/organ/external/hand/right + limb_name = "r_hand" + name = "right hand" + icon_name = "r_hand" + body_part = HAND_RIGHT + parent_organ = "r_arm" + joint = "right wrist" + amputation_point = "right wrist" + +/obj/item/organ/external/head + limb_name = "head" icon_name = "head" - display_name = "head" - max_damage = 75 - min_broken_damage = 40 + name = "head" + health = 75 + min_broken_damage = 35 body_part = HEAD - var/disfigured = 0 vital = 1 - encased = "skull" + parent_organ = "chest" + joint = "jaw" + amputation_point = "neck" + gendered_icon = 1 -/datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon) - if (!owner) - return ..() - var/g = "m" - if(owner.gender == FEMALE) g = "f" - if (status & ORGAN_MUTATED) - . = new /icon(deform_icon, "[icon_name]_[g]") - else - . = new /icon(race_icon, "[icon_name]_[g]") +/obj/item/organ/external/head/removed() + if(owner) + owner.u_equip(owner.glasses) + owner.u_equip(owner.head) + owner.u_equip(owner.l_ear) + owner.u_equip(owner.r_ear) + owner.u_equip(owner.wear_mask) + ..() -/datum/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) +/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) ..(brute, burn, sharp, edge, used_weapon, forbidden_limbs) if (!disfigured) if (brute_dam > 40) @@ -990,156 +1079,3 @@ Note that amputating the affected organ does in fact remove the infection from t disfigure("brute") if (burn_dam > 40) disfigure("burn") - -/datum/organ/external/head/proc/disfigure(var/type = "brute") - if (disfigured) - return - if(type == "brute") - owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s face.", \ - "\red Your face becomes unrecognizible mangled mess!", \ - "\red You hear a sickening crack.") - else - owner.visible_message("\red [owner]'s face melts away, turning into mangled mess!", \ - "\red Your face melts off!", \ - "\red You hear a sickening sizzle.") - disfigured = 1 - -/**************************************************** - EXTERNAL ORGAN ITEMS -****************************************************/ - -obj/item/weapon/organ - icon = 'icons/mob/human_races/r_human.dmi' - var/op_stage = 0 - var/list/organs_internal = list() - -obj/item/weapon/organ/New(loc, mob/living/carbon/human/H) - ..(loc) - if(!istype(H)) - return - if(H.dna) - if(!blood_DNA) - blood_DNA = list() - blood_DNA[H.dna.unique_enzymes] = H.dna.b_type - - // Transferring over organs from the host. - for(var/datum/organ/internal/I in H.internal_organs) - if(I.parent_organ != name) - continue - var/obj/item/organ/current_organ = I.remove() - current_organ.removed(H) - current_organ.loc = src - if(current_organ.organ_data) - organs_internal |= current_organ.organ_data - - // Forming icon for the limb - // Setting base icon for this mob's race - var/icon/base - if(H.species && H.species.icobase) - base = icon(H.species.icobase) - else - base = icon('icons/mob/human_races/r_human.dmi') - - if(base) - //Changing limb's skin tone to match owner - if(!H.species || H.species.flags & HAS_SKIN_TONE) - if (H.s_tone >= 0) - base.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) - else - base.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) - - if(base) - //Changing limb's skin color to match owner - if(!H.species || H.species.flags & HAS_SKIN_COLOR) - base.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) - - icon = base - set_dir(SOUTH) - src.transform = turn(src.transform, rand(70,130)) - - -/**************************************************** - EXTERNAL ORGAN ITEMS DEFINES -****************************************************/ - -obj/item/weapon/organ/l_arm - name = "left arm" - icon_state = "l_arm" -obj/item/weapon/organ/l_foot - name = "left foot" - icon_state = "l_foot" -obj/item/weapon/organ/l_hand - name = "left hand" - icon_state = "l_hand" -obj/item/weapon/organ/l_leg - name = "left leg" - icon_state = "l_leg" -obj/item/weapon/organ/r_arm - name = "right arm" - icon_state = "r_arm" -obj/item/weapon/organ/r_foot - name = "right foot" - icon_state = "r_foot" -obj/item/weapon/organ/r_hand - name = "right hand" - icon_state = "r_hand" -obj/item/weapon/organ/r_leg - name = "right leg" - icon_state = "r_leg" -obj/item/weapon/organ/head - name = "head" - icon_state = "head_m" - -obj/item/weapon/organ/head/New(loc, mob/living/carbon/human/H) - if(istype(H)) - src.icon_state = H.gender == MALE? "head_m" : "head_f" - ..() - //Add (facial) hair. - if(H.f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] - if(facial_hair_style) - var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(facial_hair_style.do_colouration) - facial.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) - - overlays.Add(facial) // icon.Blend(facial, ICON_OVERLAY) - - if(H.h_style && !(H.head && (H.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] - if(hair_style) - var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(hair_style.do_colouration) - hair.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) - - overlays.Add(hair) //icon.Blend(hair, ICON_OVERLAY) - - name = "[H.real_name]'s head" - H.regenerate_icons() - -obj/item/weapon/organ/attackby(obj/item/weapon/W as obj, mob/user as mob) - switch(op_stage) - if(0) - if(istype(W,/obj/item/weapon/scalpel)) - user.visible_message("[user] cuts [src] open with [W]!") - op_stage++ - return - if(1) - if(istype(W,/obj/item/weapon/retractor)) - user.visible_message("[user] cracks [src] open like an egg with [W]!") - op_stage++ - return - if(2) - if(istype(W,/obj/item/weapon/hemostat)) - if(contents.len) - var/obj/item/removing = pick(contents) - removing.loc = get_turf(user.loc) - if(!(user.l_hand && user.r_hand)) - user.put_in_hands(removing) - if(istype(removing,/obj/item/organ)) - var/obj/item/organ/removed_organ = removing - organs_internal -= removed_organ.organ_data - user.visible_message("[user] extracts [removing] from [src] with [W]!") - else - user.visible_message("[user] fishes around fruitlessly in [src] with [W].") - return - ..() \ No newline at end of file diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm new file mode 100644 index 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 7d0782abed..6bc2d9e71a 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -1,288 +1,183 @@ #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 processing. - if(owner.chem_effects[CE_ALCOHOL_TOXIC]) - if(filter_effect < 3) - owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY) - else - take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them - -/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 processing. + if(owner.chem_effects[CE_ALCOHOL_TOXIC]) + if(filter_effect < 3) + owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY) + else + take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them + +/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" 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 16d0394a85..da3c289224 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/organs/pain.dm @@ -77,10 +77,8 @@ mob/living/carbon/human/proc/handle_pain() if(analgesic > 70) 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, @@ -89,13 +87,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/antimatter/computer.dm b/code/modules/power/antimatter/computer.dm index 3a47ec7abf..d531ccfb54 100644 --- a/code/modules/power/antimatter/computer.dm +++ b/code/modules/power/antimatter/computer.dm @@ -45,7 +45,7 @@ src.state = STATE_DEFAULT if("login") var/mob/M = usr - var/obj/item/weapon/card/id/I = M.equipped() + var/obj/item/weapon/card/id/I = M.get_active_hand() if (I && istype(I)) if(src.check_access(I)) authenticated = 1 diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 23c5e0243a..b9f1075fa1 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -171,10 +171,8 @@ user << "\red There is already a [fueljar] inside!" return fueljar = W + user.remove_from_mob(W) W.loc = src - if(user.client) - user.client.screen -= W - user.u_equip(W) user.update_icons() user.visible_message("[user.name] loads an [W.name] into the [src.name].", \ "You load an [W.name].", \ diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 6285e9dfe2..fb68cea74c 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -658,7 +658,7 @@ if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(H.species.flags & IS_SYNTHETIC && H.a_intent == "grab") + if(H.species.flags & IS_SYNTHETIC && H.a_intent == I_GRAB) if(emagged || stat & BROKEN) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index d73d60926e..f652ebe9ec 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -516,7 +516,7 @@ 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) + var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help") return ..() @@ -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/power/lighting.dm b/code/modules/power/lighting.dm index 7c9ae41cf2..14bdaa1644 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -737,7 +737,7 @@ if(!proximity) return if(istype(target, /obj/machinery/light)) return - if(user.a_intent != "hurt") + if(user.a_intent != I_HURT) return shatter() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 05b877f87e..871ac5395a 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -3,6 +3,10 @@ name = "gun" desc = "Its a gun. It's pretty terrible, though." icon = 'icons/obj/gun.dmi' + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', + icon_r_hand = 'icons/mob/items/righthand_guns.dmi', + ) icon_state = "detective" item_state = "gun" flags = CONDUCT @@ -90,14 +94,14 @@ if(user && user.client && !(A in aim_targets)) var/client/C = user.client //If help intent is on and we have clicked on an eligible target, switch to aim mode automatically - if(user.a_intent == "help" && isliving(A) && !C.gun_mode) + if(user.a_intent == I_HELP && isliving(A) && !C.gun_mode) C.ToggleGunMode() if(C.gun_mode) aiming = PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at. if (!aiming) - if(user && user.a_intent == "help") //regardless of what happens, refuse to shoot if help intent is on + if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on user << "\red You refrain from firing your [src] as your intent is set to help." else Fire(A,user,params) //Otherwise, fire normally. @@ -105,7 +109,7 @@ /obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot) handle_suicide(user) - else if(user.a_intent == "hurt") //point blank shooting + else if(user.a_intent == I_HURT) //point blank shooting Fire(A, user, pointblank=1) else return ..() //Pistolwhippin' @@ -134,10 +138,7 @@ handle_post_fire(user, target, pointblank, reflex) update_icon() - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + update_held_icon() //obtains the next projectile to fire diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index db590d7b9f..9f611e593d 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -40,7 +40,7 @@ /obj/item/weapon/gun/launcher/spikethrower/special_check(user) if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") + if(H.species && H.species.name != "Vox") user << "\The [src] does not respond to you!" return 0 return ..() @@ -52,56 +52,3 @@ if(spikes < 1) return null spikes-- return new /obj/item/weapon/spike(src) - -//This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. -/obj/item/weapon/gun/energy/noisecannon - name = "alien heavy cannon" - desc = "It's some kind of enormous alien weapon, as long as a man is tall." - - icon = 'icons/obj/gun.dmi' //Actual on-sprite is handled by icon_override. - icon_state = "noisecannon" - item_state = "noisecannon" - recoil = 1 - - force = 10 - projectile_type = /obj/item/projectile/energy/sonic - cell_type = /obj/item/weapon/cell/super - fire_delay = 40 - fire_sound = 'sound/effects/basscannon.ogg' - - var/mode = 1 - - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/held.dmi' - ) - -/obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob) - if(loc != user) - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.species.name == "Vox Armalis") - ..() - return - user << "\The [src] is far too large for you to pick up." - return - -/obj/item/weapon/gun/energy/noisecannon/update_icon() - return - -//Projectile. -/obj/item/projectile/energy/sonic - name = "distortion" - icon = 'icons/obj/machines/particle_accelerator2.dmi' - icon_state = "particle" - damage = 60 - damage_type = BRUTE - check_armour = "bullet" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - - embed = 0 - weaken = 5 - stun = 5 - -/obj/item/projectile/energy/sonic/proc/split() - //TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf. - return diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 19f1157371..994256b12a 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -29,6 +29,7 @@ power_supply.give(power_supply.maxcharge) if(self_recharge) processing_objects.Add(src) + update_icon() /obj/item/weapon/gun/energy/Del() if(self_recharge) @@ -87,3 +88,4 @@ icon_state = "[modifystate][ratio]" else icon_state = "[initial(icon_state)][ratio]" + diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 2bc36508d8..dffc012998 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -24,16 +24,18 @@ obj/item/weapon/gun/energy/retro name = "retro laser" icon_state = "retro" + item_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." fire_sound = 'sound/weapons/Laser.ogg' slot_flags = SLOT_BELT w_class = 3 projectile_type = /obj/item/projectile/beam - fire_delay = 10 + fire_delay = 10 //old technology /obj/item/weapon/gun/energy/captain name = "antique laser gun" icon_state = "caplaser" + item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 5 fire_sound = 'sound/weapons/Laser.ogg' @@ -48,7 +50,7 @@ obj/item/weapon/gun/energy/retro name = "laser cannon" desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" icon_state = "lasercannon" - item_state = "laser" + item_state = null fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" slot_flags = SLOT_BELT|SLOT_BACK @@ -57,6 +59,7 @@ obj/item/weapon/gun/energy/retro fire_delay = 20 /obj/item/weapon/gun/energy/lasercannon/mounted + name = "mounted laser cannon" self_recharge = 1 use_external_power = 1 recharge_time = 10 @@ -65,6 +68,7 @@ obj/item/weapon/gun/energy/retro name = "xray laser gun" desc = "A high-power laser gun capable of expelling concentrated xray blasts." icon_state = "xray" + item_state = "xray" fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" projectile_type = /obj/item/projectile/beam/xray @@ -116,10 +120,12 @@ obj/item/weapon/gun/energy/retro /obj/item/weapon/gun/energy/lasertag/blue icon_state = "bluetag" + item_state = "bluetag" projectile_type = /obj/item/projectile/beam/lastertag/blue required_vest = /obj/item/clothing/suit/bluetag /obj/item/weapon/gun/energy/lasertag/red icon_state = "redtag" + item_state = "redtag" projectile_type = /obj/item/projectile/beam/lastertag/red required_vest = /obj/item/clothing/suit/redtag diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index e2b97672c7..6b9f6f0d51 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -29,12 +29,10 @@ projectile_type = /obj/item/projectile/beam/stun modifystate = "energystun" update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + update_held_icon() /obj/item/weapon/gun/energy/gun/mounted + name = "mounted energy gun" self_recharge = 1 use_external_power = 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 434156ad53..c7f74e1d95 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -26,6 +26,7 @@ name = "biological demolecularisor" desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" + item_state = "decloner" fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" charge_cost = 100 @@ -35,7 +36,7 @@ name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." icon_state = "floramut100" - item_state = "obj/item/gun.dmi" + item_state = "floramut" fire_sound = 'sound/effects/stealthoff.ogg' charge_cost = 100 projectile_type = /obj/item/projectile/energy/floramut @@ -59,7 +60,7 @@ projectile_type = /obj/item/projectile/energy/floramut modifystate = "floramut" update_icon() - return + update_held_icon() /obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag) //allow shooting into adjacent hydrotrays regardless of intent @@ -115,6 +116,7 @@ name = "staff of change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" icon = 'icons/obj/gun.dmi' + item_icons = null icon_state = "staffofchange" item_state = "staffofchange" fire_sound = 'sound/weapons/emitter.ogg' @@ -168,6 +170,7 @@ obj/item/weapon/gun/energy/staff/focus desc = "It's a cute rubber duck. With an evil gleam in it's eye." projectile_type = /obj/item/projectile/icarus/pointdefense icon = 'icons/obj/watercloset.dmi' + item_icons = null icon_state = "rubberducky" item_state = "rubberducky" charge_cost = 0 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index a99b71337a..1d51f7957e 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -9,10 +9,12 @@ cell_type = /obj/item/weapon/cell/crap /obj/item/weapon/gun/energy/taser/mounted + name = "mounted taser gun" self_recharge = 1 use_external_power = 1 /obj/item/weapon/gun/energy/taser/mounted/cyborg + name = "taser gun" cell_type = /obj/item/weapon/cell/secborg recharge_time = 10 //Time it takes for shots to recharge (in ticks) @@ -21,6 +23,7 @@ name = "stun revolver" desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger." icon_state = "stunrevolver" + item_state = "stunrevolver" fire_sound = 'sound/weapons/Gunshot.ogg' origin_tech = "combat=3;materials=3;powerstorage=2" charge_cost = 125 diff --git a/code/modules/projectiles/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm index 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/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index 9fac802bda..b1a0f563df 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -66,7 +66,7 @@ for(var/obj/item/O in src.contents) total_stored += O.get_storage_cost() if(total_stored + W.get_storage_cost() <= max_storage_space) - user.drop_item(W) + user.remove_from_mob(W) W.loc = src user << "You shove [W] into the hopper." else diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index 0c42c86b05..abb0e7cf47 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -133,4 +133,5 @@ name = "syringe gun revolver" desc = "A modification of the syringe gun design, using a rotating cylinder to store up to five syringes. The spring still needs to be drawn between shots." icon_state = "rapidsyringegun" + item_state = "rapidsyringegun" max_darts = 5 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 5778b3febe..75bbf810a8 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -51,7 +51,7 @@ name = "\improper STS-35 automatic rifle" desc = "A durable, rugged looking automatic weapon of a make popular on the frontier worlds. Uses 7.62mm rounds. It is unmarked." icon_state = "arifle" - item_state = "l6closednomag" //placeholder + item_state = null w_class = 4 force = 10 caliber = "a762" @@ -63,12 +63,13 @@ /obj/item/weapon/gun/projectile/automatic/sts35/update_icon() ..() icon_state = (ammo_magazine)? "arifle-0" : "arifle" + update_held_icon() /obj/item/weapon/gun/projectile/automatic/wt550 name = "\improper W-T 550 Saber" desc = "A cheap, mass produced Ward-Takahashi PDW. Uses 9mm rounds." icon_state = "wt550" - item_state = "c20r" //placeholder + item_state = "wt550" w_class = 3 caliber = "9mm" origin_tech = "combat=5;materials=2" @@ -90,7 +91,7 @@ name = "\improper Z8 Bulldog" desc = "An older model bullpup carbine, made by the now defunct Zendai Foundries. Uses armor piercing 5.56mm rounds. Makes you feel like a space marine when you hold it." icon_state = "carbine" - item_state = "l6closednomag" //placeholder + item_state = "z8carbine" w_class = 4 force = 10 caliber = "a556" diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index c95fbce180..389fcd6e15 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -45,6 +45,7 @@ name = "dart gun" desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." icon_state = "dartgun-empty" + item_state = null caliber = "dart" fire_sound = 'sound/weapons/empty.ogg' diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index adbf30922d..b29f2f3e42 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -63,6 +63,7 @@ name = "desert eagle" desc = "A robust handgun that uses .50 AE ammo" icon_state = "deagle" + item_state = "deagle" force = 14.0 caliber = ".50" load_method = MAGAZINE @@ -107,6 +108,7 @@ name = "\improper Stechtkin pistol" desc = "A small, easily concealable gun. Uses 9mm rounds." icon_state = "pistol" + item_state = null w_class = 2 caliber = "9mm" silenced = 0 diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index fb5895aad9..f0291de0f8 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -2,6 +2,7 @@ name = "revolver" desc = "A classic revolver. Uses .357 ammo" icon_state = "revolver" + item_state = "revolver" caliber = "357" origin_tech = "combat=2;materials=2" handle_casings = CYCLE_CASINGS diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index fd85bc28be..fa29d7e8ba 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -42,6 +42,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" icon_state = "cshotgun" + item_state = "cshotgun" origin_tech = "combat=5;materials=2" max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8. ammo_type = /obj/item/ammo_casing/shotgun @@ -51,7 +52,7 @@ name = "double-barreled shotgun" desc = "A true classic." icon_state = "dshotgun" - item_state = "shotgun" + item_state = "dshotgun" //SPEEDLOADER because rapid unloading. //In principle someone could make a speedloader for it, so it makes sense. load_method = SINGLE_CASING|SPEEDLOADER diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 5bde8a5cfc..24feb08771 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -6,36 +6,44 @@ nodamage = 1 check_armour = "energy" - on_hit(var/atom/change) - wabbajack(change) +/obj/item/projectile/change/on_hit(var/atom/change) + wabbajack(change) - -/obj/item/projectile/change/proc/wabbajack (mob/M as mob in living_mob_list) +/obj/item/projectile/change/proc/wabbajack(var/mob/M) if(istype(M, /mob/living) && M.stat != DEAD) - if(M.monkeyizing) return - if(M.has_brain_worms()) return //Borer stuff - RR - - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.overlays.Cut() - M.invisibility = 101 + if(M.monkeyizing) + return + if(M.has_brain_worms()) + return //Borer stuff - RR if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) del(Robot.mmi) + if(Robot.mmi) + del(Robot.mmi) else for(var/obj/item/W in M) if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something del(W) continue - W.layer = initial(W.layer) - W.loc = M.loc - W.dropped(M) + M.drop_from_inventory(W) var/mob/living/new_mob - var/randomize = pick("robot","slime","xeno","human") + var/options = list("robot", "slime") + for(var/t in all_species) + options += t + options -= "Xenomorph Queen" + options -= "Xenomorph" + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species) + options -= H.species.name + else if(isrobot(M)) + options -= "robot" + else if(isslime(M)) + options -= "slime" + + var/randomize = pick(options) switch(randomize) if("robot") new_mob = new /mob/living/silicon/robot(M.loc) @@ -48,36 +56,42 @@ if("slime") new_mob = new /mob/living/carbon/slime(M.loc) new_mob.universal_speak = 1 - if("xeno") - var/alien_caste = pick("Hunter","Sentinel","Drone","Larva") - new_mob = create_new_xenomorph(alien_caste,M.loc) - new_mob.universal_speak = 1 - if("human") - new_mob = new /mob/living/carbon/human(M.loc, pick(all_species)) - if(M.gender == MALE) - new_mob.gender = MALE - new_mob.name = pick(first_names_male) - else - new_mob.gender = FEMALE - new_mob.name = pick(first_names_female) - new_mob.name += " [pick(last_names)]" - new_mob.real_name = new_mob.name - - var/datum/preferences/A = new() //Randomize appearance for the human - A.randomize_appearance_for(new_mob) else - return + var/mob/living/carbon/human/H + if(ishuman(M)) + H = M + else + new_mob = new /mob/living/carbon/human(M.loc) + H = new_mob - for (var/obj/effect/proc_holder/spell/S in M.spell_list) - new_mob.spell_list += new S.type + if(M.gender == MALE) + H.gender = MALE + H.name = pick(first_names_male) + else + H.gender = FEMALE + H.name = pick(first_names_female) + H.name += " [pick(last_names)]" + H.real_name = H.name - new_mob.a_intent = "hurt" - if(M.mind) - M.mind.transfer_to(new_mob) + H.set_species(randomize) + H.universal_speak = 1 + var/datum/preferences/A = new() //Randomize appearance for the human + A.randomize_appearance_for(H) + + if(new_mob) + for (var/obj/effect/proc_holder/spell/S in M.spell_list) + new_mob.spell_list += new S.type + + new_mob.a_intent = "hurt" + if(M.mind) + M.mind.transfer_to(new_mob) + else + new_mob.key = M.key + + new_mob << "Your form morphs into that of \a [lowertext(randomize)]." + + del(M) + return else - new_mob.key = M.key - - new_mob << "Your form morphs into that of a [randomize]." - - del(M) - return new_mob + M << "Your form morphs into that of \a [lowertext(randomize)]." + return \ No newline at end of file diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm index c3988ff2ff..388b53a256 100644 --- a/code/modules/projectiles/targeting.dm +++ b/code/modules/projectiles/targeting.dm @@ -80,12 +80,12 @@ var/mob/living/M = loc if(M == T) return if(!istype(M)) return - if(src != M.equipped()) + if(src != M.get_active_hand()) stop_aim() return //reflex firing is disabled when help intent is set - if (M.a_intent == "help") + if (M.a_intent == I_HELP) M << "\red You refrain from firing your [src] as your intent is set to help." return diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index dfe331398d..e7832a369c 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -655,7 +655,7 @@ user << "\The [O] is not suitable for blending." return 1 - user.before_take_item(O) + user.remove_from_mob(O) O.loc = src holdingitems += O src.updateUsrDialog() @@ -794,4 +794,4 @@ if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break -#undef REAGENTS_PER_SHEET \ No newline at end of file +#undef REAGENTS_PER_SHEET diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 53c9a4ee24..7829755035 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -248,7 +248,7 @@ if(!T || !istype(T)) return if(T.wet >= 2) - return + return T.wet = 0 if(T.wet_overlay) T.overlays -= T.wet_overlay @@ -541,7 +541,7 @@ if(prob(50)) M.radiation += 50 // curing it that way may kill you instead var/absorbed = 0 - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in M.internal_organs + var/obj/item/organ/diona/nutrients/rad_organ = locate() in M.internal_organs if(rad_organ && !rad_organ.is_broken()) absorbed = 1 if(!absorbed) @@ -938,7 +938,7 @@ 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 - 5 * removed, 0) @@ -956,7 +956,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - 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)) //Peridaxon heals only non-robotic organs I.damage = max(I.damage - removed, 0) @@ -3381,7 +3381,7 @@ M.adjustToxLoss(2 * removed) if(dose > 60 && ishuman(M) && prob(5)) 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)) if(dose < 120) L.take_damage(10 * removed, 0) @@ -4038,4 +4038,4 @@ description = "A viscous, toxic liquid left over from many chemical processes." reagent_state = LIQUID color = "#ADFF2F" //rgb: 173, 255, 47, toxic green -*/ +*/ \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index dd2f879b27..d4fbbaa2cd 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -35,13 +35,13 @@ if(!target) return - if(user.a_intent != "hurt" || !isGlass) + if(user.a_intent != I_HURT || !isGlass) return ..() 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 8d43ffe715..c97ce76bb0 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -158,9 +158,7 @@ return user << "\red You slip [W] inside [src]." - user.u_equip(W) - if ((user.client && user.s_active != src)) - user.client.screen -= W + user.remove_from_mob(W) W.dropped(user) add_fingerprint(user) contents += W @@ -1569,9 +1567,9 @@ surprise.transform *= 0.6 surprise.add_blood(M) var/mob/living/carbon/human/H = M - var/datum/organ/external/E = H.get_organ("chest") + var/obj/item/organ/external/E = H.get_organ("chest") E.fracture() - for (var/datum/organ/internal/I in E.internal_organs) + for (var/obj/item/organ/I in E.internal_organs) I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1)) if (!E.hidden && prob(60)) //set it snuggly diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 6d968d8be6..bfbefbb80d 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -242,8 +242,8 @@ reagents.add_reagent("synaptizine", 5) reagents.add_reagent("hyperzine", 5) - /obj/item/weapon/reagent_containers/pill/spaceacillin - name = "Spaceacillin" +/obj/item/weapon/reagent_containers/pill/spaceacillin + name = "Spaceacillin pill" desc = "Contains antiviral agents." icon_state = "pill19" New() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 6218d8fbac..d7c140779f 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -58,8 +58,8 @@ if(mode == SYRINGE_BROKEN) user << "This syringe is broken!" return - - if(user.a_intent == "hurt" && ismob(target)) + + if(user.a_intent == I_HURT && ismob(target)) if((CLUMSY in user.mutations) && prob(50)) target = user syringestab(target, user) @@ -228,14 +228,17 @@ var/mob/living/carbon/human/H = target var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target)) +<<<<<<< HEAD var/datum/organ/external/affecting = H.get_organ(target_zone) +======= + var/obj/item/organ/external/affecting = target:get_organ(target_zone) +>>>>>>> dev - 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 if((user != target) && H.check_shields(7, "the [src.name]")) return @@ -243,7 +246,7 @@ if (target != user && H.getarmor(target_zone, "melee") > 5 && prob(50)) for(var/mob/O in viewers(world.view, user)) O.show_message(text("\red [user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!"), 1) - user.u_equip(src) + user.remove_from_mob(src) del(src) return @@ -257,8 +260,13 @@ target.take_organ_damage(3)// 7 is the same as crowbar punch var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand +<<<<<<< HEAD reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD) break_syringe(target, user) +======= + src.reagents.trans_to(target, syringestab_amount_transferred) + src.break_syringe(target, user) +>>>>>>> dev proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user) desc += " It is broken." diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 9083a47e1c..86eb5cce55 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -358,7 +358,7 @@ datum/design/aimodule/safeguard build_path = /obj/item/weapon/aiModule/safeguard datum/design/aimodule/onehuman - name = "OneHuman" + name = "OneCrewMember" id = "onehuman" req_tech = list("programming" = 4, "materials" = 6) build_path = /obj/item/weapon/aiModule/oneHuman 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/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm index 77074be63f..0c81a604a2 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm @@ -1,49 +1,49 @@ - -/datum/artifact_effect/hurt - effecttype = "hurt" - effect_type = 5 - -/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher) - if(toucher) - var/weakness = GetAnomalySusceptibility(toucher) - if(iscarbon(toucher) && prob(weakness * 100)) - var/mob/living/carbon/C = toucher - C << "\red A painful discharge of energy strikes you!" - C.adjustOxyLoss(rand(5,25) * weakness) - C.adjustToxLoss(rand(5,25) * weakness) - C.adjustBruteLoss(rand(5,25) * weakness) - C.adjustFireLoss(rand(5,25) * weakness) - C.adjustBrainLoss(rand(5,25) * weakness) - C.radiation += 25 * weakness - C.nutrition -= min(50 * weakness, C.nutrition) - C.make_dizzy(6 * weakness) - C.weakened += 6 * weakness - -/datum/artifact_effect/hurt/DoEffectAura() - if(holder) - var/turf/T = get_turf(holder) - for (var/mob/living/carbon/C in range(src.effectrange,T)) - var/weakness = GetAnomalySusceptibility(C) - if(prob(weakness * 100)) - if(prob(10)) - C << "\red You feel a painful force radiating from something nearby." - C.adjustBruteLoss(1 * weakness) - C.adjustFireLoss(1 * weakness) - C.adjustToxLoss(1 * weakness) - C.adjustOxyLoss(1 * weakness) - C.adjustBrainLoss(1 * weakness) - C.updatehealth() - -/datum/artifact_effect/hurt/DoEffectPulse() - if(holder) - var/turf/T = get_turf(holder) - for (var/mob/living/carbon/C in range(effectrange, T)) - var/weakness = GetAnomalySusceptibility(C) - if(prob(weakness * 100)) - C << "\red A wave of painful energy strikes you!" - C.adjustBruteLoss(3 * weakness) - C.adjustFireLoss(3 * weakness) - C.adjustToxLoss(3 * weakness) - C.adjustOxyLoss(3 * weakness) - C.adjustBrainLoss(3 * weakness) - C.updatehealth() + +/datum/artifact_effect/hurt + effecttype = I_HURT + effect_type = 5 + +/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher) + if(toucher) + var/weakness = GetAnomalySusceptibility(toucher) + if(iscarbon(toucher) && prob(weakness * 100)) + var/mob/living/carbon/C = toucher + C << "\red A painful discharge of energy strikes you!" + C.adjustOxyLoss(rand(5,25) * weakness) + C.adjustToxLoss(rand(5,25) * weakness) + C.adjustBruteLoss(rand(5,25) * weakness) + C.adjustFireLoss(rand(5,25) * weakness) + C.adjustBrainLoss(rand(5,25) * weakness) + C.radiation += 25 * weakness + C.nutrition -= min(50 * weakness, C.nutrition) + C.make_dizzy(6 * weakness) + C.weakened += 6 * weakness + +/datum/artifact_effect/hurt/DoEffectAura() + if(holder) + var/turf/T = get_turf(holder) + for (var/mob/living/carbon/C in range(src.effectrange,T)) + var/weakness = GetAnomalySusceptibility(C) + if(prob(weakness * 100)) + if(prob(10)) + C << "\red You feel a painful force radiating from something nearby." + C.adjustBruteLoss(1 * weakness) + C.adjustFireLoss(1 * weakness) + C.adjustToxLoss(1 * weakness) + C.adjustOxyLoss(1 * weakness) + C.adjustBrainLoss(1 * weakness) + C.updatehealth() + +/datum/artifact_effect/hurt/DoEffectPulse() + if(holder) + var/turf/T = get_turf(holder) + for (var/mob/living/carbon/C in range(effectrange, T)) + var/weakness = GetAnomalySusceptibility(C) + if(prob(weakness * 100)) + C << "\red A wave of painful energy strikes you!" + C.adjustBruteLoss(3 * weakness) + C.adjustFireLoss(3 * weakness) + C.adjustToxLoss(3 * weakness) + C.adjustOxyLoss(3 * weakness) + C.adjustBrainLoss(3 * weakness) + C.updatehealth() diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 66ba38726e..6236f8c35a 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -26,18 +26,18 @@ dat += "


    " dat += "Memorize which spell:
    " dat += "The number after the spell name is the cooldown time.
    " - dat += "Magic Missile (10)
    " + dat += "Magic Missile (15)
    " dat += "Fireball (10)
    " //dat += "Disintegrate (60)
    " - dat += "Disable Technology (60)
    " - dat += "Smoke (10)
    " + dat += "Disable Technology (40)
    " + dat += "Smoke (12)
    " dat += "Blind (30)
    " dat += "Mind Transfer (60)
    " dat += "Forcewall (10)
    " dat += "Blink (2)
    " dat += "Teleport (60)
    " - dat += "Mutate (60)
    " - dat += "Ethereal Jaunt (60)
    " + dat += "Mutate (40)
    " + dat += "Ethereal Jaunt (30)
    " dat += "Knock (10)
    " dat += "Curse of the Horseman (15)
    " // if(op) @@ -105,7 +105,7 @@ if("magicmissile") feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H) - temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage." + temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If a projectile hits a target, the target is stunned for some time." if("fireball") feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H) @@ -117,11 +117,11 @@ if("disabletech") feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H) - temp = "This spell disables all weapons, cameras and most other technology in range." + temp = "This spell releases an EMP from your person disabling most technology within range; computers, doors, prosthetics, etc." if("smoke") feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H) - temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." + temp = "This spell spawns a cloud of vision obscuring smoke at your location and does not require wizard garb." if("blind") feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H) @@ -141,11 +141,11 @@ if("teleport") feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H) - temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable." + temp = "This spell teleports you to an area of your selection, and creates a cloud of smoke around you upon arrival. Very useful if you are in danger.." if("mutate") feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H) - temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while." + temp = "This spell causes you to turn into a hulk, gaining super strength and the ability to punch down walls! You also gain the ability to fire lasers from your eyes!" if("etherealjaunt") feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 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..f6352f6b74 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -12,7 +12,7 @@ return 0 if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected == null) return 0 if (affected.status & ORGAN_DESTROYED) @@ -36,20 +36,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts the bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start the bloodless incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.display_name]!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts the bloodless incision on [target]'s [affected.name] with \the [tool].", \ + "You start the bloodless incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have made a bloodless incision on [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You have made a bloodless incision on [target]'s [affected.name] with \the [tool].",) //Could be cleaner ... affected.open = 1 @@ -61,9 +61,9 @@ spread_germs_to_organ(affected, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 7.5) affected.createwound(BURN, 12.5) @@ -77,20 +77,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ - "You start to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.display_name] as it is pushed apart!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ + "You start to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.name] as it is pushed apart!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ + "\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",) affected.open = 1 if(istype(target) && !(target.species.flags & NO_BLOOD)) @@ -101,9 +101,9 @@ affected.open = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 20) affected.createwound(BURN, 15) @@ -119,20 +119,20 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts the incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start the incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.display_name]!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts the incision on [target]'s [affected.name] with \the [tool].", \ + "You start the incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made an incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You have made an incision on [target]'s [affected.display_name] with \the [tool].",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has made an incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You have made an incision on [target]'s [affected.name] with \the [tool].",) affected.open = 1 if(istype(target) && !(target.species.flags & NO_BLOOD)) @@ -141,9 +141,9 @@ affected.createwound(CUT, 1) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!", \ - "\red Your hand slips, slicing open [target]'s [affected.display_name] in the wrong place with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!", \ + "\red Your hand slips, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!") affected.createwound(CUT, 10) /datum/surgery_step/generic/clamp_bleeders @@ -158,27 +158,27 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open && (affected.status & ORGAN_BLEEDING) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && (affected.status & ORGAN_BLEEDING) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts clamping bleeders in [target]'s [affected.display_name] with \the [tool].", \ - "You start clamping bleeders in [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("The pain in your [affected.display_name] is maddening!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \ + "You start clamping bleeders in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in your [affected.name] is maddening!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.display_name] with \the [tool].", \ - "\blue You clamp bleeders in [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.name] with \the [tool].", \ + "\blue You clamp bleeders in [target]'s [affected.name] with \the [tool].") affected.clamp() spread_germs_to_organ(affected, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!",) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) affected.createwound(CUT, 10) /datum/surgery_step/generic/retract_skin @@ -193,13 +193,13 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts to pry open the incision on [target]'s [affected.display_name] with \the [tool]." - var/self_msg = "You start to pry open the incision on [target]'s [affected.display_name] with \the [tool]." + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." + var/self_msg = "You start to pry open the incision on [target]'s [affected.name] with \the [tool]." if (target_zone == "chest") msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." @@ -207,13 +207,13 @@ msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("It feels like the skin on your [affected.display_name] is on fire!",1) + target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] keeps the incision open on [target]'s [affected.display_name] with \the [tool]." - var/self_msg = "\blue You keep the incision open on [target]'s [affected.display_name] with \the [tool]." + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "\blue [user] keeps the incision open on [target]'s [affected.name] with \the [tool]." + var/self_msg = "\blue You keep the incision open on [target]'s [affected.name] with \the [tool]." if (target_zone == "chest") msg = "\blue [user] keeps the ribcage open on [target]'s torso with \the [tool]." self_msg = "\blue You keep the ribcage open on [target]'s torso with \the [tool]." @@ -224,9 +224,9 @@ affected.open = 2 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - var/msg = "\red [user]'s hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!" - var/self_msg = "\red Your hand slips, tearing the edges of the incision on [target]'s [affected.display_name] with \the [tool]!" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "\red [user]'s hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" + var/self_msg = "\red Your hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" if (target_zone == "chest") msg = "\red [user]'s hand slips, damaging several organs in [target]'s torso with \the [tool]!" self_msg = "\red Your hand slips, damaging several organs in [target]'s torso with \the [tool]!" @@ -249,31 +249,31 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open && target_zone != "mouth" + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && target_zone != "mouth" begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool]." , \ - "You are beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Your [affected.display_name] is being burned!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("Your [affected.name] is being burned!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You cauterize the incision on [target]'s [affected.display_name] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.name] with \the [tool].", \ + "\blue You cauterize the incision on [target]'s [affected.name] with \the [tool].") affected.open = 0 affected.germ_level = 0 affected.status &= ~ORGAN_BLEEDING fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!") target.apply_damage(3, BURN, affected) -/datum/surgery_step/generic/cut_limb +/datum/surgery_step/generic/amputate allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ /obj/item/weapon/hatchet = 75 @@ -287,29 +287,29 @@ return 0 if (!hasorgans(target)) return 0 - var/datum/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) if (affected == null) return 0 if (affected.status & ORGAN_DESTROYED) return 0 - return target_zone != "chest" && target_zone != "groin" && target_zone != "head" + return !affected.cannot_amputate begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to cut off [target]'s [affected.display_name] with \the [tool]." , \ - "You are beginning to cut off [target]'s [affected.display_name] with \the [tool].") - target.custom_pain("Your [affected.display_name] is being ripped apart!",1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") + target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cuts off [target]'s [affected.display_name] with \the [tool].", \ - "\blue You cut off [target]'s [affected.display_name] with \the [tool].") - affected.droplimb(1,1,1) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] amputates [target]'s [affected.name] at the [affected.amputation_point] with \the [tool].", \ + "\blue You amputate [target]'s [affected.name] with \the [tool].") + affected.droplimb(1,DROPLIMB_EDGE) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 30) affected.fracture() diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index 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 6ad8387c3d..f81baa4468 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 @@ -150,11 +150,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 @@ -163,8 +163,8 @@ var/trans = container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) - 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 a4e6cfdc6f..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 @@ -80,7 +80,7 @@ proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user) proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool) if(!istype(M)) return 0 - if (user.a_intent == "harm") //check for Hippocratic Oath + if (user.a_intent == I_HURT) //check for Hippocratic Oath return 0 var/zone = user.zone_sel.selecting if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly. @@ -108,7 +108,7 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool) H.update_surgery() return 1 //don't want to do weapony things after surgery - if (user.a_intent == "help") + if (user.a_intent == I_HELP) user << "\red You can't see any useful way to use [tool] on [M]." return 1 return 0 diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 476e7d68cb..e023beef80 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -79,13 +79,13 @@ mob.adjustBruteLoss(10*multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/datum/organ/external/O = pick(H.organs) + var/obj/item/organ/external/O = pick(H.organs) if(prob(25)) - mob << "Your [O.display_name] feels as if it might fall off!" + mob << "Your [O.name] feels as if it might burst!" if(prob(10)) spawn(50) if(O) - O.droplimb(1) + O.droplimb(0,DROPLIMB_BLUNT) else if(prob(75)) mob << "Your whole body feels like it might fall apart!" @@ -153,11 +153,11 @@ if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob var/organ = pick(list("r_arm","l_arm","r_leg","r_leg")) - var/datum/organ/external/E = H.organs_by_name[organ] + var/obj/item/organ/external/E = H.organs_by_name[organ] if (!(E.status & ORGAN_DEAD)) E.status |= ORGAN_DEAD - H << "You can't feel your [E.display_name] anymore..." - for (var/datum/organ/external/C in E.children) + H << "You can't feel your [E.name] anymore..." + for (var/obj/item/organ/external/C in E.children) C.status |= ORGAN_DEAD H.update_body(1) mob.adjustToxLoss(15*multiplier) @@ -165,9 +165,9 @@ deactivate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.status &= ~ORGAN_DEAD - for (var/datum/organ/external/C in E.children) + for (var/obj/item/organ/external/C in E.children) C.status &= ~ORGAN_DEAD H.update_body(1) @@ -178,7 +178,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) if (E.status & ORGAN_BROKEN && prob(30)) E.status ^= ORGAN_BROKEN var/heal_amt = -5*multiplier @@ -199,13 +199,13 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.min_broken_damage = max(5, E.min_broken_damage - 30) deactivate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - for (var/datum/organ/external/E in H.organs) + for (var/obj/item/organ/external/E in H.organs) E.min_broken_damage = initial(E.min_broken_damage) ////////////////////////STAGE 3///////////////////////////////// @@ -237,7 +237,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/datum/organ/internal/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] if (B && B.damage < B.min_broken_damage) B.take_damage(5) else diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index 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 f0e0c20762..82c62d1b0e 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -261,6 +261,11 @@ #define slot_legs 21 #define slot_tie 22 +// Mob sprite sheets. These need to be strings as numbers +// cannot be used as associative list keys. +#define icon_l_hand "slot_l_hand" +#define icon_r_hand "slot_r_hand" + // Bitflags for clothing parts. #define HEAD 1 #define FACE 2 @@ -431,10 +436,6 @@ #define SEC_LEVEL_RED 2 #define SEC_LEVEL_DELTA 3 -// Click cooldowns, in tenths of a second. -#define CLICK_CD_MELEE 8 -#define CLICK_CD_RANGE 4 - #define TRANSITIONEDGE 7 // Distance from edge to move to another z-level. // A set of constants used to determine which type of mute an admin wishes to apply. @@ -508,6 +509,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 @@ -623,22 +625,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. @@ -649,7 +652,7 @@ var/list/be_special_flags = list( #define NONGLOBAL 32 // Do not add to general languages list. #define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes) #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message -#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems +#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems //Flags for zone sleeping #define ZONE_ACTIVE 1 @@ -789,15 +792,15 @@ var/list/be_special_flags = list( // Appearance change flags #define APPEARANCE_UPDATE_DNA 1 -#define APPEARANCE_RACE 2|APPEARANCE_UPDATE_DNA -#define APPEARANCE_GENDER 4|APPEARANCE_UPDATE_DNA +#define APPEARANCE_RACE (2|APPEARANCE_UPDATE_DNA) +#define APPEARANCE_GENDER (4|APPEARANCE_UPDATE_DNA) #define APPEARANCE_SKIN 8 #define APPEARANCE_HAIR 16 #define APPEARANCE_HAIR_COLOR 32 #define APPEARANCE_FACIAL_HAIR 64 #define APPEARANCE_FACIAL_HAIR_COLOR 128 #define APPEARANCE_EYE_COLOR 256 -#define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR +#define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR) #define APPEARANCE_ALL 511 // Antagonist datum flags. @@ -838,3 +841,27 @@ var/list/be_special_flags = list( //Area flags, possibly more to come #define RAD_SHIELDED 1 //shielded from radiation, clearly + +//intent flags, why wasn't this done the first time? +#define I_HELP "help" +#define I_DISARM "disarm" +#define I_GRAB "grab" +#define I_HURT "hurt" + +/* + These are used Bump() code for living mobs, in the mob_bump_flag, mob_swap_flags, and mob_push_flags vars to determine whom can bump/swap with whom. +*/ +#define HUMAN 1 +#define MONKEY 2 +#define ALIEN 4 +#define ROBOT 8 +#define SLIME 16 +#define SIMPLE_ANIMAL 32 + +#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL) + +#define NEXT_MOVE_DELAY 8 + +#define DROPLIMB_EDGE 0 +#define DROPLIMB_BLUNT 1 +#define DROPLIMB_BURN 2 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/feet.dmi b/icons/mob/feet.dmi index afeb796a29..0c99056632 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi new file mode 100644 index 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 diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi new file mode 100644 index 0000000000..fca687513a Binary files /dev/null and b/icons/mob/items/lefthand.dmi differ diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi new file mode 100644 index 0000000000..d564d9bafe Binary files /dev/null and b/icons/mob/items/lefthand_guns.dmi differ diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi new file mode 100644 index 0000000000..87b3eea46b Binary files /dev/null and b/icons/mob/items/righthand.dmi differ diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi new file mode 100644 index 0000000000..63c5c0ae01 Binary files /dev/null and b/icons/mob/items/righthand_guns.dmi differ diff --git a/icons/mob/species/armalis/feet.dmi b/icons/mob/species/armalis/feet.dmi deleted file mode 100644 index cbd83be702..0000000000 Binary files a/icons/mob/species/armalis/feet.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/gloves.dmi b/icons/mob/species/armalis/gloves.dmi deleted file mode 100644 index 7d3eed317a..0000000000 Binary files a/icons/mob/species/armalis/gloves.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/head.dmi b/icons/mob/species/armalis/head.dmi deleted file mode 100644 index ddb8859fd0..0000000000 Binary files a/icons/mob/species/armalis/head.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/held.dmi b/icons/mob/species/armalis/held.dmi deleted file mode 100644 index 517709f33c..0000000000 Binary files a/icons/mob/species/armalis/held.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/mask.dmi b/icons/mob/species/armalis/mask.dmi deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/icons/mob/species/armalis/suit.dmi b/icons/mob/species/armalis/suit.dmi deleted file mode 100644 index 05f9b082cf..0000000000 Binary files a/icons/mob/species/armalis/suit.dmi and /dev/null differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index ce8762d6e1..7c823421d3 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index f65298542d..ceeaa228a1 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -4865,7 +4865,7 @@ "bPC" = (/obj/machinery/camera{c_tag = "Medbay Port Corridor"; dir = 8; network = list("SS13")},/obj/structure/disposalpipe/segment,/obj/machinery/light_switch{pixel_x = 22; pixel_y = -9},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bPD" = (/obj/machinery/camera{c_tag = "Medbay CMO Office"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = -9},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Medical Officer's Desk"; departmentType = 5; name = "Chief Medical Officer RC"; pixel_x = -34; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bPE" = (/obj/structure/table,/obj/machinery/computer/skills{pixel_y = 4},/obj/item/device/megaphone,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bPF" = (/obj/structure/table,/obj/item/weapon/paper{desc = "A few notes scratched out by the last CMO before they departed the station."; info = "
    To the incoming CMO of Exodus:


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


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

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

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

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

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

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

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

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

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

    I've fed Runtime. She should be fine.


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

    LIST OF SPELLS AVAILABLE

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

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

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

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

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

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

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

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

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

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

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

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

    "; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) +"Ih" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "\[center]\[b]LIST OF SPELLS AVAILABLE\[/b]\[/center]\[br]\[br]Magic Missile:\[br]This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.\[br]\[br]Fireball:\[br]This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you.\[br]\[br]Disintegrate:\[br]This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.\[br]\[br]Disable Technology:\[br]This spell disables all weapons, cameras and most other technology in range.\[br]\[br]Smoke:\[br]This spell spawns a cloud of choking smoke at your location and does not require wizard garb.\[br]\[br]Blind:\[br]This spell temporarly blinds a single person and does not require wizard garb.\[br]Forcewall:\[br]This spell creates an unbreakable wall that lasts for 30 seconds and does not require wizard garb.\[br]\[br]Blink:\[br]This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience.\[br]\[br]Teleport:\[br]This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable.\[br]\[br]Mutate:\[br]This spell causes you to turn into a hulk, and gain telekinesis for a short while.\[br]\[br]Ethereal Jaunt:\[br]This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.\[br]\[br]Knock:\[br]This spell opens nearby doors and does not require wizard garb.\[br]"; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) "Ii" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/satchel/withwallet,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/wizard_station) "Ij" = (/obj/structure/toilet{pixel_y = 8},/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) "Ik" = (/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) @@ -2128,6 +2128,7 @@ "OV" = (/turf/space,/area/shuttle/skipjack/station) "OW" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "OX" = (/mob/living/carbon/human/monkey{name = "Murphey"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) +"OY" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) (1,1,1) = {" aaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoalahajeEapaqarasatauavawaxayazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtwtwtwtwtwtwtwtwtwtwtwtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaNaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaQ @@ -2258,20 +2259,20 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVqRpepepepepepepepepepeqHoVoVoVoVpFpFtctdpFpFpFtctetdpFqvqvqvpFtftgtgtgtgtgthpFpZqztitjqYqYqYtktlqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVpFtptptptptptptptptppFpFsNpFpFtptptptptptptppFpZqztrtstttttttstuqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvyhyhyhyhyhyhyhxOxOBdtxtxtxtxtxtxpFtytztypFtxtxtxtxtxtxtxtxpZqzqztAtBtBtBtCqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtqtvtDtFtEtHtGtNtvtYuhtZtZuiuaujujululyhzdyIyIyIyIumwGwHwGuntOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvAgtvuyuhuhuhuhuhtvuzuhuhuhuhuhuhuhuhuhyhyByIuAyIyIvexQxQxQvfueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuvbuvuwvguhuhuhuhuhuhuhvbtvvkuhuhuhuhuhuhuhuhuhyhyHvpzqyIyIumwGwHwGunueufufufufpFpFsNpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvbvctvvyuhuhuhuhuhuhuhtvvzuhuhuhuhujvEvAvKvKyhzrzpzEyIyIyhvMvMvMtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtqtvtDtFtEuytNtGtvtYuhtZtZuiuaujujululyhzdyIyIyIyIumwGxvwGuntOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvAgtvuhuhuhuhuhuhtvuzuhuhuhuhuhuhuhuhuhyhyByIuAyIyIvexQxQxQvfueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuvbuvuwvguhuhuhuhuhuhuhvytvvkuhuhuhuhuhuhuhuhuhyhyHvpzqyIyIumwGxvwGunueufufufufpFpFsNpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvbvctvtHuhuhuhuhuhuhuhtvvzuhuhuhuhujvEvAvKvKyhzrzpzEyIyIyhvMvMvMtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvgtvtvtvuhuhuhuhuhuhuhuhtvuhuhuhuhvNtvtvtvtvtvyhyhyhyhyhyhyhxQxQxQtxvOtxvlvmvntxufufuftxvlvmvotxvPtxvqvrvqvrvqugtxtxtxtxurururtxvsvtuPvuvsvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutvIvbvbvJtvvxvQukxovRvSuhuhtvuhuhuhuhvTtvwlwhwhwlwownwqwpxQxQxQxQxQwztxufufvBvCvCvCvCvCvCvCvCvCvDufufwAvqvqvqvqvqugvFuNuotxurururtxvGvGvHvGvGvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVwWuXuVuVuVuYwWwivavbvbwjtvwFwGwGwGwItvuhuhtvuhuhuhuhwBtvuhxQxQwmwEwmwmwmwmwmxQxQxQwPtxufufvVvWvXvXvXvXvXvXvXvYueufufugvZwawbwcwdugweuNuptxurururtxwfwfuNwfwfvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbvbwywowVwYwXxawZwouhuhwouhuhuhuhxbwouhxQxQuwxcxQxQxQwqwqtvtvtvtvtvufufvVwrwsufwtwuwvufwswrueufufugugugugugugugweuNuptxurururtxwwwwuNwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxduXuVuVuVuYxdxevavbvbxgxkxhuhuhuhxlxkuhuhxkuhuhxnxmxpxkxqxQxQxQtvwFwGwHwGwItvwJwJwJtvufufwKwLwMwNwOxrwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutxsvbvbvbtvxtuhuhuhuhtvxuxutvxvxvtvtvtvtvxqxQxQuwuWxfxfxfxfxfxwxfxfxfxwufufufxxufufxiufxiufufxxufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutxsvbvbxMtvxtuhuhuhuhtvxuxutvOYOYtvtvtvtvxqxQxQuwuWxfxfxfxfxfxwxfxfxfxwufufufxxufufxiufxiufufxxufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxyuXuVuVuVuYxyxzxAvbvbuwxHuhuhuhuhuhxHuhuhxIuhuhxKxJxLxLuhxQxQvdtvwFwGwHwGwItvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvbxNxMxHuhuhuhuhuhxHuhuhxRuhuhxQyayayaxQxQxQzcycybydxQyfyetvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvwFwGwGwGwItvygygtvyiuhxQyjylykxQxQxQyRymydxQxQxQxQxcxQxnyztvufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywObtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMdCyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvbvbuwxHuhuhuhuhuhxHuhuhxRuhuhxQyayayaxQxQxQzcycybydxQyfyetvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvvbvbxNtvwFwGwGwGwItvygygtvyiuhxQyjylykxQxQxQyRymydxQxQxQxQxcxQxnyztvufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywObtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhxkzeuhxQzgzgzgxQxQxQxQxcxQxQxQyYyXxkyJyEyFtvufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhtvwCuhuhzhuhuhuhxQxQwCymxQxQxQyYyXtvtvtvtvtvtxtxzitxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvzkzkzlznzmzCzxwDtvzOzDvMtvAbAbtvvMzDzOycAexQxQyYyXtvzsztztzszuzvufzwtxtxtxAhtxtxtxaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt diff --git a/nano/templates/law_manager.tmpl b/nano/templates/law_manager.tmpl index 4dcc756b7d..d4860c2b90 100644 --- a/nano/templates/law_manager.tmpl +++ b/nano/templates/law_manager.tmpl @@ -42,7 +42,7 @@ {{if data.isSlaved && data.isAdmin}} - This unit is law synced to {{:data.isSlaved}}. Any law differences will be lost upon sync. + This unit is law synced to {{:data.isSlaved}}. {{/if}} {{if data.isMalf || data.isAIMalf}} @@ -101,7 +101,7 @@ {{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state != 1 ? 'selected' : null)}} {{if data.isMalf}} {{:helper.link('Edit', null, {'edit_law': value.ref}, data.isAdmin ? null : 'disabled')}} - {{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.IsAdmin ? 'redButton' : null)}} + {{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.isAdmin ? 'redButton' : null)}} {{/if}} {{/for}} @@ -185,25 +185,16 @@ {{/if}} - {{if data.isMalf}} -
    -
    - Sync Laws: -
    -
    - {{:helper.link('Sync Laws', null, {'sync_laws' : 1})}} -
    -
    - {{/if}} - -
    -
    - Law Notification: -
    -
    - {{:helper.link('Notify', null, {'notify_laws' : 1})}} -
    -
    + {{if data.isAI}} +
    +
    + Law Notification: +
    +
    + {{:helper.link('Notify', null, {'notify_laws' : 1})}} +
    +
    + {{/if}} {{else data.view == 1}} {{for data.law_sets}}