From f41df2ae724dd6c2754be0d5b7c3418e5f411454 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Tue, 20 Jun 2017 05:28:35 -0400 Subject: [PATCH 1/3] Adds in Limb Augmentation and Limb Company Selection --- code/game/gamemodes/wizard/artefact.dm | 2 +- code/game/objects/items/robot/robot_parts.dm | 19 +++++-- .../carbon/human/interactive/interactive.dm | 8 +-- code/modules/mob/mob_helpers.dm | 8 ++- code/modules/surgery/limb_augmentation.dm | 53 +++++++++++++++++++ code/modules/surgery/organs/organ.dm | 33 +++++++----- code/modules/surgery/organs/organ_external.dm | 27 ++++++---- code/modules/surgery/organs/robolimbs.dm | 15 ++++++ .../surgery/organs/subtypes/standard.dm | 5 ++ paradise.dme | 1 + 10 files changed, 131 insertions(+), 40 deletions(-) create mode 100644 code/modules/surgery/limb_augmentation.dm diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 1dd20906704..4f9af54457c 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -465,7 +465,7 @@ var/global/list/multiverse = list() if("cyborg") if(M.get_species() != "Machine") for(var/obj/item/organ/O in M.bodyparts) - O.robotize() + O.robotize(make_tough = 1) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(sword, slot_r_hand) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index ef1589f50b7..b744edd79a6 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -7,7 +7,7 @@ slot_flags = SLOT_BELT var/list/part = null var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics. - var/model_info + var/model_info = "Unbranded" dir = SOUTH /obj/item/robot_parts/New(newloc, model) @@ -23,33 +23,38 @@ else name = "robot [initial(name)]" +/obj/item/robot_parts/attack_self(mob/user) + var/choice = input(user, "Select the company appearance for this limb.", "Limb Company Selection") as null|anything in selectable_robolimbs + if(!choice) + return + if(loc != user) + return + model_info = choice + to_chat(usr, "You change the company limb model to [choice].") + /obj/item/robot_parts/l_arm name = "left arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_arm" part = list("l_arm","l_hand") - model_info = 1 /obj/item/robot_parts/r_arm name = "right arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_arm" part = list("r_arm","r_hand") - model_info = 1 /obj/item/robot_parts/l_leg name = "left leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_leg" part = list("l_leg","l_foot") - model_info = 1 /obj/item/robot_parts/r_leg name = "right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_leg" part = list("r_leg","r_foot") - model_info = 1 /obj/item/robot_parts/chest name = "torso" @@ -80,6 +85,7 @@ name = "endoskeleton" desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." icon_state = "robo_suit" + model_info = null var/obj/item/robot_parts/l_arm/l_arm = null var/obj/item/robot_parts/r_arm/r_arm = null var/obj/item/robot_parts/l_leg/l_leg = null @@ -108,6 +114,9 @@ forced_ai = null return ..() +/obj/item/robot_parts/robot_suit/attack_self(mob/user) + return + /obj/item/robot_parts/robot_suit/proc/updateicon() overlays.Cut() if(l_arm) diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index 00b8e0a4544..b1d9b5bc68f 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -270,20 +270,20 @@ if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4)) var/obj/item/organ/external/R = bodyparts_by_name["r_arm"] if(R) - R.robotize() + R.robotize(make_tough = 1) else var/obj/item/organ/external/L = bodyparts_by_name["l_arm"] if(L) - L.robotize() + L.robotize(make_tough = 1) //legs if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4)) var/obj/item/organ/external/R = bodyparts_by_name["r_leg"] if(R) - R.robotize() + R.robotize(make_tough = 1) else var/obj/item/organ/external/L = bodyparts_by_name["l_leg"] if(L) - L.robotize() + L.robotize(make_tough = 1) UpdateDamageIcon() regenerate_icons() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index e1a1bdc1d8b..f8b8f7c84d7 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -16,11 +16,9 @@ return 0 /mob/living/carbon/human/isSynthetic() - // If they are 100% robotic, they count as synthetic. - for(var/obj/item/organ/external/E in bodyparts) - if(!(E.status & ORGAN_ROBOT)) - return 0 - return 1 + if(get_species() == "Machine") + return 1 + return 0 /mob/proc/get_screen_colour() diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm new file mode 100644 index 00000000000..2ea01647ec2 --- /dev/null +++ b/code/modules/surgery/limb_augmentation.dm @@ -0,0 +1,53 @@ +/datum/surgery/limb_augmentation + name = "Augment Limb" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/augment) + possible_locs = list("chest","l_arm","r_arm","r_leg","l_leg","groin") + +/datum/surgery/limb_augmentation/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_ROBOT) + return 0 + return 1 + +/datum/surgery_step/augment + name = "augment limb with robotic part" + allowed_tools = list(/obj/item/robot_parts = 100) + time = 32 + +/datum/surgery_step/augment/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/robot_parts/p = tool + if(p.part) + if(!(target_zone in p.part)) + to_chat(user, "[tool] cannot be used to augment this limb!") + return 0 + return 1 + +/datum/surgery_step/augment/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts augmenting [affected] with [tool].", "You start augmenting [affected] with [tool].") + +/datum/surgery_step/augment/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/robot_parts/L = tool + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] has finished augmenting [affected] with [tool].", \ + "You augment [affected] with [tool].") + + if(L.part) + for(var/part_name in L.part) + if(!target.get_organ(part_name)) + continue + affected.robotize(L.model_info, make_tough = 1, convert_all = 0) + if(L.sabotaged) + affected.sabotaged = 1 + break + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + qdel(tool) + + return 1 \ No newline at end of file diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index fb52fba69f9..0c45118e9a8 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -268,15 +268,22 @@ var/list/organ_cache = list() /obj/item/organ/emp_act(severity) if(!(status & ORGAN_ROBOT)) return - switch(severity) - if(1.0) - take_damage(0,20) - return - if(2.0) - take_damage(0,7) - return - if(3.0) - take_damage(0,3) + if(tough) + switch(severity) + if(1) + take_damage(0, 5.5) + if(owner) + owner.Stun(10) + if(2) + take_damage(0, 2.8) + if(owner) + owner.Stun(5) + else + switch(severity) + if(1) + take_damage(0, 20) + if(2) + take_damage(0, 7) /obj/item/organ/internal/emp_act(severity) if(!robotic) @@ -284,13 +291,11 @@ var/list/organ_cache = list() if(robotic == 2) switch(severity) if(1.0) - take_damage(20,1) + take_damage(20, 1) if(2.0) - take_damage(7,1) - if(3.0) - take_damage(3,1) + take_damage(7, 1) else if(robotic == 1) - take_damage(11,1) + take_damage(11, 1) /obj/item/organ/internal/heart/emp_act(intensity) if(owner && robotic == 2) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 151636a9a50..636942a3f77 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -46,6 +46,7 @@ var/obj/item/organ/external/parent var/list/obj/item/organ/external/children + var/list/convertable_children = list() // Internal organs of this body part var/list/internal_organs = list() @@ -194,6 +195,10 @@ ****************************************************/ /obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) + if(tough) + brute = max(0, brute - 5) + burn = max(0, burn - 4) + if((brute <= 0) && (burn <= 0)) return 0 @@ -848,18 +853,18 @@ Note that amputating the affected organ does in fact remove the infection from t return 1 // I put these two next to each other to highlight that both exist. This should likely be resolved. -/obj/item/organ/external/robotize() +/obj/item/organ/external/robotize(company, make_tough = 0, convert_all = 1) ..() //robot limbs take reduced damage - brute_mod = 0.66 - burn_mod = 0.66 + if(!make_tough) + brute_mod = 0.66 + burn_mod = 0.66 + fail_at_full_damage = 1 + else + tough = 1 // Robot parts also lack bones // This is so surgery isn't kaput, let's see how this does encased = null - fail_at_full_damage = 1 - -/obj/item/organ/external/robotize(var/company) - ..() if(company && istext(company)) set_company(company) @@ -867,8 +872,8 @@ Note that amputating the affected organ does in fact remove the infection from t cannot_break = 1 get_icon() for(var/obj/item/organ/external/T in children) - if(T) - T.robotize() + if((convert_all) || (T.type in convertable_children)) + T.robotize(company, make_tough, convert_all) @@ -900,12 +905,12 @@ Note that amputating the affected organ does in fact remove the infection from t return 0 /obj/item/organ/external/proc/is_usable() - if((status & ORGAN_ROBOT) && get_damage() >= max_damage) //robot limbs just become inoperable at max damage + if(((status & ORGAN_ROBOT) && get_damage() >= max_damage) && !tough) //robot limbs just become inoperable at max damage return return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) /obj/item/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam)) + return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam) && !tough) /obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) if(!owner || loc != owner) diff --git a/code/modules/surgery/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm index 2d31942059c..d3c297bc0c7 100644 --- a/code/modules/surgery/organs/robolimbs.dm +++ b/code/modules/surgery/organs/robolimbs.dm @@ -1,5 +1,6 @@ var/global/list/all_robolimbs = list() var/global/list/chargen_robolimbs = list() +var/global/list/selectable_robolimbs = list() var/global/datum/robolimb/basic_robolimb /proc/populate_robolimb_list() @@ -11,12 +12,15 @@ var/global/datum/robolimb/basic_robolimb if(R != "head" && R != "chest" && R != "groin" ) //Part of the method that ensures only IPCs can access head, chest and groin prosthetics. if(R.has_subtypes) //Ensures solos get added to the list as well be incorporating has_subtypes == 1 and has_subtypes == 2. chargen_robolimbs[R.company] = R //List only main brands and solo parts. + if(R.selectable) + selectable_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. + var/selectable = 1 // If set, is it available for selection on attack_self with a robo limb? var/is_monitor // If set, limb is a monitor and should be getting monitor styles. var/has_subtypes = 2 // If null, object is a model. If 1, object is a brand (that serves as the default model) with child models. If 2, object is a brand that has no child models and thus also serves as the model.. var/parts = list("chest", "groin", "head", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "l_arm", "l_hand") // Defines what parts said brand can replace on a body. @@ -31,6 +35,7 @@ var/global/datum/robolimb/basic_robolimb company = "Bishop Cybernetics alt." icon = 'icons/mob/human_races/cyberlimbs/bishop/bishop_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/bishop/monitor @@ -38,6 +43,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/bishop/bishop_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/hesphiastos @@ -51,6 +57,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_alt1.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/hesphiastos/monitor @@ -58,6 +65,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/morpheus @@ -74,6 +82,7 @@ var/global/datum/robolimb/basic_robolimb parts = list("head") unavailable_at_chargen = null is_monitor = null + selectable = 0 has_subtypes = 2 //Edge case. We want to be able to pick this one, and if we had it left as null for has_subtypes we'd be assuming it'll be chosen as a child model, //and since the parent is unavailable at chargen, we wouldn't be able to see it in the list anyway. Now, we'll be able to select the Morpheus Ckt. Alt. head as a solo-model. @@ -87,6 +96,7 @@ var/global/datum/robolimb/basic_robolimb company = "Ward-Takahashi alt." icon = 'icons/mob/human_races/cyberlimbs/wardtakahashi/wardtakahashi_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/wardtakahashi/monitor @@ -94,6 +104,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/wardtakahashi/wardtakahashi_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/xion @@ -106,6 +117,7 @@ var/global/datum/robolimb/basic_robolimb company = "Xion Manufacturing Group alt." icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/xion/monitor @@ -113,6 +125,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/xion/xion_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/zenghu @@ -131,6 +144,7 @@ var/global/datum/robolimb/basic_robolimb company = "Shellguard Munitions Elite Series" icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/shellguard/monitor @@ -138,4 +152,5 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index a6467584963..f11d123ea75 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -17,6 +17,7 @@ parent_organ = null encased = "ribcage" var/fat = FALSE + convertable_children = list(/obj/item/organ/external/groin) /obj/item/organ/external/chest/proc/makeFat(update_body_icon = 1) fat = TRUE @@ -60,6 +61,7 @@ parent_organ = "chest" amputation_point = "left shoulder" can_grasp = 1 + convertable_children = list(/obj/item/organ/external/hand) /obj/item/organ/external/arm/right limb_name = "r_arm" @@ -67,6 +69,7 @@ icon_name = "r_arm" body_part = ARM_RIGHT amputation_point = "right shoulder" + convertable_children = list(/obj/item/organ/external/hand/right) /obj/item/organ/external/leg limb_name = "l_leg" @@ -80,6 +83,7 @@ parent_organ = "groin" amputation_point = "left hip" can_stand = 1 + convertable_children = list(/obj/item/organ/external/foot) /obj/item/organ/external/leg/right limb_name = "r_leg" @@ -88,6 +92,7 @@ body_part = LEG_RIGHT icon_position = RIGHT amputation_point = "right hip" + convertable_children = list(/obj/item/organ/external/foot/right) /obj/item/organ/external/foot limb_name = "l_foot" diff --git a/paradise.dme b/paradise.dme index 71edb0e003d..023dcb1cefb 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2136,6 +2136,7 @@ #include "code\modules\surgery\generic.dm" #include "code\modules\surgery\helpers.dm" #include "code\modules\surgery\implant.dm" +#include "code\modules\surgery\limb_augmentation.dm" #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" From 9832d1b605647b6f79bd6c22717f5ab1c65fd856 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Wed, 21 Jun 2017 00:12:46 -0400 Subject: [PATCH 2/3] oops --- code/modules/surgery/limb_augmentation.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 2ea01647ec2..d25b9fdc329 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,7 +1,7 @@ /datum/surgery/limb_augmentation name = "Augment Limb" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/augment) - possible_locs = list("chest","l_arm","r_arm","r_leg","l_leg","groin") + possible_locs = list("chest","l_arm","r_arm","r_leg","l_leg") /datum/surgery/limb_augmentation/can_start(mob/user, mob/living/carbon/target) if(ishuman(target)) From f1746e011eede64ef040243020a34c3aa2f51382 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Tue, 27 Jun 2017 14:45:25 -0400 Subject: [PATCH 3/3] fixes --- code/modules/surgery/limb_augmentation.dm | 2 ++ code/modules/surgery/organs/organ_external.dm | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index d25b9fdc329..174076c5fab 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -9,6 +9,8 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 + if(affected.status & ORGAN_BROKEN) //The arm has to be in prime condition to augment it. + return 0 if(affected.status & ORGAN_ROBOT) return 0 return 1 diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 636942a3f77..7d544a61cda 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -852,7 +852,6 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -// I put these two next to each other to highlight that both exist. This should likely be resolved. /obj/item/organ/external/robotize(company, make_tough = 0, convert_all = 1) ..() //robot limbs take reduced damage