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