diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm
index 6f7021d4b18..6dde1c9aee2 100644
--- a/code/datums/uplink/devices and tools.dm
+++ b/code/datums/uplink/devices and tools.dm
@@ -21,6 +21,11 @@
path = /obj/item/device/firing_pin
desc = "A Syndicate-branded Firing pin - It should be compatible with nearly every weapon onboard."
+/datum/uplink_item/item/tools/surge
+ name = "IPC surge prevention module"
+ item_cost = 14
+ path = /obj/item/stack/nanopaste/surge
+ desc = "An internal module that allow operative IPC frames to be protected from EMP pulse. The device has limited use that varies between one to three pulses"
/datum/uplink_item/item/tools/clerical
name = "Morphic Clerical Kit"
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 2a1b30af3fa..71dce7845f3 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -12,7 +12,7 @@
/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R)
if(R.stat == DEAD)
- usr << "The [src] will not function on a deceased robot."
+ to_chat(usr, "The [src] will not function on a deceased robot.")
return 1
return 0
@@ -65,7 +65,7 @@
if(..()) return 0
if(R.intenselight)
- usr << "This cyborg's light was already upgraded"
+ to_chat(usr, "This cyborg's light was already upgraded ")
return 0
else
R.intenselight = 1
@@ -81,7 +81,7 @@
/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
if(R.health < 0)
- usr << "You have to repair the robot before using this module!"
+ to_chat(usr, "You have to repair the robot before using this module!")
return 0
if(!R.key)
@@ -123,8 +123,8 @@
if(..()) return 0
if(!R.module || !(src.type in R.module.supported_upgrades))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
+ to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
+ to_chat(usr, " There's no mounting point for the module!")
return 0
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module
@@ -133,12 +133,12 @@
if(!T)
T = locate() in R.module.modules
if(!T)
- usr << "This robot has had its taser removed!"
+ to_chat(usr, "This robot has had its taser removed!")
return 0
if(T.recharge_time <= 2)
- R << "Maximum cooling achieved for this hardpoint!"
- usr << "There's no room for another cooling unit!"
+ to_chat(R, "Maximum cooling achieved for this hardpoint!")
+ to_chat(usr, "There's no room for another cooling unit!")
return 0
else
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index 9c3830c92b4..8cf15c8d7d4 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -58,3 +58,74 @@
return
else
user << "Nothing to fix in here."
+
+
+/obj/item/stack/nanopaste/surge
+ name = "modified nanopaste"
+ singular_name = "nanite swarm"
+ desc = "A tube of paste containing swarms of repair nanites. This one appears to contain different nanites."
+ icon = 'icons/obj/nanopaste.dmi'
+ icon_state = "tube-surge"
+ origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_MAGNET = 5, TECH_POWER = 5, TECH_COMBAT = 3, TECH_ILLEGAL = 4)
+ amount = 20
+ var/used = FALSE
+ construction_cost = null
+
+/obj/item/stack/nanopaste/surge/attack(mob/living/carbon/human/M as mob, mob/user as mob, var/target_zone)
+ if (!istype(M) || !istype(user))
+ return 0
+
+ if(used)
+ to_chat(user, "[src] has depleted it's nanites.")
+ return 0
+
+ if (isipc(M))
+ var/obj/item/organ/surge/s = M.internal_organs_by_name["surge"]
+ if(isnull(s))
+ user.visible_message(
+ "[user] is trying to apply [src] to [(M == user) ? ("itself") : (M)]!",
+ "You start applying [src] to [(M == user) ? ("yourself") : (M)]!"
+ )
+
+ if (!do_mob(user, M, 2))
+ return 0
+
+ s = new /obj/item/organ/surge()
+ M.internal_organs += s
+ M.internal_organs_by_name["surge"] = s
+ user.visible_message(
+ "[user] applies some nanite paste to [(M == user) ? ("itself") : (M)]!",
+ "You apply [src] to [(M == user) ? ("youself") : (M)]."
+ )
+ to_chat(M, "You can feel nanites inside you creating something new. An internal OS voice states \"Warning: surge prevention module has been installed, it has [s.surge_left] preventions left!\"")
+ amount = 0
+ used = TRUE
+ return 1
+ else
+ if(!s.surge_left)
+ user.visible_message(
+ "[user] is trying to apply [src] to [(M == user) ? ("itself") : (M)]!",
+ "You start applying [src] to [(M == user) ? ("yourself") : (M)]!"
+ )
+
+ if (!do_mob(user, M, 2))
+ return 0
+
+ s.surge_left = rand(1, 3)
+ s.broken = 0
+ s.icon_state = "surge_ipc"
+
+ user.visible_message(
+ "[user] applies some nanite paste to [(M == user) ? ("itself") : (M)]!",
+ "You apply [src] to [(M == user) ? ("yourself") : (M)]."
+ )
+ to_chat(M, "You can feel nanites inside you regenerating your surge prevention module. An internal OS voice states \"Warning: surge prevention module repaired, it has [s.surge_left] preventions left!\"")
+ amount = 0
+ used = TRUE
+ return 1
+
+ to_chat(user, "[(M == user) ? ("You already have") : ("[M] already has")] fully functional surge prevention module installed.")
+ return 0
+ else
+ to_chat(user, "[src]'s nanites refuse to work on [(M == user) ? ("you") : (M)].")
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 6e459f2cffb..ca8c61ebd00 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -158,6 +158,21 @@ emp_act
return 0
/mob/living/carbon/human/emp_act(severity)
+ if(isipc(src))
+ var/obj/item/organ/surge/s = src.internal_organs_by_name["surge"]
+ if(!isnull(s))
+ if(s.surge_left)
+ playsound(src.loc, 'sound/magic/LightningShock.ogg', 25, 1)
+ s.surge_left -= 1
+ if(s.surge_left)
+ to_chat(src, "Warning: EMP detected, integrated surge prevention module activated. There are [s.surge_left] preventions left.")
+ else
+ s.broken = 1
+ s.icon_state = "surge_ipc_broken"
+ to_chat(src, "Warning: EMP detected, integrated surge prevention module activated. The surge prevention module is fried, replacement recommended.")
+ return 1
+ else
+ to_chat(src, "Warning: EMP detected, integrated surge prevention module is fried and unable to protect from EMP. Replacement recommended.")
for(var/obj/O in src)
if(!O) continue
O.emp_act(severity)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 70ea3e2cb96..c662701be83 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -112,4 +112,4 @@
var/datum/unarmed_attack/default_attack //default unarmed attack
- var/datum/martial_art/martial_art = null
\ No newline at end of file
+ var/datum/martial_art/martial_art = null
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 83a1e3efd98..78fe1cc1d94 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -40,7 +40,7 @@
// The thing itself isn't there anymore, but some fried remains are.
uninstall()
installed = -1
-
+
/datum/robot_component/proc/get_damage(var/type)
return Clamp(brute_damage + electronics_damage,0,max_damage)
@@ -94,6 +94,17 @@
var/obj/item/weapon/tank/jetpack/carbondioxide/synthetic/tank = null
+/datum/robot_component/surge
+ name = "surge preventor"
+ external_type = /obj/item/robot_parts/robot_component/surge
+ max_damage = 60
+ installed = 0
+ var/surge_left = 0
+
+/datum/robot_component/surge/install()
+ ..()
+ if(!surge_left)
+ surge_left = rand(1, 3)
/datum/robot_component/jetpack/install()
..()
@@ -223,6 +234,7 @@
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour(src)
components["jetpack"] = new/datum/robot_component/jetpack(src)
+ components["surge"] = new/datum/robot_component/surge(src)
jetpackComponent = components["jetpack"]
jetpackComponent.installed = 0//We start the jetpack as not installed, because its nondefault
@@ -272,6 +284,12 @@
icon_state = "armor"
icon_state_broken = "armor_broken"
+/obj/item/robot_parts/robot_component/surge
+ name = "surge preventor"
+ desc = "Cyborg component designed to save internal electronics from damage of EMP pulse."
+ icon_state = "surge"
+ icon_state_broken = "surge_broken"
+
/obj/item/robot_parts/robot_component/camera
name = "camera"
icon_state = "camera"
@@ -291,4 +309,4 @@
/obj/item/robot_parts/robot_component/radio
name = "radio"
icon_state = "radio"
- icon_state_broken = "radio_broken"
\ No newline at end of file
+ icon_state_broken = "radio_broken"
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 4e0417abb3a..b41b7a1022e 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -150,7 +150,7 @@
initialize_components()
//if(!unfinished)
// Create all the robot parts.
- for(var/V in components) if(V != "power cell" && V != "jetpack")//We don't install the jetpack onstart
+ for(var/V in components) if(V != "power cell" && V != "jetpack" && V != "surge")//We don't install the jetpack onstart
var/datum/robot_component/C = components[V]
C.installed = 1
C.wrapped = new C.external_type
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index 8b44277f249..6a7aed3b651 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -10,7 +10,7 @@
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed)
+ if(C.installed)
amount += Clamp(C.brute_damage,0,C.max_damage)
else if(C.installed == -1)
amount += C.max_damage/2
@@ -153,3 +153,19 @@
burn -= (picked.electronics_damage - burn_was)
parts -= picked
+
+/mob/living/silicon/robot/emp_act(severity)
+ if(components["surge"] && components["surge"].installed)
+ if(components["surge"].surge_left)
+ playsound(src.loc, 'sound/magic/LightningShock.ogg', 25, 1)
+ components["surge"].surge_left -= 1
+ visible_message("[src] was not affected by EMP pulse.", "Warning: Power surge detected, source - EMP. Surge prevention module re-routed surge to prevent damage to vital electronics.")
+ if(components["surge"].surge_left)
+ to_chat(src, "Surge module has [components["surge"].surge_left] preventions left!")
+ else
+ components["surge"].destroy()
+ to_chat(src, "Module is entirely fried, replacement is recommended.")
+ return
+ else
+ to_chat(src, "Warning: Power surge detected, source - EMP. Surge prevention module is depleted and requires replacement")
+ ..()
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm
index bbf3d0c8330..efe26734538 100644
--- a/code/modules/organs/subtypes/machine.dm
+++ b/code/modules/organs/subtypes/machine.dm
@@ -82,6 +82,25 @@
owner.Paralyse(emp_counter/6)
owner << "%#/ERR: Power leak detected!$%^/"
+
+/obj/item/organ/surge
+ name = "surge preventor"
+ desc = "A small device that give immunity to EMP for few pulses."
+ icon = 'icons/obj/robot_component.dmi'
+ icon_state = "surge_ipc"
+ organ_tag = "surge"
+ parent_organ = "chest"
+ vital = 0
+ var/surge_left = 0
+ var/broken = 0
+
+/obj/item/organ/surge/Initialize()
+ if(!surge_left && !broken)
+ surge_left = rand(1, 3)
+ robotize()
+ . = ..()
+
+
/obj/item/organ/eyes/optical_sensor
name = "optical sensor"
singular_name = "optical sensor"
diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm
index fd70777dd8e..253cc435a72 100644
--- a/code/modules/research/mechfab_designs.dm
+++ b/code/modules/research/mechfab_designs.dm
@@ -96,6 +96,14 @@
id = "armour"
build_path = /obj/item/robot_parts/robot_component/armour
+/datum/design/item/mechfab/robot/component/surge
+ name = "Heavy surge prevention module"
+ desc = "Used to boost prevent damage from EMP. Has limited surge preventions."
+ id = "borg_surge_module"
+ materials = list(DEFAULT_WALL_MATERIAL = 20000, "glass" = 6000, "gold" = 10000, "silver" = 15000) // Should be expensive
+ req_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 2, TECH_MAGNET = 5, TECH_POWER = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 3)
+ build_path = /obj/item/robot_parts/robot_component/surge
+
/datum/design/item/mechfab/ripley
category = "Ripley"
diff --git a/html/changelogs/Sindorman-emp.yml b/html/changelogs/Sindorman-emp.yml
new file mode 100644
index 00000000000..1ebfb6095ca
--- /dev/null
+++ b/html/changelogs/Sindorman-emp.yml
@@ -0,0 +1,13 @@
+author: PoZe
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Adds cyborg surge prevention upgrade module. It is an upgrade that makes cyborg being immune to 1-3 EMP pulses. Can be constructed by robotics, but is expensive and high tech. After being fried, module can be replaced with new module"
+ - rscadd: "Adds IPC surge prevention module. Available only via traitor uplink, costs 14 telecrystals. Just like cyborg module it make user immune to 1-3 EMP pulses. Comes in from uplink as modified nanopaste that is one time use(doesn't heal user). Module can be repaired with another traitor nanopaste"
diff --git a/icons/obj/nanopaste.dmi b/icons/obj/nanopaste.dmi
index b3c096325f9..00bafd43503 100644
Binary files a/icons/obj/nanopaste.dmi and b/icons/obj/nanopaste.dmi differ
diff --git a/icons/obj/robot_component.dmi b/icons/obj/robot_component.dmi
index 1129f25ab1c..a8a04170f93 100644
Binary files a/icons/obj/robot_component.dmi and b/icons/obj/robot_component.dmi differ