diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm
index a8f5357840a..a83532ef143 100644
--- a/code/datums/wires/nuclearbomb.dm
+++ b/code/datums/wires/nuclearbomb.dm
@@ -9,9 +9,7 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4
/datum/wires/nuclearbomb/CanUse(var/mob/living/L)
var/obj/machinery/nuclearbomb/N = holder
- if(N.panel_open)
- return 1
- return 0
+ return N.panel_open
/datum/wires/nuclearbomb/GetInteractWindow()
var/obj/machinery/nuclearbomb/N = holder
@@ -25,12 +23,14 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4
switch(index)
if(NUCLEARBOMB_WIRE_LIGHT)
N.lighthack = !N.lighthack
+ N.update_icon()
spawn(100)
N.lighthack = !N.lighthack
+ N.update_icon()
if(NUCLEARBOMB_WIRE_TIMING)
if(N.timing)
spawn
- message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (JMP)")
+ log_and_message_admins_with_location("pulsed a nuclear bomb's detonation wire, causing it to explode.", holder.x, holder.y, holder.z)
N.explode()
if(NUCLEARBOMB_WIRE_SAFETY)
N.safety = !N.safety
@@ -38,9 +38,7 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4
N.safety = !N.safety
if(N.safety == 1)
N.visible_message("\The [N] quiets down.")
- if(!N.lighthack)
- if (N.icon_state == "nuclearbomb2")
- N.icon_state = "nuclearbomb1"
+ N.secure_device()
else
N.visible_message("\The [N] emits a quiet whirling noise!")
@@ -48,15 +46,13 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4
var/obj/machinery/nuclearbomb/N = holder
switch(index)
if(NUCLEARBOMB_WIRE_SAFETY)
+ N.safety = mended
if(N.timing)
spawn
- message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (JMP)")
+ log_and_message_admins_with_location("cut a nuclear bomb's timing wire, causing it to explode.", holder.x, holder.y, holder.z)
N.explode()
if(NUCLEARBOMB_WIRE_TIMING)
- if(!N.lighthack)
- if (N.icon_state == "nuclearbomb2")
- N.icon_state = "nuclearbomb1"
- N.timing = 0
- bomb_set = 0
+ N.secure_device()
if(NUCLEARBOMB_WIRE_LIGHT)
- N.lighthack = !N.lighthack
+ N.lighthack = !mended
+ N.update_icon()
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 54ca78aa398..1d36dd21145 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -133,13 +133,6 @@
name = "disk"
icon = 'icons/obj/items.dmi'
-/obj/item/weapon/disk/nuclear
- name = "nuclear authentication disk"
- desc = "Better keep this safe."
- icon_state = "nucleardisk"
- item_state = "card-id"
- w_class = 2.0
-
/*
/obj/item/weapon/game_kit
name = "Gaming Kit"
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index bb8abe67578..dba58fa35a7 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -326,8 +326,11 @@ var/global/datum/controller/gameticker/ticker
spawn(50)
callHook("roundend")
- if (mode.station_was_nuked)
- feedback_set_details("end_proper","nuke")
+ if (universe_has_ended)
+ if(mode.station_was_nuked)
+ feedback_set_details("end_proper","nuke")
+ else
+ feedback_set_details("end_proper","universe destroyed")
if(!delay_end)
world << "Rebooting due to destruction of station in [restart_timeout/10] seconds"
else
diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm
index fb2a4994e33..0bd3e922000 100644
--- a/code/game/machinery/nuclear_bomb.dm
+++ b/code/game/machinery/nuclear_bomb.dm
@@ -6,27 +6,27 @@ var/bomb_set
icon = 'icons/obj/stationobjs.dmi'
icon_state = "nuclearbomb0"
density = 1
- var/deployable = 0.0
- var/extended = 0.0
+ var/deployable = 0
+ var/extended = 0
var/lighthack = 0
- var/opened = 0.0
- var/timeleft = 60.0
- var/timing = 0.0
+ var/timeleft = 120
+ var/timing = 0
var/r_code = "ADMIN"
var/code = ""
- var/yes_code = 0.0
- var/safety = 1.0
+ var/yes_code = 0
+ var/safety = 1
var/obj/item/weapon/disk/nuclear/auth = null
- var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open,
- // 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
+ var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
+ var/lastentered
use_power = 0
- var/datum/wires/nuclearbomb/wires
-
+ unacidable = 1
+ var/previous_level = ""
+ var/datum/wires/nuclearbomb/wires = null
/obj/machinery/nuclearbomb/New()
..()
r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
- wires = new(src)
+ wires = new/datum/wires/nuclearbomb(src)
/obj/machinery/nuclearbomb/Destroy()
qdel(wires)
@@ -35,42 +35,40 @@ var/bomb_set
/obj/machinery/nuclearbomb/process()
if (src.timing)
- bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
- src.timeleft--
- if (src.timeleft <= 0)
- explode()
- for(var/mob/M in viewers(1, src))
- if ((M.client && M.machine == src))
- src.attack_hand(M)
+ src.timeleft = max(timeleft - 2, 0) // 2 seconds per process()
+ if (timeleft <= 0)
+ spawn
+ explode()
+ nanomanager.update_uis(src)
return
-/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob)
+/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob, params)
if (istype(O, /obj/item/weapon/screwdriver))
src.add_fingerprint(user)
if (src.auth)
- if (src.opened == 0)
- src.opened = 1
+ if (panel_open == 0)
+ panel_open = 1
overlays += image(icon, "npanel_open")
user << "You unscrew the control panel of [src]."
-
+ playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
else
- src.opened = 0
+ panel_open = 0
overlays -= image(icon, "npanel_open")
user << "You screw the control panel of [src] back on."
+ playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
else
- if (src.opened == 0)
- user << "The [src] emits a buzzing noise, the panel staying locked in."
- if (src.opened == 1)
- src.opened = 0
+ if (panel_open == 0)
+ user << "\The [src] emits a buzzing noise, the panel staying locked in."
+ if (panel_open == 1)
+ panel_open = 0
overlays -= image(icon, "npanel_open")
- user << "You screw the control panel of [src] back on."
+ user << "You screw the control panel of \the [src] back on."
+ playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
flick("nuclearbombc", src)
+ return
- return
- if (istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/device/multitool))
- if (src.opened == 1)
- wires.Interact(user)
- return
+ if (panel_open && (istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters)))
+ return attack_hand(user)
if (src.extended)
if (istype(O, /obj/item/weapon/disk/nuclear))
@@ -78,13 +76,12 @@ var/bomb_set
O.loc = src
src.auth = O
src.add_fingerprint(user)
- return
+ return attack_hand(user)
if (src.anchored)
switch(removal_stage)
if(0)
if(istype(O,/obj/item/weapon/weldingtool))
-
var/obj/item/weapon/weldingtool/WT = O
if(!WT.isOn()) return
if (WT.get_fuel() < 5) // uses up 5 fuel.
@@ -150,54 +147,67 @@ var/bomb_set
return
..()
-/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
- if (src.extended)
- if (!ishuman(user))
- usr << "You don't have the dexterity to do this!"
- return 1
+/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
+ attack_hand(user)
- user.set_machine(src)
- var/dat = text("Nuclear Fission Explosive
\nAuth. Disk: []
", src, (src.auth ? "++++++++++" : "----------"))
- if (src.auth)
- if (src.yes_code)
- dat += text("\nStatus: []-[]
\nTimer: []
\n
\nTimer: [] Toggle
\nTime: - - [] + +
\n
\nSafety: [] Toggle
\nAnchor: [] Toggle
\n", (src.timing ? "Func/Set" : "Functional"), (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src, src, src, src.timeleft, src, src, (src.safety ? "On" : "Off"), src, (src.anchored ? "Engaged" : "Off"), src)
- else
- dat += text("\nStatus: Auth. S2-[]
\nTimer: []
\n
\nTimer: [] Toggle
\nTime: - - [] + +
\n
\n[] Safety: Toggle
\nAnchor: [] Toggle
\n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off"))
+/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
+ if (extended)
+ if (panel_open)
+ wires.Interact(user)
else
- if (src.timing)
- dat += text("\nStatus: Set-[]
\nTimer: []
\n
\nTimer: [] Toggle
\nTime: - - [] + +
\n
\nSafety: [] Toggle
\nAnchor: [] Toggle
\n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off"))
- else
- dat += text("\nStatus: Auth. S1-[]
\nTimer: []
\n
\nTimer: [] Toggle
\nTime: - - [] + +
\n
\nSafety: [] Toggle
\nAnchor: [] Toggle
\n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off"))
- var/message = "AUTH"
- if (src.auth)
- message = text("[]", src.code)
- if (src.yes_code)
- message = "*****"
- dat += text("
\n>[]
\n1-2-3
\n4-5-6
\n7-8-9
\nR-0-E
\n", message, src, src, src, src, src, src, src, src, src, src, src, src)
- user << browse(dat, "window=nuclearbomb;size=300x400")
- onclose(user, "nuclearbomb")
- else if (src.deployable)
+ ui_interact(user)
+ else if (deployable)
if(removal_stage < 5)
src.anchored = 1
visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
else
visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ extended = 1
if(!src.lighthack)
flick("nuclearbombc", src)
- src.icon_state = "nuclearbomb1"
- src.extended = 1
+ update_icon()
return
-/obj/machinery/nuclearbomb/verb/make_deployable()
+/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+ data["hacking"] = 0
+ data["auth"] = is_auth(user)
+ if (is_auth(user))
+ if (yes_code)
+ data["authstatus"] = timing ? "Functional/Set" : "Functional"
+ else
+ data["authstatus"] = "Auth. S2"
+ else
+ if (timing)
+ data["authstatus"] = "Set"
+ else
+ data["authstatus"] = "Auth. S1"
+ data["safe"] = safety ? "Safe" : "Engaged"
+ data["time"] = timeleft
+ data["timer"] = timing
+ data["safety"] = safety
+ data["anchored"] = anchored
+ data["yescode"] = yes_code
+ data["message"] = "AUTH"
+ if (is_auth(user))
+ data["message"] = code
+ if (yes_code)
+ data["message"] = "*****"
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "nuclear_bomb.tmpl", "Nuke Control Panel", 300, 510)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+/obj/machinery/nuclearbomb/verb/toggle_deployable()
set category = "Object"
- set name = "Make Deployable"
+ set name = "Toggle Deployable"
set src in oview(1)
- if (!usr.canmove || usr.stat || usr.restrained())
+ if(usr.incapacitated())
return
- if (!ishuman(usr))
- usr << "You don't have the dexterity to do this!"
- return 1
if (src.deployable)
usr << "You close several panels to make [src] undeployable."
@@ -207,106 +217,127 @@ var/bomb_set
src.deployable = 1
return
+/obj/machinery/nuclearbomb/proc/is_auth(var/mob/user)
+ if(auth)
+ return 1
+ if(user.can_admin_interact())
+ return 1
+ return 0
/obj/machinery/nuclearbomb/Topic(href, href_list)
- ..()
- if (!usr.canmove || usr.stat || usr.restrained())
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
- usr.set_machine(src)
+ if(..())
+ return 1
- if (href_list["auth"])
- if (src.auth)
- src.auth.loc = src.loc
- src.yes_code = 0
- src.auth = null
- else
- var/obj/item/I = usr.get_active_hand()
- if (istype(I, /obj/item/weapon/disk/nuclear))
- usr.drop_item()
- I.loc = src
- src.auth = I
- if (src.auth)
- if (href_list["type"])
- if (href_list["type"] == "E")
- if (src.code == src.r_code)
- src.yes_code = 1
- src.code = null
- else
- src.code = "ERROR"
+ if (href_list["auth"])
+ if (auth)
+ auth.loc = loc
+ yes_code = 0
+ auth = null
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/disk/nuclear))
+ usr.drop_item()
+ I.loc = src
+ auth = I
+ if (is_auth(usr))
+ if (href_list["type"])
+ if (href_list["type"] == "E")
+ if (code == r_code)
+ yes_code = 1
+ code = null
else
- if (href_list["type"] == "R")
- src.yes_code = 0
- src.code = null
+ code = "ERROR"
+ else
+ if (href_list["type"] == "R")
+ yes_code = 0
+ code = null
+ else
+ lastentered = text("[]", href_list["type"])
+ if (text2num(lastentered) == null)
+ var/turf/LOC = get_turf(usr)
+ message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]! ([LOC ? "JMP" : "null"])", 0)
+ log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!")
else
- src.code += text("[]", href_list["type"])
- if (length(src.code) > 5)
- src.code = "ERROR"
- if (src.yes_code)
- if (href_list["time"])
- var/time = text2num(href_list["time"])
- src.timeleft += time
- src.timeleft = min(max(round(src.timeleft), 60), 600)
- if (href_list["timer"])
- if (src.timing == -1.0)
- return
- if (src.safety)
- usr << "The safety is still on."
- return
- src.timing = !( src.timing )
- if (src.timing)
- if(!src.lighthack)
- src.icon_state = "nuclearbomb2"
- if(!src.safety)
- bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N
- else
- bomb_set = 0
- else
- bomb_set = 0
- if(!src.lighthack)
- src.icon_state = "nuclearbomb1"
- if (href_list["safety"])
- src.safety = !( src.safety )
- if(safety)
- src.timing = 0
- bomb_set = 0
- if (href_list["anchor"])
+ code += lastentered
+ if (length(code) > 5)
+ code = "ERROR"
+ if (yes_code)
+ if (href_list["time"])
+ var/time = text2num(href_list["time"])
+ timeleft += time
+ timeleft = Clamp(timeleft, 120, 600)
+ if (href_list["timer"])
+ if (timing == -1)
+ nanomanager.update_uis(src)
+ return
+ if (!anchored)
+ usr << "\The [src] needs to be anchored."
+ nanomanager.update_uis(src)
+ return
+ if (safety)
+ usr << "The safety is still on."
+ nanomanager.update_uis(src)
+ return
+ if (wires.IsIndexCut(NUCLEARBOMB_WIRE_TIMING))
+ usr << "Nothing happens, something might be wrong with the wiring."
+ nanomanager.update_uis(src)
+ return
- if(removal_stage == 5)
- src.anchored = 0
- visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
- return
+ if (!timing && !safety)
+ timing = 1
+ log_and_message_admins_with_location("engaged a nuclear bomb", x, y, ,z)
+ bomb_set++ //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N
+ update_icon()
+ else
+ secure_device()
+ if (href_list["safety"])
+ if (wires.IsIndexCut(NUCLEARBOMB_WIRE_SAFETY))
+ usr << "Nothing happens, something might be wrong with the wiring."
+ nanomanager.update_uis(src)
+ return
+ safety = !safety
+ if(safety)
+ secure_device()
+ if (href_list["anchor"])
+ if(removal_stage == 5)
+ anchored = 0
+ visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ nanomanager.update_uis(src)
+ return
- src.anchored = !( src.anchored )
- if(src.anchored)
+ if(!isinspace())
+ anchored = !anchored
+ if(anchored)
visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
else
+ secure_device()
visible_message("The anchoring bolts slide back into the depths of [src].")
+ else
+ usr << "There is nothing to anchor to!"
- src.add_fingerprint(usr)
- for(var/mob/M in viewers(1, src))
- if ((M.client && M.machine == src))
- src.attack_hand(M)
- else
- usr << browse(null, "window=nuclearbomb")
+ nanomanager.update_uis(src)
+
+/obj/machinery/nuclearbomb/proc/secure_device()
+ if(timing <= 0)
return
- return
+ bomb_set--
+ timing = 0
+ timeleft = Clamp(timeleft, 120, 600)
+ update_icon()
/obj/machinery/nuclearbomb/ex_act(severity)
return
-
#define NUKERANGE 80
/obj/machinery/nuclearbomb/proc/explode()
if (src.safety)
- src.timing = 0
+ timing = 0
return
- src.timing = -1.0
+ src.timing = -1
src.yes_code = 0
src.safety = 1
- if(!src.lighthack)
- src.icon_state = "nuclearbomb3"
+ update_icon()
playsound(src,'sound/machines/Alarm.ogg',100,0,5)
if (ticker && ticker.mode)
ticker.mode.explosion_in_progress = 1
@@ -329,24 +360,49 @@ var/bomb_set
ticker.station_explosion_cinematic(off_station,null)
if(ticker.mode)
ticker.mode.explosion_in_progress = 0
- world << "The station was destoyed by the nuclear blast!"
+ if(off_station == 1)
+ world << "A nuclear device was set off, but the explosion was out of reach of the station!"
+ else if(off_station == 2)
+ world << "A nuclear device was set off, but the device was not on the station!"
+ else
+ world << "The station was destoyed by the nuclear blast!"
ticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
//kinda shit but I couldn't get permission to do what I wanted to do.
if(!ticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
- world << "Resetting in 30 seconds!"
-
- feedback_set_details("end_error","nuke - unhandled ending")
-
- if(blackbox)
- blackbox.save_all_data_to_sql()
- sleep(300)
- log_game("Rebooting due to nuclear detonation")
- world.Reboot()
+ universe_has_ended = 1
return
return
+/obj/machinery/nuclearbomb/update_icon()
+ if(lighthack)
+ icon_state = "nuclearbomb0"
+ return
+
+ else if(timing == -1)
+ icon_state = "nuclearbomb3"
+ else if(timing)
+ icon_state = "nuclearbomb2"
+ else if(extended)
+ icon_state = "nuclearbomb1"
+ else
+ icon_state = "nuclearbomb0"
+/*
+if(!N.lighthack)
+ if (N.icon_state == "nuclearbomb2")
+ N.icon_state = "nuclearbomb1"
+ */
+
+//====The nuclear authentication disc====
+/obj/item/weapon/disk/nuclear
+ name = "nuclear authentication disk"
+ desc = "Better keep this safe."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "nucleardisk"
+ item_state = "card-id"
+ w_class = 1.0
+
/obj/item/weapon/disk/nuclear/New()
..()
nuke_disks |= src
@@ -360,7 +416,7 @@ var/bomb_set
log_and_message_admins_with_location("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).", T.x, T.y, T.z)
else
log_and_message_admins("[src], the last authentication disk, has been destroyed. Failed to respawn disc!")
- ..()
+ return ..()
/obj/item/weapon/disk/nuclear/touch_map_edge()
qdel(src)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 83526bfc03e..54ecebc1599 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -667,7 +667,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/canface()
return 1
-/mob/dead/observer/proc/can_admin_interact()
+/mob/proc/can_admin_interact()
+ return 0
+
+/mob/dead/observer/can_admin_interact()
return check_rights(R_ADMIN, 0, src)
/mob/dead/observer/verb/toggle_ghostsee()
diff --git a/nano/templates/nuclear_bomb.tmpl b/nano/templates/nuclear_bomb.tmpl
new file mode 100644
index 00000000000..b178f99bf60
--- /dev/null
+++ b/nano/templates/nuclear_bomb.tmpl
@@ -0,0 +1,68 @@
+
+