From 77519d160f3c27e2e3b5e32d989066adaf2ccf97 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Tue, 19 May 2015 02:17:56 +0300 Subject: [PATCH 1/6] Generalized head reattachment to work with all limbs. Now you can attach your useless chunks of meat back! Needs second step to make meat limb usable, use hemostat/cable/mousetrap. Changes how organs 'die'. Instead of damage they now acquire germs, 2-6 points per tick, twice faster after hitting acute infection stage. Once they reach necrosis stage, they die. All in all it takes ~7 minutes for organ to go bad without a freezer. As a bonus, you can now attach robogroins and roboheads (no brain included) Fixes stumps being un-cuttable, which prevented all kinds of fun stuff with replacements. Removed ORGAN_DESTROYED check from processing, take_damage should be taking care of that now. --- baystation12.dme | 3 +- code/game/objects/items/robot/robot_parts.dm | 2 + code/modules/organs/organ.dm | 12 +- code/modules/organs/organ_external.dm | 7 +- code/modules/organs/organ_stump.dm | 1 - code/modules/surgery/headreattach.dm | 70 +++++++--- code/modules/surgery/limb_reattach.dm | 129 +++++++++++++++++++ code/modules/surgery/robolimbs.dm | 62 --------- 8 files changed, 198 insertions(+), 88 deletions(-) create mode 100644 code/modules/surgery/limb_reattach.dm delete mode 100644 code/modules/surgery/robolimbs.dm diff --git a/baystation12.dme b/baystation12.dme index 2d7b5948f0..867686c6b4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1639,11 +1639,10 @@ #include "code\modules\surgery\eye.dm" #include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" -#include "code\modules\surgery\headreattach.dm" #include "code\modules\surgery\implant.dm" +#include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" -#include "code\modules\surgery\robolimbs.dm" #include "code\modules\surgery\slimes.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\tables\flipping.dm" diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index e1ebc9fdc1..520c2f9920 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -68,6 +68,7 @@ name = "torso" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" + part = list("groin","chest") construction_time = 350 construction_cost = list(DEFAULT_WALL_MATERIAL=40000) var/wires = 0.0 @@ -77,6 +78,7 @@ name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." icon_state = "head" + part = list("head") construction_time = 350 construction_cost = list(DEFAULT_WALL_MATERIAL=25000) var/obj/item/device/flash/flash1 = null diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 06dd521f64..3c3a90c331 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -53,6 +53,7 @@ var/list/organ_cache = list() if(status & ORGAN_ROBOT) return damage = max_damage + status |= ORGAN_DEAD processing_objects -= src if(dead_icon) icon_state = dead_icon @@ -76,8 +77,10 @@ var/list/organ_cache = list() if(B && prob(40)) reagents.remove_reagent("blood",0.1) blood_splatter(src,B,1) - damage += rand(1,3) - if(damage >= max_damage) + germ_level += rand(2,6) + if(germ_level >= INFECTION_LEVEL_TWO) + germ_level += rand(2,6) + if(germ_level >= INFECTION_LEVEL_THREE) die() else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs @@ -86,6 +89,11 @@ var/list/organ_cache = list() handle_rejection() handle_germ_effects() +/obj/item/organ/examine(mob/user) + ..(user) + if(status & ORGAN_DEAD) + user << "The decay has set in." + /obj/item/organ/proc/handle_germ_effects() //** Handle the effects of infections var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 4bbb173d2a..84775c2ac4 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -175,7 +175,7 @@ var/can_cut = (prob(brute*2) || sharp) && !(status & ORGAN_ROBOT) // If the limbs can break, make sure we don't exceed the maximum damage a limb can take before breaking - // Non-vital organs are limited to max_damage. You can't kill someone by bludeonging their arm all the way to 200 -- you can + // Non-vital organs are limited to max_damage. You can't kill someone by bludeonging their arm all the way to 200 -- you can // push them faster into paincrit though, as the additional damage is converted into shock. if(vital || (brute_dam + burn_dam + brute + burn) < max_damage || !config.limbs_can_break) if(brute) @@ -369,11 +369,6 @@ This function completely restores a damaged organ to perfect condition. /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 diff --git a/code/modules/organs/organ_stump.dm b/code/modules/organs/organ_stump.dm index 728f9cd1bc..68201c1413 100644 --- a/code/modules/organs/organ_stump.dm +++ b/code/modules/organs/organ_stump.dm @@ -2,7 +2,6 @@ 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)) diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index ad47b14429..782e238e1f 100644 --- a/code/modules/surgery/headreattach.dm +++ b/code/modules/surgery/headreattach.dm @@ -1,33 +1,73 @@ //This is an uguu head restoration surgery TOTALLY not yoinked from chinsky's limb reattacher -/datum/surgery_step/attach_head/ +/datum/surgery_step/attach_bodypart priority = 3 // Must be higher than /datum/surgery_step/internal - allowed_tools = list(/obj/item/organ/external/head = 100) + allowed_tools = list(/obj/item/organ/external = 100) can_infect = 0 min_duration = 80 max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/head = target.get_organ(target_zone) - return isnull(head) && target_zone == "head" && !isnull(target.species.has_limbs["head"]) + var/obj/item/organ/external/E = target.get_organ(target_zone) + return isnull(E) && !isnull(target.species.has_limbs[target_zone]) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts attaching [tool] to [target]'s neck.", \ - "You start attaching [tool] to [target]'s neck.") + var/obj/item/organ/external/E = tool + user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ + "You start attaching [E.name] to [target]'s [E.amputation_point].") end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has attached [target]'s head to the body.", \ - "\blue You have attached [target]'s head to the body.") - var/obj/item/organ/external/head = tool - user.drop_from_inventory(head) - head.replaced(target) - head.loc = target - head.status = 0 + var/obj/item/organ/external/E = tool + user.visible_message("\blue [user] has attached [target]'s [E.name] to the [E.amputation_point].", \ + "\blue You have attached [target]'s [E.name] to the [E.amputation_point].") + user.drop_from_inventory(E) + E.replaced(target) + E.loc = target target.update_body() target.updatehealth() target.UpdateDamageIcon() fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, damaging [target]'s neck!", \ - "\red Your hand slips, damaging [target]'s neck!") + var/obj/item/organ/external/E = tool + user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "\red Your hand slips, damaging [target]'s [E.amputation_point]!") target.apply_damage(10, BRUTE, null, sharp=1) + +/datum/surgery_step/connect_bodypart + priority = 3 + allowed_tools = list( + /obj/item/weapon/hemostat = 100, \ + /obj/item/stack/cable_coil = 75, \ + /obj/item/device/assembly/mousetrap = 20 + ) + can_infect = 1 + + min_duration = 120 + max_duration = 150 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + return E && (E.status & ORGAN_DESTROYED) + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You start connecting tendons and muscle in [target]'s [E.amputation_point].") + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("\blue [user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "\blue You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") + E.status &= ~ORGAN_DESTROYED + if(E.children) + for(var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DESTROYED + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "\red Your hand slips, damaging [target]'s [E.amputation_point]!") + target.apply_damage(10, BRUTE, null, sharp=1) \ No newline at end of file diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm new file mode 100644 index 0000000000..400d80a7f0 --- /dev/null +++ b/code/modules/surgery/limb_reattach.dm @@ -0,0 +1,129 @@ +//Procedures in this file: Robotic limbs attachment, meat limbs attachment +////////////////////////////////////////////////////////////////// +// LIMB SURGERY // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/limb/ + priority = 3 // Must be higher than /datum/surgery_step/internal + can_infect = 0 + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected) + return 0 + var/list/organ_data = target.species.has_limbs["[target_zone]"] + return !isnull(organ_data) + +/datum/surgery_step/limb/attach + allowed_tools = list(/obj/item/organ/external = 100) + + min_duration = 50 + max_duration = 70 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ + "You start attaching [E.name] to [target]'s [E.amputation_point].") + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("\blue [user] has attached [target]'s [E.name] to the [E.amputation_point].", \ + "\blue You have attached [target]'s [E.name] to the [E.amputation_point].") + user.drop_from_inventory(E) + E.replaced(target) + E.loc = target + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "\red Your hand slips, damaging [target]'s [E.amputation_point]!") + target.apply_damage(10, BRUTE, null, sharp=1) + +/datum/surgery_step/limb/connect + allowed_tools = list( + /obj/item/weapon/hemostat = 100, \ + /obj/item/stack/cable_coil = 75, \ + /obj/item/device/assembly/mousetrap = 20 + ) + can_infect = 1 + + min_duration = 100 + max_duration = 120 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + return E && !E.is_stump() && (E.status & ORGAN_DESTROYED) + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You start connecting tendons and muscle in [target]'s [E.amputation_point].") + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("\blue [user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "\blue You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") + E.status &= ~ORGAN_DESTROYED + if(E.children) + for(var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DESTROYED + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "\red Your hand slips, damaging [target]'s [E.amputation_point]!") + target.apply_damage(10, BRUTE, null, sharp=1) + +/datum/surgery_step/limb/mechanize + allowed_tools = list(/obj/item/robot_parts = 100) + + min_duration = 80 + max_duration = 100 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/robot_parts/p = tool + if (p.part) + if (!(target_zone in p.part)) + return 0 + return isnull(target.get_organ(target_zone)) + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + 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 + 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["[part_name]"] + if(!organ_data) + continue + 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() + + qdel(tool) + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + 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/robolimbs.dm b/code/modules/surgery/robolimbs.dm deleted file mode 100644 index d8214837bf..0000000000 --- a/code/modules/surgery/robolimbs.dm +++ /dev/null @@ -1,62 +0,0 @@ -//Procedures in this file: Robotic limbs attachment -////////////////////////////////////////////////////////////////// -// LIMB SURGERY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/limb/ - can_infect = 0 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected) - return 0 - 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) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/robot_parts/p = tool - if (p.part) - if (!(target_zone in p.part)) - return 0 - return isnull(target.get_organ(target_zone)) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - 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 - 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["[part_name]"] - if(!organ_data) - continue - 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() - - qdel(tool) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - 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) From 05975d78b12d3238c5af24c6db1691a008cf937e Mon Sep 17 00:00:00 2001 From: Chinsky Date: Tue, 19 May 2015 09:19:13 +0300 Subject: [PATCH 2/6] Adds a portable organs/lunch freezer --- .../objects/items/weapons/storage/boxes.dm | 12 ++++++++++++ code/modules/organs/organ.dm | 7 ++++--- icons/obj/storage.dmi | Bin 59802 -> 60148 bytes 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index d5af4b2bc7..8dc4b50f4c 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -628,3 +628,15 @@ new /obj/item/weapon/light/tube(src) for(var/i = 0; i < 7; i++) new /obj/item/weapon/light/bulb(src) + +/obj/item/weapon/storage/box/freezer + name = "portable freezer" + desc = "This nifty schok-resistant device will keep your 'groceries' nice and non-spoiled." + icon = 'icons/obj/storage.dmi' + icon_state = "portafreezer" + item_state = "medicalpack" + storage_slots=7 + max_w_class = 3 + can_hold = list(/obj/item/organ, /obj/item/weapon/reagent_containers/food, /obj/item/weapon/reagent_containers/glass) + max_storage_space = 21 + use_to_pickup = 1 // for picking up broken bulbs, not that most people will try \ No newline at end of file diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 3c3a90c331..0e4e9e35a8 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -60,10 +60,11 @@ var/list/organ_cache = list() /obj/item/organ/process() - // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? - if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) + // Don't process if we're in a freezer, an MMI or a stasis bag.or a freezer or something I dunno + if(istype(loc,/obj/item/device/mmi)) + return + if(istype(loc,/obj/structure/closet/body_bag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer) || istype(loc,/obj/item/weapon/storage/box/freezer)) return - //Process infections if (robotic >= 2 || (owner && owner.species && (owner.species.flags & IS_PLANT))) germ_level = 0 diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 377d12b4ff09399e07bd8ee2cf44cdcb51956eb9..e754acbc1d1c056cf648e0b51815b38475fa327c 100644 GIT binary patch delta 19336 zcmZ5{by!l}w=qSCMw|sp4j3 zalny;Quo)XaY0_K}}YqF@}P9Y4a7hmBp`T&QvHqeHsRzt#+iP*@0X1a}DY&=bt^;h-$0&eg(QprxJ`~GOfcC zAyx{YfsCe~Ek2B+&VPPss`3!1)P!oJ`W%;*%U&;{LT+sbpS<-L@A>PzsmB7G*q8Q> z3upB~DR2@i65f85d!@lA-a`pcuGL(n=~5&SXQ6}9MaBMb3Tx_tds=Erb>mj(&Dz*1 z;niY3M&(E#>iQPNIlbc0tHgVbrha}uS!ui*jQ3VEXn=CO@$R+q+_&ut z7yU_OIh38GL37VyB)sv$=8y_TW9H+QLL_3J4QdhihsdlfM&=Li1~BYipb4hMIXBD9 zRqAoOpJyj*=)0}BkXHGkIn0)=w7Kb=B$;-XGR6mQl^lX}wt=_Lh2$=B!l{N8#ib6m@0Q<>|?U&%5V$i(! zG0`W}l6=ZBenb5H(%qxVwwFT8FBc4$UcG*uv-n!ZicU`55pz&h0BCvtSJe*&M^(z zMZI0}m5GRd_wa^z=SNPtHrr}7QnRkql%7X&s%UG4)j%KyUSOqO+h8#I_qLEL5jr}$ ze1w?DCId`Dnk|k662YWWDvC6DdI$QHm{?c~9bTLnJT8!84B91w0vm{fG zrekD!@{T~w6|4rOOQSr!syERf?XEdILY2*L$i$ntV`G6y?-t~@tRJ!}0h=RQgamv< z`t|D_|++_SyWj49(!FF#L4 z%dr?1K*dEx|EjTOihn?*1-s@?+#I#is`TvypVA%qOU zp09Lt@x0n<>guTtQ0X<=dg|jUA>G5zGgd89YzwO8Fsa=#e5$z6&Dupt?cz{h3Scy6 z=7LW;9Q*y?ACHov8oL3j-*|PURi|}{FWAp%?FTBQBf_6JR?ND@Y{jS6oOJxGEErG6>_KJ zusI|qUeX_s@n~77^E1k69ANq+z8$YeUhb&%3;DJu_(11y#+iKtTDqs#X*7NU?ys#^ z+ZRqduaD-YYE5M7oUSb``k5%de3{F@yt|$Qp?COU6i4=|yGOWX z{7b;(<9BRwm?+E|yx808uLM!dFKmPCYfmAU2`v%5XMPkK!B$FjM)}CWLGa_Z-^Ulk zysom-R^we1Xyxg*+@C&m(+#SL16_%0SeTf9M@MJ9gYp-l$yWVvQXVZS%Tlu>6jjT` zhj?`}$6Nhr$XC5ii##S){vjKSi5Fc5UK5@S24)l=_27%MSzHdeA3v1VsVMF4?Kwdq zCPnYQyL(=2V!2WBfpDFKdfcq^GwbgTiYh!~X54Vi?Q?OO5!3{OfG0JeT4QFtn44F` z-JPqq;B!3w-2~-H?gF!g<)Aq4pAzaz&(I-Fc5^S3f)8Krc8 zVsCWjWk^hfM(Wogyti-PjyF3Pv9Pe1FEv)ISnl2z2M9RV#xl&}QOtxFURewUIx)`r z(3`R4#F|E;7_TgcCm#Sp$q8Uy_GeqMaX72GI1+Q6jn^9Gnuf^;n#u+HJ5NoZqgjHC zfZMEhl}S2bFl9>hj=)YMq`7T^F+@fC{{C(q?@&R%N}O#mPR=xm;E!=g!SO+3q`3>9 zLi*=2QVBkQA#L~ zKHscwkEDI}6~I)_B{-30opHxxH-Z>n*S#4)`n+{{b^hgR)yK*U+La&m&vR-Q5dvX( z0wwJbA|c5rBd|%NgM37Vq9)7Es1lW#U&TRd!X{a|J2|snZGG1l01E(>EDG9ijgw^K zzlp(V85#6hN1wzhB9ssF=qGwLThQ!sm7CD=C42%NIp7 z&uvnwGp>NrN0ADQ#h$p`JsTgA3_%JF;V*Q}-9@=qXk*|;ZN_2CJ66KdI`^gJ_KK>! zye)1TU}%`&)ugk4QMeU~hClMr{=YVjj{G}kQllal)L=EVk5-=dul;ym;M=sjBgCGj zJwjvR)J?nM=i-cL?W6z1d;7#o^YLoxdhw5QuUq%z#J`68amS|y&$#o;F;PL@L3{bx zr0zJ+f7-S5;Dc~qXr6I8z%@9_SvXG`xo+M{`wbNR-*;A0$L>ZkvsOw`1jjgRQX_q- zWptv^@M+bPn3VIp-r~vIyq}!I(Ug!VTD?228w*4yo3{0Tn;}Rh<<$S;BvqWrdt1+X z^$tg5Yin3`gy3dUYVL3j{MF9eCk84-WCKGxQURR>79gks@|?tC*xVwR%B^T^NfWwG zajeQ^PlBnhO(d39$A6ph9B4l+a(>=ve(Fs)(gE3_%uY;{a7GbxZ=UFkw+Pp;33?S4 z{&{_AMMx?-c%h5d@6w)oYiHQrExm;+snldWC2gLYyr>UHD-o#(X&XCRQ8gJYz zzJU84cN@^LNSbyNW_Vg(V``!Av)AKkbD7FvlbQnKJ!@B~x_>fD9!qMsl6sO~d*9jE znc@p+*1Il+Z|;9Ky=Sb*QW}FsH~j^k1mG3pWt?&uaO zc=-c*2{=hU2>^^qf}^qjs4ax!TzMSg`1$~D1adt;$|s9YR79kU+7l^ukLZ1pcntZy z=aAI!?zhu2QsELZ!G}jjGC$C8n!Ta5*5zY@@OE!9#?HrDp%e~E%D~**Pb0GK3+2C` zbxDv(oXZSSBh@wsFR=Cb4+%rl@tQN{0tn zvs^o>>O8H59nO@QJl#&JKRY+B!YExrI_oX3Z|$r6UHR^h^izVs88XxFtNcTbuF&z@ z^2!ScN+nT^vY?F#8Iq^motg{LH_e5SLqY}0ev5eEVnLosPH_cIbD`%R`ekkZ{xXZr zB6jBN?BoYJa`I|JncDqt_WpRj_;hQ)efyV0pv%!Lw+|Vv;A1tC;$r=e_Opr8C8WFk zE&~tH4_#)$7T_-`+I7Wu$UPOL1_!=;>!>A4gDGuRYJL*b+ZiO%A*B7*H4quOP8G_(KJ-J6*@5v|uXSvhEM%W;k zWhUHQ3D~($-4hf|ffM45qB9_^81(&iHw?uZ119sOgq@w)YHDiYlaeln7(1El*T12W zyiIyW!e#%F*Y$Y4FwOQ8HFbzle^d?5M4*g+-Z%91sXKRn4x99Zy^Wt_1TMqa=!VujyNHfh!+dh8&5%%G^y}+kTgtU$4 zh@j`@<`PS1Wn_#rf}&ZP70PvX#-zc4HUo!TvT3 zOqx6ebHDbpxlQT8p&wctyQVWo*Y3w+%4=yodrP;ViF*bOp|y#oaN>(aRui|^v7S?I z33n@F3hgU04~E@>X^N_50KNyD7^{phN@0-NL9RH z36a^L4zm3fu&=aB@1BO((z@>J{^-Oo!$lSl(%N671lCtmFHg~j&1Q(4kc&%8yVusT zET#%EMpdPB2w(`4IydcW$wE{_1f`&0mhaO&atM_!9?2BZUzgRunJY#&76l3$ox?at zJ~5)Rd(seXG^IKfCYP)sA+?lv|25zKfXIQXyBZiefd)B-2=2#YlpWmK+GdI`HjV-| z&da<=%Cs4rhBBA@UN>|}jG)5yc3pWDef`m$p(JiZSA|X!6^D8RxDgr0>eEJES9=w> z+wDkQq5yfq`;5%d|4b(J^(u9&O8=xqj92`bOkr2136eL6B?zr0jmw2D*0p9cdgCS; z!1BHj!5U2$v~%S*lhd>S|AKYwzvcmPti9;eym>c<{*h|`wXIcs%2V&<0B0dH8@Vdm zM&#xi*$7%lmYnt*_;67`9#uITXot1wr}6ZXFTb=1T)7JhF+02}3M?)*eR-f2o00K@ zcF&Y#o~EgYCS|4Rb=8^wr?od8APm7NlfcQha|ntGAd6Twgap3i$B@G5(F= z@$&LAL%PmNs`huS+&sSSi~?!Xkii0#Zq~np$*|fQuTtS@+hG80h{I4LX888*Vr$uH zj2}rhg9Xj+<9epo=|))<7I-`F;!FP637^M>;rF!`oSvI9F9=a&>a*>Q?|{Y*K;m#M`iVtu|t z(nPQmZMrMpyxrF1&3~gYm{l^B^#%@GE}e>(h` zWjpK?Trn_6p9qZ1%?fMmT+*MEbacwf34GgpVJY$+{IB*`|r$-Qmw%=W$hj7RDN z43RkMG8xy3Z4d3dIMi~eDcr8SH&I1y_O?GRUh_1MV1QS;ml~!tTVixjAATabdi{jK)e>$b1|=4;ewP_Ek8zZF;fDE} z{uxO^!>6@mQ`7EP=%REP`@+J4qp=n3n?!6LUfw0^&bl#BnEn)Q5gy^9Uz`}X>lr;; zJ@Ua%V9H`@mnZ4dT3O0#MxWurcm2)YU^$e;+$Ec(rb{54v(_8x$Wh_Z4;!JBt&=WO zn{gHrLPi9aOxL^oAz-1D@b~SMsWz;&^Q+#4?Er#Fj-GCs99GriH7$%tpC8D2I>qpB zS0CsTTA~fw*ZXnJ{*dj)aEzSWDT#fXa#00#1%wA+{Yd-c%Sk46Xjm$%^QQ9;Q^3E^ z{&>z0Ier-`xm3z!UKr{mYxqd6LCJ_lm^b~BpO7^=IL7Ih+dBaY%FmxaAPo)<#(XlA z(CqMRu)o?@T5PbAP*siBt#+&ZCGh#P7%UTU3{2!nXd%YW@3x}Dfpc2Fhpq{rdo2-M z!CNdN$c~T3J}wN(XuXKMdovRX`1l7Ia=Q0;c{{f0qb7Tph>)Lt}` z6K0n^{;{dRymc=6BO~WeDnKr6V3%mM_{KzZF-Zc*P2-?Ibo<5aMk<)Rqp|P%&$*}V zR!RRUp)b`=Hm)hbrhAaBg7;y@c{TN@y70|VltygLq9s-%oBjczl#~=hf?!S#j=S$F zoICzzCkUP`6ym~~(k6*kbc2zclGSEvE&~!i5m=sSBtiz7_JCJI_}5J?DJ3S0y!WmS z_rb?CE?usp1h(kwvKH@uB#EMgWU&%V6#CDv-gG1FceJ$WXgd`};x9h`{cG5gz=yh# zeT0}-EGkgM(;La`^!f9;8$-kn<9f*Q*$)!>8v7gD=5-mqZ3p^0|NszTK4TsEp zTDuzlUUx;G3b5BoZ@qXj`-4^HCHIk>+@IZQ7Ri22&n*;qEcu@LRPPuEt;J^m6}UzY>{t!9E*&8x4)Rs+{|@z3ans#)74G4?vCAf1`#+=NrCMv zU31j7zFP9diD-kxJyw|QGCug29ABziT!j|khGY}!>6jUsNzYp=dL&ezhfd)?X=vG2(f(Ow-c#0607{WER>KdGt?dcvchOitxweOS>Ob1;tFyu7dc zuYx{ySyd6B3~|M3jf8PeF(WH<+%zsUw|^=8GOI;Ry<{zTe{4nSb8ZXeohGbdfi$q` zfAtABjU4Vn<(2HN#!i^Ad%Nc8zrSxt?4w9W6uZ_MiukKaV0_uVz-eUB z&&hRm0ZW?(XndjpZ%g)BS^QDpyLgUpNZTQUw59z!duPT_BdHDKi+F!VAS?@}w7HW? z@v?!Ame%PeRz8P~{h)18K*6%?U~%b;+J(>_p;SGNDw>9GaD;t^<5?=yRYrZ_Pq&XZ zOLm9o5+)%*s*xBvwFr5^#Ke5h?U>)=`EQ4wnx|m|rLb9@(n{2kq&=`W9mi`^pxF`w zL`ZhNibNMwBPpY4WB}ccT(1YoYmxXfmgzOh1j*fpztd3Nzb!AaEz2#7Njeca_M%Qd z!AoQ=$QZ1UNzfl(n4dphsmJ?`Zr;eqXyX9+y|UqWwh+>Lb!&-zoGLosAcQ^~u-h+^ z&v2Af2{i_Dz7@1k0lI#6Vg4xZ^r=Cn!aVjC(*pveCWu;J0+g5RvUe+muql+6af6gv zz|2kOL>eW*(zu+m z1noxyl#sACL%2?IUWHGODdF#5NwkDnV@DC4Ri1NN;AmAszK&zFH&s8IHvOpFGY-=Ua*a^4cTb@>V8%bHDa!s}?cO8WksaJYo0iP)vkNH<BQ00RdToZ!SCIqy*Ch;rTU< zS%4sVR%Ze9nYxngzq6cv1z|LOH!^}AmQ{s>hf~ndgdHDS*OgjeNSOB29#gBi<^*V! zxxRNDO=d)Tt2g{^$p>M?KFG*?a0A$ptUAwk+NMqDy|GMRbj3(JAC+Q-s0WRo~en+#h*@*(BZGSE)kl%b2)k^&>@eM(-FXV-n)QW zePPuL5ko-CXJnV>@8BTIl7Q>+`<1pij!vo0lst*(PuHjpi6o4n(TW_KZC0cQKu&)C zpIHmi-;?Y4Csm*{SG7aX1fZg%E#K&{KTh82e9+zJ*Kg2=j;;TOKJBdWgVrYO(fcKd zW7U?1WHhchX?1XnJO*8|nhLJAO2hG5ZrJU+aJAzH`A1y8ned_zisO>a^B@`mpc?z2 z4{z6b)h((Vn+I*%DMTfL5B6-DRs!$H%W}>j1p1$bX3?M`cLBhc3C>1Yn znp_$O^Y=e5^x!lz3MjF$vDlMbsuqw)1eX!0hY6m5?_={a2X?OE@qCSlEntm+_heL* z67`C!S%%Bw4(vO)CeY-HYHz{|kcjQL)GDJ!c~a!BuD=rv@Y`YwdU`?5_Le728*{xZ2Bi_?zOX|HwmHMT)WF8-LHbk|*j8^!u~@zIXCN|+=+3Di@1Z3~SK zN5?TponEKb=fTw@I3pn7nd|9tXmm6#ubfRz6^o0GH{c!1obpHTZAlE|!oj)&}w4;(E1<;&k483|aOta-m3pI~=k)X+0!r!?!O@CN5|PeH8#G&!Q6 zH!E!MsCBb{=UPwB)|MW3XqJ3>Ehw$ZvdIt!BukW;{cV@6W3+k6{cFpzPgAVn9?*jc z?~X0EMWE4+mdF8dY!XNL3Z?%(9Ee|R+IvkQUTrZ&g@*n9Bd*IrwINCdZ@AL>M$gY3 z=3*2yYy-q@gK&RT58@$w5*}fT{i-lq=4;bd#T99c`Sm&-p6Uv+G_5Y(+pCK3ol=a} z{CpXSI1p)Qq)BnZ<$)Ki580R2eFTStpPEx}ONE zp;W^w<+tewLwmW!NiWJ5`9{9nBRVBS>-x4_t4_Bge`r4J8%eKmy`XU&_&P%y$0Ft< z;AcPJU1UFCG&2@gB+L9ls$q&jOkDh*BYe~F@Z!abY_BF;NT;74Qe)MMgrZ{1qxk;W znZlwmNGGXjprtFVm=))haEzXaMF7gFiL4`-5cbu5Ofc51r2g%RpR z@6>zeg+~i_`@?#X_1ac{QISN7SUYa7wSnRqP3HYE`GU8e9;yZG5efwVR_J@tG<|jS z$c>_(;)D@VWQ7Oq&*roBz*Z!VHbmT#I!^;5 z!Er!M$Y1e|_+vnp^pckFG~+#XLoo5Uv)%|LaS@ke>CLiAiy9x|fuhqq4cU;5ew(k) z!aTB1QW%pZx|Hw9nhK`1p33{Sq6KXgE4wJj@y{($I~=nBHrVv9QNdPNLQ$2dB^KJY zyt;H;LTNz(%_Txeno9X*=G%?IhIbLr?i+qz_HZWa^*Yw?XY1%oy5AAJY&^S&`$^W) z_Ix7`Bd7lK_{)uRW)@>=d0@A<5ZhuF>-S;VyTnHOvqwn=6Ae74W=wlqrT06m8k_q= zkpvl4l$C&$4S*bZ)sssWpBQ2?2J?By&<+v8@xrs^3ZHy*3?n9DQ3Ks`;M~R8xe`wA zy0{Y1t4nBuy;}^SwIxS<=@v+)xd|w1F`EzT4t_-c`56(F*di5@0mZ7~1l~ z4JrG~BH$aYa!ZjY7>Xu?2X;PC&S2FV5Q%08l?$qT1hpsM#cmX!G7h%J{$3PG>BGNF zSQMu%`(xGwYeD~TvD{V;oC+a{^W8E4Y5Fx&A+~#|(w7eupbpGMoqL7~^ke!&Mja~2 z!h1wq5KEeMbZBU6Cke!%S?GjjA`yas9x{_N&0p{~D27-}rLXzmVgEDuTMrB}mjrk6 zuMDiEATTpb>J>iy=a3Jw12gtt7L{H9wCZBY^ra}IzD6Km*}9h+Rz4;YbF=-dkidj~`g64eqh>UL4p_=QTPiK4sV`#~GLlf-&8SJ_k4Um4w-RHcgLxTz{ z(!(G5Ek=R;XwDx^|Dt$5_%}E1KPkZD7zsKJZuDBJ7*4&dKNSIY>2h9U_GV4HwNQ5K zn>_%1ROcT%pUMXPa%SDlM$;{>MRe-Te`T|M*QkD^cn?gJ#dFYiCqqn6p5c-3ILE-b z{^5c@AXN~>d$M-kGS&dUgW;ed;Vm6~htj;X0t^i`HLZe+%gZ_zvx;gqLyJWzR!^O@ zI(5y|Y8($*r&&ydJiLYdR7*uTuOz7xgZOlE?;B20R*2L7bFFFfsplmZM_vMLaU^OZ zCD1IEEyAkZ5>S94V+Bo}u=Y#fwhA(V=5ZwC*FHj7|AUR*7dAS#dtt-1GM;x8Ta49i zWB>zMgFaFAXIpVxkn4W$2QMnlMho*P?~V#!=7YV@#laweh1A0nW+SZ=CCW3+`#O7l zZx7oKBm07WR83H3IFoA$xvIQu%KM&WCsaqZzp|LdQe zO0an>Utf9qo&K{@sPI#21>vgs|JTu%HDhf<-VnKqKR4@6=X;GK zS7|YZAis*J8imU$Khn-a3@PcI@IN5DrO^ESvBH+C0~-!bF>ehDo9#P^9s|HJoc4$f z1lS!Osr?rf*Z((lQa#CRhRf?hux;0Wp>qAM64KWHUh*uiw<8y|GsZxCSIFD)4*sF< z&d!xW>8$JVw?Pqj5(8Wg@fCKmH8zz|g;W0!=!q8bngz6U1mc_GAWz5~7=gE$eU7(~ z#GOzk@TG*}fT{zyuUQel`140pPS)#p04l?^=9qWJPI2_?v~Lh=c%}|4RsKr~gy1>`XD+LMSCG`!;swKY|P1kf5pP-YD(mr3$Z=c)+^~U1DWrJ)7B{!a1oW1 zv9ahuX$L8ml@OOo^?KlLsrpX}MC$uN#YK1j6L$63<~N1+PFC%TAS!J8px-(4@KHF=gr`v05obxtM2qSsHJHrQgLYNH5E-jUwy}7(p(UVt3q#iLhzKnXu z1D%`Y5Wj!_mosHfm=*`RT z0YKdo}ILH7b6jykmAjzQQkQoc!x}O^2dGGYN_jO-#n8cbO9mr6ux0oxM-rxCNlTa7 zl_{E4dWq*M50}3CI7oNF#aR$V!uQ8lm;ul-D%Vf6@z?HLIJ+H_F6#qod|w6XMlV*- z{HoUT_d37i@PDgqnuGrbVGO>tEsMRT;bBLv(RZ zN)4&-ao^b?A3j}@Was}j?O&n(V4YIs&i_z&0kLcPyNkZQl#kAM9I$8ixUlQOK(GsJ zP-`F1wrD1Qk?=b`KKI4U@I0-%BHI^Osr@Ue{g^@5CYKt~!#m zt-1S@r<>E4-~)QJsa`L~P{@GAzrvpxE_fIl9sNDyRP~lm?FpMp^@&aljBeS8`)JBr zu~Xx0)F3h3WRk^dY$p2a{^+xK#0vm92ZKtmW|9t~ojTGaE>JX;Cl;}C z^}v{3i14rC6W=1TJ4&wh7k-ov%NDt~i2jquH;*|ZkyNwrT@hVXk+y?dQ_%PN=ulQF zfBrj2cBg+7`<|tc`-Skv{X9zmZB@@(>+Rsi96t=~&-LL$g+eAygD9h060Bgt@40;C z5yPqvJ<*hhHv9%(?;BDJ{evpka}M|@$FJD;dKfiaeXw{Ng$5@ zet+=}RB@FsSKI!s4v`6!tvew(VRgUZEG$A~UrXI@dp|yomQN;+K%0)(LcRIfPYH;L zyl4-ii8w1O^GRFKnLR5^pX>y#3Q{e*IC4vl^s1YPHk?QkdRlOZg)(2p3!CU$6w#EroB&qHLk%-!abnb7iX@*`na=?{)f&+pf35_FBe+ z!&~}KYhJ(Uc=SDYYwK@w zIWfI$&I8;hy%G9a(%V5k;~tUKLOOwdfx578(Mg}17izhxyJ`!r$3jX`u`;`-oh(Kv z@u_XLX4*K?kyTT}j|$5#z~?Km8EoocCw`BS9D%yQ*28V>n^0r&;)$eBziLYrZ)4gz&lBLf3N&I5rB zf7J8K(&~)@L3^SalRVV-TOm4oXUjEHrw;VkTnK~fZa*)285~832p3U;xqgbl^)2hP zxe){A6S+YWSIC33;hN3oa!q9oJ`@#8S3M`9{n`%pAiUO_^1|8;s#AXU40yd)8epc~ zKKN$JDT0eN4u`%8Pw^TF{WfiXvFDqI$LB9mv;1|LmKN1J>)gREHYV2?O!mvNNWyuQ zdq;DH%!q5(a=kw*POCXw50t#K49fV9bKWF7e?sxDbGIf8C4lgBm| z`i#VBGZ-x`?X|q-wdkH$r{jH#7kk^P%2|h5V~27bZBOw81zUS6_u1zPDpuAh%fNux zHQWLZHMq2x_R3#MRUtr5FfE!8JmT}y?9;1Z{vD^gR%n@@zw~3t)djM5@rz-k%BstI zj-wuHvEL~DBb021p4^KGpT6t-Vr(XRBIR?BF(g(!dG2zaJugn{usN+XQU=PHxaG+F z3!nM36Dy-%<$FW58sUpvALc6*VZ5?&J}mHRx&1Wo<(r~~gmMpn(V}6*2q5u&hwv8Y zyrC{0Ywdexh+L3ffDutimavv2N}#o$x*A_yGZQ%3%^1|M}P%nuQMbp|(C z=w)QbyLWr1PXJ9ni^@R1S)p@b_kZCD)?j=Swda~Rh6aAbCM^fwmW zhs=0vc1E0!e6E9F4aU^~C>t0@f|!0l*CjmPEm4`S63sX1M?t%z7J;%Q2M=D*?HgP~>R{iP{Rgt&KgAPln4pDy(FwcK%! z;PcI(fX-;#NE#j_{AAgLx9BE#s{8TM8?v`*^5lg3jA^sQZQ*KAMczcXwQ$lK{@1Ouw2+~@ zyF0}E{e}YxJ9q_>uy9i#lZ0eGKMwOQ)OM`c6J%nF@k83%Lz)%UsnoAbJOfa#xN|ak zS8Cd%)Ad3&djBM0Gt#@)xN5ca9Nfg}6garxQ`$wNoi~C-%jkKry@GMxQX07!%bS@H z(kFf7^X7^Pp%SZ)xXCFW_N!qEJMTk&5hTK_DDH2E`rg~z+FFklPala2<*f}3_(npil&j28^$F#rP_d)sl~bKT>S_%T-{16lEB zMk=tX-K`?1XFW5SNxnfAF@M5}#^dvQyKi9uSeF6wN%|3;xbhg1PumbI; zh~9iM?Cob%t*$o17ZeR@8v+$H#czn&{=cU!WgXwxR=+#=N=>xIYfB5dU z&UYEd;d#8_IpsZlRiGe4QOfvq-?s$4ErdQZ-Nl-P&XpCqwEMH}-kMFj;g?*h>JX%U z0Erq|(M8wvSey5=Raka=pdk(&gj+)N zWXXD|rmTU8CfGJ_phfGtO>SenOu$&3?Tjt4QbIid?ta&6=eb&P3zyh%R5dq-Sznad zaREh``Bpq{pr=oAJ{bmP4%dRM;42%FP6XS<(rgee_0g}YXbztFbj$>K8X_WK-MXh42Ry0a@a)i{&>_ruq=`hPtSz zC?G0obSBukEA#Ed2%_`^(fWx+935+$&V>H+YcEvqNB*CB5a)Kk|BGFH1AWj%JX=I+!S9f3@7jx5H4=G#Ty5Ch*=T){3Y$rX10^a& zrK2e|hzNF4Wf4(zR8*fgWZ+A853XRjfrm`z=w!)D>FIC;K3$>`RA0}= z;R7vLfW5w5k*Lz|c&;I<$!S1Bf-WT~`AW74c;bFF1Ym0eH4$-SlENFXq z_vhw>zp~SQLpZH}ZzOHc!N(5>a?=+4;jtDLRQl!mx9f9b+=c*;!|4(R{P|X}+toWp zZOZ(D0_J;vbS~e`z=aw_vZ|7kth?u~Y!PI;9{CFu)uIm)76IM)U$U;!ZNp8nwP7;q zavrpAfgn00M4EWWdAP}HE;&*}^sWB&U{=CRnFbcE&uU!Lm*mX&PMuQ#c)aL`tB!$a z?$X$;`gV$=0>#naWUR;uWX|NF_iEt>vRjD@3kUo&=F{dJH3WC>9KNegrdM(^6wFM9 z#NTtSx>MLJH8x1c{raWEc#p*C$|b)P#pJl~WStH{{UDLOU^g;6>De8k_w}*hQnw;^ z`nsd4YMS47^Z5zAdL$5w4ZRD+qtmaKls^jj(DoKNnwVYL1>T24q}QUGQ7%nNCD~WT zwuVT5Mh?O74D2p7;^XycG5!-!B+KP%)BXym?mVp7u56PeO*&S(OnD6`zBueuzt)6S zI?zd-mbUz>>j*;RhyPMnYdcFp9{amC>g+>8iz1$Q86$u0tl!KO2||$xgoHJg}dH& zkfM5!^wHNRtvb^hhrH`GC<5<26ca>1&K#g(_Ko6V>e{+G_BoB7ly2P-wnPR!OZypF z=coIbEP%(Ql*z-95bsO(f=bbRIb_Lhr82|&cPofB~3{XKw`{2F47_+sXrZLK3Ki~VU~*?nQP)eEmCV4}2q zQL$9d%3>83E@?+{YJoo!;lR#Y0eqIsS*k`^nHDP``oksO znw?MfsIx1MW<{$9BAR+Evt;Jt4O$csk0LDbj3Sts9O`WQG2rI?MWPGZ#|DYCFtzyf z_+1OOLUJmt#cXzC?QghwyE>B7U`M3gWNVX9>BgQVQS7`2(sDl-M} z<0ckqWb__eOk!f6#K6GvT-_J)u=>nNH%fTsZ08Qy#kZ3+7`??sd_0goDGDG!USV6? z$_0VAf#-hF(Oi~JknMq&5_XNFziy81H4?#rZ=sV!sTohP2!&(D`Bcc*Nm+F56BB0M z-hqrRyHtowo45Gx4QM?J3x@GA?F>=2YUeTvuJ<`!YEqD=J&{3#2A7#PuJputu5X)I zHdYO*hAiTD)4)TLfTV~`yV>aRLU#Zp=)Bu3E8?3BW%pb zQk^@M**w>*f7hx0IMcIFqHETf;y42VQ{o{~oYB6YyC*m5YdCxm1wqRRsFs%swEdZa z?Be{C(rJ%XT6KL)mebUAg8D-NV8kZ*7XnpQ7Itu`0lYJLTW_w&BBQ^2`SR27WJyH+ zWprP^N^G1_VW(jaTJ!;LEWAupW@DMIjD?A=2tiBd z^8hAG(rWWn0Du+`Trpu<$0mJwGQE~n_p@x8VdqUnWn0uVR>Ll4v4jD8zG-* zfNN6QGFt%0+PRuh6hx%#UM#VMhMJFBP!RK)l5AvhtbXz(FohuUJ`uu^deGE*$}=Bs zU1@;G=@KsEvVr_lFM+|q&;ADSh6DlN>C@!6I0`Z>9GsbUoOvyu13tYqho@Fdz|Zw$ zk=qA8=ro$nErI~&%Pnyabp%;iRp#6RSG%y}DS$+M6D?%CY+t!C>lpZBsA#5Zi|KX&R8dgD%TAZ0Fyn zrqw&+Xyh@mKY^(C9_3x0F4>q_|6c$&3CH$nclB4VUTvj+x-e6Wh%NWGxr>+x^US;3 z4y=}cQf)u~q1l+3v~&%3qu`K`5JEyi~=ow8B|^DH_!E z9Yd|~_x1I~*VmUbXU=Gl0})H}f0f!F>r-EeuJ3&Nvt+!zdz){&N}Zjswr<_Z(4j-w zy0vawSEk*)XSeHjr9jyMD}9$(bzo_<(lP0{be3i&HCG(dC8OG}5_i zRm{p&{a^{;;k<>lolji5)59%ku|+ZlsxNqdXQ9`^6wZ?>&0{B?cr>N`WyL|Bmu zsj096_ska@>;+x$`$bZ-f1r1C8~~|Vd*$!eX(2Vsy_>S6!%abQ)v{!=9d4?P^p5@_ znvQh5!%ac*J}roeiGi9bXvtt>Vq(nFoIZUTs7(_S6C>}_LVpkG+(Zz+P|lu-W$d$v zbOCyToJLFi*w|RuhFAq%W3sWavGQ@LN?JM|8yl-yP3dIGvhbH8H7%-NUD40Z&X&z-)TmK{J8iMolK!*L zK5GDwjG&;P!0h<(fjQHbE0~*kTCUm4DtNyym$^@i5 zs8xa1m%g|2f2Ha>e~J|Gt^g+Xc0U5XVi#jLka?TXr=58OtBi2fP&eMd&IBpui5igMz;V% z=M9tp*-GOMp`oF)YuAo;?b;C<8cIk=2qh&Yq^GA77Z)f0e@jnKH#1*v>RX

pRD@ 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 Date: Wed, 20 May 2015 02:59:19 +0300 Subject: [PATCH 3/6] Frankenstein edition: Limbs now store their own dna/species info. This allows transplanted limbs show up as they are, instead of conforming to mob. Vox-cat-monkey hybrids, rainbow skrells, go wild. Also changed rejection to cause infection instead of straight up organ damage - wouldn't want your newly acquired catpaws fracture out of blue. As a bonus, attacks are tracked per limb, so for example having kitty claws will give you the corresponding attack --- .../mob/living/carbon/human/appearance.dm | 2 + .../living/carbon/human/human_attackhand.dm | 7 +++- .../mob/living/carbon/human/update_icons.dm | 39 ++++++++++--------- code/modules/organs/organ.dm | 31 +++++++++------ code/modules/organs/organ_icon.dm | 34 ++++++++++------ code/modules/organs/robolimbs.dm | 1 + 6 files changed, 72 insertions(+), 42 deletions(-) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 52ba116d43..5f9527b93b 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -118,6 +118,7 @@ b_skin = blue force_update_limbs() + update_body() return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) @@ -127,6 +128,7 @@ s_tone = tone force_update_limbs() + update_body() return 1 /mob/living/carbon/human/proc/update_dna() diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 0deb593c84..3187ac7e02 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -176,8 +176,13 @@ miss_type = 2 // See what attack they use + var/possible_moves = list() var/datum/unarmed_attack/attack = null - for(var/datum/unarmed_attack/u_attack in H.species.unarmed_attacks) + for(var/part in list("l_hand","r_hand","l_foot","r_foot","head")) + var/obj/item/organ/external/E = H.get_organ(part) + possible_moves |= E.species.unarmed_attacks + + for(var/datum/unarmed_attack/u_attack in possible_moves) if(!u_attack.is_usable(H, src, hit_zone)) continue else diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 382ff909b3..8b13178adf 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -234,15 +234,13 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in src.mutations) var/skeleton = (SKELETON in src.mutations) - var/g = (gender == FEMALE ? "f" : "m") - //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. //Create a new, blank icon for our mob to use. if(stand_icon) qdel(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][r_skin][g_skin][b_skin]" + var/icon_key = "" var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] if(eyes) @@ -260,7 +258,12 @@ var/global/list/damage_icon_parts = list() icon_key += "3" else icon_key += "1" - + if(part) + icon_key += "[part.species.race_key]" + icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" + icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]" + if(part.s_col) + icon_key += "[rgb(part.s_col[1],part.s_col[2],part.s_col[3])]" icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]" var/icon/base_icon @@ -894,22 +897,22 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/get_tail_icon() var/icon_key = "[species.race_key][r_skin][g_skin][b_skin]" - + var/icon/tail_icon = tail_icon_cache[icon_key] - if(!tail_icon) - + if(!tail_icon) + //generate a new one tail_icon = new/icon(icon = (species.tail_animation? species.tail_animation : 'icons/effects/species.dmi')) tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - + tail_icon_cache[icon_key] = tail_icon - + return tail_icon /mob/living/carbon/human/proc/set_tail_state(var/t_state) var/image/tail_overlay = overlays_standing[TAIL_LAYER] - + if(tail_overlay && species.tail_animation) tail_overlay.icon_state = t_state return tail_overlay @@ -919,30 +922,30 @@ var/global/list/damage_icon_parts = list() //Update this if the ability to flick() images or make looping animation start at the first frame is ever added. /mob/living/carbon/human/proc/animate_tail_once(var/update_icons=1) var/t_state = "[species.tail]_once" - + var/image/tail_overlay = overlays_standing[TAIL_LAYER] if(tail_overlay && tail_overlay.icon_state == t_state) return //let the existing animation finish - + tail_overlay = set_tail_state(t_state) if(tail_overlay) spawn(15) //check that the animation hasn't changed in the meantime if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == t_state) animate_tail_stop() - + if(update_icons) update_icons() /mob/living/carbon/human/proc/animate_tail_start(var/update_icons=1) set_tail_state("[species.tail]_slow[rand(0,9)]") - + if(update_icons) update_icons() /mob/living/carbon/human/proc/animate_tail_fast(var/update_icons=1) set_tail_state("[species.tail]_loop[rand(0,9)]") - + if(update_icons) update_icons() @@ -951,14 +954,14 @@ var/global/list/damage_icon_parts = list() set_tail_state("[species.tail]_idle[rand(0,9)]") else set_tail_state("[species.tail]_static") - - + + if(update_icons) update_icons() /mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1) set_tail_state("[species.tail]_static") - + if(update_icons) update_icons() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 0e4e9e35a8..9d40b8d650 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -23,6 +23,8 @@ var/list/organ_cache = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood germ_level = 0 + var/datum/dna/dna + var/datum/species/species /obj/item/organ/proc/update_health() return @@ -34,6 +36,12 @@ var/list/organ_cache = list() max_damage = min_broken_damage * 2 if(istype(holder)) src.owner = holder + species = all_species["Human"] + if(holder.dna) + dna = holder.dna.Clone() + species = all_species[dna.species] + else + log_debug("[src] at [loc] spawned without a proper DNA.") var/mob/living/carbon/human/H = holder if(istype(H)) if(internal) @@ -42,10 +50,10 @@ var/list/organ_cache = list() if(E.internal_organs == null) E.internal_organs = list() E.internal_organs |= src - if(H.dna) + if(dna) if(!blood_DNA) blood_DNA = list() - blood_DNA[H.dna.unique_enzymes] = H.dna.b_type + blood_DNA[dna.unique_enzymes] = dna.b_type if(internal) holder.internal_organs |= src @@ -123,24 +131,23 @@ var/list/organ_cache = list() /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 + if(dna) + if(!rejecting) + if(blood_incompatible(dna.b_type, owner.dna.b_type, species, owner.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) + germ_level++ if(51 to 200) - owner.reagents.add_reagent("toxin", 1) - take_damage(1) + germ_level += rand(1,2) if(201 to 500) - take_damage(rand(2,3)) - owner.reagents.add_reagent("toxin", 2) + germ_level += rand(2,3) if(501 to INFINITY) - take_damage(4) - owner.reagents.add_reagent("toxin", rand(3,5)) + germ_level += rand(3,5) + owner.reagents.add_reagent("toxin", rand(1,2)) /obj/item/organ/proc/receive_chem(chemical as obj) return 0 diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 7036e7e725..d25ce2f5a2 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -17,11 +17,23 @@ var/global/list/limb_icon_cache = list() s_col = null if(status & ORGAN_ROBOT) return + if(species && human.species && species.name != human.species.name) + return if(!isnull(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/sync_colour_to_dna() + s_tone = null + s_col = null + if(status & ORGAN_ROBOT) + return + if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.flags & HAS_SKIN_TONE)) + s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) + if(species.flags & HAS_SKIN_COLOR) + s_col = list(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) + /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) ..() var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] @@ -35,10 +47,10 @@ var/global/list/limb_icon_cache = list() ..() overlays.Cut() - if(owner.species.has_organ["eyes"]) + if(species.has_organ["eyes"]) var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] - if(owner.species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes) + if(species.eyes) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) if(eyes) eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) else @@ -46,14 +58,14 @@ var/global/list/limb_icon_cache = list() mob_icon.Blend(eyes_icon, ICON_OVERLAY) overlays |= eyes_icon - if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS))) + if(owner.lip_style && (species && (species.flags & HAS_LIPS))) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] - if(facial_hair_style && facial_hair_style.species_allowed && (owner.species.name in facial_hair_style.species_allowed)) + if(facial_hair_style && facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(facial_hair_style.do_colouration) facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) @@ -61,7 +73,7 @@ var/global/list/limb_icon_cache = list() 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 && (owner.species.name in hair_style.species_allowed)) + if(hair_style && (species.name in hair_style.species_allowed)) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") if(hair_style.do_colouration) hair_s.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD) @@ -75,25 +87,25 @@ var/global/list/limb_icon_cache = list() if(force_icon) mob_icon = new /icon(force_icon, "[icon_name]") else - if(!owner) + if(!dna) mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]") else if(gendered_icon) - if(owner.gender == FEMALE) + if(dna.GetUIState(DNA_UI_GENDER)) 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)) + else if ((status & ORGAN_ROBOT) && !(species && 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]" : ""]") + mob_icon = new /icon(species.deform, "[icon_name][gender ? "_[gender]" : ""]") else - mob_icon = new /icon(owner.species.icobase, "[icon_name][gender ? "_[gender]" : ""]") + mob_icon = new /icon(species.icobase, "[icon_name][gender ? "_[gender]" : ""]") if(status & ORGAN_DEAD) mob_icon.ColorTone(rgb(10,50,0)) diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 8d19d60b49..bb2d571f5d 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -7,6 +7,7 @@ var/global/datum/robolimb/basic_robolimb for(var/limb_type in typesof(/datum/robolimb)) var/datum/robolimb/R = new limb_type() all_robolimbs[R.company] = R + world << "Adding [R.company] as [R], [R.type]" if(!R.unavailable_at_chargen) chargen_robolimbs[R.company] = R From bd18bdfc09ba8b0cc8b2092195d2af5491300e70 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Wed, 20 May 2015 03:53:39 +0300 Subject: [PATCH 4/6] Changelog --- html/changelogs/comma-frankenstein.yml | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 html/changelogs/comma-frankenstein.yml diff --git a/html/changelogs/comma-frankenstein.yml b/html/changelogs/comma-frankenstein.yml new file mode 100644 index 0000000000..2f97cd81f3 --- /dev/null +++ b/html/changelogs/comma-frankenstein.yml @@ -0,0 +1,39 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Chinsky + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Meat limbs now can be attached. Use limb on missing area, then hemostat to finalize it." + - rscadd: "Limbs from other races can be now attached. They'll cause rejection, but it can be kept at bay with spaceacilline to some point. Species special attack is carried over too, i.e. you can clawn people if you sew a cathand to yourself." + - rscadd: "Limbs that are left in open will rot in ~7 minutes. Use freezers or cryobags to stop it. You can still attach them, but you wish you couldn't." + - rscadd: "Limbs from other races can be now attached. They'll cause rejection, but it can be kept at bay with spaceacilline to some point. Species special attack is carried over too, i.e. you can clawn people if you sew a cathand to yourself." From de1de98f7aa62f4a981d53530959c6d88c0d51ea Mon Sep 17 00:00:00 2001 From: Chinsky Date: Wed, 20 May 2015 09:35:51 +0300 Subject: [PATCH 5/6] Fixed changelog Added some info about not quite attached limbs to examination/scanner. Added rejection info to advanced scanner Span classes (gotta start somewhere I guess) Also zombie goast file pls go --- code/game/machinery/adv_med.dm | 7 ++- code/modules/organs/organ_external.dm | 3 ++ code/modules/surgery/headreattach.dm | 73 -------------------------- code/modules/surgery/limb_reattach.dm | 24 ++++----- html/changelogs/comma-frankenstein.yml | 32 +---------- 5 files changed, 21 insertions(+), 118 deletions(-) delete mode 100644 code/modules/surgery/headreattach.dm diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 8c6be59f71..645bfa5bcc 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -390,7 +390,8 @@ infected = "Acute Infection++:" if (INFECTION_LEVEL_THREE to INFINITY) infected = "Septic:" - + if(e.rejecting) + infected += "(being rejected)" if (e.implants.len) var/unknown_body = 0 for(var/I in e.implants) @@ -406,7 +407,7 @@ if(!(e.status & ORGAN_DESTROYED)) dat += "[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]" else - dat += "[e.name]--Not Found" + dat += "[e.name]--Not [e.is_stump() ? "Found" : "Attached Completely"]" dat += "" for(var/obj/item/organ/i in occ["internal_organs"]) @@ -431,6 +432,8 @@ infection = "Acute Infection+:" if (INFECTION_LEVEL_TWO + 300 to INFINITY) infection = "Acute Infection++:" + if(i.rejecting) + infection += "(being rejected)" dat += "" dat += "[i.name]N/A[i.damage][infection]:[mech]" diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index d8817aa56d..0655bb6deb 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -928,6 +928,9 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/proc/get_wounds_desc() . = "" + if(status & ORGAN_DESTROYED && !is_stump()) + . += "tear at [amputation_point] so bad it barely hangs on few tendons" + if(status & ORGAN_ROBOT) if(brute_dam) switch(brute_dam) diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm deleted file mode 100644 index 782e238e1f..0000000000 --- a/code/modules/surgery/headreattach.dm +++ /dev/null @@ -1,73 +0,0 @@ -//This is an uguu head restoration surgery TOTALLY not yoinked from chinsky's limb reattacher -/datum/surgery_step/attach_bodypart - priority = 3 // Must be higher than /datum/surgery_step/internal - allowed_tools = list(/obj/item/organ/external = 100) - can_infect = 0 - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - return isnull(E) && !isnull(target.species.has_limbs[target_zone]) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ - "You start attaching [E.name] to [target]'s [E.amputation_point].") - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("\blue [user] has attached [target]'s [E.name] to the [E.amputation_point].", \ - "\blue You have attached [target]'s [E.name] to the [E.amputation_point].") - user.drop_from_inventory(E) - E.replaced(target) - E.loc = target - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "\red Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, null, sharp=1) - -/datum/surgery_step/connect_bodypart - priority = 3 - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 20 - ) - can_infect = 1 - - min_duration = 120 - max_duration = 150 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - return E && (E.status & ORGAN_DESTROYED) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You start connecting tendons and muscle in [target]'s [E.amputation_point].") - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("\blue [user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "\blue You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") - E.status &= ~ORGAN_DESTROYED - if(E.children) - for(var/obj/item/organ/external/C in E.children) - C.status &= ~ORGAN_DESTROYED - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "\red Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, null, sharp=1) \ No newline at end of file diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 400d80a7f0..aee13ede83 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -28,8 +28,8 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = tool - user.visible_message("\blue [user] has attached [target]'s [E.name] to the [E.amputation_point].", \ - "\blue You have attached [target]'s [E.name] to the [E.amputation_point].") + user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].>", \ + "You have attached [target]'s [E.name] to the [E.amputation_point].") user.drop_from_inventory(E) E.replaced(target) E.loc = target @@ -39,8 +39,8 @@ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = tool - user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "\red Your hand slips, damaging [target]'s [E.amputation_point]!") + user.visible_message(" [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + " Your hand slips, damaging [target]'s [E.amputation_point]!") target.apply_damage(10, BRUTE, null, sharp=1) /datum/surgery_step/limb/connect @@ -65,8 +65,8 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("\blue [user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "\blue You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") + user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") E.status &= ~ORGAN_DESTROYED if(E.children) for(var/obj/item/organ/external/C in E.children) @@ -77,8 +77,8 @@ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = tool - user.visible_message("\red [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "\red Your hand slips, damaging [target]'s [E.amputation_point]!") + user.visible_message(" [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + " Your hand slips, damaging [target]'s [E.amputation_point]!") target.apply_damage(10, BRUTE, null, sharp=1) /datum/surgery_step/limb/mechanize @@ -101,8 +101,8 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/robot_parts/L = tool - user.visible_message("\blue [user] has attached \the [tool] to [target].", \ - "\blue You have attached \the [tool] to [target].") + user.visible_message("[user] has attached \the [tool] to [target].", \ + "You have attached \the [tool] to [target].") if(L.part) for(var/part_name in L.part) @@ -124,6 +124,6 @@ qdel(tool) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, damaging [target]'s flesh!", \ - "\red Your hand slips, damaging [target]'s flesh!") + user.visible_message(" [user]'s hand slips, damaging [target]'s flesh!", \ + " Your hand slips, damaging [target]'s flesh!") target.apply_damage(10, BRUTE, null, sharp=1) diff --git a/html/changelogs/comma-frankenstein.yml b/html/changelogs/comma-frankenstein.yml index 2f97cd81f3..5210de96c4 100644 --- a/html/changelogs/comma-frankenstein.yml +++ b/html/changelogs/comma-frankenstein.yml @@ -1,39 +1,9 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# maptweak -# spellcheck (typo fixes) -# experiment -################################# -# Your name. author: Chinsky -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. -# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - rscadd: "Meat limbs now can be attached. Use limb on missing area, then hemostat to finalize it." - rscadd: "Limbs from other races can be now attached. They'll cause rejection, but it can be kept at bay with spaceacilline to some point. Species special attack is carried over too, i.e. you can clawn people if you sew a cathand to yourself." - - rscadd: "Limbs that are left in open will rot in ~7 minutes. Use freezers or cryobags to stop it. You can still attach them, but you wish you couldn't." - - rscadd: "Limbs from other races can be now attached. They'll cause rejection, but it can be kept at bay with spaceacilline to some point. Species special attack is carried over too, i.e. you can clawn people if you sew a cathand to yourself." + - rscadd: "Limbs that are left in open will rot in ~7 minutes. Use freezers or cryobags to stop it. You can still attach them, but you wish you couldn't." \ No newline at end of file From a7d6cf354561305fc68ecc10b88e5f7fb549c6c5 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Wed, 20 May 2015 09:49:10 +0300 Subject: [PATCH 6/6] tyops fiexs --- code/game/objects/items/weapons/storage/boxes.dm | 2 +- code/modules/organs/organ.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 8dc4b50f4c..3ae8ba5640 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -631,7 +631,7 @@ /obj/item/weapon/storage/box/freezer name = "portable freezer" - desc = "This nifty schok-resistant device will keep your 'groceries' nice and non-spoiled." + desc = "This nifty shock-resistant device will keep your 'groceries' nice and non-spoiled." icon = 'icons/obj/storage.dmi' icon_state = "portafreezer" item_state = "medicalpack" diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 9d40b8d650..405c058a23 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -101,7 +101,7 @@ var/list/organ_cache = list() /obj/item/organ/examine(mob/user) ..(user) if(status & ORGAN_DEAD) - user << "The decay has set in." + user << "The decay has set in." /obj/item/organ/proc/handle_germ_effects() //** Handle the effects of infections