diff --git a/_maps/map_files/MetaStation/MetaStation.v41F.dmm b/_maps/map_files/MetaStation/MetaStation.v41F.dmm index b05fc0caa49..dae47adebe4 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41F.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41F.dmm @@ -7369,7 +7369,7 @@ "cMl" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Departure Lounge"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cMm" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Departure Lounge"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cMn" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Departure Lounge"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cMo" = (/obj/structure/table/wood,/obj/item/weapon/spellbook/oneuse/smoke{name = "mysterious old book of "},/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{name = "flask of holy water"; pixel_x = -2; pixel_y = 2},/obj/item/weapon/nullrod{pixel_x = 4},/obj/item/organ/heart,/obj/item/device/soulstone/anybody,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) +"cMo" = (/obj/structure/table/wood,/obj/item/weapon/spellbook/oneuse/smoke{name = "mysterious old book of "},/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{name = "flask of holy water"; pixel_x = -2; pixel_y = 2},/obj/item/weapon/nullrod{pixel_x = 4},/obj/item/organ/internal/heart,/obj/item/device/soulstone/anybody,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) "cMp" = (/obj/structure/optable{name = "Robotics Operating Table"},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/obj/machinery/camera{c_tag = "Robotics - Aft"; dir = 1; network = list("SS13","RD")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/assembly/robotics) "cMq" = (/obj/machinery/computer/operating{name = "Robotics Operating Computer"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/assembly/robotics) "cMs" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Departure Lounge - Port Fore"; dir = 4; network = list("SS13")},/obj/structure/flora/kirbyplants{icon_state = "plant-24"; layer = 4.1; tag = "icon-plant-24"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index 86ecb31fc79..20f32f85a37 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -75,6 +75,7 @@ #define TR_KEEPSE 32 // changelings shouldn't edit the DNA's SE when turning into a monkey #define TR_DEFAULTMSG 64 #define TR_KEEPSRC 128 +#define TR_KEEPORGANS 256 //Organ stuff, It's here because "Genetics" is the most relevant file for organs #define ORGAN_ORGANIC 1 diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index f31ac20af2f..63b22f7004e 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -217,6 +217,21 @@ /datum/action/item_action/hands_free check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE +/datum/action/organ_action + check_flags = AB_CHECK_ALIVE + +/datum/action/organ_action/CheckRemoval(mob/living/carbon/user) + if(!iscarbon(user)) + return 1 + if(target in user.internal_organs) + return 0 + return 1 + +/datum/action/organ_action/IsAvailable() + var/obj/item/organ/internal/I = target + if(!I.owner) + return 0 + return ..() //Preset for spells /datum/action/spell_action diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 34ac5085c27..45f8ddab2f6 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -252,15 +252,17 @@ body += "" body += "" body += "" - if(ishuman(D)) + if(iscarbon(D)) body += "" - body += "" - body += "" + body += "" body += "" - body += "" + if(ishuman(D)) body += "" + body += "" + body += "" body += "" body += "" + body += "" body += "" body += "" if(isobj(D)) @@ -700,6 +702,17 @@ body if("left") A.dir = turn(A.dir, 45) href_list["datumrefresh"] = href_list["rotatedatum"] + else if(href_list["editorgans"]) + if(!check_rights(0)) return + + var/mob/living/carbon/C = locate(href_list["editorgans"]) + if(!istype(C)) + usr << "This can only be done to instances of type /mob/living/carbon" + return + + manipulate_organs(C) + href_list["datumrefresh"] = href_list["editorgans"] + else if(href_list["makehuman"]) if(!check_rights(R_SPAWN)) return @@ -773,9 +786,9 @@ body else if(href_list["makeai"]) if(!check_rights(R_SPAWN)) return - var/mob/living/carbon/human/H = locate(href_list["makeai"]) + var/mob/living/carbon/H = locate(href_list["makeai"]) if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" + usr << "This can only be done to instances of type /mob/living/carbon" return if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index 11a68034d8b..ee249664ab5 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -23,7 +23,7 @@ if(prob(5)) affected_mob.emote("cough") if(2) - var/obj/item/organ/appendix/A = affected_mob.getorgan(/obj/item/organ/appendix) + var/obj/item/organ/internal/appendix/A = affected_mob.getorgan(/obj/item/organ/internal/appendix) if(A) A.inflamed = 1 A.update_icon() diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 192aec3da0a..1b83792a13c 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -94,7 +94,7 @@ /datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob) if(!ismonkey(affected_mob)) ticker.mode.add_monkey(affected_mob.mind) - affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) /datum/disease/transformation/jungle_fever/stage_act() ..() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 3b38daa05c9..b2172da6dca 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1155,7 +1155,7 @@ sleep(0) //because deleting of virus is doing throught spawn(0) log_admin("[key_name(usr)] attempting to humanize [key_name(current)]") message_admins("[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]") - H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) + H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) if(H) src = H.mind diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index a24fbc63aff..b517e417d93 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -334,7 +334,7 @@ /datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner) if(..()) return - . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) /datum/mutation/human/race/gain_indication(mob/living/carbon/human/owner) return @@ -345,7 +345,7 @@ /datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner) if(..()) return - . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) /datum/mutation/human/stealth diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 83ed22584e9..c996a6bfe89 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -688,25 +688,25 @@ var/list/uplink_items = list() /datum/uplink_item/cyber_implants/thermals name = "Thermal Vision Implant" desc = "These cybernetic eyes will give you thermal vision." - item = /obj/item/cybernetic_implant/eyes/thermals + item = /obj/item/organ/internal/cyberimp/eyes/thermals cost = 8 /datum/uplink_item/cyber_implants/xray name = "X-Ray Vision Implant" desc = "These cybernetic eyes will give you X-ray vision." - item = /obj/item/cybernetic_implant/eyes/xray + item = /obj/item/organ/internal/cyberimp/eyes/xray cost = 10 /datum/uplink_item/cyber_implants/antistun name = "CNS Rebooter Implant" desc = "This implant will help you get back up on your feet faster after being stunned." - item = /obj/item/cybernetic_implant/brain/anti_stun + item = /obj/item/organ/internal/cyberimp/brain/anti_stun cost = 12 /datum/uplink_item/cyber_implants/reviver name = "Reviver Implant" desc = "This implant will attempt to revive you if you lose consciousness." - item = /obj/item/cybernetic_implant/chest/reviver + item = /obj/item/organ/internal/cyberimp/chest/reviver cost = 8 /datum/uplink_item/cyber_implants/bundle diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 4fadf3d662a..c0b078933ae 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -61,7 +61,7 @@ var/global/max_secret_rooms = 6 walltypes = list(/turf/simulated/wall/r_wall=2,/turf/simulated/wall=2,/turf/simulated/mineral/random/high_chance=1) floortypes = list(/turf/simulated/floor/plasteel,/turf/simulated/floor/engine) treasureitems = list(/obj/machinery/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/critter/cat=2) - fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/appendix=2,/obj/structure/closet/crate/freezer=2, + fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/internal/appendix=2,/obj/structure/closet/crate/freezer=2, /obj/structure/optable=1,/obj/item/weapon/scalpel=1,/obj/item/weapon/storage/firstaid/regular=3, /obj/item/weapon/tank/internals/anesthetic=1, /obj/item/weapon/surgical_drapes=2, /obj/item/device/mass_spectrometer/adv=1,/obj/item/clothing/glasses/hud/health=1) @@ -72,7 +72,7 @@ var/global/max_secret_rooms = 6 treasureitems = list(/obj/item/device/soulstone=1, /obj/item/clothing/suit/space/cult=1, /obj/item/weapon/bedsheet/cult=2, /obj/item/clothing/suit/cultrobes=2, /mob/living/simple_animal/hostile/creature=3) fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2, - /obj/item/organ/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/wood=2,/obj/item/weapon/ectoplasm=3, + /obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/wood=2,/obj/item/weapon/ectoplasm=3, /obj/item/clothing/head/helmet/space/cult=1, /obj/item/clothing/shoes/cult=1) if("wizden") diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm index 35ce34e0792..8e6662109e3 100644 --- a/code/game/gamemodes/abduction/abduction.dm +++ b/code/game/gamemodes/abduction/abduction.dm @@ -257,10 +257,7 @@ scientist.equip_to_slot_or_del(G, slot_in_backpack) var/obj/item/weapon/implant/abductor/beamplant = new /obj/item/weapon/implant/abductor(scientist) - beamplant.imp_in = scientist - beamplant.implanted = 1 - beamplant.implanted(scientist) - beamplant.home = console.pad + beamplant.implant(scientist) /datum/game_mode/abduction/check_finished() diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm index 24fc829d65b..9595f0883b9 100644 --- a/code/game/gamemodes/abduction/abduction_gear.dm +++ b/code/game/gamemodes/abduction/abduction_gear.dm @@ -264,6 +264,7 @@ icon = 'icons/obj/abductor.dmi' icon_state = "implant" activated = 1 + origin_tech = "materials=2;biotech=3;magnets=4;bluespace=5" var/obj/machinery/abductor/pad/home var/cooldown = 30 @@ -282,6 +283,29 @@ if(cooldown == initial(cooldown)) SSobj.processing.Remove(src) +/obj/item/weapon/implant/abductor/implant(var/mob/source, var/mob/user) + if(..()) + var/obj/machinery/abductor/console/console + if(ishuman(source)) + var/mob/living/carbon/human/H = source + if(H.dna && istype(H.dna.species, /datum/species/abductor)) + var/datum/species/abductor/S = H.dna.species + console = get_team_console(S.team) + home = console.pad + + if(!home) + console = get_team_console(pick(1, 2, 3, 4)) + home = console.pad + return 1 + +/obj/item/weapon/implant/abductor/proc/get_team_console(var/team) + var/obj/machinery/abductor/console/console + for(var/obj/machinery/abductor/console/c in machines) + if(c.team == team) + console = c + break + return console + /obj/item/device/firing_pin/alien name = "alien firing pin" diff --git a/code/game/gamemodes/abduction/abduction_surgery.dm b/code/game/gamemodes/abduction/abduction_surgery.dm index a618e1d2544..f22f188945b 100644 --- a/code/game/gamemodes/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/abduction/abduction_surgery.dm @@ -1,17 +1,26 @@ /datum/surgery/organ_extraction name = "experimental dissection" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin,/datum/surgery_step/incise, /datum/surgery_step/extract_organ ,/datum/surgery_step/gland_insert) - species = list(/mob/living/carbon/human) - location = "chest" - user_species_restricted = 1 - user_species_ids = list("abductor") + possible_locs = list("chest") ignore_clothes = 1 +/datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target) + if(!ishuman(user)) + return 0 + var/mob/living/carbon/human/H = user + if(H.dna && istype(H.dna.species, /datum/species/abductor)) + return 1 + if((locate(/obj/item/weapon/implant/abductor) in H)) + return 1 + return 0 + + /datum/surgery_step/extract_organ + name = "remove heart" accept_hand = 1 time = 32 - var/obj/item/IC = null - var/list/organ_types = list(/obj/item/organ/heart) + var/obj/item/organ/internal/IC = null + var/list/organ_types = list(/obj/item/organ/internal/heart) /datum/surgery_step/extract_organ/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) for(var/obj/item/I in target.internal_organs) @@ -24,14 +33,15 @@ if(IC) user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].") user.put_in_hands(IC) - target.internal_organs -= IC + IC.Remove(target, special = 1) return 1 else user << "You don't find anything in [target]'s [target_zone]!" return 0 /datum/surgery_step/gland_insert - implements = list(/obj/item/gland = 100) + name = "insert gland" + implements = list(/obj/item/organ/internal/gland = 100) time = 32 /datum/surgery_step/gland_insert/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -40,8 +50,6 @@ /datum/surgery_step/gland_insert/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] inserts [tool] into [target].", "You insert [tool] into [target].") user.drop_item() - var/obj/item/gland/gland = tool - gland.Inject(target) - return 1 - - + var/obj/item/organ/internal/gland/gland = tool + gland.Insert(target, 2) + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/abduction/gland.dm b/code/game/gamemodes/abduction/gland.dm index 73eff48987d..cf3b766282e 100644 --- a/code/game/gamemodes/abduction/gland.dm +++ b/code/game/gamemodes/abduction/gland.dm @@ -1,211 +1,234 @@ -/obj/item/gland/ +/obj/item/organ/internal/gland name = "fleshy mass" desc = "A nausea-inducing hunk of twisting flesh and metal." icon = 'icons/obj/abductor.dmi' + zone = "chest" + slot = "gland" icon_state = "gland" + status = ORGAN_ROBOTIC + origin_tech = "materials=4;biotech=5" var/cooldown_low = 300 var/cooldown_high = 300 var/next_activation = 0 var/uses // -1 For inifinite + var/human_only = 0 var/active = 0 - var/mob/living/carbon/human/host -/obj/item/gland/proc/HostCheck() - if(ishuman(host) && host == src.loc) - if(host.stat != DEAD) - return 1 +/obj/item/organ/internal/gland/proc/ownerCheck() + if(ishuman(owner)) + return 1 + if(!human_only && iscarbon(owner)) + return 1 return 0 -/obj/item/gland/proc/Start() +/obj/item/organ/internal/gland/proc/Start() active = 1 - next_activation = world.time + rand(cooldown_low,cooldown_high) - SSobj.processing |= src + next_activation = world.time + rand(cooldown_low,cooldown_high) -/obj/item/gland/proc/Inject(var/mob/living/carbon/human/target) - host = target - target.internal_organs += src - src.loc = target -/obj/item/gland/process() +/obj/item/organ/internal/gland/Remove(var/mob/living/carbon/M, special = 0) + active = 0 + if(initial(uses) == 1) + uses = initial(uses) + ..() + +/obj/item/organ/internal/gland/Insert(var/mob/living/carbon/M, special = 0) + ..() + if(special != 2 && uses) // Special 2 means abductor surgery + Start() + +/obj/item/organ/internal/gland/on_life() if(!active) - SSobj.processing.Remove(src) + return + if(!ownerCheck()) + active = 0 return if(next_activation <= world.time) - //This gives a chance to transplant the gland active into someone else if you're fast - if(!HostCheck()) - active = 0 - return activate() uses-- next_activation = world.time + rand(cooldown_low,cooldown_high) - if(uses == 0) - active = 0 + if(!uses) + active = 0 -/obj/item/gland/proc/activate() +/obj/item/organ/internal/gland/proc/activate() return -/obj/item/gland/heals +/obj/item/organ/internal/gland/heals + origin_tech = "materials=4;biotech=6" cooldown_low = 200 cooldown_high = 400 uses = -1 icon_state = "health" -/obj/item/gland/heals/activate() - host << "You feel curiously revitalized." - host.adjustBruteLoss(-20) - host.adjustOxyLoss(-20) - host.adjustFireLoss(-20) +/obj/item/organ/internal/gland/heals/activate() + owner << "You feel curiously revitalized." + owner.adjustBruteLoss(-20) + owner.adjustOxyLoss(-20) + owner.adjustFireLoss(-20) -/obj/item/gland/slime +/obj/item/organ/internal/gland/slime + origin_tech = "materials=4;biotech=6" cooldown_low = 600 cooldown_high = 1200 uses = -1 icon_state = "slime" -/obj/item/gland/slime/activate() - host << "You feel nauseous!" - if(host.is_muzzled()) - host << "The muzzle prevents you from vomiting!" +/obj/item/organ/internal/gland/slime/activate() + owner << "You feel nauseous!" + if(owner.is_muzzled()) + owner << "The muzzle prevents you from vomiting!" - host.visible_message("[host] vomits on the floor!", \ + owner.visible_message("[owner] vomits on the floor!", \ "You throw up on the floor!") - host.nutrition -= 20 - host.adjustToxLoss(-3) + owner.nutrition -= 20 + owner.adjustToxLoss(-3) - var/turf/pos = get_turf(host) - pos.add_vomit_floor(host) + var/turf/pos = get_turf(owner) + pos.add_vomit_floor(owner) playsound(pos, 'sound/effects/splat.ogg', 50, 1) var/mob/living/simple_animal/slime/Slime = new/mob/living/simple_animal/slime(pos) - Slime.Friends = list(host) - Slime.Leader = host + Slime.Friends = list(owner) + Slime.Leader = owner -/obj/item/gland/mindshock +/obj/item/organ/internal/gland/mindshock + origin_tech = "materials=4;biotech=5;magnets=3" cooldown_low = 300 cooldown_high = 300 uses = -1 icon_state = "mindshock" -/obj/item/gland/mindshock/activate() - host << "You get a headache." +/obj/item/organ/internal/gland/mindshock/activate() + owner << "You get a headache." - var/turf/T = get_turf(host) - for(var/mob/living/carbon/human/H in orange(4,T)) - if(H == host) + var/turf/T = get_turf(owner) + for(var/mob/living/carbon/H in orange(4,T)) + if(H == owner) continue H << "You hear a buzz in your head " H.confused += 20 -/obj/item/gland/pop +/obj/item/organ/internal/gland/pop + origin_tech = "materials=4;biotech=6" cooldown_low = 900 cooldown_high = 1800 uses = 6 + human_only = 1 icon_state = "species" -/obj/item/gland/pop/activate() - host << "You feel unlike yourself." +/obj/item/organ/internal/gland/pop/activate() + owner << "You feel unlike yourself." var/species = pick(list(/datum/species/lizard,/datum/species/slime,/datum/species/plant/pod,/datum/species/fly)) - hardset_dna(host, null, null, null, null, species) - host.regenerate_icons() + hardset_dna(owner, null, null, null, null, species) + owner.regenerate_icons() return -/obj/item/gland/ventcrawling +/obj/item/organ/internal/gland/ventcrawling + origin_tech = "materials=4;biotech=5;bluespace=3" cooldown_low = 1800 cooldown_high = 2400 uses = 1 icon_state = "vent" -/obj/item/gland/ventcrawling/activate() - host << "You feel very stretchy." - host.ventcrawler = 2 +/obj/item/organ/internal/gland/ventcrawling/activate() + owner << "You feel very stretchy." + owner.ventcrawler = 2 return -/obj/item/gland/viral +/obj/item/organ/internal/gland/viral + origin_tech = "materials=4;biotech=6" cooldown_low = 1800 cooldown_high = 2400 uses = 1 icon_state = "viral" -/obj/item/gland/viral/activate() - host << "You feel sick." +/obj/item/organ/internal/gland/viral/activate() + owner << "You feel sick." var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis) var/datum/disease/D = new virus_type() D.carrier = 1 - host.viruses += D - D.affected_mob = host - D.holder = host - host.med_hud_set_status() + owner.viruses += D + D.affected_mob = owner + D.holder = owner + owner.med_hud_set_status() -/obj/item/gland/emp //TODO : Replace with something more interesting +/obj/item/organ/internal/gland/emp //TODO : Replace with something more interesting + origin_tech = "materials=4;biotech=5;magnets=3" cooldown_low = 900 cooldown_high = 1600 uses = 10 icon_state = "emp" -/obj/item/gland/emp/activate() - host << "You feel a spike of pain in your head." - empulse(get_turf(host), 2, 5, 1) +/obj/item/organ/internal/gland/emp/activate() + owner << "You feel a spike of pain in your head." + empulse(get_turf(owner), 2, 5, 1) -/obj/item/gland/spiderman +/obj/item/organ/internal/gland/spiderman + origin_tech = "materials=4;biotech=6" cooldown_low = 450 cooldown_high = 900 uses = 10 icon_state = "spider" -/obj/item/gland/spiderman/activate() - host << "You feel something crawling in your skin." +/obj/item/organ/internal/gland/spiderman/activate() + owner << "You feel something crawling in your skin." if(uses == initial(uses)) - host.faction += "spiders" - new /obj/effect/spider/spiderling(host.loc) + owner.faction += "spiders" + new /obj/effect/spider/spiderling(owner.loc) -/obj/item/gland/egg +/obj/item/organ/internal/gland/egg + origin_tech = "materials=4;biotech=6" cooldown_low = 300 cooldown_high = 400 uses = -1 icon_state = "egg" -/obj/item/gland/egg/activate() - host << "You lay an egg!" - var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(host.loc) +/obj/item/organ/internal/gland/egg/activate() + owner << "You lay an egg!" + var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(owner.loc) egg.reagents.add_reagent("sacid",20) egg.desc += " It smells bad." -/obj/item/gland/bloody +/obj/item/organ/internal/gland/bloody + origin_tech = "materials=4;biotech=6" cooldown_low = 200 cooldown_high = 400 uses = -1 -/obj/item/gland/bloody/activate() - host.adjustBruteLoss(15) +/obj/item/organ/internal/gland/bloody/activate() + owner.adjustBruteLoss(15) - host.visible_message("[host]'s skin erupts with blood!",\ + owner.visible_message("[owner]'s skin erupts with blood!",\ "Blood pours from your skin!") - for(var/turf/T in oview(3,host)) //Make this respect walls and such - T.add_blood_floor(host) - for(var/mob/living/carbon/human/H in oview(3,host)) //Blood decals for simple animals would be neat. aka Carp with blood on it. + for(var/turf/T in oview(3,owner)) //Make this respect walls and such + T.add_blood_floor(owner) + for(var/mob/living/carbon/human/H in oview(3,owner)) //Blood decals for simple animals would be neat. aka Carp with blood on it. if(H.wear_suit) - H.wear_suit.add_blood(host) + H.wear_suit.add_blood(owner) H.update_inv_wear_suit(0) else if(H.w_uniform) - H.w_uniform.add_blood(host) + H.w_uniform.add_blood(owner) H.update_inv_w_uniform(0) -/obj/item/gland/bodysnatch +/obj/item/organ/internal/gland/bodysnatch + origin_tech = "materials=4;biotech=7" cooldown_low = 600 cooldown_high = 600 + human_only = 1 uses = 1 -/obj/item/gland/bodysnatch/activate() - host << "You feel something moving around inside you..." +/obj/item/organ/internal/gland/bodysnatch/activate() + owner << "You feel something moving around inside you..." //spawn cocoon with clone greytide snpc inside - var/obj/effect/cocoon/abductor/C = new (get_turf(host)) - C.Copy(host) - C.Start() - host.gib() + if(ishuman(owner)) + var/obj/effect/cocoon/abductor/C = new (get_turf(owner)) + C.Copy(owner) + C.Start() + owner.gib() return /obj/effect/cocoon/abductor @@ -243,19 +266,22 @@ M.loc = src.loc qdel(src) -/obj/item/gland/plasma +/obj/item/organ/internal/gland/plasma cooldown_low = 2400 cooldown_high = 3000 + origin_tech = "materials=4;biotech=5;plasma=3" uses = 1 -/obj/item/gland/plasma/activate() - host << "You feel bloated." +/obj/item/organ/internal/gland/plasma/activate() + owner << "You feel bloated." sleep(150) - host << "A massive stomachache overcomes you." + if(!owner) return + owner << "A massive stomachache overcomes you." sleep(50) - host.visible_message("[host] explodes in a cloud of plasma!") - var/turf/simulated/T = get_turf(host) + if(!owner) return + owner.visible_message("[owner] explodes in a cloud of plasma!") + var/turf/simulated/T = get_turf(owner) if(istype(T)) T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,300) - host.gib() - return + owner.gib() + return \ No newline at end of file diff --git a/code/game/gamemodes/abduction/machinery/dispenser.dm b/code/game/gamemodes/abduction/machinery/dispenser.dm index 91d290a508c..dd3a3c9607e 100644 --- a/code/game/gamemodes/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/abduction/machinery/dispenser.dm @@ -14,7 +14,7 @@ return rgb(rand(0,255),rand(0,255),rand(0,255)) /obj/machinery/abductor/gland_dispenser/New() - gland_types = typesof(/obj/item/gland) - /obj/item/gland + gland_types = typesof(/obj/item/organ/internal/gland) - /obj/item/organ/internal/gland gland_types = shuffle(gland_types) gland_colors = new/list(gland_types.len) amounts = new/list(gland_types.len) @@ -59,7 +59,7 @@ return /obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/gland)) + if(istype(W, /obj/item/organ/internal/gland)) if(!user.drop_item()) return W.loc = src diff --git a/code/game/gamemodes/abduction/machinery/experiment.dm b/code/game/gamemodes/abduction/machinery/experiment.dm index 4ea01595c37..e1c6bd42951 100644 --- a/code/game/gamemodes/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/abduction/machinery/experiment.dm @@ -137,7 +137,7 @@ if(H.stat == DEAD) say("Specimen deceased - please provide fresh sample.") return "Specimen deceased." - var/obj/item/gland/GlandTest = locate() in H + var/obj/item/organ/internal/gland/GlandTest = locate() in H if(!GlandTest) say("Experimental dissection not detected!") return "No glands detected!" @@ -165,7 +165,7 @@ H << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ - for(var/obj/item/gland/G in H) + for(var/obj/item/organ/internal/gland/G in H) G.Start() point_reward++ if(point_reward > 0) diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm index 79ff7f9b11e..0f4b1f855ca 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -7,10 +7,17 @@ /obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user) var/datum/mind/M = user.mind + var/list/organs = user.getorganszone("head") + user.getorganszone("eyes") + + for(var/obj/item/organ/internal/I in organs) + I.Remove(user, 1) + explosion(get_turf(user),0,0,2,0,silent=1) var/turf = get_turf(user) spawn(5) // So it's not killed in explosion var/mob/living/simple_animal/hostile/headcrab/crab = new(turf) + for(var/obj/item/organ/internal/I in organs) + I.loc = crab crab.origin = M if(M) M.transfer_to(crab) diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index 999aaf47bed..3d8916e6b66 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -26,7 +26,7 @@ user << "We transform our appearance." user.dna = chosen_dna - user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSRC),chosen_dna.real_name) + user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSRC),chosen_dna.real_name) changeling.purchasedpowers -= src feedback_add_details("changeling_powers","LFT") diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 310b470ff28..2ce8470c19c 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -12,9 +12,9 @@ return 0 user << "Our genes cry out!" - user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC) + user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC) // Human-form power now handled in monkeyize() feedback_add_details("changeling_powers","LF") .=1 - qdel(user) + qdel(user) \ No newline at end of file diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm index afc3776342f..349696c8fae 100644 --- a/code/game/gamemodes/gang/gang_pen.dm +++ b/code/game/gamemodes/gang/gang_pen.dm @@ -67,6 +67,7 @@ name = "gang implant" desc = "Makes you a gangster or such." activated = 0 + origin_tech = "materials=2;biotech=4;programming=4;syndicate=4" var/datum/gang/gang /obj/item/weapon/implant/gang/New(loc,var/setgang) @@ -85,39 +86,38 @@ Integrity: Implant's EMP function will destroy itself in the process."} return dat -/obj/item/weapon/implant/gang/implanted(mob/target) - ..() - for(var/obj/item/weapon/implant/I in target) - if(I != src) - qdel(I) +/obj/item/weapon/implant/gang/implant(mob/target) + if(..()) + for(var/obj/item/weapon/implant/I in target) + if(I != src) + qdel(I) - var/success - if(target.stat != DEAD) - if(target.mind in ticker.mode.get_gangsters()) - if(ticker.mode.remove_gangster(target.mind,0,1)) - success = 1 //Was not a gang boss, convert as usual - else - success = 1 //Not a gangster, convert as usual + var/success + if(target.stat != DEAD) + if(target.mind in ticker.mode.get_gangsters()) + if(ticker.mode.remove_gangster(target.mind,0,1)) + success = 1 //Was not a gang boss, convert as usual + else + success = 1 //Not a gangster, convert as usual - if(!target.mind) - return + if(!target.mind) + return 0 - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.sec_hud_set_implants() - if(success && ticker.mode.add_gangster(target.mind,gang,0)) - target.Paralyse(5) - else - target.visible_message("[target] seems to resist the implant!", "You feel the influence of your enemies try to invade your mind!") - qdel(src) + if(ishuman(target)) + if(success && ticker.mode.add_gangster(target.mind,gang,0)) + target.Paralyse(5) + else + target.visible_message("[target] seems to resist the implant!", "You feel the influence of your enemies try to invade your mind!") -/obj/item/weapon/implanter/gang/ - name = "implanter-gang" + qdel(src) + return -1 -/obj/item/weapon/implanter/gang/New(loc,var/gang) +/obj/item/weapon/implanter/gang + name = "implanter (gang)" + +/obj/item/weapon/implanter/gang/New(loc, var/gang) if(!gang) qdel(src) return imp = new /obj/item/weapon/implant/gang(src,gang) - ..() - update_icon() \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 1cb47606530..ceb70737d79 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -181,13 +181,9 @@ synd_mob.equip_to_slot_or_del(U, slot_in_backpack) var/obj/item/weapon/implant/weapons_auth/W = new/obj/item/weapon/implant/weapons_auth(synd_mob) - W.imp_in = synd_mob - W.implanted = 1 - W.implanted(synd_mob) + W.implant(synd_mob) var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob) - E.imp_in = synd_mob - E.implanted = 1 - E.implanted(synd_mob) + E.implant(synd_mob) synd_mob.faction |= "syndicate" synd_mob.update_icons() return 1 diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 87dbe5cd9c2..dd3b338b299 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -462,6 +462,7 @@ var/global/list/possible_items_special = list() /datum/objective/steal/exchange dangerrating = 10 + martyr_compatible = 0 /datum/objective/steal/exchange/proc/set_faction(faction,otheragent) target = otheragent diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index e446fe82255..4ec583172e6 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -60,8 +60,10 @@ "} if(patient.surgeries.len) - dat += "
Initiated Procedures
" + dat += "

Initiated Procedures
" for(var/datum/surgery/procedure in patient.surgeries) dat += "[capitalize(procedure.name)]
" + var/datum/surgery_step/surgery_step = procedure.get_surgery_step() + dat += "Next step: [capitalize(surgery_step.name)]
" dat += "
" return dat \ No newline at end of file diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index 2be31698d51..c3a71b8f485 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -1,58 +1,49 @@ -/obj/item/body_egg - name = "generic egg" +/obj/item/organ/internal/body_egg + name = "body egg" desc = "All slimy and yuck." - icon = 'icons/mob/alien.dmi' - icon_state = "larva0_dead" - var/mob/living/affected_mob + icon_state = "innards" + origin_tech = "biotech=5" + zone = "chest" + slot = "parasite_egg" -/obj/item/body_egg/New() - if(istype(loc, /mob/living)) - affected_mob = loc - affected_mob.status_flags |= XENO_HOST - SSobj.processing |= src - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - AddInfectionImages(affected_mob) - else - qdel(src) +/obj/item/organ/internal/body_egg/New(loc) + if(iscarbon(loc)) + src.Insert(loc) + return ..() -/obj/item/body_egg/Destroy() - if(affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() +/obj/item/organ/internal/body_egg/Insert(var/mob/living/carbon/M, special = 0) + ..() + owner.status_flags |= XENO_HOST + SSobj.processing |= src + owner.med_hud_set_status() + spawn(0) + AddInfectionImages(owner) + +/obj/item/organ/internal/body_egg/Remove(var/mob/living/carbon/M, special = 0) + SSobj.processing.Remove(src) + if(owner) + owner.status_flags &= ~(XENO_HOST) + owner.med_hud_set_status() spawn(0) - RemoveInfectionImages(affected_mob) - affected_mob = null + RemoveInfectionImages(owner) ..() -/obj/item/body_egg/process() - if(!affected_mob) return - if(loc != affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - SSobj.processing.Remove(src) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - RemoveInfectionImages(affected_mob) - affected_mob = null +/obj/item/organ/internal/body_egg/process() + if(!owner) return + if(!(src in owner.internal_organs)) + Remove(owner) return - egg_process() -/obj/item/body_egg/proc/egg_process() +/obj/item/organ/internal/body_egg/proc/egg_process() return -/obj/item/body_egg/proc/RefreshInfectionImage() +/obj/item/organ/internal/body_egg/proc/RefreshInfectionImage() RemoveInfectionImages() AddInfectionImages() -/obj/item/body_egg/proc/AddInfectionImages() +/obj/item/organ/internal/body_egg/proc/AddInfectionImages() return -/obj/item/body_egg/proc/RemoveInfectionImages() +/obj/item/organ/internal/body_egg/proc/RemoveInfectionImages() return \ No newline at end of file diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 12e6db99f6e..16769bb4b99 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -192,7 +192,7 @@ MASS SPECTROMETER user << "Blood level [blood_percent] %, [blood_volume] cl, type: [blood_type]" var/implant_detect - for(var/obj/item/cybernetic_implant/CI in H.internal_organs) + for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) implant_detect += "[H.name] is modified with a [CI.name].
" if(implant_detect) user.show_message("Detected cybernetic modifications:") diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index cab57a23a05..a2157fbec72 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -3,17 +3,19 @@ icon = 'icons/obj/implants.dmi' icon_state = "generic" //Shows up as the action button icon action_button_is_hands_free = 1 + origin_tech = "materials=2;biotech=3;programming=2" + var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like loyalty implants var/implanted = null var/mob/living/imp_in = null item_color = "b" - var/allow_reagents = 0 + var/allow_multiple = 0 + var/uses = -1 /obj/item/weapon/implant/proc/trigger(emote, mob/source) return - /obj/item/weapon/implant/proc/activate() return @@ -22,16 +24,53 @@ //What does the implant do upon injection? -//return 0 if the implant fails (ex. Revhead and loyalty implant.) -//return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.) -/obj/item/weapon/implant/proc/implanted(mob/source) +//return 1 if the implant injects +//return -1 if the implant fails to inject +//return 0 if there is no room for implant +/obj/item/weapon/implant/proc/implant(var/mob/source, var/mob/user) + var/obj/item/weapon/implant/imp_e = locate(src.type) in source + if(!allow_multiple && imp_e && imp_e != src) + if(imp_e.uses < initial(imp_e.uses)*2) + if(uses == -1) + imp_e.uses = -1 + else + imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) + qdel(src) + return 1 + else + return 0 + + if(activated) action_button_name = "Activate [src.name]" if(istype(source, /mob/living/carbon/human)) var/mob/living/carbon/human/H = source H.sec_hud_set_implants() + src.loc = source + imp_in = source + implanted = 1 + + if(user) + add_logs(user, source, "implanted", object="[name]") + return 1 +/obj/item/weapon/implant/proc/removed(var/mob/source) + src.loc = null + imp_in = null + implanted = 0 + + if(istype(source, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = source + H.sec_hud_set_implants() + + return 1 + +/obj/item/weapon/implant/Destroy() + if(imp_in) + removed(imp_in) + ..() + /obj/item/weapon/implant/proc/get_data() return "No information available" @@ -45,6 +84,7 @@ name = "tracking implant" desc = "Track with this." activated = 0 + origin_tech = "materials=2;magnets=2;programming=2;biotech=2" var/id = 1.0 /obj/item/weapon/implant/tracking/get_data() @@ -68,6 +108,7 @@ name = "firearms authentication implant" desc = "Lets you shoot your guns" icon_state = "auth" + origin_tech = "materials=2;magnets=2;programming=2;biotech=5;syndicate=5" activated = 0 /obj/item/weapon/implant/weapons_auth/get_data() @@ -78,181 +119,13 @@ Function: Allows operation of implant-locked weaponry, preventing equipment from falling into enemy hands."} return dat -/obj/item/weapon/implant/explosive - name = "microbomb implant" - desc = "And boom goes the weasel." - icon_state = "explosive" - var/weak = 1.6 - var/medium = 0.8 - var/heavy = 0.4 - var/delay = 7 - -/obj/item/weapon/implant/explosive/get_data() - var/dat = {"Implant Specifications:
- Name: Robust Corp RX-78 Employee Management Implant
- Life: Activates upon death.
- Important Notes: Explodes
-
- Implant Details:
- Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
- Special Features: Explodes
- Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/explosive/trigger(emote, mob/source) - if(emote == "deathgasp") - activate("death") - -/obj/item/weapon/implant/explosive/activate(cause) - if(!cause || !imp_in) return 0 - if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your microbomb implant? This will cause you to explode!", "Microbomb Implant Confirmation", "Yes", "No") != "Yes") - return 0 - for(var/obj/item/weapon/implant/explosive/E in imp_in) - heavy += 0.4 - medium += 0.8 - weak += 1.6 - delay += 7 - if(E != src) - qdel(E) - heavy = round(heavy) - medium = round(medium) - weak = round(weak) - imp_in << "You activate your microbomb implant." -//If the delay is short, just blow up already jeez - if(delay <= 7) - imp_in.gib() - explosion(src,heavy,medium,weak,weak, flame_range = weak) - qdel(src) - return - timed_explosion() - -/obj/item/weapon/implant/explosive/proc/timed_explosion() - imp_in.visible_message("[imp_in] starts beeping ominously!") - playsound(loc, 'sound/items/timer.ogg', 30, 0) - sleep(delay/4) - if(imp_in.stat) - imp_in.visible_message("[imp_in] doubles over in pain!") - imp_in.Weaken(7) - playsound(loc, 'sound/items/timer.ogg', 30, 0) - sleep(delay/4) - playsound(loc, 'sound/items/timer.ogg', 30, 0) - sleep(delay/4) - playsound(loc, 'sound/items/timer.ogg', 30, 0) - sleep(delay/4) - imp_in.gib() - explosion(src,heavy,medium,weak,weak, flame_range = weak) - qdel(src) - -/obj/item/weapon/implant/explosive/macro - name = "macrobomb implant" - desc = "And boom goes the weasel. And everything else nearby." - icon_state = "explosive" - weak = 16 - medium = 8 - heavy = 4 - delay = 70 - -/obj/item/weapon/implant/explosive/macro/activate(cause) - if(!cause || !imp_in) return 0 - if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your macrobomb implant? This will cause you to explode and gib!", "Macrobomb Implant Confirmation", "Yes", "No") != "Yes") - return 0 - for(var/obj/item/weapon/implant/explosive/macro/E in imp_in) - if(E != src) - qdel(E) - imp_in << "You activate your macrobomb implant." - timed_explosion() - -/obj/item/weapon/implant/chem - name = "chem implant" - desc = "Injects things." - icon_state = "reagents" - allow_reagents = 1 - -/obj/item/weapon/implant/chem/get_data() - var/dat = {"Implant Specifications:
- Name: Robust Corp MJ-420 Prisoner Management Implant
- Life: Deactivates upon death but remains within the body.
- Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
- will suffer from an increased appetite.

-
- Implant Details:
- Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
- the implant releases the chemicals directly into the blood stream.
- Special Features: - Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
- Can only be loaded while still in its original case.
- Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
- the implant may become unstable and either pre-maturely inject the subject or simply break."} - return dat - -/obj/item/weapon/implant/chem/New() - ..() - create_reagents(50) - -/obj/item/weapon/implant/chem/trigger(emote, mob/source) - if(emote == "deathgasp") - activate(reagents.total_volume) - -/obj/item/weapon/implant/chem/activate(cause) - if(!cause || !imp_in) return 0 - var/mob/living/carbon/R = imp_in - var/injectamount = null - if (cause == "action_button") - injectamount = reagents.total_volume - else - injectamount = cause - reagents.trans_to(R, injectamount) - R << "You hear a faint beep." - if(!reagents.total_volume) - R << "You hear a faint click from your chest." - qdel(src) - - -/obj/item/weapon/implant/loyalty - name = "loyalty implant" - desc = "Makes you loyal or such." - activated = 0 - -/obj/item/weapon/implant/loyalty/get_data() - var/dat = {"Implant Specifications:
- Name: Nanotrasen Employee Management Implant
- Life: Ten years.
- Important Notes: Personnel injected with this device tend to be much more loyal to the company.
-
- Implant Details:
- Function: Contains a small pod of nanobots that manipulate the host's mental functions.
- Special Features: Will prevent and cure most forms of brainwashing.
- Integrity: Implant will last so long as the nanobots are inside the bloodstream."} - return dat - - -/obj/item/weapon/implant/loyalty/implanted(mob/target) - ..() - if((target.mind in (ticker.mode.head_revolutionaries | ticker.mode.get_gang_bosses())) || is_shadow_or_thrall(target)) - target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") - return 0 - if(target.mind in ticker.mode.get_gangsters()) - ticker.mode.remove_gangster(target.mind) - target.visible_message("[src] was destroyed in the process!", "You feel a surge of loyalty towards Nanotrasen.") - return 0 - if(target.mind in ticker.mode.revolutionaries) - ticker.mode.remove_revolutionary(target.mind) - if(target.mind in ticker.mode.cult) - target << "You feel the corporate tendrils of Nanotrasen try to invade your mind!" - else - target << "You feel a surge of loyalty towards Nanotrasen." - return 1 - -/obj/item/weapon/implant/loyalty/Destroy() - if(imp_in.stat != DEAD) - imp_in << "You feel a sense of liberation as Nanotrasen's grip on your mind fades away." - ..() /obj/item/weapon/implant/adrenalin name = "adrenal implant" desc = "Removes all stuns and knockdowns." icon_state = "adrenal" - var/uses = 3 + origin_tech = "materials=2;biotech=4;combat=3;syndicate=4" + uses = 3 /obj/item/weapon/implant/adrenalin/get_data() var/dat = {"Implant Specifications:
@@ -285,8 +158,8 @@ name = "emp implant" desc = "Triggers an EMP." icon_state = "emp" - - var/uses = 2 + origin_tech = "materials=2;biotech=3;magnets=4;syndicate=4" + uses = 2 /obj/item/weapon/implant/emp/activate() if (src.uses < 1) return 0 diff --git a/code/game/objects/items/weapons/implants/implant_chem.dm b/code/game/objects/items/weapons/implants/implant_chem.dm new file mode 100644 index 00000000000..6f85742039b --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -0,0 +1,53 @@ +/obj/item/weapon/implant/chem + name = "chem implant" + desc = "Injects things." + icon_state = "reagents" + origin_tech = "materials=3;biotech=4" + flags = OPENCONTAINER + +/obj/item/weapon/implant/chem/get_data() + var/dat = {"Implant Specifications:
+ Name: Robust Corp MJ-420 Prisoner Management Implant
+ Life: Deactivates upon death but remains within the body.
+ Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
+ will suffer from an increased appetite.

+
+ Implant Details:
+ Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
+ the implant releases the chemicals directly into the blood stream.
+ Special Features: + Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
+ Can only be loaded while still in its original case.
+ Integrity: Implant will last so long as the subject is alive."} + return dat + +/obj/item/weapon/implant/chem/New() + ..() + create_reagents(50) + +/obj/item/weapon/implant/chem/trigger(emote, mob/source) + if(emote == "deathgasp") + activate(reagents.total_volume) + +/obj/item/weapon/implant/chem/activate(cause) + if(!cause || !imp_in) return 0 + var/mob/living/carbon/R = imp_in + var/injectamount = null + if (cause == "action_button") + injectamount = reagents.total_volume + else + injectamount = cause + reagents.trans_to(R, injectamount) + R << "You hear a faint beep." + if(!reagents.total_volume) + R << "You hear a faint click from your chest." + qdel(src) + + +/obj/item/weapon/implantcase/chem + name = "implant case - 'Remote Chemical'" + desc = "A glass case containing a remote chemical implant." + +/obj/item/weapon/implantcase/chem/New() + imp = new /obj/item/weapon/implant/chem(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm new file mode 100644 index 00000000000..719666b47b2 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -0,0 +1,119 @@ +/obj/item/weapon/implant/explosive + name = "microbomb implant" + desc = "And boom goes the weasel." + icon_state = "explosive" + origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" + var/weak = 1.6 + var/medium = 0.8 + var/heavy = 0.4 + var/delay = 7 + +/obj/item/weapon/implant/explosive/get_data() + var/dat = {"Implant Specifications:
+ Name: Robust Corp RX-78 Employee Management Implant
+ Life: Activates upon death.
+ Important Notes: Explodes
+
+ Implant Details:
+ Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
+ Special Features: Explodes
+ "} + return dat + +/obj/item/weapon/implant/explosive/trigger(emote, mob/source) + if(emote == "deathgasp") + activate("death") + +/obj/item/weapon/implant/explosive/activate(cause) + if(!cause || !imp_in) return 0 + if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your microbomb implant? This will cause you to explode!", "Microbomb Implant Confirmation", "Yes", "No") != "Yes") + return 0 + heavy = round(heavy) + medium = round(medium) + weak = round(weak) + imp_in << "You activate your microbomb implant." +//If the delay is short, just blow up already jeez + if(delay <= 7) + explosion(src,heavy,medium,weak,weak, flame_range = weak) + imp_in.gib() + qdel(src) + return + timed_explosion() + +/obj/item/weapon/implant/explosive/implant(mob/source) + var/obj/item/weapon/implant/explosive/imp_e = locate(src.type) in source + if(imp_e) + imp_e.heavy += heavy + imp_e.medium += medium + imp_e.weak += weak + imp_e.delay += delay + qdel(src) + return 1 + + return ..() + +/obj/item/weapon/implant/explosive/proc/timed_explosion() + imp_in.visible_message("[imp_in] starts beeping ominously!") + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + if(imp_in && imp_in.stat) + imp_in.visible_message("[imp_in] doubles over in pain!") + imp_in.Weaken(7) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + explosion(src,heavy,medium,weak,weak, flame_range = weak) + if(imp_in) + imp_in.gib() + qdel(src) + +/obj/item/weapon/implant/explosive/macro + name = "macrobomb implant" + desc = "And boom goes the weasel. And everything else nearby." + icon_state = "explosive" + origin_tech = "materials=3;combat=5;biotech=4;syndicate=5" + weak = 16 + medium = 8 + heavy = 4 + delay = 70 + +/obj/item/weapon/implant/explosive/macro/activate(cause) + if(!cause || !imp_in) return 0 + if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your macrobomb implant? This will cause you to explode and gib!", "Macrobomb Implant Confirmation", "Yes", "No") != "Yes") + return 0 + imp_in << "You activate your macrobomb implant." + timed_explosion() + +/obj/item/weapon/implant/explosive/macro/implant(mob/source) + var/obj/item/weapon/implant/explosive/imp_e = locate(src.type) in source + if(imp_e) + return 0 + imp_e = locate(/obj/item/weapon/implant/explosive) in source + if(imp_e) + heavy += imp_e.heavy + medium += imp_e.medium + weak += imp_e.weak + delay += imp_e.delay + qdel(imp_e) + + return ..() + + +/obj/item/weapon/implanter/explosive + name = "implanter (explosive)" + +/obj/item/weapon/implanter/explosive/New() + imp = new /obj/item/weapon/implant/explosive(src) + ..() + + +/obj/item/weapon/implantcase/explosive + name = "implant case - 'Explosive'" + desc = "A glass case containing an explosive implant." + +/obj/item/weapon/implantcase/explosive/New() + imp = new /obj/item/weapon/implant/explosive(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implant_freedom.dm similarity index 61% rename from code/game/objects/items/weapons/implants/implantfreedom.dm rename to code/game/objects/items/weapons/implants/implant_freedom.dm index 821cec4c572..e3e70e982a2 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implant_freedom.dm @@ -1,37 +1,50 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/obj/item/weapon/implant/freedom - name = "freedom implant" - desc = "Use this to escape from those evil Red Shirts." - icon_state = "freedom" - item_color = "r" - var/uses = 4.0 - - -/obj/item/weapon/implant/freedom/activate() - if (src.uses < 1) return 0 - src.uses-- - imp_in << "You feel a faint click." - if(iscarbon(imp_in)) - var/mob/living/carbon/C_imp_in = imp_in - C_imp_in.uncuff() - - -/obj/item/weapon/implant/freedom/get_data() - var/dat = {" -Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking -mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-Integrity: The battery is extremely weak and commonly after injection its -life can drive down to only 1 use.
-No Implant Specifics"} - return dat - - +/obj/item/weapon/implant/freedom + name = "freedom implant" + desc = "Use this to escape from those evil Red Shirts." + icon_state = "freedom" + item_color = "r" + origin_tech = "materials=2;magnets=3;biotech=3;syndicate=4" + uses = 4 + + +/obj/item/weapon/implant/freedom/activate() + if(uses == 0) return 0 + if(uses != -1) uses-- + imp_in << "You feel a faint click." + if(iscarbon(imp_in)) + var/mob/living/carbon/C_imp_in = imp_in + C_imp_in.uncuff() + + +/obj/item/weapon/implant/freedom/get_data() + var/dat = {" +Implant Specifications:
+Name: Freedom Beacon
+Life: optimum 5 uses
+Important Notes: Illegal
+
+Implant Details:
+Function: Transmits a specialized cluster of signals to override handcuff locking +mechanisms
+Special Features:
+Neuro-Scan- Analyzes certain shadow signals in the nervous system
+
+No Implant Specifics"} + return dat + + +/obj/item/weapon/implanter/freedom + name = "implanter (freedom)" + +/obj/item/weapon/implanter/freedom/New() + imp = new /obj/item/weapon/implant/freedom(src) + ..() + + +/obj/item/weapon/implantcase/freedom + name = "implant case - 'Freedom'" + desc = "A glass case containing a freedom implant." + +/obj/item/weapon/implantcase/freedom/New() + imp = new /obj/item/weapon/implant/freedom(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_loyality.dm b/code/game/objects/items/weapons/implants/implant_loyality.dm new file mode 100644 index 00000000000..3751cd63343 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_loyality.dm @@ -0,0 +1,65 @@ +/obj/item/weapon/implant/loyalty + name = "loyalty implant" + desc = "Makes you loyal or such." + origin_tech = "materials=2;biotech=4;programming=4" + activated = 0 + +/obj/item/weapon/implant/loyalty/get_data() + var/dat = {"Implant Specifications:
+ Name: Nanotrasen Employee Management Implant
+ Life: Ten years.
+ Important Notes: Personnel injected with this device tend to be much more loyal to the company.
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that manipulate the host's mental functions.
+ Special Features: Will prevent and cure most forms of brainwashing.
+ Integrity: Implant will last so long as the nanobots are inside the bloodstream."} + return dat + + +/obj/item/weapon/implant/loyalty/implant(mob/target) + if(..()) + if((target.mind in (ticker.mode.head_revolutionaries | ticker.mode.get_gang_bosses())) || is_shadow_or_thrall(target)) + target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") + imp_in = null + qdel(src) + return -1 + if(target.mind in ticker.mode.get_gangsters()) + ticker.mode.remove_gangster(target.mind) + target.visible_message("[src] was destroyed in the process!", "You feel a surge of loyalty towards Nanotrasen.") + imp_in = null + qdel(src) + return -1 + if(target.mind in ticker.mode.revolutionaries) + ticker.mode.remove_revolutionary(target.mind) + if(target.mind in ticker.mode.cult) + target << "You feel the corporate tendrils of Nanotrasen try to invade your mind!" + else + target << "You feel a surge of loyalty towards Nanotrasen." + return 1 + return 0 + +/obj/item/weapon/implant/loyalty/removed(mob/target) + if(..()) + if(target.stat != DEAD) + target << "You feel a sense of liberation as Nanotrasen's grip on your mind fades away." + return 1 + return 0 + + +/obj/item/weapon/implanter/loyalty + name = "implanter (loyalty)" + +/obj/item/weapon/implanter/loyalty/New() + imp = new /obj/item/weapon/implant/loyalty(src) + ..() + update_icon() + + +/obj/item/weapon/implantcase/loyalty + name = "implant case - 'Loyalty'" + desc = "A glass case containing a loyalty implant." + +/obj/item/weapon/implantcase/loyalty/New() + imp = new /obj/item/weapon/implant/loyalty(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index 5da2cd828bc..b38dbaea378 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -1,19 +1,28 @@ /obj/item/weapon/implantcase - name = "glass case" - desc = "A case containing an implant." + name = "implant case" + desc = "A glass case containing an implant." + icon = 'icons/obj/items.dmi' icon_state = "implantcase-0" item_state = "implantcase" throw_speed = 2 throw_range = 5 w_class = 1.0 + origin_tech = "materials=1;biotech=2" + materials = list(MAT_GLASS=500) var/obj/item/weapon/implant/imp = null /obj/item/weapon/implantcase/update_icon() if(imp) icon_state = "implantcase-[imp.item_color]" + origin_tech = imp.origin_tech + flags = imp.flags + reagents = imp.reagents else icon_state = "implantcase-0" + origin_tech = initial(origin_tech) + flags = initial(flags) + reagents = null /obj/item/weapon/implantcase/attackby(obj/item/weapon/W, mob/user, params) @@ -25,21 +34,13 @@ if(!in_range(src, user) && loc != user) return if(t) - name = "glass case- '[t]'" + name = "implant case - '[t]'" else - name = "glass case" - else if(istype(W, /obj/item/weapon/reagent_containers/syringe)) - if(!imp) return - if(!imp.allow_reagents) return - if(imp.reagents.total_volume >= imp.reagents.maximum_volume) - user << "[src] is full." - else - W.reagents.trans_to(imp, 5) - user << "You inject 5 units of the solution. The syringe now contains [W.reagents.total_volume] units." + name = "implant case" else if(istype(W, /obj/item/weapon/implanter)) var/obj/item/weapon/implanter/I = W if(I.imp) - if((imp || I.imp.implanted)) + if(imp || I.imp.implanted) return I.imp.loc = src imp = I.imp @@ -56,55 +57,28 @@ update_icon() I.update_icon() + /*else if(istype(W, /obj/item/ammo_casing/shotgun/implanter)) + var/obj/item/ammo_casing/shotgun/implanter/I = W + if(I.implanter) + src.attackby(I.implanter, user, params) */ // COMING SOON -- c0 + +/obj/item/weapon/implantcase/New() + ..() + update_icon() + /obj/item/weapon/implantcase/tracking - name = "glass case- 'Tracking'" - desc = "A case containing a tracking implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" + name = "implant case - 'Tracking'" + desc = "A glass case containing a tracking implant." /obj/item/weapon/implantcase/tracking/New() imp = new /obj/item/weapon/implant/tracking(src) ..() -/obj/item/weapon/implantcase/explosive - name = "glass case- 'Explosive'" - desc = "A case containing an explosive implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" - -/obj/item/weapon/implantcase/explosive/New() - imp = new /obj/item/weapon/implant/explosive(src) - ..() - - -/obj/item/weapon/implantcase/chem - name = "glass case- 'Chem'" - desc = "A case containing a chemical implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" - -/obj/item/weapon/implantcase/chem/New() - imp = new /obj/item/weapon/implant/chem(src) - ..() - - -/obj/item/weapon/implantcase/loyalty - name = "glass case- 'Loyalty'" - desc = "A case containing a loyalty implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" - -/obj/item/weapon/implantcase/loyalty/New() - imp = new /obj/item/weapon/implant/loyalty(src) - ..() - /obj/item/weapon/implantcase/weapons_auth - name = "glass case- 'Firearms Authentication'" - desc = "A case containing a firearms authentication implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" + name = "implant case - 'Firearms Authentication'" + desc = "A glass case containing a firearms authentication implant." /obj/item/weapon/implantcase/weapons_auth/New() imp = new /obj/item/weapon/implant/weapons_auth(src) diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 72aca3d4a66..5b36e5337ae 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -132,11 +132,8 @@ if(istype(imp, /obj/item/weapon/implant/loyalty)) M.visible_message("[M] has been implanted by the [src.name].") - if(imp.implanted(M)) - imp.loc = M - imp.imp_in = M - imp.implanted = 1 - implant_list -= imp + if(imp.implant(M)) + implant_list -= imp break return diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index cb54e6386b1..034e31ac510 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -1,82 +1,74 @@ /obj/item/weapon/implanter name = "implanter" + desc = "A sterile automatic implant injector." icon = 'icons/obj/items.dmi' icon_state = "implanter0" item_state = "syringe_0" throw_speed = 3 throw_range = 5 w_class = 2.0 + origin_tech = "materials=1;biotech=3;programming=2" + materials = list(MAT_METAL=600, MAT_GLASS=200) var/obj/item/weapon/implant/imp = null /obj/item/weapon/implanter/update_icon() if(imp) icon_state = "implanter1" + origin_tech = imp.origin_tech else icon_state = "implanter0" + origin_tech = initial(origin_tech) /obj/item/weapon/implanter/attack(mob/living/carbon/M, mob/user) if(!iscarbon(M)) return if(user && imp) - if(M.head && (M.head.flags & THICKMATERIAL)) - user << "[M]'s [M.head.name] is in the way! Take it off first!" - return - M.visible_message("[user] is attemping to implant [M].") + if(M != user) + M.visible_message("[user] is attemping to implant [M].") var/turf/T = get_turf(M) - if(T && (M == user || do_after(user, 50, target = M))) + if(T && (M == user || do_after(user, 50))) if(user && M && (get_turf(M) == T) && src && imp) - if(M.head && (M.head.flags & THICKMATERIAL)) - return - M.visible_message("[user] has implanted [M].", "[user] implants you with the implant.") - add_logs(user, M, "implanted", src) - user << "You implant the implant into [M]." - if(imp.implanted(M)) - imp.loc = M - imp.imp_in = M - imp.implanted = 1 + if(imp.implant(M, user)) + user << "You implant the implant into [M]." + M.visible_message("[user] has implanted [M].", "[user] implants you with the implant.") + imp = null + update_icon() - imp = null - update_icon() - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - H.sec_hud_set_implants() - - - -/obj/item/weapon/implanter/loyalty - name = "implanter-loyalty" - -/obj/item/weapon/implanter/loyalty/New() - imp = new /obj/item/weapon/implant/loyalty(src) +/obj/item/weapon/implanter/attackby(obj/item/weapon/W, mob/user, params) ..() - update_icon() + if(istype(W, /obj/item/weapon/pen)) + var/t = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_hand() != W) + return + if(!in_range(src, user) && loc != user) + return + if(t) + name = "implanter ([t])" + else + name = "implanter" - -/obj/item/weapon/implanter/explosive - name = "implanter-explosive" - -/obj/item/weapon/implanter/explosive/New() - imp = new /obj/item/weapon/implant/explosive(src) +/obj/item/weapon/implanter/New() ..() - update_icon() + spawn(1) + update_icon() + + /obj/item/weapon/implanter/adrenalin - name = "implanter-adrenalin" + name = "implanter (adrenalin)" /obj/item/weapon/implanter/adrenalin/New() imp = new /obj/item/weapon/implant/adrenalin(src) ..() - update_icon() /obj/item/weapon/implanter/emp - name = "implanter-EMP" + name = "implanter (EMP)" /obj/item/weapon/implanter/emp/New() imp = new /obj/item/weapon/implant/emp(src) ..() - update_icon() diff --git a/code/game/objects/items/weapons/implants/implantuplink.dm b/code/game/objects/items/weapons/implants/implantuplink.dm index 74a2b365aa9..b19bb66d995 100644 --- a/code/game/objects/items/weapons/implants/implantuplink.dm +++ b/code/game/objects/items/weapons/implants/implantuplink.dm @@ -3,18 +3,33 @@ desc = "Summon things." icon = 'icons/obj/radio.dmi' icon_state = "radio" + origin_tech = "materials=2;magnets=4;programming=4;biotech=4;syndicate=8;bluespace=5" /obj/item/weapon/implant/uplink/New() hidden_uplink = new(src) hidden_uplink.uses = 10 ..() -/obj/item/weapon/implant/uplink/implanted(mob/source) - ..() - hidden_uplink.uplink_owner="[source.key]" - return 1 +/obj/item/weapon/implant/uplink/implant(mob/source) + var/obj/item/weapon/implant/imp_e = locate(src.type) in source + if(imp_e) + imp_e.hidden_uplink.uses += hidden_uplink.uses + qdel(src) + return 1 + if(..()) + hidden_uplink.uplink_owner="[source.key]" + return 1 + return 0 /obj/item/weapon/implant/uplink/activate() if(hidden_uplink) - hidden_uplink.check_trigger(imp_in) \ No newline at end of file + hidden_uplink.check_trigger(imp_in) + + +/obj/item/weapon/implanter/uplink + name = "implanter (uplink)" + +/obj/item/weapon/implanter/uplink/New() + imp = new /obj/item/weapon/implant/uplink(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 1ceaaa88648..becd01a5308 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -53,17 +53,11 @@ return if("implant") - var/obj/item/weapon/implanter/F = new /obj/item/weapon/implanter(src) - F.imp = new /obj/item/weapon/implant/freedom(F) - var/obj/item/weapon/implanter/U = new /obj/item/weapon/implanter(src) - U.imp = new /obj/item/weapon/implant/uplink(U) - var/obj/item/weapon/implanter/C = new /obj/item/weapon/implanter(src) - C.imp = new /obj/item/weapon/implant/emp(C) - var/obj/item/weapon/implanter/K = new /obj/item/weapon/implanter(src) - K.imp = new /obj/item/weapon/implant/adrenalin(K) - var/obj/item/weapon/implanter/S = new /obj/item/weapon/implanter(src) - S.imp = new /obj/item/weapon/implant/explosive(S) - S.name += " (explosive)" + new /obj/item/weapon/implanter/freedom(src) + new /obj/item/weapon/implanter/uplink(src) + new /obj/item/weapon/implanter/emp(src) + new /obj/item/weapon/implanter/adrenalin(src) + new /obj/item/weapon/implanter/explosive(src) return if("hacker") @@ -173,8 +167,8 @@ ..() new /obj/item/weapon/grenade/empgrenade(src) new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/implanter/emp/(src) - new /obj/item/device/flashlight/emp/(src) + new /obj/item/weapon/implanter/emp(src) + new /obj/item/device/flashlight/emp(src) return /obj/item/weapon/storage/box/syndie_kit/chemical diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 0203442b693..4552fb78ff5 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -72,7 +72,7 @@ new /obj/item/weapon/storage/belt/medical(src) new /obj/item/device/flash/handheld(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) - new /obj/item/cybernetic_implant/eyes/hud/medical(src) + new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) /obj/structure/closet/secure_closet/animal name = "animal control" diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index d7497060491..8844b5c5be4 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -400,6 +400,7 @@ var/list/TYPES_SHORTCUTS = list( /obj/machinery/portable_atmospherics = "PORT_ATMOS", /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK", /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", + /obj/item/organ/internal = "ORGAN_INT", ) var/global/list/g_fancy_list_of_types = null diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm new file mode 100644 index 00000000000..ae500213e59 --- /dev/null +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -0,0 +1,56 @@ +/client/proc/manipulate_organs(mob/living/carbon/C in world) + set name = "Manipulate Organs" + set category = "Debug" + var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add organ", "add implant", "drop organ/implant", "remove organ/implant", "cancel") + + var/list/organs = list() + switch(operation) + if("add organ") + for(var/path in typesof(/obj/item/organ/internal) - /obj/item/organ/internal) + var/dat = replacetext("[path]", "/obj/item/organ/internal/", ":") + organs[dat] = path + + var/obj/item/organ/internal/organ = input("Select organ type:", "Organ Manipulation", null) in organs + organ = organs[organ] + organ = new organ + organ.Insert(C) + + if("add implant") + for(var/path in typesof(/obj/item/weapon/implant) - /obj/item/weapon/implant) + var/dat = replacetext("[path]", "/obj/item/weapon/implant/", ":") + organs[dat] = path + + var/obj/item/weapon/implant/organ = input("Select implant type:", "Organ Manipulation", null) in organs + organ = organs[organ] + organ = new organ + organ.implant(C) + + if("drop organ/implant", "remove organ/implant") + for(var/obj/item/organ/internal/I in C.internal_organs) + organs["[I.name] ([I.type])"] = I + + for(var/obj/item/weapon/implant/I in C) + organs["[I.name] ([I.type])"] = I + + var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) in organs + organ = organs[organ] + if(!organ) return + var/obj/item/organ/internal/O + var/obj/item/weapon/implant/I + + if(isorgan(organ)) + O = organ + O.Remove(C) + else + I = organ + I.removed(C) + + organ.loc = get_turf(C) + + if(operation == "remove organ/implant") + qdel(organ) + else if(I) // Put the implant in case. + var/obj/item/weapon/implantcase/case = new(get_turf(C)) + case.imp = I + I.loc = case + case.update_icon() \ No newline at end of file diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index d947599c6d5..5152ab29436 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -159,6 +159,8 @@ var/intercom_range_display_status = 0 src.verbs += /client/proc/print_pointers src.verbs += /client/proc/count_movable_instances src.verbs += /client/proc/cmd_show_at_list + src.verbs += /client/proc/cmd_show_at_list + src.verbs += /client/proc/manipulate_organs //src.verbs += /client/proc/cmd_admin_rejuvenate feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm index 7e36cf7e04a..4e6a69d591b 100644 --- a/code/modules/awaymissions/exile.dm +++ b/code/modules/awaymissions/exile.dm @@ -1,18 +1,10 @@ //Exile implants will allow you to use the station gate, but not return home. //This will allow security to exile badguys/for badguys to exile their kill targets -/obj/item/weapon/implanter/exile - name = "implanter-exile" - -/obj/item/weapon/implanter/exile/New() - imp = new /obj/item/weapon/implant/exile( src ) - ..() - update_icon() - - /obj/item/weapon/implant/exile name = "exile implant" desc = "Prevents you from returning from away missions" + origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3" activated = 0 /obj/item/weapon/implant/exile/get_data() @@ -22,11 +14,16 @@ return dat +/obj/item/weapon/implanter/exile + name = "implanter (exile)" + +/obj/item/weapon/implanter/exile/New() + imp = new /obj/item/weapon/implant/exile( src ) + ..() + /obj/item/weapon/implantcase/exile - name = "glass case- 'Exile'" - desc = "A case containing an exile implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" + name = "implant case - 'Exile'" + desc = "A glass case containing an exile implant." /obj/item/weapon/implantcase/exile/New() imp = new /obj/item/weapon/implant/exile(src) diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm index 54c0ed1c52e..ef5f43f7495 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm @@ -36,7 +36,7 @@ /datum/table_recipe/appendixburger name = "Appendix burger" reqs = list( - /obj/item/organ/appendix = 1, + /obj/item/organ/internal/appendix = 1, /obj/item/weapon/reagent_containers/food/snacks/bun = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/burger/appendix diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index b7552f60814..81a3f2a4cf5 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -114,7 +114,7 @@ if(89) new /obj/item/organ/brain/alien(src) if(90) - new /obj/item/organ/heart(src) + new /obj/item/organ/internal/heart(src) if(91) new /obj/item/device/soulstone/anybody(src) if(92) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index f4e3a3a3573..f96c94af11a 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -34,7 +34,12 @@ /mob/living/carbon/alien/New() verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + internal_organs += new /obj/item/organ/brain/alien + for(var/obj/item/organ/internal/I in internal_organs) + I.Insert(src) + + AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null)) ..() @@ -54,7 +59,7 @@ return storedPlasma /mob/living/carbon/alien/check_eye_prot() - return 2 + return ..() + 2 /mob/living/carbon/alien/getToxLoss() return 0 @@ -185,7 +190,7 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/mob/living/C in mob_list) if(C.status_flags & XENO_HOST) - var/obj/item/body_egg/alien_embryo/A = locate() in C + var/obj/item/organ/internal/body_egg/alien_embryo/A = locate() in C var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") client.images += I return diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 0f742d02a10..b62a11e5153 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -2,55 +2,53 @@ // It functions almost identically (see code/datums/diseases/alien_embryo.dm) var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/body_egg/alien_embryo +/obj/item/organ/internal/body_egg/alien_embryo name = "alien embryo" + icon = 'icons/mob/alien.dmi' + icon_state = "larva0_dead" var/stage = 0 -/obj/item/body_egg/alien_embryo/egg_process() +/obj/item/organ/internal/body_egg/alien_embryo/on_life() + switch(stage) + if(2, 3) + if(prob(1)) + owner.emote("sneeze") + if(prob(1)) + owner.emote("cough") + if(prob(1)) + owner << "Your throat feels sore." + if(prob(1)) + owner << "Mucous runs down the back of your throat." + if(4) + if(prob(1)) + owner.emote("sneeze") + if(prob(1)) + owner.emote("cough") + if(prob(2)) + owner << "Your muscles ache." + if(prob(20)) + owner.take_organ_damage(1) + if(prob(2)) + owner << "Your stomach hurts." + if(prob(20)) + owner.adjustToxLoss(1) + if(5) + owner << "You feel something tearing its way out of your stomach..." + owner.adjustToxLoss(10) + +/obj/item/organ/internal/body_egg/alien_embryo/egg_process() if(stage < 5 && prob(3)) stage++ spawn(0) RefreshInfectionImage() - switch(stage) - if(2, 3) - if(affected_mob == DEAD) - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - affected_mob << "Your throat feels sore." - if(prob(1)) - affected_mob << "Mucous runs down the back of your throat." - if(4) - if(affected_mob == DEAD) - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(2)) - affected_mob << "Your muscles ache." - if(prob(20)) - affected_mob.take_organ_damage(1) - if(prob(2)) - affected_mob << "Your stomach hurts." - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - if(5) - if(affected_mob != DEAD) - affected_mob << "You feel something tearing its way out of your stomach..." - affected_mob.adjustToxLoss(10) - affected_mob.updatehealth() - if(prob(50)) - AttemptGrow() + if(stage == 5 && prob(50)) + AttemptGrow() -/obj/item/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = 1) +/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = 1) + if(!owner) return var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET) var/client/C = null @@ -61,55 +59,47 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds if(candidates.len) C = pick(candidates) - else if(affected_mob.client) - C = affected_mob.client + else if(owner.client) + C = owner.client else stage = 4 // Let's try again later. return - if(affected_mob.lying) - affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie") + if(owner.lying) + owner.overlays += image('icons/mob/alien.dmi', loc = owner, icon_state = "burst_lie") else - affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand") + owner.overlays += image('icons/mob/alien.dmi', loc = owner, icon_state = "burst_stand") spawn(6) - var/location = get_turf(affected_mob) - if(!location) - location = affected_mob.loc - var/mob/living/carbon/alien/larva/new_xeno = new(location) + var/atom/xeno_loc = owner + if(!gib_on_success) + xeno_loc = get_turf(xeno_loc) + + var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc) new_xeno.key = C.key new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention if(gib_on_success) - affected_mob.gib() - if(istype(new_xeno.loc,/mob/living/carbon)) - var/mob/living/carbon/digester = new_xeno.loc - digester.stomach_contents += new_xeno + owner.stomach_contents += new_xeno + owner.gib() qdel(src) -/*---------------------------------------- -Proc: RefreshInfectionImage() -Des: Removes the current icons located in the infected mob adds the current stage -----------------------------------------*/ -/obj/item/body_egg/alien_embryo/RefreshInfectionImage() - RemoveInfectionImages() - AddInfectionImages() /*---------------------------------------- Proc: AddInfectionImages(C) Des: Adds the infection image to all aliens for this embryo ----------------------------------------*/ -/obj/item/body_egg/alien_embryo/AddInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/AddInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) - var/I = image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "infected[stage]") + var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]") alien.client.images += I /*---------------------------------------- Proc: RemoveInfectionImage(C) Des: Removes all images from the mob infected by this embryo ----------------------------------------*/ -/obj/item/body_egg/alien_embryo/RemoveInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/RemoveInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) for(var/image/I in alien.client.images) - if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == affected_mob) + if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == owner) qdel(I) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 6f514dc0d3b..ff8b9538eb8 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -116,7 +116,7 @@ var/const/MAX_ACTIVE_TIME = 400 if(loc == L) return 0 if(stat != CONSCIOUS) return 0 - if(locate(/obj/item/body_egg/alien_embryo) in L) return 0 + if(locate(/obj/item/organ/internal/body_egg/alien_embryo) in L) return 0 if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage L.visible_message("[src] leaps at [L]'s face!", \ @@ -176,8 +176,7 @@ var/const/MAX_ACTIVE_TIME = 400 icon_state = "[initial(icon_state)]_impregnated" if(!target.getlimb(/obj/item/organ/limb/robot/chest) && !(target.status_flags & XENO_HOST)) - new /obj/item/body_egg/alien_embryo(target) - + new /obj/item/organ/internal/body_egg/alien_embryo(target) if(iscorgi(target)) var/mob/living/simple_animal/pet/dog/corgi/C = target diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index c301a6a8d04..5df89ec19ae 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -9,7 +9,7 @@ throw_speed = 3 throw_range = 5 layer = 4.1 - origin_tech = "biotech=3" + origin_tech = "biotech=4" attack_verb = list("attacked", "slapped", "whacked") var/mob/living/carbon/brain/brainmob = null diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6c4d86d89ae..c54c9e9f592 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -530,4 +530,16 @@ var/const/GALOSHES_DONT_HELP = 8 I.throw_at(target,I.throw_range,I.throw_speed,src) if(61 to 90) //throw it down to the floor var/turf/target = get_turf(loc) - I.throw_at(target,I.throw_range,I.throw_speed,src) \ No newline at end of file + I.throw_at(target,I.throw_range,I.throw_speed,src) + +/mob/living/carbon/emp_act(severity) + for(var/obj/item/organ/internal/O in internal_organs) + O.emp_act(severity) + ..() + + +/mob/living/carbon/check_eye_prot() + var/number = ..() + for(var/obj/item/organ/internal/cyberimp/eyes/EFP in internal_organs) + number += EFP.flash_protect + return number \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 647e09e5efb..c9ff89d92bd 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -268,7 +268,7 @@ if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/obj/item/cybernetic_implant/eyes/hud/CIH = locate(/obj/item/cybernetic_implant/eyes/hud) in H.internal_organs + var/obj/item/organ/internal/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/internal/cyberimp/eyes/hud) if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH) var/perpname = get_face_name(get_id_name("")) if(perpname) @@ -277,9 +277,9 @@ msg += "Rank: [R.fields["rank"]]
" msg += "\[Front photo\] " msg += "\[Side photo\]
" - if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/cybernetic_implant/eyes/hud/medical)) + if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical)) var/implant_detect - for(var/obj/item/cybernetic_implant/CI in internal_organs) + for(var/obj/item/organ/internal/cyberimp/CI in internal_organs) implant_detect += "[name] is modified with a [CI.name].
" if(implant_detect) msg += "Detected cybernetic modifications:
" @@ -294,8 +294,9 @@ msg += "\[Medical evaluation\]
" - if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH,/obj/item/cybernetic_implant/eyes/hud/security)) - if(!user.stat && user != src) //|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/security)) + if(!user.stat && user != src) + //|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. var/criminal = "None" R = find_record("name", perpname, data_core.security) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 679fb191dc1..658bd354c0c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -22,10 +22,13 @@ /obj/item/organ/limb/r_arm, /obj/item/organ/limb/r_leg, /obj/item/organ/limb/l_leg) for(var/obj/item/organ/limb/O in organs) O.owner = src - internal_organs += new /obj/item/organ/appendix - internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/internal/appendix + internal_organs += new /obj/item/organ/internal/heart internal_organs += new /obj/item/organ/brain + for(var/obj/item/organ/internal/I in internal_organs) + I.Insert(src) + // for spawned humans; overwritten by other code ready_dna(src) randomize_human(src) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index af0c7205b31..70d3d476103 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -172,7 +172,7 @@ if(blocked <= 0) return 0 var/obj/item/organ/limb/organ = null - if(isorgan(def_zone)) + if(islimb(def_zone)) organ = def_zone else if(!def_zone) def_zone = ran_zone(def_zone) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 06944984cf5..5522563f1cd 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -11,7 +11,7 @@ emp_act var/organnum = 0 if(def_zone) - if(isorgan(def_zone)) + if(islimb(def_zone)) return checkarmor(def_zone, type) var/obj/item/organ/limb/affecting = get_organ(ran_zone(def_zone)) return checkarmor(affecting, type) @@ -190,7 +190,6 @@ emp_act apply_effect(20, PARALYZE, armor) if(prob(I.force + min(100,100 - src.health)) && src != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(mind) - ticker.mode.remove_gangster(mind) if(bloody) //Apply blood if(wear_mask) wear_mask.add_blood(src) @@ -469,4 +468,4 @@ emp_act L.take_damage(I.w_class*I.embedded_impact_pain_multiplier) visible_message("\the [I.name] embeds itself in [src]'s [L.getDisplayName()]!","\the [I.name] embeds itself in your [L.getDisplayName()]!") return - return ..() + return ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 3e512e7b825..6950ff303f8 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -80,7 +80,7 @@ ///checkeyeprot() ///Returns a number between -1 to 2 /mob/living/carbon/human/check_eye_prot() - var/number = 0 + var/number = ..() if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item number += HFP.flash_protect @@ -90,9 +90,6 @@ if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask var/obj/item/clothing/mask/MFP = src.wear_mask number += MFP.flash_protect - var/obj/item/cybernetic_implant/eyes/EFP = locate() in src - if(EFP) - number += EFP.flash_protect return number /mob/living/carbon/human/check_ear_prot() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0e90a523120..12266289786 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1040,7 +1040,6 @@ H.apply_effect(20, PARALYZE, armor) if(prob(I.force + ((100 - H.health)/2)) && H != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(H.mind) - ticker.mode.remove_gangster(H.mind) if(bloody) //Apply blood if(H.wear_mask) @@ -1101,7 +1100,7 @@ if(blocked <= 0) return 0 var/obj/item/organ/limb/organ = null - if(isorgan(def_zone)) + if(islimb(def_zone)) organ = def_zone else if(!def_zone) def_zone = ran_zone(def_zone) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 16d75fc08a4..8f6db5b5086 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -9,6 +9,8 @@ if(..()) . = 1 + for(var/obj/item/organ/internal/O in internal_organs) + O.on_life() //Updates the number of stored chemicals for powers handle_changeling() @@ -456,7 +458,6 @@ return 1 /mob/living/carbon/update_sight() - if(stat == DEAD) sight |= SEE_TURFS sight |= SEE_MOBS @@ -521,3 +522,8 @@ //We totally need a sweat system cause it totally makes sense...~ bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers + +/mob/living/carbon/handle_actions() + ..() + for(var/obj/item/I in internal_organs) + give_action_button(I, 1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 1d1bbcc64d5..7a2a5379910 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -16,10 +16,13 @@ verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down - internal_organs += new /obj/item/organ/appendix - internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/internal/appendix + internal_organs += new /obj/item/organ/internal/heart internal_organs += new /obj/item/organ/brain + for(var/obj/item/organ/internal/I in internal_organs) + I.Insert(src) + if(name == "monkey") name = text("monkey ([rand(1, 1000)])") real_name = name @@ -272,4 +275,11 @@ if(wear_mask) protection = max(1 - wear_mask.permeability_coefficient, protection) protection = protection/7 //the rest of the body isn't covered. - return protection \ No newline at end of file + return protection + +/mob/living/carbon/monkey/check_eye_prot() + var/number = ..() + if(istype(src.wear_mask, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/MFP = src.wear_mask + number += MFP.flash_protect + return number \ No newline at end of file diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 4d32293c25b..5fbd65c7037 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -138,27 +138,27 @@ if(A.CheckRemoval(src)) A.Remove(src) for(var/obj/item/I in src) - if(I.action_button_name) - if(!I.action) - if(I.action_button_is_hands_free) - I.action = new/datum/action/item_action/hands_free - else - I.action = new/datum/action/item_action - I.action.name = I.action_button_name - I.action.target = I - I.action.Grant(src) - for(var/obj/item/T in I) - if(T.action_button_name && T.action_button_internal) - if(!T.action) - if(T.action_button_is_hands_free) - T.action = new/datum/action/item_action/hands_free - else - T.action = new/datum/action/item_action - T.action.name = T.action_button_name - T.action.target = T - T.action.Grant(src) + give_action_button(I, 1) return +/mob/living/proc/give_action_button(var/obj/item/I, recursive = 0) + if(I.action_button_name) + if(!I.action) + if(istype(I, /obj/item/organ/internal)) + I.action = new/datum/action/organ_action + else if(I.action_button_is_hands_free) + I.action = new/datum/action/item_action/hands_free + else + I.action = new/datum/action/item_action + I.action.name = I.action_button_name + I.action.target = I + I.action.Grant(src) + + if(recursive) + for(var/obj/item/T in I) + give_action_button(I, recursive - 1) + + //this handles hud updates. Calls update_vision() and handle_hud_icons() /mob/living/proc/handle_regular_hud_updates() if(!client) return 0 diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 2fe08fe36ed..587e686d67d 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -21,13 +21,15 @@ var/datum/mind/origin var/egg_lain = 0 -/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/human/victim) - var/obj/item/body_egg/changeling_egg/egg = new(victim) +/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim) + var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim) + egg.Insert(victim) if(origin) - egg.owner = origin + egg.origin = origin else if(mind) // Let's make this a feature - egg.owner = mind - victim.internal_organs += egg + egg.origin = mind + for(var/obj/item/organ/internal/I in src) + I.loc = egg visible_message("[src] lays an egg in a [victim].") egg_lain = 1 @@ -35,9 +37,10 @@ if(egg_lain) target.attack_animal(src) return - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(H.stat == DEAD) + if(iscarbon(target) && !ismonkey(target)) + // Changeling egg can survive in aliens! + var/mob/living/carbon/C = target + if(C.stat == DEAD) Infect(target) src << "With your egg laid you feel your death rapidly approaching, time to die..." spawn(100) @@ -48,32 +51,36 @@ -/obj/item/body_egg/changeling_egg +/obj/item/organ/internal/body_egg/changeling_egg name = "changeling egg" - desc = "Twitching and disgusting" - var/datum/mind/owner + desc = "Twitching and disgusting." + origin_tech = "biotech=7" // You need to be really lucky to obtain it. + var/datum/mind/origin var/time - var/used -/obj/item/body_egg/changeling_egg/egg_process() - //Changeling eggs grow in dead people +/obj/item/organ/internal/body_egg/changeling_egg/egg_process() + // Changeling eggs grow in dead people time++ if(time >= EGG_INCUBATION_TIME) Pop() + Remove(owner) + qdel(src) -/obj/item/body_egg/changeling_egg/proc/Pop() - if(!used) - var/mob/living/carbon/monkey/M = new(affected_mob.loc) - if(owner) - owner.transfer_to(M) - if(owner.changeling) - owner.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null) - M.key = owner.key - if(ishuman(affected_mob)) - var/mob/living/carbon/human/H = affected_mob - H.internal_organs.Remove(src) - affected_mob.gib() - used = 1 - qdel(src) +/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop() + var/mob/living/carbon/monkey/M = new(owner) + owner.stomach_contents += M + + for(var/obj/item/organ/internal/I in src) + I.Insert(M, 1) + + if(!origin && owner.mind) + origin = owner.mind + + if(origin) + origin.transfer_to(M) + if(origin.changeling) + origin.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null) + M.key = origin.key + owner.gib() #undef EGG_INCUBATION_TIME diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 400a0facf8b..857b7f35181 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -125,7 +125,7 @@ return 1 return 0 -/proc/isorgan(A) +/proc/islimb(A) if(istype(A, /obj/item/organ/limb)) return 1 return 0 diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 46d057fd8fc..674b88eacb6 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -3,15 +3,18 @@ return //Handle items on mob - //first implants + //first implants & organs var/list/implants = list() + var/list/int_organs = list() + if (tr_flags & TR_KEEPIMPLANTS) for(var/obj/item/weapon/implant/W in src) implants += W - if(tr_flags & TR_KEEPITEMS) - for(var/obj/item/W in (src.contents-implants)) - unEquip(W) + if (tr_flags & TR_KEEPORGANS) + for(var/obj/item/organ/internal/I in internal_organs) + int_organs += I + I.Remove(src, 1) //Make mob invisible and spawn animation regenerate_icons() @@ -70,6 +73,14 @@ I.loc = O I.implanted = O + //re-add organs to new mob + if(tr_flags & TR_KEEPORGANS) + for(var/obj/item/organ/internal/I in O.internal_organs) + qdel(I) + + for(var/obj/item/organ/internal/I in int_organs) + I.Insert(O, 1) + //transfer mind and delete old mob if(mind) mind.transfer_to(O) @@ -98,12 +109,19 @@ return //Handle items on mob - //first implants + //first implants & organs var/list/implants = list() + var/list/int_organs = list() + if (tr_flags & TR_KEEPIMPLANTS) for(var/obj/item/weapon/implant/W in src) implants += W + if (tr_flags & TR_KEEPORGANS) + for(var/obj/item/organ/internal/I in internal_organs) + int_organs += I + I.Remove(src, 1) + //now the rest if (tr_flags & TR_KEEPITEMS) for(var/obj/item/W in (src.contents-implants)) @@ -187,6 +205,13 @@ I.implanted = O O.sec_hud_set_implants() + if(tr_flags & TR_KEEPORGANS) + for(var/obj/item/organ/internal/I in O.internal_organs) + qdel(I) + + for(var/obj/item/organ/internal/I in int_organs) + I.Insert(O, 1) + if(mind) mind.transfer_to(O) O.a_intent = "help" diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index c9e36f27b46..37e5ff55bd2 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -213,7 +213,5 @@ Contents: equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src) - E.imp_in = src - E.implanted = 1 - E.implanted(src) + E.implant(src) return 1 diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index abf6b2663a7..1501167a730 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -118,7 +118,7 @@ req_tech = list("materials" = 6, "programming" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 500) - build_path = /obj/item/cybernetic_implant/eyes/hud/medical + build_path = /obj/item/organ/internal/cyberimp/eyes/hud/medical category = list("Medical Designs") /datum/design/cyberimp_security_hud @@ -128,7 +128,7 @@ req_tech = list("materials" = 6, "programming" = 5, "biotech" = 4, "combat" = 2) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 750, MAT_GOLD = 750) - build_path = /obj/item/cybernetic_implant/eyes/hud/security + build_path = /obj/item/organ/internal/cyberimp/eyes/hud/security category = list("Medical Designs") /datum/design/cyberimp_xray @@ -138,7 +138,7 @@ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/cybernetic_implant/eyes/xray + build_path = /obj/item/organ/internal/cyberimp/eyes/xray category = list("Medical Designs") /datum/design/cyberimp_thermals @@ -148,7 +148,7 @@ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "syndicate" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/cybernetic_implant/eyes/thermals + build_path = /obj/item/organ/internal/cyberimp/eyes/thermals category = list("Medical Designs") /datum/design/cyberimp_antidrop @@ -158,7 +158,7 @@ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 400, MAT_GOLD = 400) - build_path = /obj/item/cybernetic_implant/brain/anti_drop + build_path = /obj/item/organ/internal/cyberimp/brain/anti_drop category = list("Medical Designs") /datum/design/cyberimp_antistun @@ -168,7 +168,7 @@ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 1000) - build_path = /obj/item/cybernetic_implant/brain/anti_stun + build_path = /obj/item/organ/internal/cyberimp/brain/anti_stun category = list("Medical Designs") /datum/design/cyberimp_nutriment @@ -178,7 +178,7 @@ req_tech = list("materials" = 6, "programming" = 4, "biotech" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 500) - build_path = /obj/item/cybernetic_implant/chest/nutriment + build_path = /obj/item/organ/internal/cyberimp/chest/nutriment category = list("Medical Designs") /datum/design/cyberimp_nutriment_plus @@ -188,7 +188,7 @@ req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 750) - build_path = /obj/item/cybernetic_implant/chest/nutriment/plus + build_path = /obj/item/organ/internal/cyberimp/chest/nutriment/plus category = list("Medical Designs") /datum/design/cyberimp_reviver @@ -198,5 +198,5 @@ req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "syndicate" = 4) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/cybernetic_implant/chest/reviver - category = list("Medical Designs") + build_path = /obj/item/organ/internal/cyberimp/chest/reviver + category = list("Medical Designs") \ No newline at end of file diff --git a/code/modules/surgery/appendectomy.dm b/code/modules/surgery/appendectomy.dm index 0ba1db2da7c..c89d1776deb 100644 --- a/code/modules/surgery/appendectomy.dm +++ b/code/modules/surgery/appendectomy.dm @@ -2,15 +2,15 @@ name = "appendectomy" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/extract_appendix, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "groin" - requires_organic_chest = 1 + possible_locs = list("groin") //extract appendix /datum/surgery_step/extract_appendix + name = "extract appendix" accept_hand = 1 time = 64 - var/obj/item/organ/appendix/A = null + var/obj/item/organ/internal/appendix/A = null /datum/surgery_step/extract_appendix/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) A = locate() in target.internal_organs @@ -23,9 +23,7 @@ if(A) user.visible_message("[user] successfully removes [target]'s appendix!", "You successfully removes [target]'s appendix.") A.loc = get_turf(target) - target.internal_organs -= A - for(var/datum/disease/appendicitis in target.viruses) - appendicitis.cure() + A.Remove(target) else user << "You can't find an appendix in [target]!" return 1 \ No newline at end of file diff --git a/code/modules/surgery/brain_removal.dm b/code/modules/surgery/brain_removal.dm index 0d57fb6f9a2..0d2426775a6 100644 --- a/code/modules/surgery/brain_removal.dm +++ b/code/modules/surgery/brain_removal.dm @@ -2,11 +2,13 @@ name = "brain removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/extract_brain) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "head" + possible_locs = list("head") + requires_organic_bodypart = 0 //extract brain /datum/surgery_step/extract_brain + name = "extract brain" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 55) time = 64 var/obj/item/organ/brain/B = null diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 6f556860bee..9ad5d579ae1 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -2,12 +2,12 @@ name = "cavity implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "chest" - requires_organic_chest = 1 + possible_locs = list("chest") //handle cavity /datum/surgery_step/handle_cavity + name = "implant item" accept_hand = 1 accept_any_item = 1 time = 32 @@ -25,7 +25,7 @@ /datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(tool) - if(IC || tool.w_class > 3 || (tool.flags & NODROP) || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) + if(IC || tool.w_class > 3 || NODROP in tool.flags || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) user << "You can't seem to fit [tool] in [target]'s [target_zone]!" return 0 else diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm index 6a38e160560..fe976b25824 100644 --- a/code/modules/surgery/core_removal.dm +++ b/code/modules/surgery/core_removal.dm @@ -7,6 +7,7 @@ //extract brain /datum/surgery_step/extract_core + name = "extract core" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 100) time = 16 diff --git a/code/modules/surgery/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm index ced4776f535..ed6813bf087 100644 --- a/code/modules/surgery/cybernetic_implants.dm +++ b/code/modules/surgery/cybernetic_implants.dm @@ -1,42 +1,45 @@ #define MAX_BRAIN_IMPLANT 2 #define MAX_CHEST_IMPLANT 3 -/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/implant, datum/surgery/surgery) +/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/implant, datum/surgery/surgery) user.visible_message("[user] begins to implant [target] with [implant].", "You begin to implant [target] with [implant]...") //[[[[EYES]]]] -/datum/surgery/eye_cybernetic_implant/eyes +/datum/surgery/cybernetic_implant/eyes name = "eye cybernetic implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/cybernetic_implant/eyes, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) - location = "eyes" + possible_locs = list("eyes") /datum/surgery_step/cybernetic_implant/eyes - implements = list(/obj/item/cybernetic_implant/eyes = 100) + name = "insert eye cybernetic implant" + implements = list(/obj/item/organ/internal/cyberimp/eyes = 100) time = 32 -/datum/surgery_step/cybernetic_implant/eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/eyes/implant, datum/surgery/surgery) +/datum/surgery_step/cybernetic_implant/eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/eyes/implant, datum/surgery/surgery) if(implant) var/full = 0 - if(locate(/obj/item/cybernetic_implant/eyes,target.internal_organs)) + if(locate(/obj/item/organ/internal/cyberimp/eyes, target.internal_organs)) full = 1 insert(user,target,implant,target_zone,full) return 1 //[[[[BRAIN]]]] -/datum/surgery/eye_cybernetic_implant/brain +/datum/surgery/cybernetic_implant/brain name = "brain cybernetic implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/brain, /datum/surgery_step/close) - location = "head" + possible_locs = list("head") + requires_organic_bodypart = 0 /datum/surgery_step/cybernetic_implant/brain - implements = list(/obj/item/cybernetic_implant/brain = 100) + name = "insert brain cybernetic implant" + implements = list(/obj/item/organ/internal/cyberimp/brain = 100) time = 32 -/datum/surgery_step/cybernetic_implant/brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/brain/implant, datum/surgery/surgery) +/datum/surgery_step/cybernetic_implant/brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/brain/implant, datum/surgery/surgery) if(implant) var/full = 0 for(var/obj/item/I in target.internal_organs) - if(istype(I,/obj/item/cybernetic_implant/brain)) + if(istype(I,/obj/item/organ/internal/cyberimp/brain)) full++ if(full < MAX_BRAIN_IMPLANT) @@ -45,20 +48,22 @@ return 1 //[[[[CHEST]]]] -/datum/surgery/eye_cybernetic_implant/chest +/datum/surgery/cybernetic_implant/chest name = "torso cybernetic implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/chest, /datum/surgery_step/close) - location = "chest" + possible_locs = list("chest") + requires_organic_bodypart = 0 /datum/surgery_step/cybernetic_implant/chest - implements = list(/obj/item/cybernetic_implant/chest = 100) + name = "insert torso cybernetic implant" + implements = list(/obj/item/organ/internal/cyberimp/chest = 100) time = 32 -/datum/surgery_step/cybernetic_implant/chest/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/chest/implant, datum/surgery/surgery) +/datum/surgery_step/cybernetic_implant/chest/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/chest/implant, datum/surgery/surgery) if(implant) var/full = 0 for(var/obj/item/I in target.internal_organs) - if(istype(I,/obj/item/cybernetic_implant/chest)) + if(istype(I,/obj/item/organ/internal/cyberimp/chest)) full++ if(full < MAX_CHEST_IMPLANT) full = 0 @@ -66,14 +71,10 @@ insert(user,target,implant,target_zone,full) return 1 -/datum/surgery_step/cybernetic_implant/proc/insert(mob/user, mob/living/carbon/target, obj/item/cybernetic_implant/implant,target_zone,full) +/datum/surgery_step/cybernetic_implant/proc/insert(mob/user, mob/living/carbon/target, obj/item/organ/internal/cyberimp/implant,target_zone,full) if(full) user << "You can't seem to implant anything else into the [target]'s [target_zone]!" else - if(!user.drop_item()) - return user.visible_message("[user] inserts [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone]!", "You insert [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone].") - implant.owner = target - implant.function() - target.internal_organs |= implant - implant.loc = target \ No newline at end of file + user.drop_item() + implant.Insert(target) \ No newline at end of file diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 71e136efa72..06117fb80d7 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -2,11 +2,12 @@ name = "eye surgery" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "eyes" - + possible_locs = list("eyes") + requires_organic_bodypart = 0 //fix eyes /datum/surgery_step/fix_eyes + name = "fix eyes" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/screwdriver = 45, /obj/item/weapon/pen = 25) time = 64 diff --git a/code/modules/surgery/gender_reassignment.dm b/code/modules/surgery/gender_reassignment.dm index 4cc6be2d953..797450ae2f6 100644 --- a/code/modules/surgery/gender_reassignment.dm +++ b/code/modules/surgery/gender_reassignment.dm @@ -2,12 +2,12 @@ name = "gender reassignment" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/reshape_genitals, /datum/surgery_step/close) species = list(/mob/living/carbon/human) - location = "groin" - requires_organic_chest = 1 + possible_locs = list("groin") //reshape_genitals /datum/surgery_step/reshape_genitals + name = "reshape genitals" implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/hatchet = 50, /obj/item/weapon/wirecutters = 35) time = 64 diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/generic_steps.dm index a4ea6e51ba2..1f01549e999 100644 --- a/code/modules/surgery/generic_steps.dm +++ b/code/modules/surgery/generic_steps.dm @@ -1,6 +1,7 @@ //make incision /datum/surgery_step/incise + name = "make incision" implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/kitchen/knife = 65, /obj/item/weapon/shard = 45) time = 24 @@ -11,15 +12,22 @@ //clamp bleeders /datum/surgery_step/clamp_bleeders + name = "clamp bleeders" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/wirecutters = 60, /obj/item/stack/cable_coil = 15) time = 48 /datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to clamp bleeders in [target]'s [parse_zone(target_zone)].", "You begin to clamp bleeders in [target]'s [parse_zone(target_zone)]...") +/datum/surgery_step/clamp_bleeders/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(locate(/datum/surgery_step/saw) in surgery.steps) + target.heal_organ_damage(20,0) + return ..() + //retract skin /datum/surgery_step/retract_skin + name = "retract skin" implements = list(/obj/item/weapon/retractor = 100, /obj/item/weapon/screwdriver = 45, /obj/item/weapon/wirecutters = 35) time = 32 @@ -30,6 +38,7 @@ //close incision /datum/surgery_step/close + name = "mend incision" implements = list(/obj/item/weapon/cautery = 100, /obj/item/weapon/weldingtool = 70, /obj/item/weapon/lighter = 45, /obj/item/weapon/match = 20) time = 32 @@ -55,14 +64,26 @@ return 0 +/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(locate(/datum/surgery_step/saw) in surgery.steps) + target.heal_organ_damage(45,0) + return ..() + + //saw bone /datum/surgery_step/saw + name = "saw bone" implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchen/knife/butcher = 25) time = 64 /datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].", "You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...") +/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.apply_damage(50,"brute","[target_zone]") - + user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!", "You saw [target]'s [parse_zone(target_zone)] open.") + return 1 \ No newline at end of file diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 4982c6bcc64..021eddeb277 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -1,65 +1,64 @@ /proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user) if(istype(M)) + var/mob/living/carbon/human/H + var/obj/item/organ/limb/affecting + var/selected_zone = user.zone_sel.selecting + + if(istype(M, /mob/living/carbon/human)) + H = M + affecting = H.get_organ(check_zone(selected_zone)) + if(M.lying || isslime(M)) //if they're prone or a slime - var/list/all_surgeries = surgeries_list.Copy() - var/list/available_surgeries = list() - for(var/i in all_surgeries) - var/datum/surgery/S = all_surgeries[i] + var/datum/surgery/current_surgery - if(locate(S.type) in M.surgeries) - continue - if(S.user_species_restricted) - if(!istype(user, /mob/living/carbon/human)) + for(var/datum/surgery/S in M.surgeries) + if(S.location == selected_zone) + current_surgery = S + + if(!current_surgery) + var/list/all_surgeries = surgeries_list.Copy() + var/list/available_surgeries = list() + for(var/i in all_surgeries) + var/datum/surgery/S = all_surgeries[i] + if(!S.possible_locs.Find(selected_zone)) continue - var/mob/living/carbon/human/doc = user - if(!(doc.dna.species.id in S.user_species_ids)) + if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) continue - if(S.target_must_be_dead && M.stat != DEAD) - continue - if(S.target_must_be_fat && !(M.disabilities & FAT)) - continue - - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M //So we can use get_organ and not some terriblly long Switch or something worse - RR - - if(S.requires_organic_chest && H.getlimb(/obj/item/organ/limb/robot/chest)) //This a seperate case to below, see "***" in surgery.dm - RR + if(!S.can_start(user, M)) continue + for(var/path in S.species) + if(istype(M, path)) + available_surgeries[S.name] = S + break - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting)) + var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries + if(P && user.Adjacent(M) && (I in user)) + var/datum/surgery/S = available_surgeries[P] + var/datum/surgery/procedure = new S.type + if(procedure) + procedure.location = selected_zone + if(procedure.ignore_clothes || get_location_accessible(M, selected_zone)) + M.surgeries += procedure + procedure.organ = affecting + user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].", \ + "You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].") - if(affecting.status == ORGAN_ROBOTIC && affecting.body_part != HEAD) //Cannot operate on Robotic organs except for the head. - RR - continue + add_logs(user, M, "operated", addition="Operation type: [procedure.name], location: [selected_zone]") + else + user << "You need to expose [M]'s [parse_zone(selected_zone)] first!" - for(var/path in S.species) - if(istype(M, path)) - available_surgeries[S.name] = S - break - - var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries - if(P) - var/datum/surgery/S = available_surgeries[P] - var/datum/surgery/procedure = new S.type - if(procedure) - if(get_location_accessible(M, procedure.location) || procedure.ignore_clothes) - if(procedure.location == "anywhere") // if location == "anywhere" change location to the surgeon's target, otherwise leave location as is. - procedure.location = user.zone_sel.selecting - M.surgeries += procedure - user.visible_message("[user] drapes [I] over [M]'s [parse_zone(procedure.location)] to prepare for \an [procedure.name].", "You drape [I] over [M]'s [parse_zone(procedure.location)] to prepare for \an [procedure.name].") - - add_logs(user, M, "operated", addition="Operation type: [procedure.name]") - feedback_add_details("surgery_initiated","[procedure.name]") - return 1 - else - user << "You need to expose [M]'s [procedure.location] first!" - return 1 //return 1 so we don't slap the guy in the dick with the drapes. - else - return 1 //once the input menu comes up, cancelling it shouldn't hit the guy with the drapes either. + else if(current_surgery.status == 1 && !current_surgery.step_in_progress) + M.surgeries -= current_surgery + user.visible_message("[user] removes the drapes from [M]'s [parse_zone(selected_zone)].", \ + "You remove the drapes from [M]'s [parse_zone(selected_zone)].") + qdel(current_surgery) + return 1 return 0 -/proc/get_location_modifier(mob/M) +proc/get_location_modifier(mob/M) var/turf/T = get_turf(M) if(locate(/obj/structure/optable, T)) return 1 diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 86851838afc..b3ab5a6379c 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -2,22 +2,19 @@ name = "implant removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "chest" - requires_organic_chest = 1 - + possible_locs = list("chest") + requires_organic_bodypart = 0 //extract implant /datum/surgery_step/extract_implant + name = "extract implant" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 65) time = 64 var/obj/item/weapon/implant/I = null /datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - for(var/obj/item/weapon/implant/W in target) - if(W.imp_in == target) //Checking that it's actually implanted, not just in his pocket - I = W - break + I = locate(/obj/item/weapon/implant) in target if(I) user.visible_message("[user] begins to extract [I] from [target]'s [target_zone].", "You begin to extract [I] from [target]'s [target_zone]...") else @@ -26,10 +23,25 @@ /datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(I) user.visible_message("[user] successfully removes [I] from [target]'s [target_zone]!", "You successfully remove [I] from [target]'s [target_zone].") - qdel(I) - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - H.sec_hud_set_implants() + I.removed(target) + + var/obj/item/weapon/implantcase/case + + if(istype(user.get_item_by_slot(slot_l_hand), /obj/item/weapon/implantcase)) + case = user.get_item_by_slot(slot_l_hand) + else if(istype(user.get_item_by_slot(slot_r_hand), /obj/item/weapon/implantcase)) + case = user.get_item_by_slot(slot_r_hand) + else + case = locate(/obj/item/weapon/implantcase) in get_turf(target) + + if(case && !case.imp) + case.imp = I + I.loc = case + case.update_icon() + user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") + else + qdel(I) + else user << "You can't find anything in [target]'s [target_zone]!" - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/surgery/limb augmentation.dm b/code/modules/surgery/limb augmentation.dm index 22d168044c0..d7ff7340302 100644 --- a/code/modules/surgery/limb augmentation.dm +++ b/code/modules/surgery/limb augmentation.dm @@ -5,6 +5,7 @@ //SURGERY STEPS /datum/surgery_step/replace + name = "sever muscules" implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/wirecutters = 55) time = 32 @@ -14,15 +15,15 @@ /datum/surgery_step/add_limb + name = "replace limb" implements = list(/obj/item/robot_parts = 100) time = 32 var/obj/item/organ/limb/L = null // L because "limb" - allowed_organs = list("r_arm","l_arm","r_leg","l_leg","chest","head") /datum/surgery_step/add_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - L = new_organ + L = surgery.organ if(L) user.visible_message("[user] begins to augment [target]'s [parse_zone(user.zone_sel.selecting)].", "You begin to augment [target]'s [parse_zone(user.zone_sel.selecting)]...") else @@ -36,8 +37,7 @@ name = "augmentation" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/add_limb) species = list(/mob/living/carbon/human) - location = "anywhere" //Check attempt_initate_surgery() (in code/modules/surgery/helpers) to see what this does if you can't tell - has_multi_loc = 1 //Multi location stuff, See multiple_location_example.dm + possible_locs = list("r_arm","l_arm","r_leg","l_leg","chest","head") //SURGERY STEP SUCCESSES @@ -45,34 +45,6 @@ /datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(L) if(ishuman(target)) - switch(L.body_part) - if(CHEST) - if(!istype(tool,/obj/item/robot_parts/chest)) - user << "That is the wrong robotic limb for this body part." - return 0 - if(HEAD) - if(!istype(tool,/obj/item/robot_parts/head)) - user << "That is the wrong robotic limb for this body part." - return 0 - if(ARM_LEFT) - if(!istype(tool,/obj/item/robot_parts/l_arm)) - user << "That is the wrong robotic limb for this body part." - return 0 - if(ARM_RIGHT) - if(!istype(tool,/obj/item/robot_parts/r_arm)) - user << "That is the wrong robotic limb for this body part." - return 0 - if(LEG_LEFT) - if(!istype(tool,/obj/item/robot_parts/l_leg)) - user << "That is the wrong robotic limb for this body part." - return 0 - if(LEG_RIGHT) - if(!istype(tool,/obj/item/robot_parts/r_leg)) - user << "That is the wrong robotic limb for this body part." - return 0 - - if(!user.drop_item()) - return 0 var/mob/living/carbon/human/H = target user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") L.loc = get_turf(target) @@ -94,6 +66,7 @@ H.organs += new /obj/item/organ/limb/robot/chest(src) for(var/datum/disease/appendicitis/A in H.viruses) //If they already have Appendicitis, Remove it A.cure(1) + user.drop_item() qdel(tool) H.update_damage_overlays(0) H.update_augments() //Gives them the Cyber limb overlay diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 532e90e1e9e..7fcf8616e62 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -1,14 +1,17 @@ /datum/surgery/lipoplasty name = "lipoplasty" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/cut_fat, /datum/surgery_step/remove_fat, /datum/surgery_step/close) - species = list(/mob/living/carbon/human) - target_must_be_fat = 1 - location = "chest" - requires_organic_chest = 1 + possible_locs = list("chest") + +/datum/surgery/lipoplasty/can_start(mob/user, mob/living/carbon/target) + if(target.disabilities & FAT) + return 1 + return 0 //cut fat /datum/surgery_step/cut_fat + name = "cut excess fat" implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchen/knife/butcher = 25) time = 64 @@ -21,6 +24,7 @@ //remove fat /datum/surgery_step/remove_fat + name = "remove loose fat" implements = list(/obj/item/weapon/retractor = 100, /obj/item/weapon/screwdriver = 45, /obj/item/weapon/wirecutters = 35) time = 32 diff --git a/code/modules/surgery/multiple_location_example.dm b/code/modules/surgery/multiple_location_example.dm deleted file mode 100644 index e5e331843e5..00000000000 --- a/code/modules/surgery/multiple_location_example.dm +++ /dev/null @@ -1,54 +0,0 @@ -/* -//CONTENTS// -Multiple location example surgery - - - -//THE SURGERY// -it is very similar to a normal surgery. -Location = "anywhere" is the unique difference. - -/datum/surgery/multiLocExample - name = "Multiple Location Surgery Example" - steps = list(/datum/surgery_step/multiLocExampleStep) - species = list(/mob/living/carbon) - location = "anywhere" //A Location "Anywhere" is handled in /code/modules/surgery/helpers attempt_initiate_surgery(), it is converted into a User.zone_sel.selecting. - has_multi_loc = 1 //Needed to handle Multilocation - -//THE STEPS// -The block of "If's" is necessary, add or remove so you have just the areas you want, and set them to convert L(or your subsitute) to what you want it to be -EG: a zone on a mob (where user is targetting) to the limb thats actually there. - - -/datum/surgery_step/multiLocExampleStep - implements = list() - time = 9001 - allowed_organs = list("r_arm","l_arm","r_leg","l_leg","chest","head", "etc") - // allowed_organs is a list of organs this operation works with, it is defined in the earliest instance of the surgery_step (Eg, datum/surgery_step/multiLocExampleStep) - // allowed_organs is handled in Handle_Multi_Loc() in surgery_step.dm - - -/datum/surgery_step/multiLocExampleStep/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - L = new_organ //new_organ is a variable in /datum/surgery_step, it is null by default, and is given a value in Handle_Multi_Loc() - //Although Handle_Multi_Loc() is /datum/surgery_step/SURGERYNAME/Handle_Multi_Loc() you do not need to rewrite it in the surgery - if(L) - user.visible_message("Generic Statement.") - else - user.visible_message("Generic Statement 2.") - - -/datum/surgery_step/multiLocExampleStep/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) -You can use whatever you substituted "L" for here for useful things, swapping limbs for other limbs, etc. -if the surgery is intended to be MultiLoc but should only be performable once per limb, add this -"surgery.invalid_locations += user.zone_sel.selecting" -Just after you have swapped limbs around, see limb augmentation for an example of this - -*/ - -//This file is commented out as to avoid: -// a snowflakey removal of it 100% of the time -// it's an example, it doesn't work perfectly due to just being the multiple locations section. -// It is also not set to compile, due to being Empty (according to the compiler) - -//Enjoy making Multi-location operations! (if you understood my Rambling) -//If you didn't understand this, Ask for RobRichards in Coderbus \ No newline at end of file diff --git a/code/modules/surgery/organs/augments.dm b/code/modules/surgery/organs/augments_external.dm similarity index 95% rename from code/modules/surgery/organs/augments.dm rename to code/modules/surgery/organs/augments_external.dm index 263315aba1b..d3acb5135d9 100644 --- a/code/modules/surgery/organs/augments.dm +++ b/code/modules/surgery/organs/augments_external.dm @@ -1,51 +1,51 @@ -/////AUGMENTATION\\\\\ -//See code/modules/surgery/organs/organ.dm for the parent "limb" - - -/obj/item/organ/limb/robot - name = "cyberlimb" - desc = "You should never be seeing this!" - status = ORGAN_ROBOTIC - -/obj/item/organ/limb/robot/chest - name = "chest" - desc = "A Robotic chest" - icon_state = "chest" - max_damage = 200 - body_part = CHEST - -/obj/item/organ/limb/robot/head - name = "head" - desc = "A Robotic head" - icon_state = "head" - max_damage = 200 - body_part = HEAD - -/obj/item/organ/limb/robot/l_arm - name = "l_arm" - desc = "A Robotic arm" - icon_state = "l_arm" - max_damage = 75 - body_part = ARM_LEFT - -/obj/item/organ/limb/robot/l_leg - name = "l_leg" - desc = "A Robotic leg" - icon_state = "l_leg" - max_damage = 75 - body_part = LEG_LEFT - -/obj/item/organ/limb/robot/r_arm - name = "r_arm" - desc = "A Robotic arm" - icon_state = "r_arm" - max_damage = 75 - body_part = ARM_RIGHT - -/obj/item/organ/limb/robot/r_leg - name = "r_leg" - desc = "A Robotic leg" - icon_state = "r_leg" - max_damage = 75 - body_part = LEG_RIGHT - +/////AUGMENTATION\\\\\ +//See code/modules/surgery/organs/organ.dm for the parent "limb" + + +/obj/item/organ/limb/robot + name = "cyberlimb" + desc = "You should never be seeing this!" + status = ORGAN_ROBOTIC + +/obj/item/organ/limb/robot/chest + name = "chest" + desc = "A Robotic chest" + icon_state = "chest" + max_damage = 200 + body_part = CHEST + +/obj/item/organ/limb/robot/head + name = "head" + desc = "A Robotic head" + icon_state = "head" + max_damage = 200 + body_part = HEAD + +/obj/item/organ/limb/robot/l_arm + name = "l_arm" + desc = "A Robotic arm" + icon_state = "l_arm" + max_damage = 75 + body_part = ARM_LEFT + +/obj/item/organ/limb/robot/l_leg + name = "l_leg" + desc = "A Robotic leg" + icon_state = "l_leg" + max_damage = 75 + body_part = LEG_LEFT + +/obj/item/organ/limb/robot/r_arm + name = "r_arm" + desc = "A Robotic arm" + icon_state = "r_arm" + max_damage = 75 + body_part = ARM_RIGHT + +/obj/item/organ/limb/robot/r_leg + name = "r_leg" + desc = "A Robotic leg" + icon_state = "r_leg" + max_damage = 75 + body_part = LEG_RIGHT + diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm new file mode 100644 index 00000000000..ab814cbf9df --- /dev/null +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -0,0 +1,127 @@ +/obj/item/organ/internal/cyberimp/eyes + name = "cybernetic eyes" + desc = "artificial photoreceptors with specialized functionality" + icon_state = "eye_implant" + implant_overlay = "eye_implant_overlay" + slot = "eye_sight" + zone = "eyes" + w_class = 1 + + var/sight_flags = 0 + var/eye_color = "fff" + var/old_eye_color = "fff" + var/flash_protect = 0 + var/aug_message = "Your vision is augmented!" + + +/obj/item/organ/internal/cyberimp/eyes/Insert(var/mob/living/carbon/M, var/special = 0) + ..() + if(istype(owner, /mob/living/carbon/human) && eye_color) + var/mob/living/carbon/human/HMN = owner + old_eye_color = HMN.eye_color + HMN.eye_color = eye_color + HMN.regenerate_icons() + if(aug_message && !special) + owner << "[aug_message]" + M.sight |= sight_flags + +/obj/item/organ/internal/cyberimp/eyes/Remove(var/mob/living/carbon/M, var/special = 0) + M.sight ^= sight_flags + if(istype(M,/mob/living/carbon/human) && eye_color) + var/mob/living/carbon/human/HMN = owner + HMN.eye_color = old_eye_color + HMN.regenerate_icons() + ..() + +/obj/item/organ/internal/cyberimp/eyes/on_life() + ..() + owner.sight |= sight_flags + +/obj/item/organ/internal/cyberimp/eyes/emp_act(severity) + if(!owner) + return + if(severity > 1) + if(prob(10 * severity)) + return + var/save_sight = owner.sight + owner.sight &= 0 + owner.disabilities |= BLIND + owner << "Static obfuscates your vision!" + spawn(60 / severity) + if(owner) + owner.sight |= save_sight + owner.disabilities ^= BLIND + + + +/obj/item/organ/internal/cyberimp/eyes/xray + name = "X-ray implant" + desc = "These cybernetic eye implants will give you X-ray vision. Blinking is futile." + eye_color = "000" + implant_color = "#000000" + origin_tech = "materials=6;programming=4;biotech=6;magnets=5" + sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS + +/obj/item/organ/internal/cyberimp/eyes/thermals + name = "Thermals implant" + desc = "These cybernetic eye implants will give you Thermal vision. Vertical slit pupil included." + eye_color = "FC0" + implant_color = "#FFCC00" + sight_flags = SEE_MOBS + flash_protect = -1 + origin_tech = "materials=6;programming=4;biotech=5;magnets=5;syndicate=4" + aug_message = "You see prey everywhere you look..." + + +// HUD implants +/obj/item/organ/internal/cyberimp/eyes/hud + name = "HUD implant" + desc = "These cybernetic eyes will display a HUD over everything you see. Maybe." + slot = "eye_hud" + var/HUD_type = 0 + +/obj/item/organ/internal/cyberimp/eyes/hud/Insert(var/mob/living/carbon/M, var/special = 0) + ..() + if(HUD_type) + var/datum/atom_hud/H = huds[HUD_type] + H.add_hud_to(M) + M.permanent_huds |= H + +/obj/item/organ/internal/cyberimp/eyes/hud/Remove(var/mob/living/carbon/M, var/special = 0) + if(HUD_type) + var/datum/atom_hud/H = huds[HUD_type] + M.permanent_huds ^= H + H.remove_hud_from(M) + ..() + +/obj/item/organ/internal/cyberimp/eyes/hud/medical + name = "Medical HUD implant" + desc = "These cybernetic eye implants will display a medical HUD over everything you see." + eye_color = "0ff" + implant_color = "#00FFFF" + origin_tech = "materials=4;programming=3;biotech=4" + aug_message = "You suddenly see health bars floating above people's heads..." + HUD_type = DATA_HUD_MEDICAL_ADVANCED + +/obj/item/organ/internal/cyberimp/eyes/hud/security + name = "Security HUD implant" + desc = "These cybernetic eye implants will display a security HUD over everything you see." + eye_color = "d00" + implant_color = "#CC0000" + origin_tech = "materials=4;programming=4;biotech=3;combat=1" + aug_message = "Job indicator icons pop up in your vision. That is not a certified surgeon..." + HUD_type = DATA_HUD_SECURITY_ADVANCED + + +// Welding shield implant +/obj/item/organ/internal/cyberimp/eyes/shield + name = "welding shield implant" + desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." + slot = "eye_shield" + origin_tech = "materials=4;biotech=3" + implant_color = "#101010" + flash_protect = 2 + // Welding with thermals will still hurt your eyes a bit. + +/obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity) + return \ No newline at end of file diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm new file mode 100644 index 00000000000..b904d93f9e3 --- /dev/null +++ b/code/modules/surgery/organs/augments_internal.dm @@ -0,0 +1,273 @@ +#define STUN_SET_AMOUNT 2 + +/obj/item/organ/internal/cyberimp + name = "cybernetic implant" + desc = "a state-of-the-art implant that improves a baseline's functionality" + status = ORGAN_ROBOTIC + var/implant_color = "#FFFFFF" + var/implant_overlay + +/obj/item/organ/internal/cyberimp/New(var/mob/M = null) + if(iscarbon(M)) + src.Insert(M) + if(implant_overlay) + var/image/overlay = new /image(icon, implant_overlay) + overlay.color = implant_color + overlays |= overlay + return ..() + + + +//[[[[BRAIN]]]] + +/obj/item/organ/internal/cyberimp/brain + name = "cybernetic brain implant" + desc = "injectors of extra sub-routines for the brain" + icon_state = "brain_implant" + implant_overlay = "brain_implant_overlay" + zone = "head" + +/obj/item/organ/internal/cyberimp/brain/emp_act(severity) + if(!owner) + return + var/stun_amount = 5 + (severity-1 ? 0 : 5) + owner.Stun(stun_amount) + owner << "Your body seizes up!" + return stun_amount + + +/obj/item/organ/internal/cyberimp/brain/anti_drop + name = "Anti-drop implant" + desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + var/active = 0 + var/l_hand_ignore = 0 + var/r_hand_ignore = 0 + var/obj/item/l_hand_obj = null + var/obj/item/r_hand_obj = null + implant_color = "#DE7E00" + slot = "brain_antidrop" + origin_tech = "materials=5;programming=4;biotech=4" + organ_action_name = "Toggle Anti-Drop" + +/obj/item/organ/internal/cyberimp/brain/anti_drop/ui_action_click() + active = !active + if(active) + l_hand_obj = owner.l_hand + r_hand_obj = owner.r_hand + if(l_hand_obj) + if(owner.l_hand.flags & NODROP) + l_hand_ignore = 1 + else + owner.l_hand.flags |= NODROP + l_hand_ignore = 0 + + if(r_hand_obj) + if(owner.r_hand.flags & NODROP) + r_hand_ignore = 1 + else + owner.r_hand.flags |= NODROP + r_hand_ignore = 0 + + if(!l_hand_obj && !r_hand_obj) + owner << "You are not holding any items, your hands relax..." + active = 0 + else + var/msg = 0 + msg += !l_hand_ignore && l_hand_obj ? 1 : 0 + msg += !r_hand_ignore && r_hand_obj ? 2 : 0 + switch(msg) + if(1) + owner << "Your left hand's grip tightens." + if(2) + owner << "Your right hand's grip tightens." + if(3) + owner << "Both of your hand's grips tighten." + else + release_items() + owner << "Your hands relax..." + l_hand_obj = null + r_hand_obj = null + +/obj/item/organ/internal/cyberimp/brain/anti_drop/emp_act(severity) + if(!owner) + return + var/range = severity ? 10 : 5 + var/atom/A + var/obj/item/L_item = owner.l_hand + var/obj/item/R_item = owner.r_hand + + release_items() + ..() + if(L_item) + A = pick(oview(range)) + L_item.throw_at(A, range, 2) + owner << "Your left arm spasms and throws the [L_item.name]!" + if(R_item) + A = pick(oview(range)) + R_item.throw_at(A, range, 2) + owner << "Your right arm spasms and throws the [R_item.name]!" + +/obj/item/organ/internal/cyberimp/brain/anti_drop/proc/release_items() + if(!l_hand_ignore && l_hand_obj in owner.contents) + l_hand_obj.flags ^= NODROP + if(!r_hand_ignore && r_hand_obj in owner.contents) + r_hand_obj.flags ^= NODROP + +/obj/item/organ/internal/cyberimp/brain/anti_drop/Remove(var/mob/living/carbon/M, special = 0) + if(active) + ui_action_click() + ..() + + +/obj/item/organ/internal/cyberimp/brain/anti_stun + name = "CNS Rebooter implant" + desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." + implant_color = "#FFFF00" + slot = "brain_antistun" + origin_tech = "materials=6;programming=4;biotech=5" + +/obj/item/organ/internal/cyberimp/brain/anti_stun/on_life() + ..() + if(crit_fail) + return + + if(owner.stunned > STUN_SET_AMOUNT) + owner.stunned = STUN_SET_AMOUNT + if(owner.weakened > STUN_SET_AMOUNT) + owner.weakened = STUN_SET_AMOUNT + +/obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) + if(crit_fail) + return + crit_fail = 1 + spawn(90 / severity) + crit_fail = 0 + + +//[[[[CHEST]]]] + +/obj/item/organ/internal/cyberimp/chest + name = "cybernetic torso implant" + desc = "implants for the organs in your torso" + icon_state = "chest_implant" + implant_overlay = "chest_implant_overlay" + zone = "chest" + +/obj/item/organ/internal/cyberimp/chest/nutriment + name = "Nutriment pump implant" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." + icon_state = "chest_implant" + implant_color = "#00AA00" + var/hunger_threshold = NUTRITION_LEVEL_STARVING + var/synthesizing = 0 + var/poison_amount = 5 + slot = "stomach" + origin_tech = "materials=5;programming=3;biotech=4" + +/obj/item/organ/internal/cyberimp/chest/nutriment/on_life() + if(synthesizing) + return + + if(owner.nutrition <= hunger_threshold) + synthesizing = 1 + owner << "You feel less hungry..." + owner.nutrition += 50 + spawn(50) + synthesizing = 0 + +/obj/item/organ/internal/cyberimp/chest/nutriment/emp_act(severity) + if(!owner) + return + owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning + owner << "You feel like your insides are burning." + + +/obj/item/organ/internal/cyberimp/chest/nutriment/plus + name = "Nutriment pump implant PLUS" + desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." + icon_state = "chest_implant" + implant_color = "#006607" + hunger_threshold = NUTRITION_LEVEL_HUNGRY + poison_amount = 10 + origin_tech = "materials=5;programming=3;biotech=5" + + + +/obj/item/organ/internal/cyberimp/chest/reviver + name = "Reviver implant" + desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + icon_state = "chest_implant" + implant_color = "#AD0000" + origin_tech = "materials=6;programming=3;biotech=6;syndicate=4" + slot = "heartdrive" + var/revive_cost = 0 + var/reviving = 0 + var/cooldown = 0 + +/obj/item/organ/internal/cyberimp/chest/reviver/on_life() + if(reviving) + if(owner.stat == UNCONSCIOUS) + spawn(30) + if(prob(90) && owner.getOxyLoss()) + owner.adjustOxyLoss(-3) + revive_cost += 5 + if(prob(75) && owner.getBruteLoss()) + owner.adjustBruteLoss(-1) + revive_cost += 20 + if(prob(75) && owner.getFireLoss()) + owner.adjustFireLoss(-1) + revive_cost += 20 + if(prob(40) && owner.getToxLoss()) + owner.adjustToxLoss(-1) + revive_cost += 50 + else + cooldown = revive_cost + world.time + reviving = 0 + return + + if(cooldown > world.time) + return + if(owner.stat != UNCONSCIOUS) + return + if(owner.suiciding) + return + + revive_cost = 0 + reviving = 1 + +/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity) + if(!owner) + return + + if(reviving) + revive_cost += 200 + else + cooldown += 200 + + if(istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + if(H.stat != DEAD && prob(50 / severity)) + H.heart_attack = 1 + spawn(600 / severity) + H.heart_attack = 0 + if(H.stat == CONSCIOUS) + H << "You feel your heart beating again!" + + +//BOX O' IMPLANTS + +/obj/item/weapon/storage/box/cyber_implants + name = "boxed cybernetic implants" + desc = "A sleek, sturdy box." + icon_state = "cyber_implants" + var/list/boxed = list(/obj/item/organ/internal/cyberimp/eyes/xray,/obj/item/organ/internal/cyberimp/eyes/thermals, + /obj/item/organ/internal/cyberimp/brain/anti_stun, /obj/item/organ/internal/cyberimp/chest/reviver) + var/amount = 5 + +/obj/item/weapon/storage/box/cyber_implants/New() + ..() + var/i + var/implant + for(i = 0, i < amount, i++) + implant = pick(boxed) + new implant(src) \ No newline at end of file diff --git a/code/modules/surgery/organs/cybernetic_implants.dm b/code/modules/surgery/organs/cybernetic_implants.dm deleted file mode 100644 index 273543bbae1..00000000000 --- a/code/modules/surgery/organs/cybernetic_implants.dm +++ /dev/null @@ -1,395 +0,0 @@ -#define STUN_SET_AMOUNT 2 - -/obj/item/cybernetic_implant - name = "cybernetic implant" - desc = "a state-of-the-art implant that improves a baseline's functionality" - icon = 'icons/obj/surgery.dmi' - var/mob/living/carbon/owner = null - var/implant_color = "#FFFFFF" - -/obj/item/cybernetic_implant/New(var/mob/M = null) - owner = M - return ..() - -/obj/item/cybernetic_implant/proc/function() - return - - -//[[[[EYES]]]] - -/obj/item/cybernetic_implant/eyes - name = "cybernetic eyes" - desc = "artificial photoreceptors with specialized functionality" - icon_state = "eye_implant" - var/eye_color = "fff" - var/flash_protect = 0 - -/obj/item/cybernetic_implant/eyes/New() - var/icon/overlay = new /icon('icons/obj/surgery.dmi',"eye_implant_overlay") - overlay.ColorTone(implant_color) - overlays |= overlay - ..() - -/obj/item/cybernetic_implant/eyes/proc/update_eye_color(fluff_message) - if(istype(owner,/mob/living/carbon/human)) - var/mob/living/carbon/human/HMN = owner - HMN.eye_color = eye_color - HMN.regenerate_icons() - if(fluff_message) - owner << "[fluff_message]" - -/obj/item/cybernetic_implant/eyes/hud/medical - name = "Medical HUD implant" - desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." - eye_color = "0ff" - implant_color = "#00FFFF" - origin_tech = "materials=4;programming=3;biotech=4" - -/obj/item/cybernetic_implant/eyes/hud/medical/function() - if(!owner) - return - - var/datum/atom_hud/H = huds[DATA_HUD_MEDICAL_ADVANCED] - H.add_hud_to(owner) - owner.permanent_huds |= H - update_eye_color("You suddenly see health bars floating above people's heads...") - -/obj/item/cybernetic_implant/eyes/hud/security - name = "Security HUD implant" - desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." - eye_color = "d00" - implant_color = "#CC0000" - origin_tech = "materials=4;programming=4;biotech=3;combat=1" - -/obj/item/cybernetic_implant/eyes/hud/security/function() - if(!owner) - return - - var/datum/atom_hud/H = huds[DATA_HUD_SECURITY_ADVANCED] - H.add_hud_to(owner) - owner.permanent_huds |= H - update_eye_color("Job indicator icons pop up in your vision. That is not a certified surgeon...") - -/obj/item/cybernetic_implant/eyes/xray - name = "X-ray implant" - desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." - eye_color = "000" - implant_color = "#000000" - origin_tech = "materials=6;programming=4;biotech=6;magnets=5" - -/obj/item/cybernetic_implant/eyes/xray/function() - if(!owner) - return - - owner.sight |= SEE_MOBS - owner.sight |= SEE_OBJS - owner.sight |= SEE_TURFS - owner.permanent_sight_flags |= SEE_MOBS - owner.permanent_sight_flags |= SEE_OBJS - owner.permanent_sight_flags |= SEE_TURFS - update_eye_color("Your vision is augmented!") - -/obj/item/cybernetic_implant/eyes/thermals - name = "Thermals implant" - desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." - eye_color = "FC0" - implant_color = "#FFCC00" - flash_protect = -1 - origin_tech = "materials=6;programming=4;biotech=5;magnets=5;syndicate=4" - -/obj/item/cybernetic_implant/eyes/thermals/function() - if(!owner) - return - - owner.sight |= SEE_MOBS - owner.permanent_sight_flags |= SEE_MOBS - update_eye_color("You see prey everywhere you look...") - -/obj/item/cybernetic_implant/eyes/emp_act(severity) - if(!owner) - return - if(severity > 1) - if(prob(5)) - return - var/save_sight = owner.sight - owner.sight &= 0 - owner.disabilities |= BLIND - owner << "Static obfuscates your vision!" - spawn(50) - owner.sight |= save_sight - owner.disabilities ^= BLIND - - -//[[[[BRAIN]]]] - -/obj/item/cybernetic_implant/brain - name = "cybernetic brain implant" - desc = "injectors of extra sub-routines for the brain" - icon_state = "brain_implant" - -/obj/item/cybernetic_implant/brain/New() - var/icon/overlay = new /icon('icons/obj/surgery.dmi',"brain_implant_overlay") - overlay.ColorTone(implant_color) - overlays |= overlay - ..() - -/obj/item/cybernetic_implant/brain/emp_act(severity) - if(!owner) - return - var/stun_amount = 5 + (severity-1 ? 0 : 5) - owner.Stun(stun_amount) - owner << "Your body seizes up!" - return stun_amount - -/obj/item/cybernetic_implant/brain/anti_drop - name = "Anti-drop implant" - desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." - var/active = 0 - var/l_hand_ignore = 0 - var/r_hand_ignore = 0 - var/obj/item/l_hand_obj = null - var/obj/item/r_hand_obj = null - implant_color = "#DE7E00" - origin_tech = "materials=5;programming=4;biotech=4" - -/obj/item/cybernetic_implant/brain/anti_drop/function() - action_button_name = "Toggle Anti-Drop" - -/obj/item/cybernetic_implant/brain/anti_drop/ui_action_click() - active = !active - if(active) - l_hand_obj = owner.l_hand - r_hand_obj = owner.r_hand - if(l_hand_obj) - if(owner.l_hand.flags & NODROP) - l_hand_ignore = 1 - else - owner.l_hand.flags |= NODROP - l_hand_ignore = 0 - - if(r_hand_obj) - if(owner.r_hand.flags & NODROP) - r_hand_ignore = 1 - else - owner.r_hand.flags |= NODROP - r_hand_ignore = 0 - - if(!l_hand_obj && !r_hand_obj) - owner << "You are not holding any items, your hands relax..." - active = 0 - else - var/msg = 0 - msg += !l_hand_ignore && l_hand_obj ? 1 : 0 - msg += !r_hand_ignore && r_hand_obj ? 2 : 0 - switch(msg) - if(1) - owner << "Your left hand's grip tightens." - if(2) - owner << "Your right hand's grip tightens." - if(3) - owner << "Both of your hand's grips tighten." - else - release_items() - owner << "Your hands relax..." - l_hand_obj = null - r_hand_obj = null - -/obj/item/cybernetic_implant/brain/anti_drop/emp_act(severity) - if(!owner) - return - var/range = severity ? 10 : 5 - var/atom/A - var/obj/item/L_item = owner.l_hand - var/obj/item/R_item = owner.r_hand - - release_items() - ..() - if(L_item) - A = pick(oview(range)) - L_item.throw_at(A, range, 2) - owner << "Your left arm spasms and throws the [L_item.name]!" - if(R_item) - A = pick(oview(range)) - R_item.throw_at(A, range, 2) - owner << "Your right arm spasms and throws the [R_item.name]!" - -/obj/item/cybernetic_implant/brain/anti_drop/proc/release_items() - if(!l_hand_ignore && l_hand_obj in owner.contents) - l_hand_obj.flags ^= NODROP - if(!r_hand_ignore && r_hand_obj in owner.contents) - r_hand_obj.flags ^= NODROP - -/obj/item/cybernetic_implant/brain/anti_stun - name = "CNS Rebooter implant" - desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." - implant_color = "#FFFF00" - origin_tech = "materials=6;programming=4;biotech=5" - -/obj/item/cybernetic_implant/brain/anti_stun/function() - SSobj.processing |= src - -/obj/item/cybernetic_implant/brain/anti_stun/process() - if(!owner) - SSobj.processing.Remove(src) - qdel(src) - return - if(owner.stat == DEAD) - return - - if(owner.stunned > STUN_SET_AMOUNT) - owner.stunned = STUN_SET_AMOUNT - if(owner.weakened > STUN_SET_AMOUNT) - owner.weakened = STUN_SET_AMOUNT - -/obj/item/cybernetic_implant/brain/anti_stun/emp_act(severity) - if(!owner) - return - SSobj.processing.Remove(src) - spawn(..() * 10) - SSobj.processing |= src - - -//[[[[CHEST]]]] - -/obj/item/cybernetic_implant/chest - name = "cybernetic torso implant" - desc = "implants for the organs in your torso" - icon_state = "chest_implant" - -/obj/item/cybernetic_implant/chest/New() - var/icon/overlay = new /icon('icons/obj/surgery.dmi',"chest_implant_overlay") - overlay.ColorTone(implant_color) - overlays |= overlay - ..() - -/obj/item/cybernetic_implant/chest/nutriment - name = "Nutriment pump implant" - desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." - icon_state = "chest_implant" - implant_color = "#00AA00" - var/hunger_threshold = NUTRITION_LEVEL_STARVING - var/synthesizing = 0 - var/nutriment_amount = 30 - var/poison_amount = 5 - origin_tech = "materials=5;programming=3;biotech=4" - -/obj/item/cybernetic_implant/chest/nutriment/function() - SSobj.processing |= src - -/obj/item/cybernetic_implant/chest/nutriment/process() - if(synthesizing) - return - if(!owner) - SSobj.processing.Remove(src) - qdel(src) - return - if(owner.stat == DEAD) - return - - if(owner.nutrition <= hunger_threshold) - synthesizing = 1 - spawn(50) - owner << "You feel less hungry..." - owner.nutrition += nutriment_amount - synthesizing = 0 - -/obj/item/cybernetic_implant/chest/nutriment/plus - name = "Nutriment pump implant PLUS" - desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." - icon_state = "chest_implant" - implant_color = "#006607" - hunger_threshold = NUTRITION_LEVEL_HUNGRY - nutriment_amount = 50 - poison_amount = 10 - origin_tech = "materials=5;programming=3;biotech=5" - -/obj/item/cybernetic_implant/chest/nutriment/emp_act(severity) - if(!owner) - return - owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning - owner << "You feel like your insides are burning." - - -/obj/item/cybernetic_implant/chest/reviver - name = "Reviver implant" - desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" - icon_state = "chest_implant" - implant_color = "#AD0000" - origin_tech = "materials=6;programming=3;biotech=6;syndicate=4" - var/revive_cost = 0 - var/reviving = 0 - var/cooldown = 0 - -/obj/item/cybernetic_implant/chest/reviver/function() - SSobj.processing |= src - -/obj/item/cybernetic_implant/chest/reviver/process() - if(!owner) - SSobj.processing.Remove(src) - qdel(src) - return - - if(reviving) - if(owner.stat == UNCONSCIOUS) - spawn(30) - if(prob(90) && owner.getOxyLoss()) - owner.adjustOxyLoss(-3) - revive_cost += 5 - if(prob(75) && owner.getBruteLoss()) - owner.adjustBruteLoss(-1) - revive_cost += 20 - if(prob(75) && owner.getFireLoss()) - owner.adjustFireLoss(-1) - revive_cost += 20 - if(prob(40) && owner.getToxLoss()) - owner.adjustToxLoss(-1) - revive_cost += 50 - else - cooldown = revive_cost + world.time - reviving = 0 - return - - if(cooldown > world.time) - return - if(owner.stat != UNCONSCIOUS) - return - if(owner.suiciding) - SSobj.processing.Remove(src) - return - - revive_cost = 0 - reviving = 1 - -/obj/item/cybernetic_implant/chest/reviver/emp_act(severity) - if(reviving) - revive_cost += 200 - else - cooldown += 200 - - if(istype(owner, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = owner - if(H.stat != DEAD && prob(50 / severity)) - H.heart_attack = 1 - spawn(600 / severity) - H.heart_attack = 0 - if(H.stat == CONSCIOUS) - H << "You feel your heart beating again!" - - -//BOX O' IMPLANTS - -/obj/item/weapon/storage/box/cyber_implants - name = "boxed cybernetic implants" - desc = "A sleek, sturdy box." - icon_state = "cyber_implants" - var/list/boxed = list(/obj/item/cybernetic_implant/eyes/xray,/obj/item/cybernetic_implant/eyes/thermals, - /obj/item/cybernetic_implant/brain/anti_stun, /obj/item/cybernetic_implant/chest/reviver) - var/amount = 5 - -/obj/item/weapon/storage/box/cyber_implants/New() - ..() - var/i - var/implant - for(i = 0, i < amount, i++) - implant = pick(boxed) - new implant(src) \ No newline at end of file diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index dd0529d4344..18b4185ea52 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -1,13 +1,33 @@ -/mob/proc/getorgan() +mob/proc/getorgan(typepath) return -/mob/living/carbon/getorgan(typepath) + +mob/proc/getorganszone(zone) + return + +mob/proc/getorganslot(slot) + return + + +mob/living/carbon/getorgan(typepath) return (locate(typepath) in internal_organs) -/mob/proc/getlimb() +mob/living/carbon/getorganszone(zone) + var/list/returnorg = list() + for(var/obj/item/organ/internal/O in internal_organs) + if(zone == O.zone) + returnorg += O + return returnorg + +mob/living/carbon/getorganslot(slot) + for(var/obj/item/organ/internal/O in internal_organs) + if(slot == O.slot) + return O + +mob/proc/getlimb() return -/mob/living/carbon/human/getlimb(typepath) +mob/living/carbon/human/getlimb(typepath) return (locate(typepath) in organs) - - +proc/isorgan(atom/A) + return istype(A, /obj/item/organ/internal) \ No newline at end of file diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ_external.dm similarity index 85% rename from code/modules/surgery/organs/organ.dm rename to code/modules/surgery/organs/organ_external.dm index 05ae58ccc21..9e231fae5d1 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -1,199 +1,171 @@ -/obj/item/organ - name = "organ" - icon = 'icons/obj/surgery.dmi' - - - -/obj/item/organ/heart - name = "heart" - icon_state = "heart-on" - var/beating = 1 - -/obj/item/organ/heart/update_icon() - if(beating) - icon_state = "heart-on" - else - icon_state = "heart-off" - - -/obj/item/organ/appendix - name = "appendix" - icon_state = "appendix" - var/inflamed = 1 - -/obj/item/organ/appendix/update_icon() - if(inflamed) - icon_state = "appendixinflamed" - else - icon_state = "appendix" - - -//Looking for brains? -//Try code/modules/mob/living/carbon/brain/brain_item.dm - -//Old Datum Limbs: -// code/modules/unused/limbs.dm - - -/obj/item/organ/limb - name = "limb" - var/mob/owner = null - var/body_part = null - var/brutestate = 0 - var/burnstate = 0 - var/brute_dam = 0 - var/burn_dam = 0 - var/max_damage = 0 - var/status = ORGAN_ORGANIC - var/list/embedded_objects = list() - - - -/obj/item/organ/limb/chest - name = "chest" - desc = "why is it detached..." - icon_state = "chest" - max_damage = 200 - body_part = CHEST - - -/obj/item/organ/limb/head - name = "head" - desc = "what a way to get a head in life..." - icon_state = "head" - max_damage = 200 - body_part = HEAD - - -/obj/item/organ/limb/l_arm - name = "l_arm" - desc = "why is it detached..." - icon_state = "l_arm" - max_damage = 75 - body_part = ARM_LEFT - - -/obj/item/organ/limb/l_leg - name = "l_leg" - desc = "why is it detached..." - icon_state = "l_leg" - max_damage = 75 - body_part = LEG_LEFT - - -/obj/item/organ/limb/r_arm - name = "r_arm" - desc = "why is it detached..." - icon_state = "r_arm" - max_damage = 75 - body_part = ARM_RIGHT - - -/obj/item/organ/limb/r_leg - name = "r_leg" - desc = "why is it detached..." - icon_state = "r_leg" - max_damage = 75 - body_part = LEG_RIGHT - - - -//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. -//Damage will not exceed max_damage using this proc -//Cannot apply negative damage -/obj/item/organ/limb/proc/take_damage(brute, burn) - if(owner && (owner.status_flags & GODMODE)) return 0 //godmode - brute = max(brute,0) - burn = max(burn,0) - - - if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger - brute = max(0, brute - 5) - burn = max(0, burn - 4) - - var/can_inflict = max_damage - (brute_dam + burn_dam) - if(!can_inflict) return 0 - - if((brute + burn) < can_inflict) - brute_dam += brute - burn_dam += burn - else - if(brute > 0) - if(burn > 0) - brute = round( (brute/(brute+burn)) * can_inflict, 1 ) - burn = can_inflict - brute //gets whatever damage is left over - brute_dam += brute - burn_dam += burn - else - brute_dam += can_inflict - else - if(burn > 0) - burn_dam += can_inflict - else - return 0 - return update_organ_icon() - - -//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. -//Damage cannot go below zero. -//Cannot remove negative damage (i.e. apply damage) -/obj/item/organ/limb/proc/heal_damage(brute, burn, robotic) - - if(robotic && status != ORGAN_ROBOTIC) // This makes organic limbs not heal when the proc is in Robotic mode. - brute = max(0, brute - 3) - burn = max(0, burn - 3) - - if(!robotic && status == ORGAN_ROBOTIC) // This makes robolimbs not healable by chems. - brute = max(0, brute - 3) - burn = max(0, burn - 3) - - brute_dam = max(brute_dam - brute, 0) - burn_dam = max(burn_dam - burn, 0) - return update_organ_icon() - - -//Returns total damage...kinda pointless really -/obj/item/organ/limb/proc/get_damage() - return brute_dam + burn_dam - - -//Updates an organ's brute/burn states for use by update_damage_overlays() -//Returns 1 if we need to update overlays. 0 otherwise. -/obj/item/organ/limb/proc/update_organ_icon() - if(status == ORGAN_ORGANIC) //Robotic limbs show no damage - RR - var/tbrute = round( (brute_dam/max_damage)*3, 1 ) - var/tburn = round( (burn_dam/max_damage)*3, 1 ) - if((tbrute != brutestate) || (tburn != burnstate)) - brutestate = tbrute - burnstate = tburn - return 1 - return 0 - -//Returns a display name for the organ -/obj/item/organ/limb/proc/getDisplayName() //Added "Chest" and "Head" just in case, this may not be needed - switch(name) - if("l_leg") return "left leg" - if("r_leg") return "right leg" - if("l_arm") return "left arm" - if("r_arm") return "right arm" - if("chest") return "chest" - if("head") return "head" - else return name - - -//Remove all embedded objects from all limbs on the human mob -/mob/living/carbon/human/proc/remove_all_embedded_objects() - var/turf/T = get_turf(src) - - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) - L.embedded_objects -= I - I.loc = T - - clear_alert("embeddedobject") - -/mob/living/carbon/human/proc/has_embedded_objects() - . = 0 - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) +/obj/item/organ + name = "organ" + icon = 'icons/obj/surgery.dmi' + var/mob/living/carbon/owner = null + var/status = ORGAN_ORGANIC + + +//Old Datum Limbs: +// code/modules/unused/limbs.dm + + +/obj/item/organ/limb + name = "limb" + var/body_part = null + var/brutestate = 0 + var/burnstate = 0 + var/brute_dam = 0 + var/burn_dam = 0 + var/max_damage = 0 + var/list/embedded_objects = list() + + + +/obj/item/organ/limb/chest + name = "chest" + desc = "why is it detached..." + icon_state = "chest" + max_damage = 200 + body_part = CHEST + + +/obj/item/organ/limb/head + name = "head" + desc = "what a way to get a head in life..." + icon_state = "head" + max_damage = 200 + body_part = HEAD + + +/obj/item/organ/limb/l_arm + name = "l_arm" + desc = "why is it detached..." + icon_state = "l_arm" + max_damage = 75 + body_part = ARM_LEFT + + +/obj/item/organ/limb/l_leg + name = "l_leg" + desc = "why is it detached..." + icon_state = "l_leg" + max_damage = 75 + body_part = LEG_LEFT + + +/obj/item/organ/limb/r_arm + name = "r_arm" + desc = "why is it detached..." + icon_state = "r_arm" + max_damage = 75 + body_part = ARM_RIGHT + + +/obj/item/organ/limb/r_leg + name = "r_leg" + desc = "why is it detached..." + icon_state = "r_leg" + max_damage = 75 + body_part = LEG_RIGHT + + + +//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. +//Damage will not exceed max_damage using this proc +//Cannot apply negative damage +/obj/item/organ/limb/proc/take_damage(brute, burn) + if(owner && (owner.status_flags & GODMODE)) return 0 //godmode + brute = max(brute,0) + burn = max(burn,0) + + + if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger + brute = max(0, brute - 5) + burn = max(0, burn - 4) + + var/can_inflict = max_damage - (brute_dam + burn_dam) + if(!can_inflict) return 0 + + if((brute + burn) < can_inflict) + brute_dam += brute + burn_dam += burn + else + if(brute > 0) + if(burn > 0) + brute = round( (brute/(brute+burn)) * can_inflict, 1 ) + burn = can_inflict - brute //gets whatever damage is left over + brute_dam += brute + burn_dam += burn + else + brute_dam += can_inflict + else + if(burn > 0) + burn_dam += can_inflict + else + return 0 + return update_organ_icon() + + +//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. +//Damage cannot go below zero. +//Cannot remove negative damage (i.e. apply damage) +/obj/item/organ/limb/proc/heal_damage(brute, burn, robotic) + + if(robotic && status != ORGAN_ROBOTIC) // This makes organic limbs not heal when the proc is in Robotic mode. + brute = max(0, brute - 3) + burn = max(0, burn - 3) + + if(!robotic && status == ORGAN_ROBOTIC) // This makes robolimbs not healable by chems. + brute = max(0, brute - 3) + burn = max(0, burn - 3) + + brute_dam = max(brute_dam - brute, 0) + burn_dam = max(burn_dam - burn, 0) + return update_organ_icon() + + +//Returns total damage...kinda pointless really +/obj/item/organ/limb/proc/get_damage() + return brute_dam + burn_dam + + +//Updates an organ's brute/burn states for use by update_damage_overlays() +//Returns 1 if we need to update overlays. 0 otherwise. +/obj/item/organ/limb/proc/update_organ_icon() + if(status == ORGAN_ORGANIC) //Robotic limbs show no damage - RR + var/tbrute = round( (brute_dam/max_damage)*3, 1 ) + var/tburn = round( (burn_dam/max_damage)*3, 1 ) + if((tbrute != brutestate) || (tburn != burnstate)) + brutestate = tbrute + burnstate = tburn + return 1 + return 0 + +//Returns a display name for the organ +/obj/item/organ/limb/proc/getDisplayName() //Added "Chest" and "Head" just in case, this may not be needed + switch(name) + if("l_leg") return "left leg" + if("r_leg") return "right leg" + if("l_arm") return "left arm" + if("r_arm") return "right arm" + if("chest") return "chest" + if("head") return "head" + else return name + + +//Remove all embedded objects from all limbs on the human mob +/mob/living/carbon/human/proc/remove_all_embedded_objects() + var/turf/T = get_turf(src) + + for(var/obj/item/organ/limb/L in organs) + for(var/obj/item/I in L.embedded_objects) + L.embedded_objects -= I + I.loc = T + + clear_alert("embeddedobject") + +/mob/living/carbon/human/proc/has_embedded_objects() + . = 0 + for(var/obj/item/organ/limb/L in organs) + for(var/obj/item/I in L.embedded_objects) return 1 \ No newline at end of file diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm new file mode 100644 index 00000000000..ae4e1e00a55 --- /dev/null +++ b/code/modules/surgery/organs/organ_internal.dm @@ -0,0 +1,95 @@ +/obj/item/organ/internal + origin_tech = "biotech=2" + var/zone = "chest" + var/slot + var/vital = 0 + var/organ_action_name = null + +/obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M, special = 0) + if(!iscarbon(M) || owner) + return + + var/obj/item/organ/internal/replaced = M.getorganslot(slot) + if(replaced) + replaced.Remove(M, special = 1) + + owner = M + M.internal_organs |= src + loc = null + if(organ_action_name) + action_button_name = organ_action_name + +/obj/item/organ/internal/proc/Remove(var/mob/living/carbon/M, special = 0) + owner = null + if(M) + M.internal_organs -= src + if(vital && !special) + M.death() + + if(organ_action_name) + action_button_name = null + +/obj/item/organ/internal/proc/on_life() + return + +/obj/item/organ/internal/Destroy() + if(owner) + Remove(owner, 1) + ..() + +//Looking for brains? +//Try code/modules/mob/living/carbon/brain/brain_item.dm + + + +/obj/item/organ/internal/heart + name = "heart" + icon_state = "heart-on" + zone = "chest" + slot = "heart" + origin_tech = "biotech=3" + vital = 1 + var/beating = 1 + +/obj/item/organ/internal/heart/update_icon() + if(beating) + icon_state = "heart-on" + else + icon_state = "heart-off" + +/obj/item/organ/internal/heart/Insert(var/mob/living/carbon/M, special = 0) + ..() + beating = 1 + update_icon() + +/obj/item/organ/internal/heart/Remove(var/mob/living/carbon/M, special = 0) + ..() + spawn(120) + beating = 0 + update_icon() + + +/obj/item/organ/internal/appendix + name = "appendix" + icon_state = "appendix" + zone = "groin" + slot = "appendix" + var/inflamed = 0 + +/obj/item/organ/internal/appendix/update_icon() + if(inflamed) + icon_state = "appendixinflamed" + name = "inflamed appendix" + else + icon_state = "appendix" + name = "appendix" + +/obj/item/organ/internal/appendix/Remove(var/mob/living/carbon/M, special = 0) + for(var/datum/disease/appendicitis in M.viruses) + appendicitis.cure() + ..() + +/obj/item/organ/internal/appendix/Insert(var/mob/living/carbon/M, special = 0) + ..() + if(inflamed) + M.AddDisease(new /datum/disease/appendicitis) \ No newline at end of file diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 4dd1f600b2d..52a52d10a74 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -1,11 +1,11 @@ /datum/surgery/plastic_surgery name = "plastic surgery" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/reshape_face, /datum/surgery_step/close) - species = list(/mob/living/carbon/human) - location = "head" + possible_locs = list("head") //reshape_face /datum/surgery_step/reshape_face + name = "reshape face" implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/kitchen/knife = 50, /obj/item/weapon/wirecutters = 35) time = 64 diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index f8e7de333d9..5ca4083ab6c 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -1,22 +1,18 @@ - - /datum/surgery/embedded_removal name = "removal of embedded objects" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/remove_object) - species = list(/mob/living/carbon/human) - location = "anywhere" - has_multi_loc = 1 + possible_locs = list("r_arm","l_arm","r_leg","l_leg","chest","head") /datum/surgery_step/remove_object + name = "remove embedded objects" time = 32 - allowed_organs = list("r_arm","l_arm","r_leg","l_leg","chest","head") accept_hand = 1 var/obj/item/organ/limb/L = null /datum/surgery_step/remove_object/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - L = new_organ + L = surgery.organ if(L) user.visible_message("[user] looks for objects embedded in [target]'s [parse_zone(user.zone_sel.selecting)].", "You look for objects embedded in [target]'s [parse_zone(user.zone_sel.selecting)]...") else @@ -33,9 +29,6 @@ I.loc = get_turf(H) L.embedded_objects -= I - if(!H.has_embedded_objects()) - H.clear_alert("embeddedobject") - if(objects > 0) user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L.getDisplayName()]!", "You sucessfully remove [objects] objects from [H]'s [L.getDisplayName()].") else diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index d7f7fdfebb5..9a9196562fd 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -1,17 +1,22 @@ /datum/surgery - var/name = null + var/name = "surgery" var/status = 1 var/list/steps = list() //Steps in a surgery var/step_in_progress = 0 //Actively performing a Surgery var/list/species = list(/mob/living/carbon/human) //Acceptable Species var/location = "chest" //Surgery location var/target_must_be_dead = 0 //Needs to be dead - var/target_must_be_fat = 0 //Needs to be fat - var/requires_organic_chest = 0 //Prevents you from performing an operation on Robotic chests*** - var/has_multi_loc = 0 //Multiple locations - RR - var/user_species_restricted = 0 //Surgery only performable BY species - var/list/user_species_ids + var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs + var/list/possible_locs = list() //Multiple locations -- c0 var/ignore_clothes = 0 //This surgery ignores clothes + var/obj/item/organ/organ //Operable body part + + +/datum/surgery/proc/can_start(mob/user, mob/living/carbon/target) + // if 0 surgery wont show up in list + // put special restrictions here + return 1 + /datum/surgery/proc/next_step(mob/user, mob/living/carbon/target) if(step_in_progress) return @@ -54,8 +59,4 @@ //RESOLVED ISSUES //"Todo" jobs that have been completed //combine hands/feet into the arms - Hands/feet were removed - RR -//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see multiple_location_example.dm - RR - - -//*** This may seem entirely redundant because of Organic organs only having operations but you CAN circumvent that due to -//all surgeries (except augmentation) not checking where the surgeon aims so this is just a double check, it IS needed - RR \ No newline at end of file +//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see multiple_location_example.dm - RR \ No newline at end of file diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index e630e7da48e..bd442c7c5a7 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -4,8 +4,7 @@ var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand. var/time = 10 //how long does the step take? - var/new_organ = null //Used for multilocation operations - var/list/allowed_organs = list()//Allowed organs, see Handle_Multi_Loc below - RR + var/name /datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -39,10 +38,7 @@ /datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) surgery.step_in_progress = 1 - if(surgery.has_multi_loc) //if it is multi-location, handle that - Handle_Multi_Loc(user, target) - - preop(user, target, target_zone, tool) + preop(user, target, target_zone, tool, surgery) if(do_after(user, time, target = target)) var/advance = 0 @@ -73,61 +69,11 @@ /datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] succeeds!", "You succeed.") - feedback_add_details("surgery_step_success","[src.type]") - return 1 - -/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(ishuman(target) || ismonkey(target) || isalienadult(target)) - var/mob/living/carbon/M = target - M.apply_damage(75,"brute","[target_zone]") - user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!", "You saw [target]'s [parse_zone(target_zone)] open.") - feedback_add_details("surgery_step_success","[src.type]") return 1 /datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] screws up!", "You screw up!") - feedback_add_details("surgery_step_failed","[src.type]") return 0 -/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(locate(/datum/surgery_step/saw) in surgery.steps) - target.heal_organ_damage(45,0) - return ..() - /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) return 1 - -/datum/surgery_step/proc/Handle_Multi_Loc(mob/user, mob/living/carbon/target) //this is here so MultiLoc Surgeries don't need to rewrite it each time - RR - - - if(user.zone_sel.selecting in allowed_organs) - - switch(user.zone_sel.selecting) //Switch, for Aran - RR - if("r_arm") - new_organ = target.getlimb(/obj/item/organ/limb/r_arm) - if("l_arm") - new_organ = target.getlimb(/obj/item/organ/limb/l_arm) - if("r_leg") - new_organ = target.getlimb(/obj/item/organ/limb/r_leg) - if("l_leg") - new_organ = target.getlimb(/obj/item/organ/limb/l_leg) - if("chest") - new_organ = target.getlimb(/obj/item/organ/limb/chest) - if("groin") - new_organ = target.getlimb(/obj/item/organ/limb/chest) - if("head") - new_organ = target.getlimb(/obj/item/organ/limb/head) - if("eyes") - new_organ = target.getlimb(/obj/item/organ/limb/head) - if("mouth") - new_organ = target.getlimb(/obj/item/organ/limb/head) - else - user << "You cannot perform this operation on this body part!" //Explain to the surgeon what went wrong - RR - return 0 - - return new_organ - - else - return 0 - - diff --git a/code/modules/surgery/xenomorph_removal.dm b/code/modules/surgery/xenomorph_removal.dm index 9650e824122..97cabb6d003 100644 --- a/code/modules/surgery/xenomorph_removal.dm +++ b/code/modules/surgery/xenomorph_removal.dm @@ -2,13 +2,13 @@ name = "xenomorph removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/xenomorph_removal, /datum/surgery_step/close) species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - location = "chest" - requires_organic_chest = 1 + possible_locs = list("chest") //remove xeno from premises /datum/surgery_step/xenomorph_removal + name = "remove foregin body" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/shovel/spade = 65, /obj/item/weapon/cultivator = 50, /obj/item/weapon/crowbar = 35) time = 64 @@ -23,7 +23,7 @@ return 1 /datum/surgery_step/xenomorph_removal/proc/remove_xeno(mob/user, mob/living/carbon/target) - var/obj/item/body_egg/alien_embryo/A = locate() in target.contents + var/obj/item/organ/internal/body_egg/alien_embryo/A = target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) if(A) user << "You found an unknown alien organism in [target]'s chest!" if(A.stage < 4) @@ -33,12 +33,13 @@ if(prob(10)) A.AttemptGrow() + A.Remove(target) A.loc = get_turf(target) return 1 /datum/surgery_step/xenomorph_removal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - var/obj/item/body_egg/alien_embryo/A = locate() in target.contents + var/obj/item/organ/internal/body_egg/alien_embryo/A = target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) if(A) if(prob(50)) A.AttemptGrow(0) diff --git a/html/changelog.html b/html/changelog.html index bb5ed90ea8d..266437d44fd 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,18 @@ -->
+

04 August 2015

+

Kor updated:

+ +

Summoner99 updated:

+ +

02 August 2015

Incoming5643 updated: