From 04f7b3f2de869bd4ccabb54e9177dbcb624557d4 Mon Sep 17 00:00:00 2001 From: c0 Date: Fri, 31 Jul 2015 22:18:31 +0300 Subject: [PATCH 01/12] Surgery, Implants and Organs rework: Phase 1 --- .../MetaStation/MetaStation.v41F.dmm | 2 +- code/datums/diseases/appendicitis.dm | 2 +- code/game/asteroid.dm | 4 +- code/game/gamemodes/abduction/abduction.dm | 5 +- .../gamemodes/abduction/abduction_gear.dm | 24 ++ .../gamemodes/abduction/abduction_surgery.dm | 28 +- code/game/gamemodes/gang/gang_pen.dm | 54 +-- code/game/gamemodes/nuclear/nuclear.dm | 8 +- code/game/machinery/computer/Operating.dm | 4 +- .../objects/items/weapons/implants/implant.dm | 227 +++-------- .../items/weapons/implants/implant_chem.dm | 54 +++ .../weapons/implants/implant_explosive.dm | 119 ++++++ .../{implantfreedom.dm => implant_freedom.dm} | 73 ++-- .../weapons/implants/implant_loyality.dm | 65 ++++ .../items/weapons/implants/implantcase.dm | 76 ++-- .../items/weapons/implants/implantchair.dm | 7 +- .../items/weapons/implants/implanter.dm | 70 ++-- .../items/weapons/implants/implantuplink.dm | 25 +- code/modules/awaymissions/exile.dm | 21 +- .../recipes/tablecraft/recipes_burger.dm | 2 +- code/modules/mining/abandoned_crates.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 4 +- .../mob/living/carbon/monkey/monkey.dm | 4 +- code/modules/ninja/ninja_event.dm | 4 +- .../research/designs/medical_designs.dm | 2 +- code/modules/surgery/appendectomy.dm | 10 +- code/modules/surgery/brain_removal.dm | 4 +- code/modules/surgery/cavity_implant.dm | 6 +- code/modules/surgery/core_removal.dm | 1 + code/modules/surgery/cybernetic_implants.dm | 20 +- code/modules/surgery/eye_surgery.dm | 5 +- code/modules/surgery/gender_reassignment.dm | 4 +- code/modules/surgery/generic_steps.dm | 19 +- code/modules/surgery/helpers.dm | 57 ++- code/modules/surgery/implant_removal.dm | 35 +- code/modules/surgery/limb augmentation.dm | 37 +- code/modules/surgery/lipoplasty.dm | 12 +- .../{augments.dm => augments_external.dm} | 102 ++--- ...netic_implants.dm => augments_internal.dm} | 0 code/modules/surgery/organs/helpers.dm | 25 +- .../organs/{organ.dm => organ_external.dm} | 368 ++++++++---------- code/modules/surgery/organs/organ_internal.dm | 59 +++ code/modules/surgery/plastic_surgery.dm | 4 +- .../modules/surgery/remove_embedded_object.dm | 13 +- code/modules/surgery/surgery.dm | 22 +- code/modules/surgery/surgery_step.dm | 60 +-- code/modules/surgery/xenomorph_removal.dm | 4 +- tgstation.dme | 12 +- 48 files changed, 934 insertions(+), 831 deletions(-) create mode 100644 code/game/objects/items/weapons/implants/implant_chem.dm create mode 100644 code/game/objects/items/weapons/implants/implant_explosive.dm rename code/game/objects/items/weapons/implants/{implantfreedom.dm => implant_freedom.dm} (84%) create mode 100644 code/game/objects/items/weapons/implants/implant_loyality.dm rename code/modules/surgery/organs/{augments.dm => augments_external.dm} (95%) rename code/modules/surgery/organs/{cybernetic_implants.dm => augments_internal.dm} (100%) rename code/modules/surgery/organs/{organ.dm => organ_external.dm} (85%) create mode 100644 code/modules/surgery/organs/organ_internal.dm 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/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/game/asteroid.dm b/code/game/asteroid.dm index 938c48b5343..0f5ebca201e 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..81c871b20d5 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,13 +33,14 @@ 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 + name = "insert gland" implements = list(/obj/item/gland = 100) time = 32 @@ -42,6 +52,4 @@ user.drop_item() var/obj/item/gland/gland = tool gland.Inject(target) - return 1 - - + return 1 \ 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/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/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..8b847d4f1de --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -0,0 +1,54 @@ +/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. 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/implantcase/chem + name = "glass case - 'Remote Chemical'" + desc = "A 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..dad37115fe5 --- /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
+ 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 + 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/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) + if(imp_in) + 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" + 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 = "glass case - 'Explosive'" + desc = "A 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 84% rename from code/game/objects/items/weapons/implants/implantfreedom.dm rename to code/game/objects/items/weapons/implants/implant_freedom.dm index 821cec4c572..40505d82489 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implant_freedom.dm @@ -1,37 +1,36 @@ -//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
+Integrity: The battery is extremely weak and commonly after injection its +life can drive down to only 1 use.
+No Implant Specifics"} + return dat + + 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..7c054c253df --- /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 = "glass case - 'Loyalty'" + desc = "A 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..8cf41c2f730 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'" + name = "glass case - 'Tracking'" desc = "A case containing a tracking implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" /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'" + name = "glass case - 'Firearms Authentication'" desc = "A case containing a firearms authentication implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" /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/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm index 7e36cf7e04a..cf659e59b5c 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'" + name = "glass case - 'Exile'" desc = "A case containing an exile implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" /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/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 679fb191dc1..4cda20901dd 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -22,8 +22,8 @@ /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 spawned humans; overwritten by other code diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 1d1bbcc64d5..9cbc5ce8407 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -16,8 +16,8 @@ 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 if(name == "monkey") 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..51963c82627 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -199,4 +199,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") + 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..b725717945a 100644 --- a/code/modules/surgery/cybernetic_implants.dm +++ b/code/modules/surgery/cybernetic_implants.dm @@ -5,12 +5,13 @@ 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 + name = "insert eye cybernetic implant" implements = list(/obj/item/cybernetic_implant/eyes = 100) time = 32 @@ -23,12 +24,14 @@ 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 + name = "insert brain cybernetic implant" implements = list(/obj/item/cybernetic_implant/brain = 100) time = 32 @@ -45,12 +48,14 @@ 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 + name = "insert torso cybernetic implant" implements = list(/obj/item/cybernetic_implant/chest = 100) time = 32 @@ -70,10 +75,9 @@ 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() + user.drop_item() target.internal_organs |= implant implant.loc = 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..81731314f49 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,6 +12,7 @@ //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 @@ -20,6 +22,7 @@ //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 +33,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 +59,25 @@ 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..c4ba5c2680d 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -1,54 +1,53 @@ /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 + if(istype(M, /mob/living/carbon/human)) + H = M + affecting = H.get_organ(check_zone(user.zone_sel.selecting)) + 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] - + if(!S.possible_locs.Find(user.zone_sel.selecting)) + continue if(locate(S.type) in M.surgeries) continue - if(S.user_species_restricted) - if(!istype(user, /mob/living/carbon/human)) - continue - var/mob/living/carbon/human/doc = user - if(!(doc.dna.species.id in S.user_species_ids)) - continue - if(S.target_must_be_dead && M.stat != DEAD) + if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) continue - if(S.target_must_be_fat && !(M.disabilities & FAT)) + if(!S.can_start(user, M)) 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 - continue - - - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting)) - - if(affecting.status == ORGAN_ROBOTIC && affecting.body_part != HEAD) //Cannot operate on Robotic organs except for the head. - RR - continue - for(var/path in S.species) if(istype(M, path)) available_surgeries[S.name] = S break + for(var/datum/surgery/S in M.surgeries) + if(S.status == 1 && !S.step_in_progress) + available_surgeries["cancel " + S.name] = S + var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries if(P) var/datum/surgery/S = available_surgeries[P] + if(S in M.surgeries) + M.surgeries -= S + qdel(S) + return 1 + 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 + procedure.location = user.zone_sel.selecting + if(procedure.ignore_clothes || get_location_accessible(M, procedure.location)) 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].") + if(affecting) + procedure.organ = affecting + 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!" @@ -59,7 +58,7 @@ -/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 @@ -80,13 +79,13 @@ for(var/obj/item/clothing/I in list(C.back, C.wear_mask, C.head)) covered_locations |= I.body_parts_covered face_covered |= I.flags_inv - eyesmouth_covered |= I.flags_cover + eyesmouth_covered |= I.flags if(ishuman(C)) var/mob/living/carbon/human/H = C for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.ears)) covered_locations |= I.body_parts_covered face_covered |= I.flags_inv - eyesmouth_covered |= I.flags_cover + eyesmouth_covered |= I.flags switch(location) if("head") diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 86851838afc..6b4feb8749e 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -2,22 +2,18 @@ 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") //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 +22,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/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/cybernetic_implants.dm b/code/modules/surgery/organs/augments_internal.dm similarity index 100% rename from code/modules/surgery/organs/cybernetic_implants.dm rename to code/modules/surgery/organs/augments_internal.dm diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index dd0529d4344..a0bdf9e3369 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -1,13 +1,22 @@ -/mob/proc/getorgan() +mob/proc/getorgan() return -/mob/living/carbon/getorgan(typepath) + +mob/proc/getorgansloc() + return + +mob/living/carbon/getorgan(typepath) return (locate(typepath) in internal_organs) -/mob/proc/getlimb() +mob/living/carbon/getorgansloc(zone) + var/list/returnorg = list() + for(var/obj/item/organ/internal/O in internal_organs) + if(zone == O.zone) + returnorg += O + + return returnorg + +mob/proc/getlimb() return -/mob/living/carbon/human/getlimb(typepath) - return (locate(typepath) in organs) - - - +mob/living/carbon/human/getlimb(typepath) + return (locate(typepath) in organs) \ 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..99cb764ccdd --- /dev/null +++ b/code/modules/surgery/organs/organ_internal.dm @@ -0,0 +1,59 @@ +/obj/item/organ/internal + var/zone = "chest" + var/slot + var/vital = 0 + +/obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M) + owner = M + M.internal_organs += src + loc = null + +/obj/item/organ/internal/proc/Remove(var/mob/living/carbon/M, var/special = 0) + owner = null + M.internal_organs -= src + if(vital && !special) + M.death() + +//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" + 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/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" + else + icon_state = "appendix" + +/obj/item/organ/internal/appendix/Remove(var/mob/living/carbon/M) + for(var/datum/disease/appendicitis in M.viruses) + appendicitis.cure() + ..() + +/obj/item/organ/internal/appendix/Insert(var/mob/living/carbon/M) + ..() + 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..5ae9a9b849f 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -1,5 +1,5 @@ /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 @@ -7,11 +7,17 @@ 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 +60,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..686fc3c0e8e 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,11 +38,8 @@ /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) - if(do_after(user, time, target = target)) + preop(user, target, target_zone, tool, surgery) + if(do_after(user, time)) var/advance = 0 var/prob_chance = 100 @@ -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..8528c349179 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 diff --git a/tgstation.dme b/tgstation.dme index b8939f6fa7d..2029e03a330 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -677,10 +677,13 @@ #include "code\game\objects\items\weapons\grenades\spawnergrenade.dm" #include "code\game\objects\items\weapons\grenades\syndieminibomb.dm" #include "code\game\objects\items\weapons\implants\implant.dm" +#include "code\game\objects\items\weapons\implants\implant_chem.dm" +#include "code\game\objects\items\weapons\implants\implant_explosive.dm" +#include "code\game\objects\items\weapons\implants\implant_freedom.dm" +#include "code\game\objects\items\weapons\implants\implant_loyality.dm" #include "code\game\objects\items\weapons\implants\implantcase.dm" #include "code\game\objects\items\weapons\implants\implantchair.dm" #include "code\game\objects\items\weapons\implants\implanter.dm" -#include "code\game\objects\items\weapons\implants\implantfreedom.dm" #include "code\game\objects\items\weapons\implants\implantpad.dm" #include "code\game\objects\items\weapons\implants\implantuplink.dm" #include "code\game\objects\items\weapons\melee\energy.dm" @@ -1502,10 +1505,11 @@ #include "code\modules\surgery\surgery_step.dm" #include "code\modules\surgery\tools.dm" #include "code\modules\surgery\xenomorph_removal.dm" -#include "code\modules\surgery\organs\augments.dm" -#include "code\modules\surgery\organs\cybernetic_implants.dm" +#include "code\modules\surgery\organs\augments_external.dm" +#include "code\modules\surgery\organs\augments_internal.dm" #include "code\modules\surgery\organs\helpers.dm" -#include "code\modules\surgery\organs\organ.dm" +#include "code\modules\surgery\organs\organ_external.dm" +#include "code\modules\surgery\organs\organ_internal.dm" #include "code\modules\telesci\bscrystal.dm" #include "code\modules\telesci\gps.dm" #include "code\modules\telesci\telepad.dm" From 47524811c522f513e886f1288a0cba6cc0522b44 Mon Sep 17 00:00:00 2001 From: c0 Date: Sat, 1 Aug 2015 01:56:54 +0300 Subject: [PATCH 02/12] Renamed "glass case" -> "implant case". Changed implant syndiekit to be less FUCKS. --- .../items/weapons/implants/implant_chem.dm | 4 ++-- .../weapons/implants/implant_explosive.dm | 4 ++-- .../items/weapons/implants/implant_freedom.dm | 15 ++++++++++++++ .../weapons/implants/implant_loyality.dm | 4 ++-- .../items/weapons/implants/implantcase.dm | 8 ++++---- .../items/weapons/storage/uplink_kits.dm | 20 +++++++------------ code/modules/awaymissions/exile.dm | 4 ++-- 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/code/game/objects/items/weapons/implants/implant_chem.dm b/code/game/objects/items/weapons/implants/implant_chem.dm index 8b847d4f1de..b419c15df27 100644 --- a/code/game/objects/items/weapons/implants/implant_chem.dm +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -46,8 +46,8 @@ /obj/item/weapon/implantcase/chem - name = "glass case - 'Remote Chemical'" - desc = "A case containing a remote chemical implant." + 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) diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm index dad37115fe5..c901f99fdbf 100644 --- a/code/game/objects/items/weapons/implants/implant_explosive.dm +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -111,8 +111,8 @@ /obj/item/weapon/implantcase/explosive - name = "glass case - 'Explosive'" - desc = "A case containing an explosive implant." + 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) diff --git a/code/game/objects/items/weapons/implants/implant_freedom.dm b/code/game/objects/items/weapons/implants/implant_freedom.dm index 40505d82489..f395bf87489 100644 --- a/code/game/objects/items/weapons/implants/implant_freedom.dm +++ b/code/game/objects/items/weapons/implants/implant_freedom.dm @@ -34,3 +34,18 @@ 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 index 7c054c253df..3751cd63343 100644 --- a/code/game/objects/items/weapons/implants/implant_loyality.dm +++ b/code/game/objects/items/weapons/implants/implant_loyality.dm @@ -57,8 +57,8 @@ /obj/item/weapon/implantcase/loyalty - name = "glass case - 'Loyalty'" - desc = "A case containing a loyalty implant." + 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) diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index 8cf41c2f730..b38dbaea378 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -68,8 +68,8 @@ /obj/item/weapon/implantcase/tracking - name = "glass case - 'Tracking'" - desc = "A case containing a tracking implant." + 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) @@ -77,8 +77,8 @@ /obj/item/weapon/implantcase/weapons_auth - name = "glass case - 'Firearms Authentication'" - desc = "A case containing a firearms authentication implant." + 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/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/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm index cf659e59b5c..4e6a69d591b 100644 --- a/code/modules/awaymissions/exile.dm +++ b/code/modules/awaymissions/exile.dm @@ -22,8 +22,8 @@ ..() /obj/item/weapon/implantcase/exile - name = "glass case - 'Exile'" - desc = "A case containing an exile implant." + 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) From 1c93a6e70857e7b6db68c5fb94050959a6247ada Mon Sep 17 00:00:00 2001 From: c0 Date: Sat, 1 Aug 2015 02:03:16 +0300 Subject: [PATCH 03/12] Swapped some lines, not sure why --- code/game/objects/items/weapons/implants/implant_explosive.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm index c901f99fdbf..70749dc537c 100644 --- a/code/game/objects/items/weapons/implants/implant_explosive.dm +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -34,8 +34,8 @@ 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) + imp_in.gib() qdel(src) return timed_explosion() @@ -65,9 +65,9 @@ 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() - explosion(src,heavy,medium,weak,weak, flame_range = weak) qdel(src) /obj/item/weapon/implant/explosive/macro From 8e0e6f31912fbb08040f81a8e489b0522b1b8d45 Mon Sep 17 00:00:00 2001 From: c0 Date: Sun, 2 Aug 2015 00:37:29 +0300 Subject: [PATCH 04/12] Tweaks and fixes --- .../items/weapons/implants/implant_chem.dm | 3 +- .../weapons/implants/implant_explosive.dm | 2 +- .../items/weapons/implants/implant_freedom.dm | 3 +- code/modules/surgery/helpers.dm | 88 +++++++++---------- .../surgery/multiple_location_example.dm | 54 ------------ 5 files changed, 47 insertions(+), 103 deletions(-) delete mode 100644 code/modules/surgery/multiple_location_example.dm diff --git a/code/game/objects/items/weapons/implants/implant_chem.dm b/code/game/objects/items/weapons/implants/implant_chem.dm index b419c15df27..6f85742039b 100644 --- a/code/game/objects/items/weapons/implants/implant_chem.dm +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -18,8 +18,7 @@ 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."} + Integrity: Implant will last so long as the subject is alive."} return dat /obj/item/weapon/implant/chem/New() diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm index 70749dc537c..719666b47b2 100644 --- a/code/game/objects/items/weapons/implants/implant_explosive.dm +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -17,7 +17,7 @@ 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) diff --git a/code/game/objects/items/weapons/implants/implant_freedom.dm b/code/game/objects/items/weapons/implants/implant_freedom.dm index f395bf87489..e3e70e982a2 100644 --- a/code/game/objects/items/weapons/implants/implant_freedom.dm +++ b/code/game/objects/items/weapons/implants/implant_freedom.dm @@ -28,8 +28,7 @@ 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 diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index c4ba5c2680d..021eddeb277 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -2,58 +2,58 @@ 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(user.zone_sel.selecting)) + 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] - if(!S.possible_locs.Find(user.zone_sel.selecting)) - continue - if(locate(S.type) in M.surgeries) - continue - if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) - continue - if(!S.can_start(user, M)) - continue - - for(var/path in S.species) - if(istype(M, path)) - available_surgeries[S.name] = S - break + var/datum/surgery/current_surgery for(var/datum/surgery/S in M.surgeries) - if(S.status == 1 && !S.step_in_progress) - available_surgeries["cancel " + S.name] = S + if(S.location == selected_zone) + current_surgery = S - var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries - if(P) - var/datum/surgery/S = available_surgeries[P] - if(S in M.surgeries) - M.surgeries -= S - qdel(S) - return 1 + 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 + if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) + continue + if(!S.can_start(user, M)) + continue - var/datum/surgery/procedure = new S.type - if(procedure) - procedure.location = user.zone_sel.selecting - if(procedure.ignore_clothes || get_location_accessible(M, procedure.location)) - M.surgeries += procedure - if(affecting) + 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 && 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(procedure.location)] to prepare for \an [procedure.name].", \ - "You drape [I] over [M]'s [parse_zone(procedure.location)] to prepare for \an [procedure.name].") + 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].") - add_logs(user, M, "operated", addition="Operation type: [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. + 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!" + + 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 @@ -79,13 +79,13 @@ proc/get_location_modifier(mob/M) for(var/obj/item/clothing/I in list(C.back, C.wear_mask, C.head)) covered_locations |= I.body_parts_covered face_covered |= I.flags_inv - eyesmouth_covered |= I.flags + eyesmouth_covered |= I.flags_cover if(ishuman(C)) var/mob/living/carbon/human/H = C for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.ears)) covered_locations |= I.body_parts_covered face_covered |= I.flags_inv - eyesmouth_covered |= I.flags + eyesmouth_covered |= I.flags_cover switch(location) if("head") 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 From 93b72c863ae710ec80fae9ec7d967e3e7d02145d Mon Sep 17 00:00:00 2001 From: c0 Date: Sun, 2 Aug 2015 14:15:06 +0300 Subject: [PATCH 05/12] Added progress bars to surgeries --- code/modules/surgery/surgery_step.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 686fc3c0e8e..bd442c7c5a7 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -39,7 +39,7 @@ surgery.step_in_progress = 1 preop(user, target, target_zone, tool, surgery) - if(do_after(user, time)) + if(do_after(user, time, target = target)) var/advance = 0 var/prob_chance = 100 From 600d424ea593209c7f061c20493acf442cf579c1 Mon Sep 17 00:00:00 2001 From: c0 Date: Sun, 2 Aug 2015 22:28:45 +0300 Subject: [PATCH 06/12] Moved cyberimplants to internal organs system --- code/_onclick/hud/action.dm | 20 ++ code/datums/uplink_item.dm | 8 +- code/game/objects/items/devices/scanners.dm | 2 +- .../crates_lockers/closets/secure/medical.dm | 2 +- code/modules/mob/living/carbon/alien/alien.dm | 7 +- code/modules/mob/living/carbon/carbon.dm | 14 +- .../mob/living/carbon/human/examine.dm | 11 +- code/modules/mob/living/carbon/human/human.dm | 3 + .../mob/living/carbon/human/human_helpers.dm | 5 +- code/modules/mob/living/carbon/life.dm | 8 +- .../mob/living/carbon/monkey/monkey.dm | 12 +- code/modules/mob/living/life.dm | 38 +-- .../research/designs/medical_designs.dm | 18 +- code/modules/surgery/cybernetic_implants.dm | 27 +- code/modules/surgery/generic_steps.dm | 8 +- code/modules/surgery/organs/augments_eyes.dm | 127 +++++++++ .../surgery/organs/augments_internal.dm | 252 +++++------------- code/modules/surgery/organs/helpers.dm | 16 +- code/modules/surgery/organs/organ_internal.dm | 19 +- code/modules/surgery/surgery.dm | 1 - tgstation.dme | 1 + 21 files changed, 341 insertions(+), 258 deletions(-) create mode 100644 code/modules/surgery/organs/augments_eyes.dm diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index f31ac20af2f..10c6399b17e 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -212,11 +212,31 @@ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_ALIVE|AB_CHECK_INSIDE /datum/action/item_action/CheckRemoval(mob/living/user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + if(target in C.internal_organs) + return 0 + return !(target in user) /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/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/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/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/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index f4e3a3a3573..04ab010bc33 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 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 696c9a3b5a4..2bedc742483 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -266,7 +266,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) @@ -275,9 +275,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:
" @@ -292,8 +292,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 4cda20901dd..658bd354c0c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -26,6 +26,9 @@ 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_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/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 9cbc5ce8407..7a2a5379910 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -20,6 +20,9 @@ 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/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 51963c82627..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 + 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/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm index b725717945a..ed6813bf087 100644 --- a/code/modules/surgery/cybernetic_implants.dm +++ b/code/modules/surgery/cybernetic_implants.dm @@ -1,7 +1,7 @@ #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]]]] @@ -12,13 +12,13 @@ /datum/surgery_step/cybernetic_implant/eyes name = "insert eye cybernetic implant" - implements = list(/obj/item/cybernetic_implant/eyes = 100) + 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 @@ -32,14 +32,14 @@ /datum/surgery_step/cybernetic_implant/brain name = "insert brain cybernetic implant" - implements = list(/obj/item/cybernetic_implant/brain = 100) + 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) @@ -56,14 +56,14 @@ /datum/surgery_step/cybernetic_implant/chest name = "insert torso cybernetic implant" - implements = list(/obj/item/cybernetic_implant/chest = 100) + 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 @@ -71,13 +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 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() user.drop_item() - target.internal_organs |= implant - implant.loc = target \ No newline at end of file + implant.Insert(target) \ No newline at end of file diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/generic_steps.dm index 81731314f49..1f01549e999 100644 --- a/code/modules/surgery/generic_steps.dm +++ b/code/modules/surgery/generic_steps.dm @@ -19,6 +19,11 @@ /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 @@ -79,5 +84,6 @@ 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.") + + 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/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm new file mode 100644 index 00000000000..3cdfda38de5 --- /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(owner,/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 index 273543bbae1..ee26bab3a0d 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -1,139 +1,33 @@ #define STUN_SET_AMOUNT 2 -/obj/item/cybernetic_implant +/obj/item/organ/internal/cyberimp 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 + status = ORGAN_ROBOTIC var/implant_color = "#FFFFFF" + var/implant_overlay -/obj/item/cybernetic_implant/New(var/mob/M = null) - owner = M +/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 ..() -/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 +/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/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) +/obj/item/organ/internal/cyberimp/brain/emp_act(severity) if(!owner) return var/stun_amount = 5 + (severity-1 ? 0 : 5) @@ -141,7 +35,8 @@ owner << "Your body seizes up!" return stun_amount -/obj/item/cybernetic_implant/brain/anti_drop + +/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 @@ -150,12 +45,11 @@ 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/cybernetic_implant/brain/anti_drop/function() - action_button_name = "Toggle Anti-Drop" - -/obj/item/cybernetic_implant/brain/anti_drop/ui_action_click() +/obj/item/organ/internal/cyberimp/brain/anti_drop/ui_action_click() active = !active if(active) l_hand_obj = owner.l_hand @@ -194,7 +88,7 @@ l_hand_obj = null r_hand_obj = null -/obj/item/cybernetic_implant/brain/anti_drop/emp_act(severity) +/obj/item/organ/internal/cyberimp/brain/anti_drop/emp_act(severity) if(!owner) return var/range = severity ? 10 : 5 @@ -213,27 +107,28 @@ 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() +/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/cybernetic_implant/brain/anti_stun +/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/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) +/obj/item/organ/internal/cyberimp/brain/anti_stun/on_life() + ..() + if(crit_fail) return if(owner.stunned > STUN_SET_AMOUNT) @@ -241,94 +136,77 @@ if(owner.weakened > STUN_SET_AMOUNT) owner.weakened = STUN_SET_AMOUNT -/obj/item/cybernetic_implant/brain/anti_stun/emp_act(severity) - if(!owner) +/obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) + if(crit_fail) return - SSobj.processing.Remove(src) - spawn(..() * 10) - SSobj.processing |= src + crit_fail = 1 + spawn(90 / severity) + crit_fail = 0 //[[[[CHEST]]]] -/obj/item/cybernetic_implant/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/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 +/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/nutriment_amount = 30 var/poison_amount = 5 + slot = "stomach" 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() +/obj/item/organ/internal/cyberimp/chest/nutriment/on_life() if(synthesizing) return - if(!owner) - SSobj.processing.Remove(src) - qdel(src) - return if(owner.stat == DEAD) return if(owner.nutrition <= hunger_threshold) synthesizing = 1 + owner << "You feel less hungry..." + owner.nutrition += 50 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) +/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/cybernetic_implant/chest/reviver +/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/cybernetic_implant/chest/reviver/function() - SSobj.processing |= src - -/obj/item/cybernetic_implant/chest/reviver/process() - if(!owner) - SSobj.processing.Remove(src) - qdel(src) - return - +/obj/item/organ/internal/cyberimp/chest/reviver/on_life() if(reviving) if(owner.stat == UNCONSCIOUS) spawn(30) @@ -354,13 +232,15 @@ 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) +/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity) + if(!owner) + return + if(reviving) revive_cost += 200 else @@ -382,8 +262,8 @@ 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/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() diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index a0bdf9e3369..151aed42fca 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -1,20 +1,28 @@ -mob/proc/getorgan() +mob/proc/getorgan(typepath) return -mob/proc/getorgansloc() +mob/proc/getorganszone(zone) return +mob/proc/getorganslot(slot) + return + + mob/living/carbon/getorgan(typepath) return (locate(typepath) in internal_organs) -mob/living/carbon/getorgansloc(zone) +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 diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 99cb764ccdd..d41710296c9 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -2,18 +2,27 @@ var/zone = "chest" var/slot var/vital = 0 + var/organ_action_name = null -/obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M) +/obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M, special = 0) 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, var/special = 0) +/obj/item/organ/internal/proc/Remove(var/mob/living/carbon/M, special = 0) owner = null 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 + //Looking for brains? //Try code/modules/mob/living/carbon/brain/brain_item.dm @@ -45,15 +54,17 @@ /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) +/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) +/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/surgery.dm b/code/modules/surgery/surgery.dm index 5ae9a9b849f..9a9196562fd 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -6,7 +6,6 @@ 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_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 diff --git a/tgstation.dme b/tgstation.dme index 2029e03a330..9aad023590f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1506,6 +1506,7 @@ #include "code\modules\surgery\tools.dm" #include "code\modules\surgery\xenomorph_removal.dm" #include "code\modules\surgery\organs\augments_external.dm" +#include "code\modules\surgery\organs\augments_eyes.dm" #include "code\modules\surgery\organs\augments_internal.dm" #include "code\modules\surgery\organs\helpers.dm" #include "code\modules\surgery\organs\organ_external.dm" From 439dd6d0111aa6a9b306a5b882c2418f8e5a5c15 Mon Sep 17 00:00:00 2001 From: Ikarrus Date: Sun, 2 Aug 2015 14:20:47 -0600 Subject: [PATCH 07/12] Head Beating no longer deconvert gangsters I've seen enough rounds where security just goes full Hitler and beats everyone, gangster or no, to death and just leaves their corpse in the brig afterwards. Gangs have implant breakers and security still has implants. Head beatings are no longer needed and just lead to extreme mad. --- .../mob/living/carbon/human/human_defense.dm | 3 +- .../mob/living/carbon/human/species.dm | 1 - html/changelogs/ikarrus-removebeats.yml | 36 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 html/changelogs/ikarrus-removebeats.yml diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 06944984cf5..311807bb989 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -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/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0e90a523120..a70baec13b7 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) diff --git a/html/changelogs/ikarrus-removebeats.yml b/html/changelogs/ikarrus-removebeats.yml new file mode 100644 index 00000000000..7d4ce263ecc --- /dev/null +++ b/html/changelogs/ikarrus-removebeats.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: Ikarrus + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscdel: "Head beatings no longer deconvert gangsters." From 32be0a1df8af825e0d9e9bdf91758dde25e3c385 Mon Sep 17 00:00:00 2001 From: PatchouliKnowledge Date: Mon, 3 Aug 2015 15:48:51 +0300 Subject: [PATCH 08/12] You can't exchange documents if you are to commit sudoku --- code/game/gamemodes/objective.dm | 1 + 1 file changed, 1 insertion(+) 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 From 667d5e75c357ca0127df2fd3e26fd3262176669f Mon Sep 17 00:00:00 2001 From: c0 Date: Mon, 3 Aug 2015 23:24:17 +0300 Subject: [PATCH 09/12] Transferred body eggs to new organs system --- code/__DEFINES/genetics.dm | 1 + code/_onclick/hud/action.dm | 5 - code/datums/datumvars.dm | 25 +++- code/datums/diseases/transformation.dm | 2 +- code/datums/mind.dm | 2 +- code/datums/mutations.dm | 4 +- .../gamemodes/changeling/powers/headcrab.dm | 7 ++ .../gamemodes/changeling/powers/humanform.dm | 2 +- .../gamemodes/changeling/powers/lesserform.dm | 4 +- code/game/objects/items/body_egg.dm | 73 +++++------ code/modules/admin/verbs/debug.dm | 1 + code/modules/admin/verbs/manipulate_organs.dm | 55 +++++++++ code/modules/admin/verbs/mapping.dm | 2 + code/modules/mob/living/carbon/alien/alien.dm | 2 +- .../carbon/alien/special/alien_embryo.dm | 114 ++++++++---------- .../living/carbon/alien/special/facehugger.dm | 5 +- .../mob/living/carbon/brain/brain_item.dm | 2 +- .../mob/living/carbon/human/human_damage.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 4 +- .../mob/living/carbon/human/species.dm | 2 +- .../living/simple_animal/hostile/headcrab.dm | 63 +++++----- code/modules/mob/mob_helpers.dm | 2 +- code/modules/mob/transform_procs.dm | 35 +++++- code/modules/surgery/implant_removal.dm | 1 + code/modules/surgery/organs/augments_eyes.dm | 6 +- .../surgery/organs/augments_internal.dm | 4 +- code/modules/surgery/organs/helpers.dm | 5 +- code/modules/surgery/organs/organ_internal.dm | 34 +++++- code/modules/surgery/xenomorph_removal.dm | 5 +- tgstation.dme | 1 + 30 files changed, 293 insertions(+), 177 deletions(-) create mode 100644 code/modules/admin/verbs/manipulate_organs.dm 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 10c6399b17e..63b22f7004e 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -212,11 +212,6 @@ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_ALIVE|AB_CHECK_INSIDE /datum/action/item_action/CheckRemoval(mob/living/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - if(target in C.internal_organs) - return 0 - return !(target in user) /datum/action/item_action/hands_free 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/transformation.dm b/code/datums/diseases/transformation.dm index 93fd9239761..69e66e43351 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 c21d96be8a3..12be3beba8f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1161,7 +1161,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/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/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/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..99dfeadd05b --- /dev/null +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -0,0 +1,55 @@ +/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] ([I.type])"] = I + + for(var/obj/item/weapon/implant/I in C) + organs["[I] ([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 \ 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/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 04ab010bc33..f96c94af11a 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -190,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 7763954c786..bfca0c02171 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/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..8ed71d82690 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) @@ -469,4 +469,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/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0e90a523120..d24c1a42450 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1101,7 +1101,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/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 62fb5c75178..316eff9795e 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 45fe320ce0c..d645bf4a6ef 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/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 6b4feb8749e..b3ab5a6379c 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -3,6 +3,7 @@ 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) possible_locs = list("chest") + requires_organic_bodypart = 0 //extract implant diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 3cdfda38de5..ab814cbf9df 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -26,12 +26,12 @@ 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(owner,/mob/living/carbon/human) && eye_color) + 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() ..() @@ -88,11 +88,11 @@ 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" diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index ee26bab3a0d..b904d93f9e3 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -114,9 +114,9 @@ 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 @@ -167,8 +167,6 @@ /obj/item/organ/internal/cyberimp/chest/nutriment/on_life() if(synthesizing) return - if(owner.stat == DEAD) - return if(owner.nutrition <= hunger_threshold) synthesizing = 1 diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index 151aed42fca..18b4185ea52 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -27,4 +27,7 @@ mob/proc/getlimb() return mob/living/carbon/human/getlimb(typepath) - return (locate(typepath) in organs) \ No newline at end of file + 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_internal.dm b/code/modules/surgery/organs/organ_internal.dm index d41710296c9..af2b5d1a7ca 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -1,21 +1,31 @@ /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)) + return + + var/obj/item/organ/internal/replaced = M.getorganslot(slot) + if(replaced) + replaced.Remove(M, special = 1) + + owner = M - M.internal_organs += src + 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 - M.internal_organs -= src - if(vital && !special) - M.death() + if(M) + M.internal_organs -= src + if(vital && !special) + M.death() if(organ_action_name) action_button_name = null @@ -23,6 +33,11 @@ /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 @@ -33,6 +48,7 @@ icon_state = "heart-on" zone = "chest" slot = "heart" + origin_tech = "biotech=3" vital = 1 var/beating = 1 @@ -42,6 +58,16 @@ 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 diff --git a/code/modules/surgery/xenomorph_removal.dm b/code/modules/surgery/xenomorph_removal.dm index 8528c349179..97cabb6d003 100644 --- a/code/modules/surgery/xenomorph_removal.dm +++ b/code/modules/surgery/xenomorph_removal.dm @@ -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/tgstation.dme b/tgstation.dme index 9aad023590f..f5124222594 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -838,6 +838,7 @@ #include "code\modules\admin\verbs\fps.dm" #include "code\modules\admin\verbs\getlogs.dm" #include "code\modules\admin\verbs\machine_upgrade.dm" +#include "code\modules\admin\verbs\manipulate_organs.dm" #include "code\modules\admin\verbs\mapping.dm" #include "code\modules\admin\verbs\massmodvar.dm" #include "code\modules\admin\verbs\modifyvariables.dm" From d3c363a2e4ecfeb3824a8107fc013d42b5c82135 Mon Sep 17 00:00:00 2001 From: c0 Date: Tue, 4 Aug 2015 00:14:24 +0300 Subject: [PATCH 10/12] Changelog --- code/modules/admin/verbs/manipulate_organs.dm | 7 ++-- html/changelogs/c0-organs-part1.yml | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 html/changelogs/c0-organs-part1.yml diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index 99dfeadd05b..ae500213e59 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -27,10 +27,10 @@ if("drop organ/implant", "remove organ/implant") for(var/obj/item/organ/internal/I in C.internal_organs) - organs["[I] ([I.type])"] = I + organs["[I.name] ([I.type])"] = I for(var/obj/item/weapon/implant/I in C) - organs["[I] ([I.type])"] = I + organs["[I.name] ([I.type])"] = I var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) in organs organ = organs[organ] @@ -52,4 +52,5 @@ else if(I) // Put the implant in case. var/obj/item/weapon/implantcase/case = new(get_turf(C)) case.imp = I - I.loc = case \ No newline at end of file + I.loc = case + case.update_icon() \ No newline at end of file diff --git a/html/changelogs/c0-organs-part1.yml b/html/changelogs/c0-organs-part1.yml new file mode 100644 index 00000000000..b993bf1c3ca --- /dev/null +++ b/html/changelogs/c0-organs-part1.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: CoreOverload + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Implants, implant cases and implanters got RnD levels and can be DA'ed for science." + - rscadd: "Surgically removed implant can be placed into an implant case. Remove implant with empty implant case in inactive hand." + - rscadd: "Surgical steps now got progress bars." + - rscadd: "You can cancel a surgery by using drape on operable body part again. This works only before you perform surgery's first step." + - rscadd: "Operating computer shows next step for surgeries. No more alt-tabbing to view next step on wiki while operating." + - tweak: "You cannot start two surgeries on one body part at once. You can start two multiloc surgeries (i.e. two augumentations) on diffirent body parts at once." + - tweak: "Monkey <-> Human transformations now keep your internal organs, cyberimplants and xeno embryos included." From 88f2073a5e2be4cf16c2594d678fe47240bc7326 Mon Sep 17 00:00:00 2001 From: c0 Date: Tue, 4 Aug 2015 01:46:32 +0300 Subject: [PATCH 11/12] Abductor glands are organs now --- .../gamemodes/abduction/abduction_surgery.dm | 6 +- code/game/gamemodes/abduction/gland.dm | 224 ++++++++++-------- .../abduction/machinery/dispenser.dm | 4 +- .../abduction/machinery/experiment.dm | 4 +- code/modules/surgery/organs/organ_internal.dm | 3 +- 5 files changed, 133 insertions(+), 108 deletions(-) diff --git a/code/game/gamemodes/abduction/abduction_surgery.dm b/code/game/gamemodes/abduction/abduction_surgery.dm index 81c871b20d5..f22f188945b 100644 --- a/code/game/gamemodes/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/abduction/abduction_surgery.dm @@ -41,7 +41,7 @@ /datum/surgery_step/gland_insert name = "insert gland" - implements = list(/obj/item/gland = 100) + 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) @@ -50,6 +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) + 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/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index af2b5d1a7ca..ae4e1e00a55 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -6,14 +6,13 @@ var/organ_action_name = null /obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M, special = 0) - if(!iscarbon(M)) + 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 From 915937cb366e1ff93d962c536ac0755c583c98cd Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Tue, 4 Aug 2015 05:12:35 +0000 Subject: [PATCH 12/12] Automatic changelog compile --- html/changelog.html | 12 +++++++ html/changelogs/.all_changelog.yml | 9 ++++++ html/changelogs/KORPHAERON-PR-SOULSTONE.yml | 36 --------------------- html/changelogs/Summoners99-hisssss.yml | 8 ----- 4 files changed, 21 insertions(+), 44 deletions(-) delete mode 100644 html/changelogs/KORPHAERON-PR-SOULSTONE.yml delete mode 100644 html/changelogs/Summoners99-hisssss.yml 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:

+
    +
  • Soulstones will now attempt to pull ghosts from beyond if the targeted corpse has no soul.
  • +
+

Summoner99 updated:

+
    +
  • Added the *roar emote back to Alien Larva
  • +
  • Fixed aliens not being able to do the *hiss and *screech emotes
  • +
  • Changed how the plural emote system works and now some emotes have plural versions, example is: *hiss and *hisses.
  • +
+

02 August 2015

Incoming5643 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6ed5452de7c..6800be71c06 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1436,3 +1436,12 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. so they no longer disintegrate when the electronics are removed! - tweak: Put a safety net in place so future airlocks without assemblies produce the default assembly instead of disintegrating. +2015-08-04: + Kor: + - rscadd: Soulstones will now attempt to pull ghosts from beyond if the targeted + corpse has no soul. + Summoner99: + - rscadd: Added the *roar emote back to Alien Larva + - bugfix: Fixed aliens not being able to do the *hiss and *screech emotes + - tweak: 'Changed how the plural emote system works and now some emotes have plural + versions, example is: *hiss and *hisses.' diff --git a/html/changelogs/KORPHAERON-PR-SOULSTONE.yml b/html/changelogs/KORPHAERON-PR-SOULSTONE.yml deleted file mode 100644 index fc3c9e715bb..00000000000 --- a/html/changelogs/KORPHAERON-PR-SOULSTONE.yml +++ /dev/null @@ -1,36 +0,0 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -# tgs (TG-ported fixes?) -################################# - -# Your name. -author: Kor - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: - - rscadd: "Soulstones will now attempt to pull ghosts from beyond if the targeted corpse has no soul." diff --git a/html/changelogs/Summoners99-hisssss.yml b/html/changelogs/Summoners99-hisssss.yml deleted file mode 100644 index 29532476ba3..00000000000 --- a/html/changelogs/Summoners99-hisssss.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: Summoner99 - -delete-after: True - -changes: - - rscadd: "Added the *roar emote back to Alien Larva" - - bugfix: "Fixed aliens not being able to do the *hiss and *screech emotes" - - tweak: "Changed how the plural emote system works and now some emotes have plural versions, example is: *hiss and *hisses." \ No newline at end of file