diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index de82f0b8c34..1a1ed2b4c5e 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -201,4 +201,37 @@
icon_state = "memorizer"
item_state = "nullrod"
+/obj/item/device/flash/armimplant
+ name = "photon projector"
+ desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocals fix the flashbulb if it ever burns out."
+ var/flashcd = 20
+ var/overheat = 0
+ var/obj/item/organ/internal/cyberimp/arm/flash/I = null
+
+/obj/item/device/flash/armimplant/Destroy()
+ I = null
+ return ..()
+
+/obj/item/device/flash/armimplant/burn_out()
+ if(I && I.owner)
+ to_chat(I.owner, "Your photon projector implant overheats and deactivates!")
+ I.Retract()
+ overheat = FALSE
+ addtimer(src, "cooldown", flashcd * 2)
+
+/obj/item/device/flash/armimplant/try_use_flash(mob/user = null)
+ if(overheat)
+ if(I && I.owner)
+ to_chat(I.owner, "Your photon projector is running too hot to be used again so quickly!")
+ return FALSE
+ overheat = TRUE
+ addtimer(src, "cooldown", flashcd)
+ playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
+ update_icon(1)
+ return TRUE
+
+/obj/item/device/flash/armimplant/proc/cooldown()
+ overheat = FALSE
+
+
/obj/item/device/flash/synthetic //just a regular flash now
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index 13bc85999e0..c642226a8d6 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -151,6 +151,13 @@
origin_tech = "materials=3;combat=4"
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
+/obj/item/weapon/kitchen/knife/combat/cyborg
+ name = "cyborg knife"
+ icon = 'icons/obj/items_cyborg.dmi'
+ icon_state = "knife"
+ desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable."
+ origin_tech = null
+
/obj/item/weapon/kitchen/knife/carrotshiv
name = "carrot shiv"
icon_state = "carrotshiv"
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 1c1dbbd8363..2bb2924837d 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -200,26 +200,29 @@
name = "energy blade"
desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal."
icon_state = "blade"
- force = 30
- sharp = 1
- edge = 1
+ force = 30 //Normal attacks deal esword damage
+ hitsound = 'sound/weapons/blade1.ogg'
+ active = 1
throwforce = 1//Throwing or dropping the item deletes it.
throw_speed = 3
throw_range = 1
w_class = WEIGHT_CLASS_BULKY //So you can't hide it in your pocket or some such.
- armour_penetration = 50
- attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
var/datum/effect/system/spark_spread/spark_system
+ sharp = 1
+ edge = 1
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
/obj/item/weapon/melee/energy/blade/New()
+ ..()
spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
-/obj/item/weapon/melee/energy/blade/dropped()
- ..()
- qdel(src)
-
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
return
+
+/obj/item/weapon/melee/energy/blade/hardlight
+ name = "hardlight blade"
+ desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
+ icon_state = "lightblade"
+ item_state = "lightblade"
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 150f2d647bc..52c66369fe9 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -922,7 +922,7 @@
"brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain,
"cell" = /obj/item/organ/internal/cell,
"optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2.
- "charger" = /obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
+ "charger" = /obj/item/organ/internal/cyberimp/arm/power_cord
)
vision_organ = /obj/item/organ/internal/eyes/optical_sensor
diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm
index 8fec6cd8b8e..a767c94cc9c 100644
--- a/code/modules/projectiles/guns/mounted.dm
+++ b/code/modules/projectiles/guns/mounted.dm
@@ -1,30 +1,20 @@
/obj/item/weapon/gun/energy/gun/advtaser/mounted
name = "mounted taser"
desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots."
- icon_state = "armcannon"
+ icon = 'icons/obj/items_cyborg.dmi'
+ icon_state = "taser"
+ item_state = "armcannonstun4"
force = 5
- flags = NODROP
- w_class = WEIGHT_CLASS_HUGE
- can_flashlight = 0
selfcharge = 1
+ can_flashlight = 0
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead
-/obj/item/weapon/gun/energy/gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow...
- ..()
- loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases.
-
/obj/item/weapon/gun/energy/laser/mounted
name = "mounted laser"
- desc = "An arm mounted cannon that fires lethal lasers. Doesn't come with a charge beam."
- icon_state = "armcannon"
+ desc = "An arm mounted cannon that fires lethal lasers."
+ icon = 'icons/obj/items_cyborg.dmi'
+ icon_state = "laser"
item_state = "armcannonlase"
force = 5
- flags = NODROP
- w_class = WEIGHT_CLASS_HUGE
- materials = null
selfcharge = 1
- trigger_guard = TRIGGER_GUARD_ALLOW_ALL
-
-/obj/item/weapon/gun/energy/laser/mounted/dropped()
- ..()
- loc = null
+ trigger_guard = TRIGGER_GUARD_ALLOW_ALL
\ No newline at end of file
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 601ad98346a..52a5b9e027c 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -271,6 +271,17 @@
build_path = /obj/item/organ/internal/cyberimp/mouth/breathing_tube
category = list("Misc", "Medical Designs")
+/datum/design/cyberimp_toolset
+ name = "Toolset Arm Implant"
+ desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm."
+ id = "ci-toolset"
+ req_tech = list("materials" = 3, "engineering" = 4, "biotech" = 4, "powerstorage" = 4)
+ build_type = PROTOLATHE | MECHFAB
+ materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500)
+ construction_time = 200
+ build_path = /obj/item/organ/internal/cyberimp/arm/toolset
+ category = list("Misc", "Medical Designs")
+
/datum/design/cyberimp_medical_hud
name = "Medical HUD implant"
desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control."
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
new file mode 100644
index 00000000000..a3c1b2bb474
--- /dev/null
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -0,0 +1,315 @@
+/obj/item/organ/internal/cyberimp/arm
+ name = "arm-mounted implant"
+ desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
+ parent_organ = "r_arm"
+ slot = "r_arm_device"
+ icon_state = "implant-toolkit"
+ w_class = WEIGHT_CLASS_NORMAL
+ actions_types = list(/datum/action/item_action/organ_action/toggle)
+
+ var/list/items_list = list()
+ // Used to store a list of all items inside, for multi-item implants.
+ // I would use contents, but they shuffle on every activation/deactivation leading to interface inconsistencies.
+
+ var/obj/item/holder = null
+ // You can use this var for item path, it would be converted into an item on New()
+
+/obj/item/organ/internal/cyberimp/arm/New()
+ ..()
+ if(ispath(holder))
+ holder = new holder(src)
+
+ update_icon()
+ slot = parent_organ + "_device"
+ items_list = contents.Copy()
+
+/obj/item/organ/internal/cyberimp/arm/update_icon()
+ if(parent_organ == "r_arm")
+ transform = null
+ else // Mirroring the icon
+ transform = matrix(-1, 0, 0, 0, 1, 0)
+
+/obj/item/organ/internal/cyberimp/arm/examine(mob/user)
+ ..()
+ to_chat(user, "[src] is assembled in the [parent_organ == "r_arm" ? "right" : "left"] arm configuration. You can use a screwdriver to reassemble it.")
+
+/obj/item/organ/internal/cyberimp/arm/attackby(obj/item/weapon/W, mob/user, params)
+ ..()
+ if(isscrewdriver(W))
+ if(parent_organ == "r_arm")
+ parent_organ = "l_arm"
+ else
+ parent_organ = "r_arm"
+ slot = parent_organ + "_device"
+ to_chat(user, "You modify [src] to be installed on the [parent_organ == "r_arm" ? "right" : "left"] arm.")
+ update_icon()
+ else if(istype(W, /obj/item/weapon/card/emag))
+ emag_act()
+
+/obj/item/organ/internal/cyberimp/arm/remove(mob/living/carbon/M, special = 0)
+ Retract()
+ . = ..()
+
+/obj/item/organ/internal/cyberimp/arm/emag_act()
+ return 0
+
+/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity)
+ if(prob(15/severity) && owner)
+ to_chat(owner, "[src] is hit by EMP!")
+ // give the owner an idea about why his implant is glitching
+ Retract()
+ ..()
+
+/obj/item/organ/internal/cyberimp/arm/proc/Retract()
+ if(!holder || (holder in src))
+ return
+
+ owner.visible_message("[owner] retracts [holder] back into \his [parent_organ == "r_arm" ? "right" : "left"] arm.",
+ "[holder] snaps back into your [parent_organ == "r_arm" ? "right" : "left"] arm.",
+ "You hear a short mechanical noise.")
+
+ if(istype(holder, /obj/item/device/flash/armimplant))
+ var/obj/item/device/flash/F = holder
+ F.set_light(0)
+
+ owner.unEquip(holder, 1)
+ holder.forceMove(src)
+ holder = null
+ playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
+
+/obj/item/organ/internal/cyberimp/arm/proc/Extend(var/obj/item/item)
+ if(!(item in src))
+ return
+
+
+ holder = item
+
+ holder.flags |= NODROP
+ holder.unacidable = 1
+ holder.slot_flags = null
+ holder.w_class = WEIGHT_CLASS_HUGE
+ holder.materials = null
+
+ if(istype(holder, /obj/item/device/flash/armimplant))
+ var/obj/item/device/flash/F = holder
+ F.set_light(7)
+
+ var/arm_slot = (parent_organ == "r_arm" ? slot_r_hand : slot_l_hand)
+ var/obj/item/arm_item = owner.get_item_by_slot(arm_slot)
+
+ if(arm_item)
+ if(!owner.unEquip(arm_item))
+ owner << "Your [arm_item] interferes with [src]!"
+ return
+ else
+ owner << "You drop [arm_item] to activate [src]!"
+
+ if(parent_organ == "r_arm" ? !owner.put_in_r_hand(holder) : !owner.put_in_l_hand(holder))
+ owner << "Your [src] fails to activate!"
+ return
+
+ // Activate the hand that now holds our item.
+ if(parent_organ == "r_arm" ? owner.hand : !owner.hand)
+ owner.swap_hand()
+
+ owner.visible_message("[owner] extends [holder] from \his [parent_organ == "r_arm" ? "right" : "left"] arm.",
+ "You extend [holder] from your [parent_organ == "r_arm" ? "right" : "left"] arm.",
+ "You hear a short mechanical noise.")
+ playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
+
+/obj/item/organ/internal/cyberimp/arm/ui_action_click()
+ if(crit_fail || (!holder && !contents.len))
+ to_chat(owner, "The implant doesn't respond. It seems to be broken...")
+ return
+
+ // You can emag the arm-mounted implant by activating it while holding emag in it's hand.
+ var/arm_slot = (parent_organ == "r_arm" ? slot_r_hand : slot_l_hand)
+ if(istype(owner.get_item_by_slot(arm_slot), /obj/item/weapon/card/emag) && emag_act())
+ return
+
+ if(!holder || (holder in src))
+ holder = null
+ if(contents.len == 1)
+ Extend(contents[1])
+ else // TODO: make it similar to borg's storage-like module selection
+ var/obj/item/choise = input("Activate which item?", "Arm Implant", null, null) as null|anything in items_list
+ if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && istype(choise) && (choise in contents))
+ // This monster sanity check is a nice example of how bad input() is.
+ Extend(choise)
+ else
+ Retract()
+
+
+/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity)
+ if(prob(30/severity) && owner && !crit_fail)
+ Retract()
+ owner.visible_message("A loud bang comes from [owner]\'s [parent_organ == "r_arm" ? "right" : "left"] arm!")
+ playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1)
+ to_chat(owner, "You feel an explosion erupt inside your [parent_organ == "r_arm" ? "right" : "left"] arm as your implant breaks!")
+ owner.adjust_fire_stacks(20)
+ owner.IgniteMob()
+ owner.adjustFireLoss(25)
+ crit_fail = 1
+ else // The gun will still discharge anyway.
+ ..()
+
+
+/obj/item/organ/internal/cyberimp/arm/gun/laser
+ name = "arm-mounted laser implant"
+ desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arm and remains inside when not in use."
+ icon_state = "arm_laser"
+ origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
+ contents = newlist(/obj/item/weapon/gun/energy/laser/mounted)
+
+/obj/item/organ/internal/cyberimp/arm/gun/laser/l
+ parent_organ = "l_arm"
+
+
+/obj/item/organ/internal/cyberimp/arm/gun/taser
+ name = "arm-mounted taser implant"
+ desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use."
+ icon_state = "arm_taser"
+ origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
+ contents = newlist(/obj/item/weapon/gun/energy/gun/advtaser/mounted)
+
+/obj/item/organ/internal/cyberimp/arm/gun/taser/l
+ parent_organ = "l_arm"
+
+
+/obj/item/organ/internal/cyberimp/arm/toolset
+ name = "integrated toolset implant"
+ desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm. Contains all neccessary tools."
+ origin_tech = "materials=3;engineering=4;biotech=3;powerstorage=4"
+ contents = newlist(/obj/item/weapon/screwdriver/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/weldingtool/largetank/cyborg,
+ /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, /obj/item/device/multitool/cyborg)
+
+/obj/item/organ/internal/cyberimp/arm/toolset/l
+ parent_organ = "l_arm"
+
+/obj/item/organ/internal/cyberimp/arm/toolset/emag_act()
+ if(!(locate(/obj/item/weapon/kitchen/knife/combat/cyborg) in items_list))
+ to_chat(usr, "You unlock [src]'s integrated knife!")
+ items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src)
+ return 1
+ return 0
+
+/obj/item/organ/internal/cyberimp/arm/esword
+ name = "arm-mounted energy blade"
+ desc = "An illegal, and highly dangerous cybernetic implant that can project a deadly blade of concentrated enregy."
+ contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight)
+ origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5"
+
+/obj/item/organ/internal/cyberimp/arm/medibeam
+ name = "integrated medical beamgun"
+ desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
+ contents = newlist(/obj/item/weapon/gun/medbeam)
+ origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1"
+
+/obj/item/organ/internal/cyberimp/arm/flash
+ name = "integrated high-intensity photon projector" //Why not
+ desc = "An integrated projector mounted onto a user's arm, that is able to be used as a powerful flash."
+ contents = newlist(/obj/item/device/flash/armimplant)
+ origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3"
+
+/obj/item/organ/internal/cyberimp/arm/flash/New()
+ ..()
+ if(locate(/obj/item/device/flash/armimplant) in items_list)
+ var/obj/item/device/flash/armimplant/F = locate(/obj/item/device/flash/armimplant) in items_list
+ F.I = src
+
+/obj/item/organ/internal/cyberimp/arm/baton
+ name = "arm electrification implant"
+ desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
+ contents = newlist(/obj/item/borg/stun)
+ origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3"
+
+/obj/item/organ/internal/cyberimp/arm/combat
+ name = "combat cybernetics implant"
+ desc = "A powerful cybernetic implant that contains combat modules built into the user's arm"
+ contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight, /obj/item/weapon/gun/medbeam, /obj/item/borg/stun, /obj/item/device/flash/armimplant)
+ origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5"
+
+/obj/item/organ/internal/cyberimp/arm/combat/New()
+ ..()
+ if(locate(/obj/item/device/flash/armimplant) in items_list)
+ var/obj/item/device/flash/armimplant/F = locate(/obj/item/device/flash/armimplant) in items_list
+ F.I = src
+
+/obj/item/organ/internal/cyberimp/arm/surgery
+ name = "surgical toolset implant"
+ desc = "A set of surgical tools hidden behind a concealed panel on the user's arm"
+ contents = newlist(/obj/item/weapon/retractor, /obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, /obj/item/weapon/circular_saw, /obj/item/weapon/bonegel, /obj/item/weapon/FixOVein, /obj/item/weapon/bonesetter)
+ origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3"
+
+// lets make IPCs even *more* vulnerable to EMPs!
+/obj/item/organ/internal/cyberimp/arm/power_cord
+ name = "APC-compatible power adapter implant"
+ desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment"
+ origin_tech = "materials=3;biotech=2;powerstorage=3"
+ contents = newlist(/obj/item/apc_powercord)
+
+/obj/item/organ/internal/cyberimp/arm/power_cord/emp_act(severity)
+ // To allow repair via nanopaste/screwdriver
+ // also so IPCs don't also catch on fire and fall even more apart upon EMP
+ damage = 1
+ crit_fail = TRUE
+
+/obj/item/organ/internal/cyberimp/arm/power_cord/surgeryize()
+ if(crit_fail && owner)
+ to_chat(owner, "Your [src] feels functional again.")
+ crit_fail = FALSE
+
+
+/obj/item/apc_powercord
+ name = "power cable"
+ desc = "Insert into a nearby APC to draw power from it."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "wire1"
+ flags = NOBLUDGEON
+
+/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
+ return ..()
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/obj/machinery/power/apc/A = target
+ var/mob/living/carbon/human/H = user
+ if(H.get_int_organ(/obj/item/organ/internal/cell))
+ if(A.emagged || A.stat & BROKEN)
+ var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
+ s.set_up(3, 1, A)
+ s.start()
+ to_chat(H, "The APC power currents surge erratically, damaging your chassis!")
+ H.adjustFireLoss(10,0)
+ else if(A.cell && A.cell.charge > 0)
+ if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
+ to_chat(user, "You are already fully charged!")
+ else
+ addtimer(src, "powerdraw_loop", 0, TRUE, A, H)
+ else
+ to_chat(user, "There is no charge to draw from that APC.")
+ else
+ to_chat(user, "You lack a cell in which to store charge!")
+
+/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
+ H.visible_message("[H] inserts a power connector into \the [A].", "You begin to draw power from \the [A].")
+ while(do_after(H, 10, target = A))
+ if(loc != H)
+ to_chat(H, "You must keep your connector out while charging!")
+ break
+ if(A.cell.charge == 0)
+ to_chat(H, "\The [A] has no more charge.")
+ break
+ A.charging = 1
+ if(A.cell.charge >= 500)
+ H.nutrition += 50
+ A.cell.charge -= 500
+ to_chat(H, "You siphon off some of the stored charge for your own use.")
+ else
+ H.nutrition += A.cell.charge/10
+ A.cell.charge = 0
+ to_chat(H, "You siphon off the last of \the [A]'s charge.")
+ break
+ if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
+ to_chat(H, "You are now fully charged.")
+ break
+ H.visible_message("[H] unplugs from \the [A].", "You unplug from \the [A].")
\ 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 13061db2c4d..0a99a9b9e5a 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -273,175 +273,6 @@
if(H.stat == CONSCIOUS)
to_chat(H, "You feel your heart beating again!")
-//ARM...THAT GO IN THE CHEST
-/obj/item/organ/internal/cyberimp/chest/arm_mod//dummy parent item for making arm-mod implants. works best with nodrop items that are sent to nullspace upon being dropped.
- name = "Arm-mounted item implant"
- desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
- icon_state = "chest_implant"
- implant_color = "#007ACC"
- slot = "shoulders"
- origin_tech = "materials=5;biotech=4;powerstorage=4"
- actions_types = list(/datum/action/item_action/organ_action/toggle)
- var/obj/holder//is defined as the retractable item itself. ensure this is defined somewhere!
- var/out = 0//determines if the item is in the owner's hand or not
- var/overloaded = 0//is set to 1 when owner gets EMPed. if set to 1, implant doesn't work.
- var/lasthand = null
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/ui_action_click()
- toggle_item()
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/toggle_item()
- if(overloaded)//ensure the implant isn't broken
- to_chat(owner, "The implant doesn't respond. It seems to be broken...")
- return
- owner.changeNext_move(CLICK_CD_MELEE)
- if(owner.next_move < world.time)
- return // No spam
- if(out)//check if the owner has the item out already
- owner.unEquip(holder, 1)//if he does, take it away. then,
- holder.loc = null//stash it in nullspace
- out = 0//and set this to clarify the item isn't out.
- owner.visible_message("[owner] retracts [holder].","You retract [holder].")
- playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
- else//if he doesn't have the item out
- if(owner.put_in_hands(holder))//put it in his hands.
- lasthand = owner.get_active_hand()
- out = 1
- owner.visible_message("[owner] extends [holder]!","You extend [holder]!")
- playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
- else//if this fails to put the item in his hands,
- holder.loc = null//keep it in nullspace
- to_chat(owner, "You can't extend [holder] if you can't use your hands!")
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/emp_act(severity)//if the implant gets EMPed...
- if(!owner || overloaded)//ensure that it's in an owner and that it's not already EMPed, then...
- return
- if(out)//check if he has the item out...
- owner.unEquip(holder, 1)//if he does, take it away.
- holder.loc = null
- out = 0
- owner.visible_message("[holder] forcibly retracts into [owner]'s arm.")
- overload() // Make sure this doesn't happen again
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/overload()
- owner.visible_message("A loud bang comes from [owner]...")
- playsound(get_turf(owner), 'sound/effects/bang.ogg', 100, 1)
- to_chat(owner, "You feel an explosion erupt inside you as your chest implant breaks. Is it hot in here?")
- owner.adjust_fire_stacks(20)
- owner.IgniteMob()//ignite the owner, as well as
- owner.say("AUUUUUUUUUUUUUUUUUUGH!!")
- if(prob(50))
- if(lasthand == "r_hand")
- var/obj/item/organ/external/limb = owner.get_organ("r_arm")
- limb.droplimb(0, DROPLIMB_EDGE)
- else if(lasthand == "l_hand")
- var/obj/item/organ/external/limb = owner.get_organ("l_arm")
- limb.droplimb(0, DROPLIMB_EDGE)
- owner.say("I HAVE BEEN DISARMED!!!")
- owner.adjustFireLoss(25)//severely injure him!
- overloaded = TRUE
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/tase//mounted, self-charging taser!
- name = "Arm-cannon taser implant"
- desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arms and remains in the shoulders when not in use."
- icon_state = "armcannon_tase_implant"
- origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
- actions_types = list(/datum/action/item_action/organ_action/toggle)
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created...
- ..()
- holder = new /obj/item/weapon/gun/energy/gun/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun)
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser!
- name = "Arm-cannon laser implant"
- desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arms and remains in the shoulders when not in use."
- icon_state = "armcannon_lase_implant"
- origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
- actions_types = list(/datum/action/item_action/organ_action/toggle)
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/lase/New()
- ..()
- holder = new /obj/item/weapon/gun/energy/laser/mounted(src)
-
-// lets make IPCs even *more* vulnerable to EMPs!
-/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
- name = "APC-compatible power adapter implant"
- desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment"
- origin_tech = "materials=3;biotech=2;powerstorage=3"
- slot = "shoulders2"
- actions_types = list(/datum/action/item_action/organ_action/toggle)
-
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/New()
- ..()
- holder = new /obj/item/apc_powercord(src)
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/overload()
- // To allow repair via nanopaste/screwdriver
- // also so IPCs don't also catch on fire and fall even more apart upon EMP
- damage = 1
- overloaded = TRUE
-
-/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/surgeryize()
- if(overloaded && owner)
- to_chat(owner, "Your [src] feels functional again.")
- overloaded = FALSE
-
-
-/obj/item/apc_powercord
- name = "power cable"
- desc = "Insert into a nearby APC to draw power from it."
- icon = 'icons/obj/power.dmi'
- icon_state = "wire1"
- flags = NODROP | NOBLUDGEON
-
-/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
- if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
- return ..()
- user.changeNext_move(CLICK_CD_MELEE)
- var/obj/machinery/power/apc/A = target
- var/mob/living/carbon/human/H = user
- if(H.get_int_organ(/obj/item/organ/internal/cell))
- if(A.emagged || A.stat & BROKEN)
- var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
- s.set_up(3, 1, A)
- s.start()
- to_chat(H, "The APC power currents surge erratically, damaging your chassis!")
- H.adjustFireLoss(10,0)
- else if(A.cell && A.cell.charge > 0)
- if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
- to_chat(user, "You are already fully charged!")
- else
- addtimer(src, "powerdraw_loop", 0, TRUE, A, H)
- else
- to_chat(user, "There is no charge to draw from that APC.")
- else
- to_chat(user, "You lack a cell in which to store charge!")
-
-/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
- H.visible_message("[H] inserts a power connector into \the [A].", "You begin to draw power from \the [A].")
- while(do_after(H, 10, target = A))
- if(loc != H)
- to_chat(H, "You must keep your connector out while charging!")
- break
- if(A.cell.charge == 0)
- to_chat(H, "\The [A] has no more charge.")
- break
- A.charging = 1
- if(A.cell.charge >= 500)
- H.nutrition += 50
- A.cell.charge -= 500
- to_chat(H, "You siphon off some of the stored charge for your own use.")
- else
- H.nutrition += A.cell.charge/10
- A.cell.charge = 0
- to_chat(H, "You siphon off the last of \the [A]'s charge.")
- break
- if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
- to_chat(H, "You are now fully charged.")
- break
- H.visible_message("[H] unplugs from \the [A].", "You unplug from \the [A].")
-
//BOX O' IMPLANTS
/obj/item/weapon/storage/box/cyber_implants
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 47535c044eb..602a6e295d5 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -5,7 +5,6 @@
force = 1
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
- var/zone = "chest"
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
vital = 0
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index e44f20046db..d3f3c2c933b 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -38,7 +38,6 @@ var/static/regex/multispin_words = regex("like a record baby")
/obj/item/organ/internal/vocal_cords //organs that are activated through speech with the :x channel
name = "vocal cords"
icon_state = "appendix"
- zone = "mouth"
slot = "vocal_cords"
parent_organ = "mouth"
var/spans = null
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 420d56de43d..5dcb5954da5 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -14,7 +14,7 @@
/datum/surgery/organ_manipulation_boneless
name = "Organ Manipulation"
- possible_locs = list("chest","head","groin", "eyes", "mouth")
+ possible_locs = list("chest","head","groin", "eyes", "mouth", "l_arm", "r_arm")
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize)
requires_organic_bodypart = 1
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index e1dc252412d..5d8a81f4bc6 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -12,7 +12,7 @@
/datum/surgery/cybernetic_repair/internal
name = "Internal Component Manipulation"
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/manipulate_robotic_organs)
- possible_locs = list("eyes", "chest","head","groin")
+ possible_locs = list("eyes", "chest","head","groin","l_arm","r_arm")
requires_organic_bodypart = 0
/datum/surgery/cybernetic_amputation
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 1461df9bbbe..ae7ba3e5f1a 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index c66e67820a3..9317819aa92 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi
index 9b38b205075..03b8eba0f8c 100644
Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ
diff --git a/icons/obj/items_cyborg.dmi b/icons/obj/items_cyborg.dmi
new file mode 100644
index 00000000000..cddb57303d2
Binary files /dev/null and b/icons/obj/items_cyborg.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 2d1bb9ac749..cccdb4d16fb 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index e4569806d57..2b49b438b85 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 0775e9b2577..6cee9859062 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2148,6 +2148,7 @@
#include "code\modules\surgery\slime.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\tools.dm"
+#include "code\modules\surgery\organs\augments_arms.dm"
#include "code\modules\surgery\organs\augments_eyes.dm"
#include "code\modules\surgery\organs\augments_internal.dm"
#include "code\modules\surgery\organs\autoimplanter.dm"
diff --git a/sound/weapons/flashbang.ogg b/sound/weapons/flashbang.ogg
new file mode 100644
index 00000000000..389aad77bc2
Binary files /dev/null and b/sound/weapons/flashbang.ogg differ