diff --git a/baystation12.dme b/baystation12.dme
index b215b4ab325..e62c74269c7 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -151,7 +151,9 @@
#define FILE_DIR "code/WorkInProgress/Mini"
#define FILE_DIR "code/WorkInProgress/organs"
#define FILE_DIR "code/WorkInProgress/Ported"
+#define FILE_DIR "code/WorkInProgress/Ported/Abi79"
#define FILE_DIR "code/WorkInProgress/Ported/Bureaucracy"
+#define FILE_DIR "code/WorkInProgress/Ported/Spawners"
#define FILE_DIR "code/WorkInProgress/Ported/ZeroPoint"
#define FILE_DIR "code/WorkInProgress/SkyMarshal"
#define FILE_DIR "code/WorkInProgress/Tastyfish"
@@ -430,6 +432,7 @@
#include "code\game\gamemodes\sandbox\h_sandbox.dm"
#include "code\game\gamemodes\sandbox\sandbox.dm"
#include "code\game\gamemodes\traitor\traitor.dm"
+#include "code\game\gamemodes\traitor\traitorinfo.dm"
#include "code\game\gamemodes\wizard\spellbook.dm"
#include "code\game\gamemodes\wizard\spells.dm"
#include "code\game\gamemodes\wizard\wizard.dm"
@@ -644,7 +647,6 @@
#include "code\game\objects\devices\PDA\cart.dm"
#include "code\game\objects\devices\PDA\PDA.dm"
#include "code\game\objects\devices\PDA\radio.dm"
-#include "code\game\objects\devices\PDA\uplink.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\candle.dm"
@@ -690,7 +692,6 @@
#include "code\game\objects\items\weapons\toilets.dm"
#include "code\game\objects\items\weapons\tools.dm"
#include "code\game\objects\items\weapons\twohanded.dm"
-#include "code\game\objects\items\weapons\uplinks.dm"
#include "code\game\objects\items\weapons\implants\implant.dm"
#include "code\game\objects\items\weapons\implants\implantcase.dm"
#include "code\game\objects\items\weapons\implants\implantchair.dm"
@@ -1045,6 +1046,8 @@
#include "code\WorkInProgress\Mini\customitems.dm"
#include "code\WorkInProgress\Ported\head.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
+#include "code\WorkInProgress\Ported\Abi79\uplink_kits.dm"
+#include "code\WorkInProgress\Ported\Abi79\uplinks.dm"
#include "code\WorkInProgress\Ported\Bureaucracy\copier.dm"
#include "code\WorkInProgress\Ported\Bureaucracy\filing.dm"
#include "code\WorkInProgress\Ported\ZeroPoint\Laser2.dm"
diff --git a/code/WorkInProgress/Ported/Abi79/uplink_kits.dm b/code/WorkInProgress/Ported/Abi79/uplink_kits.dm
new file mode 100644
index 00000000000..b7b053135ec
--- /dev/null
+++ b/code/WorkInProgress/Ported/Abi79/uplink_kits.dm
@@ -0,0 +1,53 @@
+/obj/item/weapon/storage/syndie_kit
+ name = "Box"
+ desc = "A sleek, sturdy box"
+ icon_state = "box_of_doom"
+ item_state = "syringe_kit"
+
+/obj/item/weapon/storage/syndie_kit/imp_freedom
+ name = "Freedom Implant (with injector)"
+
+/obj/item/weapon/storage/syndie_kit/imp_freedom/New()
+ var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src)
+ O.imp = new /obj/item/weapon/implant/freedom(O)
+ O.update()
+ ..()
+ return
+
+/obj/item/weapon/storage/syndie_kit/imp_compress
+ name = "Compressed Matter Implant (with injector)"
+
+/obj/item/weapon/storage/syndie_kit/imp_compress/New()
+ new /obj/item/weapon/implanter/compressed(src)
+ ..()
+ return
+
+/obj/item/weapon/storage/syndie_kit/imp_explosive
+ name = "Explosive Implant (with injector)"
+
+/obj/item/weapon/storage/syndie_kit/imp_explosive/New()
+ var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src)
+ O.imp = new /obj/item/weapon/implant/explosive(O)
+ O.name = "(BIO-HAZARD) BIO-detpack"
+ O.update()
+ ..()
+ return
+
+/obj/item/weapon/storage/syndie_kit/imp_uplink
+ name = "Uplink Implant (with injector)"
+
+/obj/item/weapon/storage/syndie_kit/imp_uplink/New()
+ var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src)
+ O.imp = new /obj/item/weapon/implant/uplink(O)
+ O.update()
+ ..()
+ return
+
+/obj/item/weapon/storage/syndie_kit/space
+ name = "Space Suit and Helmet"
+
+/obj/item/weapon/storage/syndie_kit/space/New()
+ new /obj/item/clothing/suit/space/syndicate(src)
+ new /obj/item/clothing/head/helmet/space/syndicate(src)
+ ..()
+ return
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/Abi79/uplinks.dm b/code/WorkInProgress/Ported/Abi79/uplinks.dm
new file mode 100644
index 00000000000..2c00b224506
--- /dev/null
+++ b/code/WorkInProgress/Ported/Abi79/uplinks.dm
@@ -0,0 +1,337 @@
+/*
+
+SYNDICATE UPLINKS
+
+TO-DO:
+ Once wizard is fixed, make sure the uplinks work correctly for it. wizard.dm is right now uncompiled and with broken code in it.
+
+ Clean the code up and comment it. Part of it is right now copy-pasted, with the general Topic() and modifications by Abi79.
+
+ I should take a more in-depth look at both the copy-pasted code for the individual uplinks below, and at each gamemode's code
+ to see how uplinks are assigned and if there are any bugs with those.
+
+
+A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message.
+
+*/
+
+/obj/item/device/uplink
+ var/welcome // Welcoming menu message
+ var/menu_message = "" // The actual menu text
+ var/items // List of items
+ var/list/ItemList // Parsed list of items
+ var/uses // Numbers of crystals
+
+ New()
+ welcome = ticker.mode.uplink_welcome
+ items = dd_replacetext(ticker.mode.uplink_items, "\n", "") // Getting the text string of items
+ ItemList = dd_text2list(src.items, ";") // Parsing the items text string
+ uses = ticker.mode.uplink_uses
+
+//Let's build a menu!
+ proc/generate_menu()
+ src.menu_message = "[src.welcome]
"
+ src.menu_message += "Tele-Crystals left: [src.uses]
"
+ src.menu_message += "
"
+ src.menu_message += "Request item:
"
+ src.menu_message += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
+
+ var/cost
+ var/item
+ var/name
+ var/path_obj
+ var/path_text
+ var/category_items = 1 //To prevent stupid :P
+
+ for(var/D in ItemList)
+ var/list/O = stringsplit(D, ":")
+ if(O.len != 3) //If it is not an actual item, make a break in the menu.
+ if(category_items < 1) //If there were no itens in the last category...
+ src.menu_message += "We apologize, as you could not afford anything from this category.
"
+ if(O.len == 1) //If there is one item, it's probably a title
+ src.menu_message += "[O[1]]
"
+ category_items = 0
+ else //Else, it's a white space.
+ src.menu_message += "
"
+ continue
+
+ path_text = O[1]
+ cost = text2num(O[2])
+
+ if(cost>uses)
+ continue
+
+ path_obj = text2path(path_text)
+ item = new path_obj()
+ name = O[3]
+ del item
+
+ src.menu_message += "[name] ([cost])
"
+ category_items++
+
+ src.menu_message += "
"
+ return
+
+ Topic(href, href_list)
+ if (href_list["buy_item"])
+ if(text2num(href_list["cost"]) > uses) // Not enough crystals for the item
+ return 0
+
+ if(usr:mind && ticker.mode.traitors[usr:mind])
+ var/datum/traitorinfo/info = ticker.mode.traitors[usr:mind]
+ info.spawnlist += href_list["buy_item"]
+
+ uses -= text2num(href_list["cost"])
+
+ return 1
+
+
+/*
+ *PDA uplink
+ */
+
+//Syndicate uplink hidden inside a traitor PDA
+//Communicate with traitor through the PDA's note function.
+
+/obj/item/device/uplink/pda
+ name = "uplink module"
+ desc = "An electronic uplink system of unknown origin."
+ icon = 'module.dmi'
+ icon_state = "power_mod"
+ var/obj/item/device/pda/hostpda = null
+
+ var/orignote = null //Restore original notes when locked.
+ var/active = 0 //Are we currently active?
+ var/lock_code = "" //The unlocking password.
+
+ proc
+ unlock()
+ if ((isnull(src.hostpda)) || (src.active))
+ return
+
+ src.orignote = src.hostpda.note
+ src.active = 1
+ src.hostpda.mode = 1 //Switch right to the notes program
+
+ src.generate_menu()
+ print_to_host(menu_message)
+
+ for (var/mob/M in viewers(1, src.hostpda.loc))
+ if (M.client && M.machine == src.hostpda)
+ src.hostpda.attack_self(M)
+
+ return
+
+ print_to_host(var/text)
+ if (isnull(hostpda))
+ return
+ hostpda.note = text
+
+ for (var/mob/M in viewers(1, hostpda.loc))
+ if (M.client && M.machine == hostpda)
+ hostpda.attack_self(M)
+ return
+
+ shutdown_uplink()
+ if (isnull(src.hostpda))
+ return
+ active = 0
+ hostpda.note = orignote
+ if (hostpda.mode==1)
+ hostpda.mode = 0
+ hostpda.updateDialog()
+ return
+
+ attack_self(mob/user as mob)
+ src.generate_menu()
+ src.hostpda.note = src.menu_message
+
+
+ Topic(href, href_list)
+ if ((isnull(src.hostpda)) || (!src.active))
+ return
+
+ if (usr.stat || usr.restrained() || !in_range(src.hostpda, usr))
+ return
+
+ if(..() == 1) // We can afford the item
+ var/path_obj = text2path(href_list["buy_item"])
+ var/mob/A = src.hostpda.loc
+ var/item = new path_obj(get_turf(src.hostpda))
+ if(ismob(A)) //&& !istype(item, /obj/spawner))
+ if(!A.r_hand)
+ item:loc = A
+ A.r_hand = item
+ item:layer = 20
+ else if(!A.l_hand)
+ item:loc = A
+ A.l_hand = item
+ item:layer = 20
+ usr.update_clothing()
+ // usr.client.onBought("[item:name]") When we have the stats again, uncomment.
+ /* if(istype(item, /obj/spawner)) // Spawners need to have del called on them to avoid leaving a marker behind
+ del item*/
+ //HEADFINDBACK
+ src.attack_self(usr)
+ src.hostpda.attack_self(usr)
+ return
+
+
+/*
+ *Portable radio uplink
+ */
+
+//A Syndicate uplink disguised as a portable radio
+/obj/item/device/uplink/radio/implanted
+ uses = 5
+
+/obj/item/device/uplink/radio
+ name = "ship bounced radio"
+ icon = 'device.dmi'
+ icon_state = "radio"
+ var/temp = null //Temporary storage area for a message offering the option to destroy the radio
+ var/selfdestruct = 0 //Set to 1 while the radio is self destructing itself.
+ var/obj/item/device/radio/origradio = null
+ flags = FPRINT | TABLEPASS | CONDUCT | ONBELT
+ w_class = 2.0
+ item_state = "radio"
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 20
+ m_amt = 100
+
+ attack_self(mob/user as mob)
+ var/dat
+
+ if (src.selfdestruct)
+ dat = "Self Destructing..."
+ else
+ if (src.temp)
+ dat = "[src.temp]
Clear"
+ else
+ src.generate_menu()
+ dat = src.menu_message
+ if (src.origradio) // Checking because sometimes the radio uplink may be spawned by itself, not as a normal unlockable radio
+ dat += "Lock
"
+ dat += "
"
+ dat += "Self-Destruct"
+
+ user << browse(dat, "window=radio")
+ onclose(user, "radio")
+ return
+
+ Topic(href, href_list)
+ if (usr.stat || usr.restrained())
+ return
+
+ var/mob/living/carbon/human/H = usr
+
+ if (!( istype(H, /mob/living/carbon/human)))
+ return 1
+
+ if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
+ usr.machine = src
+
+ if(href_list["buy_item"])
+ if(..() == 1) // We can afford the item
+ var/path_obj = text2path(href_list["buy_item"])
+ var/item = new path_obj(get_turf(src.loc))
+ var/mob/A = src.loc
+ if(ismob(A)) //&& !istype(item, /obj/spawner))
+ if(!A.r_hand)
+ item:loc = A
+ A.r_hand = item
+ item:layer = 20
+ else if(!A.l_hand)
+ item:loc = A
+ A.l_hand = item
+ item:layer = 20
+ /* if(istype(item, /obj/spawner)) // Spawners need to have del called on them to avoid leaving a marker behind
+ del item*/
+ // usr.client.onBought("[item:name]") When we have the stats again, uncomment.
+ src.attack_self(usr)
+ return
+
+ else if (href_list["lock"] && src.origradio)
+ // presto chango, a regular radio again! (reset the freq too...)
+ usr.machine = null
+ usr << browse(null, "window=radio")
+ var/obj/item/device/radio/T = src.origradio
+ var/obj/item/device/uplink/radio/R = src
+ R.loc = T
+ T.loc = usr
+ // R.layer = initial(R.layer)
+ R.layer = 0
+ if (usr.client)
+ usr.client.screen -= R
+ if (usr.r_hand == R)
+ usr.u_equip(R)
+ usr.r_hand = T
+
+ else
+ usr.u_equip(R)
+ usr.l_hand = T
+ R.loc = T
+ T.layer = 20
+ T.set_frequency(initial(T.frequency))
+ T.attack_self(usr)
+ return
+
+ else if (href_list["selfdestruct"])
+ src.temp = "Self-Destruct"
+
+ else if (href_list["selfdestruct2"])
+ src.selfdestruct = 1
+ spawn (100)
+ explode()
+ return
+
+ else if (href_list["clear_selfdestruct"])
+ src.temp = null
+
+ if (istype(src.loc, /mob))
+ attack_self(src.loc)
+ else
+ for(var/mob/M in viewers(1, src))
+ if (M.client)
+ src.attack_self(M)
+ return
+
+ proc/explode()
+ var/turf/location = get_turf(src.loc)
+ if(location)
+ location.hotspot_expose(700,125)
+ explosion(location, 0, 0, 2, 4, 1)
+
+ del(src.master)
+ del(src)
+ return
+
+ proc/shutdown_uplink()
+ if (!src.origradio)
+ return
+ var/list/nearby = viewers(1, src)
+ for(var/mob/M in nearby)
+ if (M.client && M.machine == src)
+ M << browse(null, "window=radio")
+ M.machine = null
+
+ var/obj/item/device/radio/T = src.origradio
+ var/obj/item/weapon/syndicate_uplink/R = src
+ var/mob/L = src.loc
+ R.loc = T
+ T.loc = L
+ // R.layer = initial(R.layer)
+ R.layer = 0
+ if (istype(L))
+ if (L.client)
+ L.client.screen -= R
+ if (L.r_hand == R)
+ L.u_equip(R)
+ L.r_hand = T
+ else
+ L.u_equip(R)
+ L.l_hand = T
+ T.layer = 20
+ T.set_frequency(initial(T.frequency))
+ return
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/Bureaucracy/copier.dm b/code/WorkInProgress/Ported/Bureaucracy/copier.dm
new file mode 100644
index 00000000000..9f933b822dd
--- /dev/null
+++ b/code/WorkInProgress/Ported/Bureaucracy/copier.dm
@@ -0,0 +1,156 @@
+// Contains: copy machine
+
+/obj/machinery/copier
+ name = "Copy Machine"
+ icon = 'bureaucracy.dmi'
+ icon_state = "copier"
+ density = 1
+ anchored = 1
+ var/num_copies = 1 // number of copies selected, will be maintained between jobs
+ var/copying = 0 // are we copying
+ var/job_num_copies = 0 // number of copies remaining
+ var/top_open = 1 // the top is open
+ var/obj/item/weapon/template // the paper OR photo being scanned
+ var/copy_wait = 0 // wait for current page to finish
+ var/max_copies = 10 // MAP EDITOR: can set the number of max copies, possibly to 5 or something for public, more for QM, robutist, etc.
+
+/obj/machinery/copier/New()
+ ..()
+ update()
+
+/obj/machinery/copier/attackby(obj/item/weapon/O as obj, mob/user as mob)
+ if(!top_open)
+ return
+
+ if (istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo))
+ // put it inside
+ template = O
+ usr.drop_item()
+ O.loc = src
+ top_open = 0
+ update()
+ updateDialog()
+
+/obj/machinery/copier/attack_paw(user as mob)
+ return src.attack_hand(user)
+
+/obj/machinery/copier/attack_ai(user as mob)
+ return src.attack_hand(user)
+
+/obj/machinery/copier/attack_hand(user as mob)
+ // da UI
+ var/dat
+ if(..())
+ return
+
+ if(src.stat)
+ user << "[name] does not seem to be responding to your button mashing."
+ return
+
+ /*
+ if(top_open)
+ user << "[name] beeps, \"Please place a paper on top and close the lid.\""
+ return
+ */
+
+ dat = "Copy MachineXeno Corp. Copying Machine
"
+
+ if(copying)
+ dat += "[job_num_copies] copies remaining.
"
+ dat += "Cancel"
+ else
+ if(!top_open)
+ dat += "Open Top
"
+
+ dat += "Number of Copies: "
+
+ dat += "-"
+ dat += "-"
+ dat += " [num_copies] "
+ dat += "+"
+ dat += "+
"
+
+ if(template)
+ dat += "Copy"
+ else
+ dat += "No paper to be copied.
"
+ dat += "Please place a paper or photograph on top and close the lid."
+
+ dat += "
"
+
+ user << browse(dat, "window=copy_machine")
+ onclose(user, "copy_machine")
+
+/obj/machinery/copier/proc/update()
+ if(top_open)
+ icon_state = "copier_o"
+ else if(copying)
+ icon_state = "copier_s"
+ else
+ icon_state = "copier"
+
+/obj/machinery/copier/Topic(href, href_list)
+ if(..())
+ return
+ usr.machine = src
+ src.add_fingerprint(usr)
+
+ if(href_list["num"])
+ num_copies += text2num(href_list["num"])
+ if(num_copies < 1)
+ num_copies = 1
+ else if(num_copies > max_copies)
+ num_copies = max_copies
+ updateDialog()
+ if(href_list["open"])
+ template.loc = src.loc
+ template = null
+ top_open = 1
+ updateDialog()
+ update()
+ if(href_list["copy"])
+ copying = 1
+ job_num_copies = num_copies
+ update()
+ updateDialog()
+ if(href_list["cancel"])
+ copying = 0
+ job_num_copies = 0
+ update()
+ updateDialog()
+
+/obj/machinery/copier/process()
+ if(src.stat)
+ usr << "[name] does not seem to be responding to your button mashing."
+ return
+
+ if(copying && !copy_wait)
+ copy_wait = 1
+ // make noise
+ playsound(src, 'polaroid1.ogg', 50, 1)
+ spawn(5)
+ if(!copying)
+ return // user cancelled
+
+ if(istype(template, /obj/item/weapon/paper))
+ // make duplicate paper
+ var/obj/item/weapon/paper/P = new(src.loc)
+ P.name = template.name
+ P.info = template:info
+ P.stamped = template:stamped
+ P.icon_state = template.icon_state
+ else if(istype(template, /obj/item/weapon/photo))
+ // make duplicate photo
+ var/obj/item/weapon/photo/P = new(src.loc)
+ P.name = template.name
+ P.desc = template.desc
+ P.icon = template.icon
+
+ // copy counting stuff
+ job_num_copies -= 1
+ if(job_num_copies == 0)
+ usr << "[name] beeps happily."
+ copying = 0
+ update()
+ updateDialog()
+ copy_wait = 0
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/Bureaucracy/filing.dm b/code/WorkInProgress/Ported/Bureaucracy/filing.dm
new file mode 100644
index 00000000000..5f6363dadc6
--- /dev/null
+++ b/code/WorkInProgress/Ported/Bureaucracy/filing.dm
@@ -0,0 +1,23 @@
+/obj/structure/filingcabinet
+ name = "Filing Cabinet"
+ desc = "A large cabinet with drawers."
+ icon = 'computer.dmi'
+ icon_state = "messyfiles"
+ density = 1
+ anchored = 1
+
+/obj/structure/filingcabinet/attackby(obj/item/weapon/paper/P,mob/M)
+ if(istype(P))
+ M << "You put the [P] in the [src]."
+ M.drop_item()
+ P.loc = src
+ else
+ M << "You can't put a [P] in the [src]!"
+
+/obj/structure/filingcabinet/attack_hand(mob/user)
+ if(src.contents.len <= 0)
+ user << "The [src] is empty."
+ return
+ var/obj/item/weapon/paper/P = input(user,"Choose a sheet to take out.","[src]", "Cancel") as null|obj in src.contents
+ if(in_range(src,user))
+ P.loc = user.loc
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/Spawners/spawner.dm b/code/WorkInProgress/Ported/Spawners/spawner.dm
new file mode 100644
index 00000000000..097d8f3c410
--- /dev/null
+++ b/code/WorkInProgress/Ported/Spawners/spawner.dm
@@ -0,0 +1,208 @@
+/obj/spawner
+ name = "object spawner"
+
+/obj/spawner/bomb
+ name = "bomb"
+ icon = 'screen1.dmi'
+ icon_state = "x"
+ var/btype = 0 //0 = radio, 1= prox, 2=time
+ var/explosive = 1 // 0= firebomb
+ var/btemp = 500 // bomb temperature (degC)
+ var/active = 0
+
+/obj/spawner/bomb/radio
+ btype = 0
+
+/obj/spawner/bomb/proximity
+ btype = 1
+
+/obj/spawner/bomb/timer
+ btype = 2
+
+/obj/spawner/bomb/timer/syndicate
+ btemp = 450
+
+/obj/spawner/bomb/suicide
+ btype = 3
+
+/obj/spawner/newbomb
+ // Remember to delete it if you use it for anything else other than uplinks. See the commented line in its New() - Abi
+ // Going in depth: the reason we do not do a Del() in its New()is because then we cannot access its properties.
+ // I might be doing this wrong / not knowing of a Byond function. If I'm doing it wrong, let me know please.
+ name = "bomb"
+ icon = 'screen1.dmi'
+ icon_state = "x"
+ var/btype = 0 // 0=radio, 1=prox, 2=time
+ var/btemp1 = 1500
+ var/btemp2 = 1000 // tank temperatures
+
+/obj/spawner/newbomb/timer
+ btype = 2
+
+/obj/spawner/newbomb/timer/syndicate
+ name = "Low-Yield Bomb"
+ btemp1 = 1500
+ btemp2 = 1000
+
+/obj/spawner/newbomb/proximity
+ btype = 1
+
+/obj/spawner/newbomb/radio
+ btype = 0
+
+/obj/spawner/bomb/New()
+ ..()
+
+ switch (src.btype)
+ // radio
+ if (0)
+ var/obj/item/assembly/r_i_ptank/R = new /obj/item/assembly/r_i_ptank(src.loc)
+ var/obj/item/weapon/tank/plasma/p3 = new /obj/item/weapon/tank/plasma(R)
+ var/obj/item/device/radio/signaler/p1 = new /obj/item/device/radio/signaler(R)
+ var/obj/item/device/igniter/p2 = new /obj/item/device/igniter(R)
+ R.part1 = p1
+ R.part2 = p2
+ R.part3 = p3
+ p1.master = R
+ p2.master = R
+ p3.master = R
+ R.status = explosive
+ p1.b_stat = 0
+ p2.status = 1
+ p3.air_contents.temperature = btemp + T0C
+
+ // proximity
+ if (1)
+ var/obj/item/assembly/m_i_ptank/R = new /obj/item/assembly/m_i_ptank(src.loc)
+ var/obj/item/weapon/tank/plasma/p3 = new /obj/item/weapon/tank/plasma(R)
+ var/obj/item/device/prox_sensor/p1 = new /obj/item/device/prox_sensor(R)
+ var/obj/item/device/igniter/p2 = new /obj/item/device/igniter(R)
+ R.part1 = p1
+ R.part2 = p2
+ R.part3 = p3
+ p1.master = R
+ p2.master = R
+ p3.master = R
+ R.status = explosive
+
+ p3.air_contents.temperature = btemp + T0C
+ p2.status = 1
+
+ if(src.active)
+ R.part1.state = 1
+ R.part1.icon_state = text("motion[]", 1)
+ R.c_state(1, src)
+
+ // timer
+ if (2)
+ var/obj/item/assembly/t_i_ptank/R = new /obj/item/assembly/t_i_ptank(src.loc)
+ var/obj/item/weapon/tank/plasma/p3 = new /obj/item/weapon/tank/plasma(R)
+ var/obj/item/device/timer/p1 = new /obj/item/device/timer(R)
+ var/obj/item/device/igniter/p2 = new /obj/item/device/igniter(R)
+ R.part1 = p1
+ R.part2 = p2
+ R.part3 = p3
+ p1.master = R
+ p2.master = R
+ p3.master = R
+ R.status = explosive
+
+ p3.air_contents.temperature = btemp + T0C
+ p2.status = 1
+ //bombvest
+ if(3)
+ var/obj/item/clothing/suit/armor/a_i_a_ptank/R = new /obj/item/clothing/suit/armor/a_i_a_ptank(src.loc)
+ var/obj/item/weapon/tank/plasma/p4 = new /obj/item/weapon/tank/plasma(R)
+ var/obj/item/device/healthanalyzer/p1 = new /obj/item/device/healthanalyzer(R)
+ var/obj/item/device/igniter/p2 = new /obj/item/device/igniter(R)
+ var/obj/item/clothing/suit/armor/vest/p3 = new /obj/item/clothing/suit/armor/vest(R)
+ R.part1 = p1
+ R.part2 = p2
+ R.part3 = p3
+ R.part4 = p4
+ p1.master = R
+ p2.master = R
+ p3.master = R
+ p4.master = R
+ R.status = explosive
+
+ p4.air_contents.temperature = btemp + T0C
+ p2.status = 1
+
+ del(src)
+
+
+/obj/spawner/newbomb/New()
+ ..()
+
+ switch (src.btype)
+ // radio
+ if (0)
+
+ var/obj/item/device/transfer_valve/V = new(src.loc)
+ var/obj/item/weapon/tank/plasma/PT = new(V)
+ var/obj/item/weapon/tank/oxygen/OT = new(V)
+
+ var/obj/item/device/radio/signaler/S = new(V)
+
+ V.tank_one = PT
+ V.tank_two = OT
+ V.attached_device = S
+
+ S.master = V
+ PT.master = V
+ OT.master = V
+
+ S.b_stat = 0
+
+ PT.air_contents.temperature = btemp1 + T0C
+ OT.air_contents.temperature = btemp2 + T0C
+
+ V.update_icon()
+
+ // proximity
+ if (1)
+
+ var/obj/item/device/transfer_valve/V = new(src.loc)
+ var/obj/item/weapon/tank/plasma/PT = new(V)
+ var/obj/item/weapon/tank/oxygen/OT = new(V)
+
+ var/obj/item/device/prox_sensor/P = new(V)
+
+ V.tank_one = PT
+ V.tank_two = OT
+ V.attached_device = P
+
+ P.master = V
+ PT.master = V
+ OT.master = V
+
+
+ PT.air_contents.temperature = btemp1 + T0C
+ OT.air_contents.temperature = btemp2 + T0C
+
+ V.update_icon()
+
+
+ // timer
+ if (2)
+ var/obj/item/device/transfer_valve/V = new(src.loc)
+ var/obj/item/weapon/tank/plasma/PT = new(V)
+ var/obj/item/weapon/tank/oxygen/OT = new(V)
+
+ var/obj/item/device/timer/T = new(V)
+
+ V.tank_one = PT
+ V.tank_two = OT
+ V.attached_device = T
+
+ T.master = V
+ PT.master = V
+ OT.master = V
+ T.time = 30
+
+ PT.air_contents.temperature = btemp1 + T0C
+ OT.air_contents.temperature = btemp2 + T0C
+
+ V.update_icon()
+ //del(src)
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/ZeroPoint/Laser2.dm b/code/WorkInProgress/Ported/ZeroPoint/Laser2.dm
new file mode 100644
index 00000000000..8b764b91be4
--- /dev/null
+++ b/code/WorkInProgress/Ported/ZeroPoint/Laser2.dm
@@ -0,0 +1,128 @@
+/obj/machinery/engine/laser
+ name = "Zero-point laser"
+ desc = "A super-powerful laser"
+ var/visible = 1
+ var/state = 1.0
+ var/obj/beam/e_beam/first
+ var/power = 500
+ icon = 'engine.dmi'
+ icon_state = "laser"
+ anchored = 1
+ var/id
+ var/on = 0
+ var/freq = 50000
+ var/phase = 0
+ var/phase_variance = 0
+
+/obj/machinery/engine/laser/process()
+ if(on)
+ if(!first)
+ src.first = new /obj/beam/e_beam(src.loc)
+ src.first.master = src
+ src.first.dir = src.dir
+ src.first.power = src.power
+ src.first.freq = src.freq
+ src.first.phase = src.phase
+ src.first.phase_variance = src.phase_variance
+ step(first, dir)
+ if(first)
+ src.first.updatebeam()
+ else
+ src.first.updatebeam()
+ else
+ if(first)
+ del first
+
+/obj/machinery/engine/laser/proc/setpower(var/powera)
+ src.power = powera
+ if(first)
+ first.setpower(src.power)
+
+
+/obj/beam/e_beam
+ name = "Laser beam"
+ icon = 'projectiles.dmi'
+ icon_state = "u_laser"
+ var/obj/machinery/engine/laser/master = null
+ var/obj/beam/e_beam/next = null
+ var/power
+ var/freq = 50000
+ var/phase = 0
+ var/phase_variance = 0
+ anchored = 1
+
+/obj/beam/e_beam/New()
+ src.sd_SetLuminosity(4)
+
+/obj/beam/e_beam/proc/updatebeam()
+ if(!next)
+ if(get_step(src.loc,src.dir))
+ var/obj/beam/e_beam/e = new /obj/beam/e_beam(src.loc)
+ e.dir = src.dir
+ src.next = e
+ e.master = src.master
+ e.power = src.power
+ e.phase = src.phase
+ src.phase+=src.phase_variance
+ e.freq = src.freq
+ e.phase_variance = src.phase_variance
+ if(src.loc.density == 0)
+ for(var/atom/o in src.loc.contents)
+ if(o.density || o == src.master || (ismob(o) && !istype(o, /mob/dead)) )
+ o.laser_act(src)
+ del src
+ return
+ else
+ src.loc.laser_act(src)
+ del e
+ return
+ step(e,e.dir)
+ if(e)
+ e.updatebeam()
+ else
+ next.updatebeam()
+
+/atom/proc/laser_act(var/obj/beam/e_beam/b)
+ return
+
+/mob/living/carbon/laser_act(var/obj/beam/e_beam/b)
+ for(var/t in organs)
+ var/datum/organ/external/affecting = organs["[t]"]
+ if (affecting.take_damage(0, b.power/400,0,0))
+ UpdateDamageIcon()
+ else
+ UpdateDamage()
+
+/obj/beam/e_beam/Bump(atom/Obstacle)
+ Obstacle.laser_act(src)
+ del(src)
+ return
+
+
+/obj/beam/e_beam/proc/setpower(var/powera)
+ src.power = powera
+ if(src.next)
+ src.next.setpower(powera)
+
+/obj/beam/e_beam/Bumped()
+ src.hit()
+ return
+
+/obj/beam/e_beam/HasEntered(atom/movable/AM as mob|obj)
+ if (istype(AM, /obj/beam))
+ return
+ spawn( 0 )
+ AM.laser_act(src)
+ src.hit()
+ return
+ return
+
+/obj/beam/e_beam/Del()
+ if(next)
+ del(next)
+ ..()
+ return
+
+/obj/beam/e_beam/proc/hit()
+ del src
+ return
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/ZeroPoint/LaserComputer.dm b/code/WorkInProgress/Ported/ZeroPoint/LaserComputer.dm
new file mode 100644
index 00000000000..fe33d3ca04d
--- /dev/null
+++ b/code/WorkInProgress/Ported/ZeroPoint/LaserComputer.dm
@@ -0,0 +1,130 @@
+//The laser control computer
+//Used to control the lasers
+/obj/machinery/computer/lasercon
+ name = "Laser control computer"
+ var/obj/machinery/engine/laser/laser = null
+ icon_state = "atmos"
+ var/id
+ var/advanced = 0
+
+/obj/machinery/computer/lasercon/New()
+ spawn(1)
+ if(istype(src.id,/list))
+ laser = list()
+ for(var/obj/machinery/engine/laser/las in world)
+ if(las.id in src.id)
+ laser += las
+ else
+ for(var/obj/machinery/engine/laser/las in world)
+ if(las.id == src.id)
+ laser = list(las)
+
+
+
+/obj/machinery/computer/lasercon/attack_ai(mob/user)
+ add_fingerprint(user)
+
+ if(stat & (BROKEN|NOPOWER))
+ return
+ interact(user)
+
+/obj/machinery/computer/lasercon/attack_hand(mob/user)
+ add_fingerprint(user)
+
+ if(stat & (BROKEN|NOPOWER))
+ return
+ interact(user)
+
+
+/obj/machinery/computer/lasercon/proc/interact(mob/user)
+
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=powcomp")
+ return
+
+
+ user.machine = src
+ var/t = "Laser status monitor
"
+
+ var/obj/machinery/engine/laser/laser = src.laser[1]
+
+ if(!laser)
+ t += "\red No laser found"
+ else
+
+
+ t += "Power level: - - - - [add_lspace(laser.power,5)] + + + +
"
+ if(advanced)
+ t += "Frequency: - - [add_lspace(laser.freq,5)] + +
"
+
+ t += "Output: [laser.on ? "Online Offline" : "Online Offline "]
"
+
+ t += "
Close"
+
+ user << browse(t, "window=lascomp;size=420x700")
+ onclose(user, "lascomp")
+
+
+/obj/machinery/computer/lasercon/Topic(href, href_list)
+ ..()
+ if( href_list["close"] )
+ usr << browse(null, "window=lascomp")
+ usr.machine = null
+ return
+
+ else if( href_list["input"] )
+ var/i = text2num(href_list["input"])
+ var/d = 0
+ switch(i)
+ if(-4)
+ d = -1000
+ if(4)
+ d = 1000
+ if(1)
+ d = 1
+ if(-1)
+ d = -1
+ if(2)
+ d = 10
+ if(-2)
+ d = -10
+ if(3)
+ d = 100
+ if(-3)
+ d = -100
+ for(var/obj/machinery/engine/laser/laser in src.laser)
+ laser.power += d
+ laser.setpower(max(1, min(3000, laser.power)))// clamp to range
+ src.updateDialog()
+ else if( href_list["online"] )
+ for(var/obj/machinery/engine/laser/laser in src.laser)
+ laser.on = !laser.on
+ src.updateDialog()
+ else if( href_list["freq"] )
+ var/amt = text2num(href_list["freq"])
+ for(var/obj/machinery/engine/laser/laser in src.laser)
+ if(laser.freq+amt>0)
+ laser.freq+=amt
+ src.updateDialog()
+/obj/machinery/computer/lasercon/process()
+ if(!(stat & (NOPOWER|BROKEN)) )
+ use_power(250)
+
+ //src.updateDialog()
+
+
+/obj/machinery/computer/lasercon/power_change()
+
+ if(stat & BROKEN)
+ icon_state = "broken"
+ else
+ if( powered() )
+ icon_state = initial(icon_state)
+ stat &= ~NOPOWER
+ else
+ spawn(rand(0, 15))
+ src.icon_state = "c_unpowered"
+ stat |= NOPOWER
+
diff --git a/code/WorkInProgress/Ported/ZeroPoint/SuperMatter.dm b/code/WorkInProgress/Ported/ZeroPoint/SuperMatter.dm
new file mode 100644
index 00000000000..75d236f10ee
--- /dev/null
+++ b/code/WorkInProgress/Ported/ZeroPoint/SuperMatter.dm
@@ -0,0 +1,120 @@
+#define NITROGEN_RETARDATION_FACTOR 4 //Higher == N2 slows reaction more
+#define THERMAL_RELEASE_MODIFIER 50 //Higher == less heat released during reaction
+#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction
+#define OXYGEN_RELEASE_MODIFIER 1500 //Higher == less oxygen released at high temperature/power
+#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power
+
+/obj/machinery/engine/supermatter
+ name = "Supermatter"
+ desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it."
+ icon = 'engine.dmi'
+ icon_state = "darkmatter"
+ density = 1
+ anchored = 1
+
+ var/gasefficency = 0.25
+
+ var/det = 0
+ var/previousdet = 0
+ var/const/explosiondet = 3500
+
+ var/const/warningtime = 50 // Make the CORE OVERLOAD message repeat only every aprox. ?? seconds
+ var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning
+
+/obj/machinery/engine/klaxon
+ name = "Emergency Klaxon"
+ icon = 'engine.dmi'
+ icon_state = "darkmatter"
+ density = 1
+ anchored = 1
+ var/obj/machinery/engine/supermatter/sup
+
+/obj/machinery/engine/klaxon/process()
+ if(!sup)
+ for(var/obj/machinery/engine/supermatter/T in world)
+ sup = T
+ break
+ if(sup.det >= 1)
+ return
+
+/obj/machinery/engine/supermatter/process()
+
+ var/turf/simulated/L = loc
+
+ //Ok, get the air from the turf
+ var/datum/gas_mixture/env = L.return_air()
+
+ //Remove gas from surrounding area
+ var/transfer_moles = gasefficency * env.total_moles()
+ var/datum/gas_mixture/removed = env.remove(transfer_moles)
+
+ previousdet = det
+ det += (removed.temperature - 1000) / 150
+ det = max(det, 0)
+
+ if(det > 0 && removed.temperature > 1000) // while the core is still damaged and it's still worth noting its status
+ if((world.realtime - lastwarning) / 10 >= warningtime)
+ lastwarning = world.realtime
+ if(explosiondet - det <= 300)
+ radioalert("CORE EXPLOSION IMMINENT","Core control computer")
+ else if(det >= previousdet) // The damage is still going up
+ radioalert("CORE OVERLOAD","Core control computer")
+ else // Phew, we're safe
+ radioalert("Core returning to safe operating levels.","Core control computer")
+
+ if(det > explosiondet)
+ roundinfo.core = 1
+ //proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, force = 0)
+ explosion(src.loc,8,15,20,30,1)
+ det = 0
+
+ if (!removed)
+ return 1
+
+ var/power = max(round((removed.temperature - T0C) / 20), 0) //Total laser power plus an overload factor
+
+ //Get the collective laser power
+ for(var/dir in cardinal)
+ var/turf/T = get_step(L, dir)
+ for(var/obj/beam/e_beam/item in T)
+ power += item.power
+
+ //Ok, 100% oxygen atmosphere = best reaction
+ //Maxes out at 100% oxygen pressure
+ var/oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0)
+
+ var/device_energy = oxygen * power
+
+ device_energy *= removed.temperature / T0C
+
+ device_energy = round(device_energy * REACTION_POWER_MODIFIER)
+
+ //To figure out how much temperature to add each tick, consider that at one atmosphere's worth
+ //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature
+ //that the device energy is around 2140. At that stage, we don't want too much heat to be put out
+ //Since the core is effectively "cold"
+
+ //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
+ //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
+ removed.temperature += max((device_energy / THERMAL_RELEASE_MODIFIER), 0)
+
+ removed.temperature = min(removed.temperature, 1500)
+
+ //Calculate how much gas to release
+ removed.toxins += max(round(device_energy / PLASMA_RELEASE_MODIFIER), 0)
+
+ removed.oxygen += max(round((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER), 0)
+
+ env.merge(removed)
+
+//Not functional currently. -- SkyMarshal
+/*
+ for(var/mob/living/carbon/l in view(src, 6)) // you have to be seeing the core to get hallucinations
+ if(prob(10) && !(l.glasses && istype(l.glasses, /obj/item/clothing/glasses/meson)))
+ l.hallucination = 50
+*/
+ for(var/mob/living/l in view(src,3))
+ l.bruteloss += 50
+ l.updatehealth()
+
+ return 1
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/head.dm b/code/WorkInProgress/Ported/head.dm
new file mode 100644
index 00000000000..d1cac9bc30d
--- /dev/null
+++ b/code/WorkInProgress/Ported/head.dm
@@ -0,0 +1,54 @@
+//This looks to be the traitor win tracker code. Gonna comment it out as we lack it currently.
+/*
+client/proc/add_roundsjoined()
+ if(!makejson)
+ return
+ var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `roundsjoined` (`ckey`) VALUES ('[ckey(src.key)]')")
+ if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
+client/proc/add_roundssurvived()
+ if(!makejson)
+ return
+ var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `roundsurvived` (`ckey`) VALUES ('[ckey(src.key)]')")
+ if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
+client/proc/onDeath(var/mob/A = src.mob)
+ if(!makejson)
+ return
+ roundinfo.deaths++
+ if(!ismob(A))
+ return
+ var/ckey = src.ckey
+ var/area
+ var/attacker
+ var/tod = time2text(world.realtime)
+ var/health
+ var/last
+ if(isturf(A.loc))
+ area = A.loc:loc:name
+ else
+ area = A.loc:name
+ if(ishuman(A.lastattacker))
+ attacker = A.lastattacker:name
+ else
+ attacker = "None"
+ health = "Oxy:[A.oxyloss]Brute:[A.bruteloss]Burn:[A.fireloss]Toxins:[A.toxloss]"
+ if(A.logs.len >= 1)
+ last = A.logs[A.logs.len]
+ else
+ last = "None"
+ var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `deathlog` (`ckey`,`location`,`lastattacker`,`ToD`,`health`,`lasthit`) VALUES ('[ckey]',[dbcon.Quote(area)],[dbcon.Quote(attacker)],'[tod]','[health]',[dbcon.Quote(last)])")
+ if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
+client/proc/onBought(names)
+ if(!makejson) return
+ if(!names) return
+ var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `traitorbuy` (`type`) VALUES ([dbcon.Quote(names)])")
+ if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
+*/
+
+datum/roundinfo
+ var/core = 0
+ var/deaths = 0
+ var/revies = 0
+ var/starttime = 0
+ var/endtime = 0
+ var/lenght = 0
+ var/mode = 0
\ No newline at end of file
diff --git a/code/WorkInProgress/Ported/policetape.dm b/code/WorkInProgress/Ported/policetape.dm
new file mode 100644
index 00000000000..8e0e1e094bc
--- /dev/null
+++ b/code/WorkInProgress/Ported/policetape.dm
@@ -0,0 +1,167 @@
+/obj/item/policetaperoll/attack_self(mob/user as mob)
+ if(icon_state == "rollstart")
+ tapestartx = src.loc.x
+ tapestarty = src.loc.y
+ tapestartz = src.loc.z
+ usr << "\blue You place the first end of the police tape."
+ icon_state = "rollstop"
+ else
+ tapeendx = src.loc.x
+ tapeendy = src.loc.y
+ tapeendz = src.loc.z
+ var/tapetest = 0
+ if(tapestartx == tapeendx && tapestarty > tapeendy && tapestartz == tapeendz)
+ for(var/Y=tapestarty,Y>=tapeendy,Y--)
+ var/turf/T = get_turf(locate(tapestartx,Y,tapestartz))
+ if(T.density == 1)
+ usr << "\blue You can't run police tape through a wall!"
+ icon_state = "rollstart"
+ return
+ for(var/Y=tapestarty,Y>=tapeendy,Y--)
+ var/turf/T = get_turf(locate(tapestartx,Y,tapestartz))
+ for(var/obj/item/policetape/Ptest in T)
+ if(Ptest.icon_state == "vertical")
+ tapetest = 1
+ if(tapetest != 1)
+ var/obj/item/policetape/P = new/obj/item/policetape(tapestartx,Y,tapestartz)
+ P.loc = locate(tapestartx,Y,tapestartz)
+ P.icon_state = "vertical"
+ usr << "\blue You finish placing the police tape." //Git Test
+
+ if(tapestartx == tapeendx && tapestarty < tapeendy && tapestartz == tapeendz)
+ for(var/Y=tapestarty,Y<=tapeendy,Y++)
+ var/turf/T = get_turf(locate(tapestartx,Y,tapestartz))
+ if(T.density == 1)
+ usr << "\blue You can't run police tape through a wall!"
+ icon_state = "rollstart"
+ return
+ for(var/Y=tapestarty,Y<=tapeendy,Y++)
+ var/turf/T = get_turf(locate(tapestartx,Y,tapestartz))
+ for(var/obj/item/policetape/Ptest in T)
+ if(Ptest.icon_state == "vertical")
+ tapetest = 1
+ if(tapetest != 1)
+ var/obj/item/policetape/P = new/obj/item/policetape(tapestartx,Y,tapestartz)
+ P.loc = locate(tapestartx,Y,tapestartz)
+ P.icon_state = "vertical"
+ usr << "\blue You finish placing the police tape."
+
+ if(tapestarty == tapeendy && tapestartx > tapeendx && tapestartz == tapeendz)
+ for(var/X=tapestartx,X>=tapeendx,X--)
+ var/turf/T = get_turf(locate(X,tapestarty,tapestartz))
+ if(T.density == 1)
+ usr << "\blue You can't run police tape through a wall!"
+ icon_state = "rollstart"
+ return
+ for(var/X=tapestartx,X>=tapeendx,X--)
+ var/turf/T = get_turf(locate(X,tapestarty,tapestartz))
+ for(var/obj/item/policetape/Ptest in T)
+ if(Ptest.icon_state == "horizontal")
+ tapetest = 1
+ if(tapetest != 1)
+ var/obj/item/policetape/P = new/obj/item/policetape(X,tapestarty,tapestartz)
+ P.loc = locate(X,tapestarty,tapestartz)
+ P.icon_state = "horizontal"
+ usr << "\blue You finish placing the police tape."
+
+ if(tapestarty == tapeendy && tapestartx < tapeendx && tapestartz == tapeendz)
+ for(var/X=tapestartx,X<=tapeendx,X++)
+ var/turf/T = get_turf(locate(X,tapestarty,tapestartz))
+ if(T.density == 1)
+ usr << "\blue You can't run police tape through a wall!"
+ icon_state = "rollstart"
+ return
+ for(var/X=tapestartx,X<=tapeendx,X++)
+ var/turf/T = get_turf(locate(X,tapestarty,tapestartz))
+ for(var/obj/item/policetape/Ptest in T)
+ if(Ptest.icon_state == "horizontal")
+ tapetest = 1
+ if(tapetest != 1)
+ var/obj/item/policetape/P = new/obj/item/policetape(X,tapestarty,tapestartz)
+ P.loc = locate(X,tapestarty,tapestartz)
+ P.icon_state = "horizontal"
+ usr << "\blue You finish placing the police tape."
+
+ if(tapestarty != tapeendy && tapestartx != tapeendx)
+ usr << "\blue Police tape can only be laid horizontally or vertically."
+ icon_state = "rollstart"
+
+/obj/item/policetape/Bumped(M as mob)
+ if(src.allowed(M))
+ var/turf/T = get_turf(src)
+ M:loc = T
+
+/obj/item/policetape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group || (height==0)) return 1
+
+ if ((mover.flags & 2 || istype(mover, /obj/effect/meteor) || mover.throwing == 1) )
+ return 1
+ else
+ return 0
+
+/obj/item/policetape/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ breaktape(W, user)
+
+/obj/item/policetape/attack_hand(mob/user as mob)
+ breaktape(null, user)
+
+/obj/item/policetape/attack_paw(mob/user as mob)
+ breaktape(/obj/item/weapon/wirecutters,user)
+
+/obj/item/policetape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob)
+ if(user.a_intent == "help" && ((!is_sharp(W) && src.allowed(user)) ||(!is_cut(W) && !src.allowed(user))))
+ user << "You can't break the tape with that!"
+ return
+ user.show_viewers(text("\blue [] breaks the police tape!", user))
+ var/OX = src.x
+ var/OY = src.y
+ if(src.icon_state == "horizontal")
+ var/N = 0
+ var/X = OX + 1
+ var/turf/T = src.loc
+ while(N != 1)
+ N = 1
+ T = locate(X,T.y,T.z)
+ for (var/obj/item/policetape/P in T)
+ N = 0
+ if(P.icon_state == "horizontal")
+ del(P)
+ X += 1
+
+ X = OX - 1
+ N = 0
+ while(N != 1)
+ N = 1
+ T = locate(X,T.y,T.z)
+ for (var/obj/item/policetape/P in T)
+ N = 0
+ if(P.icon_state == "horizontal")
+ del(P)
+ X -= 1
+
+ if(src.icon_state == "vertical")
+ var/N = 0
+ var/Y = OY + 1
+ var/turf/T = src.loc
+ while(N != 1)
+ N = 1
+ T = locate(T.x,Y,T.z)
+ for (var/obj/item/policetape/P in T)
+ N = 0
+ if(P.icon_state == "vertical")
+ del(P)
+ Y += 1
+
+ Y = OY - 1
+ N = 0
+ while(N != 1)
+ N = 1
+ T = locate(T.x,Y,T.z)
+ for (var/obj/item/policetape/P in T)
+ N = 0
+ if(P.icon_state == "vertical")
+ del(P)
+ Y -= 1
+
+ del(src)
+ return
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index ea080c637bc..cf5e242af05 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -246,7 +246,7 @@ datum/mind
text = "Uplink: give"
var/obj/item/weapon/syndicate_uplink/suplink = find_syndicate_uplink()
- var/obj/item/weapon/integrated_uplink/iuplink = find_integrated_uplink()
+ var/obj/item/device/uplink/iuplink = find_integrated_uplink()
var/crystals
if (suplink)
crystals = suplink.uses
@@ -799,7 +799,7 @@ datum/mind
if("crystals")
if (usr.client.holder.level >= 3)
var/obj/item/weapon/syndicate_uplink/suplink = find_syndicate_uplink()
- var/obj/item/weapon/integrated_uplink/iuplink = find_integrated_uplink()
+ var/obj/item/device/uplink/iuplink = find_integrated_uplink()
var/crystals
if (suplink)
crystals = suplink.uses
@@ -867,7 +867,7 @@ datum/mind
proc/find_integrated_uplink()
//world << "DEBUG: find_integrated_uplink()"
- var/obj/item/weapon/integrated_uplink/uplink = null
+ var/obj/item/device/uplink/uplink = null
var/list/L = current.get_contents()
for (var/obj/item/device/pda/pda in L)
uplink = pda.uplink
@@ -877,8 +877,8 @@ datum/mind
proc/take_uplink() //assuming only one uplink because I am tired of all this uplink shit --rastaf0
var/list/L = current.get_contents()
- var/obj/item/weapon/syndicate_uplink/suplink = null
- var/obj/item/weapon/integrated_uplink/iuplink = null
+ var/obj/item/device/uplink/radio/suplink = null
+ var/obj/item/device/uplink/pda/iuplink = null
for (var/obj/item/device/radio/radio in L)
suplink = radio.traitorradio
if (suplink)
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 66b16cbf4b9..fee7d93abe2 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -342,6 +342,20 @@
origin_tech = "magnets=1;engineering=1"
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
+/obj/item/device/hacktool
+ name = "hacktool"
+ icon_state = "hacktool"
+ flags = FPRINT | TABLEPASS | CONDUCT
+ var/in_use = 0
+ force = 5.0
+ w_class = 2.0
+ throwforce = 5.0
+ throw_range = 15
+ throw_speed = 3
+ desc = "An item of dubious origins, with wires and antennas protruding out of it."
+ m_amt = 60
+ g_amt = 20
+
/obj/item/blueprints
name = "station blueprints"
desc = "Blueprints of the station. There's stamp \"Classified\" and several coffee stains on it."
diff --git a/code/defines/obj/door.dm b/code/defines/obj/door.dm
index 4b8d10feafb..5272dd3cc0c 100644
--- a/code/defines/obj/door.dm
+++ b/code/defines/obj/door.dm
@@ -6,13 +6,15 @@
opacity = 1
density = 1
layer = 2.7
+ anchored = 1
var/secondsElectrified = 0
var/visible = 1
var/p_open = 0
var/operating = 0
- anchored = 1
var/autoclose = 0
var/glass = 0
+ var/forcecrush = 0
+ var/holdopen = 0
/obj/machinery/door/firedoor
diff --git a/code/defines/obj/storage.dm b/code/defines/obj/storage.dm
index 725ed11dae4..432954fd460 100644
--- a/code/defines/obj/storage.dm
+++ b/code/defines/obj/storage.dm
@@ -59,6 +59,7 @@
desc = "Full of masks and emergency anesthetic tanks."
/obj/item/weapon/storage/box/syndicate
+ icon_state = "box_of_doom"
/obj/item/weapon/storage/box/ert
name = "medical box"
diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm
index 5a39dc37dbe..587d98969fc 100644
--- a/code/defines/procs/gamehelpers.dm
+++ b/code/defines/procs/gamehelpers.dm
@@ -25,20 +25,36 @@
return A
return 0
-/proc/in_range(source, user)
+/proc/get_random_turf(var/atom/A, var/list/L)
+ while(L.len > 0)
+ var/dir = pick(L)
+ L -= dir
+ var/turf/T = get_step(A,dir)
+ var/possible = 1
+
+ if(T.density == 0)
+ for(var/obj/I in T)
+ if(I.density == 1)
+ possible = 0
+ break
+
+ if(possible)
+ return T
+
+ return
+
+/proc/in_range(source, user, telepathy=1)
if(get_dist(source, user) <= 1)
return 1
- /*
- else//TK TODO: remove this
- if(istype(user, /mob/living/carbon))
- if(user:mutations & TK && get_dist(source, user) <= 7)
- if(user:equipped()) return 0
+ else
+ if (istype(user, /mob/living/carbon))
+ if (user:mutations & telepathy)
var/X = source:x
var/Y = source:y
var/Z = source:z
spawn(0)
//I really shouldnt put this here but i dont have a better idea
- var/obj/effect/overlay/O = new /obj/effect/overlay ( locate(X,Y,Z) )
+ var/obj/effect/overlay/O = new /obj/effect/overlay( locate(X,Y,Z) )
O.name = "sparkles"
O.anchored = 1
O.density = 0
@@ -49,7 +65,9 @@
flick("empdisable",O)
spawn(5)
del(O)
- return 1*/
+
+
+ return 1
return 0 //not in range and not telekinetic
diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm
index b8797da8376..a30f6fa1725 100644
--- a/code/defines/procs/helpers.dm
+++ b/code/defines/procs/helpers.dm
@@ -1470,4 +1470,24 @@ proc/get_opposite(var/checkdir)
if(SOUTHEAST)
return NORTHWEST
if(SOUTHWEST)
- return NORTHEAST
\ No newline at end of file
+ return NORTHEAST
+
+/proc/stringsplit(txt, character)
+ var
+ cur_text = txt
+ last_found = 1
+ found_char = findtext(cur_text,character)
+ list/list = list()
+ if(found_char)
+ var/fs = copytext(cur_text,last_found,found_char)
+ list += fs
+ last_found = found_char+length(character)
+ found_char = findtext(cur_text,character,last_found)
+ while(found_char)
+ var
+ found_string = copytext(cur_text,last_found,found_char)
+ last_found = found_char+length(character)
+ list += found_string
+ found_char = findtext(cur_text,character,last_found)
+ list += copytext(cur_text,last_found,length(cur_text)+1)
+ return list
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index af87271db81..8b6d29b6b7b 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -3,6 +3,49 @@
config_tag = "blob"
required_players = 0
+ uplink_welcome = "Syndicate Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
var/const/waittime_l = 2000 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 3000 //upper bound on time before intercept arrives (in tenths of seconds)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 907de549c2c..19ceefe907d 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -9,6 +9,49 @@
required_players = 1
required_enemies = 1
+ uplink_welcome = "Syndicate Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
var
changeling_amount
const
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 7a4d64d0c0e..b4b4f3efcec 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -5,6 +5,49 @@
required_players = 20
required_enemies = 2
+ uplink_welcome = "Syndicate Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
/datum/game_mode/traitor/changeling/announce()
world << "The current game mode is - Traitor+Changeling!"
world << "There is an alien creature on the station along with some syndicate operatives out for their own gain! Do not let the changeling and the traitors succeed!"
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index b94c3cab429..2617c957b06 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -39,6 +39,49 @@
var/const/max_cultists_to_start = 4
var/acolytes_survived = 0
+ uplink_welcome = "Nar-Sie Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
/datum/game_mode/cult/announce()
world << "The current game mode is - Cult!"
diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm
index cfe2d183045..e295150c8a5 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -3,6 +3,49 @@
config_tag = "extended"
required_players = 0
+ uplink_welcome = "Syndicate Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
/datum/game_mode/announce()
world << "The current game mode is - Extended Role-Playing!"
world << "Just have fun and role-play!"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 897ab9a9817..3fb66ef2b79 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -23,6 +23,9 @@
list/restricted_jobs = list()
required_players = 0
required_enemies = 0
+ uplink_welcome
+ uplink_items
+ uplink_uses
/datum/game_mode/proc/announce() //to be calles when round starts
world << "Notice: [src] did not define announce()"
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index deff8194d9d..c9112b95372 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -15,6 +15,49 @@
var/to_nuke_or_not_to_nuke = 0
var/apcs = 0 //Adding dis to track how many APCs the AI hacks. --NeoFite
+ uplink_welcome = "Crazy AI Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
/datum/game_mode/malfunction/announce()
world << "The current game mode is - AI Malfunction!"
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index cd5dca83d6b..a83c13c8341 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -7,6 +7,48 @@
var/nometeors = 1
required_players = 0
+ uplink_welcome = "EVIL METEOR Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
/datum/game_mode/meteor/announce()
world << "The current game mode is - Meteor!"
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index fbd7c5ff477..2629442706a 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -8,6 +8,49 @@
required_players = 3
required_enemies = 2
+ uplink_welcome = "Corporate Backed Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 40
+
var/const/agents_possible = 5 //If we ever need more syndicate agents.
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 750537d11e1..57f7e3f6425 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -18,6 +18,49 @@
required_players = 3
required_enemies = 3
+ uplink_welcome = "Revolutionary Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
var/finished = 0
var/checkwin_counter = 0
var/const/max_headrevs = 3
@@ -130,7 +173,7 @@
if (!where)
mob << "The Syndicate were unfortunately unable to get you a flash."
else
- mob << "The flash in your [where] would help you to use your extremal persuade skill."
+ mob << "The flash in your [where] would help you to use your extreme persuasion skills."
return 1
//////////////////////////////////////
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 34d4c13f2d2..9dff9159acb 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -9,6 +9,49 @@
required_players = 0
required_enemies = 1
+ uplink_welcome = "Syndicate Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
@@ -163,12 +206,12 @@
killer << "\red Code Phrase: \black [syndicate_code_phrase]"
killer.mind.store_memory("Code Phrase: [syndicate_code_phrase]")
else
- killer << "Unfortunetly, the Syndicate did not provide you with a code phrase."
+ killer << "Unfortunately, the Syndicate did not provide you with a code phrase."
if(prob(80))
killer << "\red Code Response: \black [syndicate_code_response]"
killer.mind.store_memory("Code Response: [syndicate_code_response]")
else
- killer << "Unfortunetly, the Syndicate did not provide you with a code response."
+ killer << "Unfortunately, the Syndicate did not provide you with a code response."
killer << "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe."
//End code phrase.
@@ -215,7 +258,7 @@
traitor_mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
traitor_mob.mutations &= ~CLUMSY
- // find a radio! toolbox(es), backpack, belt, headset
+ // find a radio! toolbox(es), backpack, belt, headset, pockets
var/loc = ""
var/obj/item/device/R = null //Hide the uplink in a PDA if available, otherwise radio
if (!R && istype(traitor_mob.belt, /obj/item/device/pda))
@@ -248,11 +291,11 @@
R = foo
loc = "in the [S.name] on your back"
break
- if (!R && istype(traitor_mob.slot_l_store, /obj/item/device/pda))
- R = traitor_mob.slot_l_store
+ if (!R && istype(traitor_mob.l_store, /obj/item/device/pda))
+ R = traitor_mob.l_store
loc = "in your pocket"
- if (!R && istype(traitor_mob.slot_r_store, /obj/item/device/pda))
- R = traitor_mob.slot_r_store
+ if (!R && istype(traitor_mob.r_store, /obj/item/device/pda))
+ R = traitor_mob.r_store
loc = "in your pocket"
if (!R && traitor_mob.w_uniform && istype(traitor_mob.belt, /obj/item/device/radio))
R = traitor_mob.belt
@@ -264,10 +307,10 @@
R = traitor_mob.r_ear
loc = "on your head"
if (!R)
- traitor_mob << "Unfortunately, the Syndicate wasn't able to get you a radio."
+ traitor_mob << "Unfortunately, the Syndicate wasn't able to get you an uplink."
. = 0
else
- if (istype(R, /obj/item/device/radio))
+ if (istype(R, /obj/item/device/radio) || prob(10))
// generate list of radio freqs
var/freq = 1441
var/list/freqlist = list()
@@ -279,10 +322,12 @@
freq += 1
freq = freqlist[rand(1, freqlist.len)]
- var/obj/item/weapon/syndicate_uplink/T = new /obj/item/weapon/syndicate_uplink(R)
+ var/obj/item/device/uplink/radio/T = new /obj/item/device/uplink/radio(R)
R:traitorradio = T
R:traitor_frequency = freq
T.name = R.name
+ T.icon = R.icon
+ T.w_class = R.w_class
T.icon_state = R.icon_state
T.origradio = R
traitor_mob << "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
@@ -291,7 +336,7 @@
// generate a passcode if the uplink is hidden in a PDA
var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
- var/obj/item/weapon/integrated_uplink/T = new /obj/item/weapon/integrated_uplink(R)
+ var/obj/item/device/uplink/pda/T = new /obj/item/device/uplink/pda(R)
R:uplink = T
T.lock_code = pda_pass
T.hostpda = R
@@ -304,11 +349,11 @@
traitor_mob << "\red Code Phrase: \black [syndicate_code_phrase]"
traitor_mob.mind.store_memory("Code Phrase: [syndicate_code_phrase]")
else
- traitor_mob << "Unfortunetly, the Syndicate did not provide you with a code phrase."
+ traitor_mob << "Unfortunately, the Syndicate did not provide you with a code phrase."
if(prob(80))
traitor_mob << "\red Code Response: \black [syndicate_code_response]"
traitor_mob.mind.store_memory("Code Response: [syndicate_code_response]")
else
- traitor_mob << "Unfortunetly, the Syndicate did not provide you with a code response."
+ traitor_mob << "Unfortunately, the Syndicate did not provide you with a code response."
traitor_mob << "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe."
//End code phrase.
diff --git a/code/game/gamemodes/traitor/traitorinfo.dm b/code/game/gamemodes/traitor/traitorinfo.dm
new file mode 100644
index 00000000000..e3f18712e73
--- /dev/null
+++ b/code/game/gamemodes/traitor/traitorinfo.dm
@@ -0,0 +1,6 @@
+/datum/traitorinfo
+ var/starting_objective = ""
+ var/starting_player_count = 0
+ var/starting_occupation = ""
+ var/ckey = ""
+ var/list/spawnlist = list( )
\ No newline at end of file
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 1d6b3dcea03..04e6726c598 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -8,6 +8,49 @@
required_players = 0
required_enemies = 1
+ uplink_welcome = "Wizardly Uplink Console:"
+ uplink_items = {"Highly Visible and Dangerous Weapons;
+/obj/item/weapon/gun/projectile:6:Revolver;
+/obj/item/ammo_magazine/a357:2:Ammo-357;
+/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
+/obj/item/weapon/melee/energy/sword:4:Energy Sword;
+/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle;
+/obj/item/weapon/storage/emp_kit:4:5 EMP Grenades;
+Whitespace:Seperator;
+Stealthy and Inconspicuous Weapons;
+/obj/item/weapon/pen/sleepypen:3:Sleepy Pen;
+/obj/item/weapon/soap/syndie:1:Syndicate Soap;
+/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
+Whitespace:Seperator;
+Stealth and Camouflage Items;
+/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
+/obj/item/weapon/card/id/syndicate:3:Agent ID card;
+/obj/item/clothing/mask/gas/voice:4:Voice Changer;
+/obj/item/clothing/glasses/thermal:4:Thermal Imaging Glasses;
+/obj/item/device/chameleon:4:Chameleon-Projector;
+/obj/item/weapon/stamperaser:1:Stamp Remover;
+Whitespace:Seperator;
+Devices and Tools;
+/obj/item/weapon/card/emag:3:Cryptographic Sequencer;
+/obj/item/device/hacktool:4:Hacktool;
+/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox;
+/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module;
+/obj/item/device/radio/headset/traitor:3:Headset with Binary Translator;
+/obj/item/weapon/plastique:2:C-4;
+/obj/item/device/powersink:5:Powersink (DANGER!);
+/obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!);
+Whitespace:Seperator;
+Implants;
+/obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant;
+/obj/item/weapon/storage/syndie_kit/imp_compress:5:Compressed Matter Implant;
+/obj/item/weapon/storage/syndie_kit/imp_explosive:6:Explosive Implant;
+/obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals);
+Whitespace:Seperator;
+Badassery;
+/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
+ uplink_uses = 10
+
var/finished = 0
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 0c205ac7fce..685f1eb085f 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -7,6 +7,9 @@
#define AIRLOCK_WIRE_OPEN_DOOR 7
#define AIRLOCK_WIRE_AI_CONTROL 8
#define AIRLOCK_WIRE_ELECTRIFY 9
+#define AIRLOCK_WIRE_CRUSH 10
+#define AIRLOCK_WIRE_LIGHT 11
+#define AIRLOCK_WIRE_HOLDOPEN 12
/*
New methods:
@@ -30,16 +33,16 @@
//This generates the randomized airlock wire assignments for the game.
/proc/RandomAirlockWires()
//to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else).
- var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0)
- airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0)
- airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0)
- airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0)
+ var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
var/flagIndex = 1
- for (var/flag=1, flag<512, flag+=flag)
+ for (var/flag=1, flag<4096, flag+=flag)
var/valid = 0
while (!valid)
- var/colorIndex = rand(1, 9)
- if (wires[colorIndex]==0)
+ var/colorIndex = rand(1, 11)
+ if (wires[colorIndex] == 0)
valid = 1
wires[colorIndex] = flag
airlockIndexToFlag[flagIndex] = flag
@@ -61,12 +64,14 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
icon_state = "door_closed"
var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
+ var/synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no
+ var/synHacking = 0 // Is hack in process y/n?
var/secondsMainPowerLost = 0 //The number of seconds until power is restored.
var/secondsBackupPowerLost = 0 //The number of seconds until power is restored.
var/spawnPowerRestoreRunning = 0
var/welded = null
var/locked = 0
- var/wires = 511
+ var/wires = 4095
secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it.
var/aiDisabledIdScanner = 0
var/aiHacking = 0
@@ -77,8 +82,11 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
autoclose = 1
var/doortype = 0
var/justzap = 0
+ var/safetylight = 1
var/obj/item/weapon/airlock_electronics/electronics = null
+/obj/machinery/door/airlock/New()
+
/obj/machinery/door/airlock/command
name = "Airlock"
icon = 'Doorcom.dmi'
@@ -266,6 +274,12 @@ About the new airlock wires panel:
open()
else
close()
+ if(AIRLOCK_WIRE_CRUSH)
+ src.forcecrush = !src.forcecrush
+ if(AIRLOCK_WIRE_LIGHT)
+ src.safetylight = !src.safetylight
+ if(AIRLOCK_WIRE_HOLDOPEN)
+ src.holdopen = !src.holdopen
@@ -350,6 +364,13 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/canAIHack()
return ((src.aiControlDisabled==1) && (!src.isAllPowerCut()));
+/obj/machinery/door/airlock/proc/canSynControl()
+ return (src.synDoorHacked && (!src.isAllPowerCut()));
+
+/obj/machinery/door/airlock/proc/canSynHack(obj/item/device/hacktool/H)
+ if(in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut())
+ return 1
+
/obj/machinery/door/airlock/proc/arePowerSystemsOn()
return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0)
@@ -421,7 +442,7 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/update_icon()
if(overlays) overlays = null
if(density)
- if(locked)
+ if(locked && safetylight)
icon_state = "door_locked"
else
icon_state = "door_closed"
@@ -505,6 +526,121 @@ About the new airlock wires panel:
if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))
t1 += text("Backup Power Output wire is cut.
\n")
+ if (src.isWireCut(AIRLOCK_WIRE_CRUSH))
+ t1 += text("Airlock extra force wire is cut.
\n")
+ else if(!src.forcecrush)
+ t1 += text("Airlock extra force disabled Enable it?
\n")
+ else
+ t1 += text("Airlock extra force enabled Disable it?
\n")
+
+ if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
+ t1 += text("Door bolt drop wire is cut.
\n")
+ else if (!src.locked)
+ t1 += text("Door bolts are up. Drop them?
\n", src)
+ else
+ t1 += text("Door bolts are down.")
+ if (src.arePowerSystemsOn())
+ t1 += text(" Raise?
\n", src)
+ else
+ t1 += text(" Cannot raise door bolts due to power failure.
\n")
+
+ if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY))
+ t1 += text("Electrification wire is cut.
\n")
+ if (src.secondsElectrified==-1)
+ t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src)
+ else if (src.secondsElectrified>0)
+ t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src)
+ else
+ t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src)
+
+ if(src.isWireCut(AIRLOCK_WIRE_LIGHT))
+ t1 += "Bolt indication light wire is cut.
\n"
+ else if(!src.safetylight)
+ t1 += text("Bolt Indication light is disabled Enable it?
\n")
+ else
+ t1 += text("Bolt Indication light is enabled Disable it?
\n")
+
+ if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN))
+ t1 += "Behavior Control light wire is cut.
\n"
+ else if(!src.holdopen)
+ t1 += text("Door behavior is set to: Automatically close Toggle?
\n")
+ else
+ t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n")
+
+ if (src.welded)
+ t1 += text("Door appears to have been welded shut.
\n")
+ else if (!src.locked)
+ if (src.density)
+ t1 += text("Open door
\n", src)
+ else
+ t1 += text("Close door
\n", src)
+
+ t1 += text("Close
\n", src)
+ user << browse(t1, "window=airlock")
+ onclose(user, "airlock")
+
+//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door
+//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door
+
+/obj/machinery/door/airlock/proc/attack_hack(mob/user as mob, obj/item/device/hacktool/C)
+ if(!C)
+ return
+ if(C.in_use)
+ user << "We are already hacking another airlock."
+ return
+ if (!src.canSynControl() && src.canSynHack(C))
+ src.synhack(user, C)
+ return
+
+ //Separate interface for the hacker.
+ var/t1 = text("Airlock Control
\n")
+ if (src.secondsMainPowerLost > 0)
+ if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)))
+ t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost)
+ else
+ t1 += text("Main power is offline indefinitely.
\n")
+ else
+ t1 += text("Main power is online.")
+
+ if (src.secondsBackupPowerLost > 0)
+ if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)))
+ t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost)
+ else
+ t1 += text("Backup power is offline indefinitely.
\n")
+ else if (src.secondsMainPowerLost > 0)
+ t1 += text("Backup power is online.")
+ else
+ t1 += text("Backup power is offline, but will turn on if main power fails.")
+ t1 += "
\n"
+
+ if (src.isWireCut(AIRLOCK_WIRE_IDSCAN))
+ t1 += text("IdScan wire is cut.
\n")
+ else if (src.aiDisabledIdScanner)
+ t1 += text("IdScan disabled. Enable?
\n", src)
+ else
+ t1 += text("IdScan enabled. Disable?
\n", src)
+
+ if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1))
+ t1 += text("Main Power Input wire is cut.
\n")
+ if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))
+ t1 += text("Main Power Output wire is cut.
\n")
+ if (src.secondsMainPowerLost == 0)
+ t1 += text("Temporarily disrupt main power?.
\n", src)
+ if (src.secondsBackupPowerLost == 0)
+ t1 += text("Temporarily disrupt backup power?.
\n", src)
+
+ if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1))
+ t1 += text("Backup Power Input wire is cut.
\n")
+ if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))
+ t1 += text("Backup Power Output wire is cut.
\n")
+
+ if (src.isWireCut(AIRLOCK_WIRE_CRUSH))
+ t1 += text("Airlock extra force wire is cut.
\n")
+ else if(!src.forcecrush)
+ t1 += text("Airlock extra force disabled Enable it?
\n")
+ else
+ t1 += text("Airlock extra force enabled Disable it?
\n")
+
if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
t1 += text("Door bolt drop wire is cut.
\n")
else if (!src.locked)
@@ -524,6 +660,20 @@ About the new airlock wires panel:
else
t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src)
+ if(src.isWireCut(AIRLOCK_WIRE_LIGHT))
+ t1 += "Bolt indication light wire is cut.
\n"
+ else if(!src.safetylight)
+ t1 += text("Bolt indication light is disabled Enable it?
\n")
+ else
+ t1 += text("Bolt indication light is enabled Disable it?
\n")
+
+ if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN))
+ t1 += "Behavior Control light wire is cut.
\n"
+ else if(!src.holdopen)
+ t1 += text("Door behavior is set to: Automatically close Toggle?
\n")
+ else
+ t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n")
+
if (src.welded)
t1 += text("Door appears to have been welded shut.
\n")
else if (!src.locked)
@@ -536,10 +686,6 @@ About the new airlock wires panel:
user << browse(t1, "window=airlock")
onclose(user, "airlock")
-//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door
-//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door
-
-
/obj/machinery/door/airlock/proc/hack(mob/user as mob)
if (src.aiHacking==0)
src.aiHacking=1
@@ -628,7 +774,10 @@ About the new airlock wires panel:
"Blue" = 6,
"Green" = 7,
"Grey" = 8,
- "Black" = 9
+ "Black" = 9,
+ "Pink" = 10,
+ "Brown" = 11,
+ "Maroon" = 12
)
for(var/wiredesc in wires)
var/is_uncut = src.wires & airlockWireColorToFlag[wires[wiredesc]]
@@ -644,7 +793,7 @@ About the new airlock wires panel:
t1 += "Attach signaler"
t1 += "
"
- t1 += text("
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."))
+ t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red."))
t1 += text("Close
\n", src)
@@ -716,9 +865,8 @@ About the new airlock wires panel:
src.update_icon()
add_fingerprint(usr)
src.updateUsrDialog()
- else if(istype(usr, /mob/living/silicon)) // unranged silicon interface
- //AI
- if (!src.canAIControl())
+ else //AI or Syndicate using hacktool
+ if (!src.canAIControl() || (istype(usr.equipped(), /obj/item/device/hacktool/) && (!src.canSynControl() || !in_range(src, usr))))
usr << "Airlock control connection lost!"
return
//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door
@@ -771,6 +919,21 @@ About the new airlock wires panel:
close()
else
usr << text("The airlock is already closed.
\n")
+ if (8)
+ if(!src.forcecrush)
+ usr << text("Door extra force not enabled!
\n")
+ else
+ src.forcecrush = 0
+ if (9)
+ if(!src.safetylight)
+ usr << text("Bolt indication light not enabled!
\n")
+ else
+ src.safetylight = 0
+ if (10)
+ if(!src.holdopen)
+ usr << text("Door Behavior already set to: Wait for clearance to close
\n")
+ else
+ src.holdopen = 1
else if (href_list["aiEnable"])
var/code = text2num(href_list["aiEnable"])
@@ -834,6 +997,21 @@ About the new airlock wires panel:
// close()
else
usr << text("The airlock is already opened.
\n")
+ if (8)
+ if(src.forcecrush)
+ usr << text("Door extra force already enabled!
\n")
+ else
+ src.forcecrush = 1
+ if (9)
+ if(src.safetylight)
+ usr << text("Bolt indication light already enabled!
\n")
+ else
+ src.safetylight = 1
+ if (10)
+ if(src.holdopen)
+ usr << text("Door Behavior already set to: Automatically close
\n")
+ else
+ src.holdopen = 0
src.update_icon()
src.updateUsrDialog()
@@ -866,6 +1044,8 @@ About the new airlock wires panel:
return src.attack_hand(user)
else if (istype(C, /obj/item/device/multitool))
return src.attack_hand(user)
+ else if (istype(C, /obj/item/device/hacktool))
+ return src.attack_hack(user, C)
else if (istype(C, /obj/item/device/assembly/signaler))
return src.attack_hand(user)
else if (istype(C, /obj/item/weapon/pai_cable)) // -- TLE
@@ -980,6 +1160,85 @@ About the new airlock wires panel:
..()
return
+/obj/machinery/door/airlock/proc/synhack(mob/user as mob, obj/item/device/hacktool/I)
+ if (src.synHacking==0)
+ src.synHacking=1
+ I.in_use = 1
+ spawn(20 )
+ user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over."
+ sleep(25 )
+ if (src.canSynControl())
+ user << "Hack cancelled, control already possible."
+ src.synHacking=0
+ I.in_use = 0
+ return
+ else if (!src.canSynHack(I))
+ user << "\red Connection lost. Stand still and stay near the airlock!"
+ src.synHacking=0
+ I.in_use = 0
+ return
+ user << "Connection established."
+ sleep(10 )
+ user << "Attempting to hack into airlock. This may take some time."
+ sleep(100 )
+ // Alerting the AIs
+ var/list/cameras = list()
+ for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area
+ cameras += C
+
+ var/alertoption = prob(50) // 50% chance of warning the AI
+ if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning)
+ alertoption = 3
+ else if (prob(18)) //18% chance of sending the AI just the area
+ alertoption = 2
+
+ for (var/mob/living/silicon/ai/aiPlayer in world)
+ if (aiPlayer.stat != 2)
+ switch(alertoption)
+ if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras)
+ if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc)
+ if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking")
+ for (var/mob/living/silicon/robot/robotPlayer in world)
+ if (robotPlayer.stat != 2)
+ switch(alertoption)
+ if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc)
+ if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking")
+
+ // ...And done
+
+ if (!src.canSynHack(I))
+ user << "\red Hack aborted: landline connection lost. Stay closer to the airlock."
+ src.synHacking=0
+ I.in_use = 0
+ return
+ else if (src.canSynControl())
+ user << "Local override already in place, hack aborted."
+ src.synHacking=0
+ I.in_use = 0
+ return
+ user << "Upload access confirmed. Loading control program into airlock software."
+ sleep(85 )
+ if (!src.canSynHack(I))
+ user << "\red Hack aborted: cable connection lost. Do not move away from the airlock."
+ src.synHacking=0
+ I.in_use = 0
+ return
+ else if (src.canSynControl())
+ user << "Upload access aborted, local override already in place."
+ src.synHacking=0
+ I.in_use = 0
+ return
+ user << "Transfer complete. Forcing airlock to execute program."
+ sleep(25 )
+ //disable blocked control
+ src.synDoorHacked = 1
+ user << "Bingo! We're in. Airlock control panel coming right up."
+ sleep(5 )
+ //bring up airlock dialog
+ src.synHacking = 0
+ I.in_use = 0
+ src.attack_hack(user, I)
+
/obj/machinery/door/airlock/open()
if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
return 0
@@ -1002,6 +1261,8 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/New()
..()
+ if(src.holdopen)
+ wires -= 2^11
if (src.closeOtherId != null)
spawn (5)
for (var/obj/machinery/door/airlock/A in machines)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 2ba7288c837..b0d76edb76f 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -289,14 +289,63 @@
/obj/machinery/door/proc/close()
if(density)
return 1
- if(src.operating)
+ if (src.operating)
return
src.operating = 1
+ var/held = 0
+
+ if(src.holdopen)
+ while(held == 0)
+ var/list/objects = locate() in get_turf(src)
+ for(var/obj/T in objects)
+ if(T.anchored)
+ held = 1
+ break
+ for(var/mob/T in objects)
+ held = 1
+ break
+ sleep(150)
animate("closing")
src.density = 1
- src.layer = 3.1
- sleep(10)
+ spawn(4)
+ if(!istype(src, /obj/machinery/door/window))
+ for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way
+
+ if(src.forcecrush) // Save an AI, crush a limb
+ var/limbname = pick("l arm", "r arm", "l hand","r hand", "l foot", "r foot")
+ var/limbdisplay
+
+ for(var/organ in L:organs)
+ var/datum/organ/external/temp = L:organs["[organ]"]
+ if (istype(temp, /datum/organ/external) && temp.name == limbname)
+ limbdisplay = temp.display_name // Take the name for down below
+ temp.take_damage(60, 0) //OH GOD IT HURTS
+ break
+
+ L << "\red The airlock crushes your [limbdisplay]!"
+ for(var/mob/O in viewers(L, null))
+ O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1)
+
+
+ else
+ L << "\red The airlock forces you out of the way!" //Lucky you
+ for(var/mob/O in viewers(L, null))
+ O.show_message("\red The airlock pushes [L.name] out of the way!", 1)
+
+ var/list/lst = list(NORTH,SOUTH,EAST,WEST)
+ var/turf/T = get_random_turf(L, lst)
+ if(T)
+ L.loc = T
+
+ for(var/obj/item/I in src.loc) // Move items out of the way
+ if(!I.anchored)
+ var/list/lst = list(NORTH,SOUTH,EAST,WEST)
+ var/turf/T = get_random_turf(I, lst)
+ if(T)
+ I.loc = T
+
+ sleep(6)
update_icon()
if(src.visible && (!src.glass))
diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm
index d6197dd8a02..efb4bdd0c47 100644
--- a/code/game/objects/devices/PDA/PDA.dm
+++ b/code/game/objects/devices/PDA/PDA.dm
@@ -32,7 +32,7 @@
var/cart = "" //A place to stick cartridge menu information
var/over_jumpsuit = 1 // If set to 0, it won't display on top of the mob's jumpsuit
- var/obj/item/weapon/integrated_uplink/uplink = null
+ var/obj/item/device/uplink/pda/uplink = null
var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
diff --git a/code/game/objects/devices/PDA/uplink.dm b/code/game/objects/devices/PDA/uplink.dm
deleted file mode 100644
index bca3ca79c15..00000000000
--- a/code/game/objects/devices/PDA/uplink.dm
+++ /dev/null
@@ -1,245 +0,0 @@
-/obj/item/weapon/integrated_uplink
- name = "uplink module"
- desc = "An electronic uplink system of unknown origin."
- icon = 'module.dmi'
- icon_state = "power_mod"
- var/uses = 10
- var/obj/item/device/pda/hostpda = null
- var/orignote = null //Restore original notes when locked.
- var/active = 0 //Are we currently active??
- var/menu_message = ""
- var/lock_code = "password" //What's the password?
-
-//Communicate with traitor through the PDA's note function.
-/obj/item/weapon/integrated_uplink/proc/print_to_host(var/text)
- if (isnull(hostpda))
- return
- hostpda.note = text
-
- for (var/mob/M in viewers(1, hostpda.loc))
- if (M.client && M.machine == hostpda)
- hostpda.attack_self(M)
-
- return
-
-//Let's build a menu!
-/obj/item/weapon/integrated_uplink/proc/generate_menu()
- menu_message = "Syndicate Uplink Console:
"
- menu_message += "Tele-Crystals left: [uses]
"
- menu_message += "
"
- menu_message += "Request item:
"
- menu_message += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
- menu_message += "
"
- menu_message += "Revolver (6)
"
- menu_message += "Ammo-357 for use with Revolver (2)
"
- menu_message += "Ammo-418 for use with Revolver (3)
"
- menu_message += "Energy Crossbow (5)
"
- menu_message += "Energy Sword (4)
"
- menu_message += "
"
- menu_message += "Chameleon Jumpsuit (3)
"
- menu_message += "Syndicate Shoes (2)
"
- menu_message += "Syndicate Card (3)
"
- menu_message += "Voice-Changer (4)
"
- menu_message += "Thermal Glasses (4)
"
- menu_message += "Stamp Remover (1)
" //Allows doccuments to be de-stamped
- menu_message += "
"
- menu_message += "Freedom Implant (with injector) (3)
"
- menu_message += "Uplink Implant (5 crystals inside) (10)
"
-// menu_message += "Paralysis Pen (3)
"
-//When given the choice, people have been P2W
- menu_message += "Sleepy Pen (4)
" //Terrible -Pete.
- menu_message += "
"
- menu_message += "Explosive Implant (with injector) (6)
"
- menu_message += "Detomatix Cartridge (3)
"
- menu_message += "Plastic Explosives (2)
"
- menu_message += "Power Sink (5)
"
- menu_message += "Syndicate-made Space Suit (inludes a helmet) (3)
"
- menu_message += "
"
- menu_message += "Chameleon-projector (4)
"
-// menu_message += "Cloaking Device (4)
"
- menu_message += "Electromagnet Card (3)
"
- menu_message += "5 EMP Grenades (4)
"
- menu_message += "
"
- menu_message += "Binary Translator (3)
"
- menu_message += "Hacked AI Module (7)
"
- menu_message += "
"
- menu_message += "Singularity Beacon (does not include a screwdriver) (7)
"
- menu_message += "
"
- menu_message += "Syndicate Toolbox (Includes various tools) (1)
"
- menu_message += "Syndicate Soap (1)
"
- menu_message += "Syndicate Balloon (Useless) (10)
"
- menu_message += "
"
- menu_message += "Syndicate Bundle (Contains an assorted selection of syndicate items)(10)
"
-
- menu_message += "
"
- return
-
-/obj/item/weapon/integrated_uplink/proc/unlock()
- if ((isnull(hostpda)) || (active))
- return
-
- orignote = hostpda.note
- active = 1
- hostpda.mode = 1 //Switch right to the notes program
-
- generate_menu()
- print_to_host(menu_message)
- return
-
-/obj/item/weapon/integrated_uplink/Topic(href, href_list)
- if ((isnull(hostpda)) || (!active))
- return
-
- if (usr.stat || usr.restrained() || !in_range(hostpda, usr))
- return
-
- if (href_list["buy_item"])
- switch(href_list["buy_item"])
- if("revolver")
- if (uses >= 6)
- uses -= 6
- new /obj/item/weapon/gun/projectile(get_turf(hostpda))
- if("revolver_ammo")
- if (uses >= 2)
- uses -= 2
- new /obj/item/ammo_magazine/a357(get_turf(hostpda))
- if("suffocation_revolver_ammo")
- if (uses >= 3)
- uses -= 3
- new /obj/item/ammo_magazine/a418(get_turf(hostpda))
- if("xbow")
- if (uses >= 5)
- uses -= 5
- new /obj/item/weapon/gun/energy/crossbow(get_turf(hostpda))
- if("empbox")
- if (uses >= 4)
- uses -= 4
- new /obj/item/weapon/storage/emp_kit(get_turf(hostpda))
- if("voice")
- if (uses >= 4)
- uses -= 4
- new /obj/item/clothing/mask/gas/voice(get_turf(hostpda))
- if("jump")
- if (uses >= 3)
- uses -= 3
- new /obj/item/clothing/under/chameleon(get_turf(hostpda))
- if("shoes")
- if (uses >= 2)
- uses -= 2
- new /obj/item/clothing/shoes/syndigaloshes(get_turf(hostpda))
- if("card")
- if (uses >= 3)
- uses -= 3
- new /obj/item/weapon/card/id/syndicate(get_turf(hostpda))
- if("emag")
- if (uses >= 3)
- uses -= 3
- new /obj/item/weapon/card/emag(get_turf(hostpda))
- if("imp_freedom")
- if (uses >= 3)
- uses -= 3
- var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(get_turf(hostpda))
- O.imp = new /obj/item/weapon/implant/freedom(O)
- O.update()
- if("imp_uplink")
- if (uses >= 10)
- uses -= 10
- var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(get_turf(hostpda))
- O.imp = new /obj/item/weapon/implant/uplink(O)
- O.update()
- if("imp_exp")
- if (src.uses >= 6)
- src.uses -= 6
- var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(get_turf(hostpda))
- O.imp = new /obj/item/weapon/implant/explosive(O)
- O.name = "(BIO-HAZARD) BIO-detpack"
- O.update()
- if("sleepypen")
- if (uses >= 4)
- uses -= 4
- new /obj/item/weapon/pen/sleepypen(get_turf(hostpda))
- if("paralysispen")
- if (uses >= 3)
- uses -= 3
- new /obj/item/weapon/pen/paralysis(get_turf(src))
- if("projector")
- if (uses >= 4)
- uses -= 4
- new /obj/item/device/chameleon(get_turf(hostpda))
- /*if("cloak")
- if (uses >= 4)
- uses -= 4
- new /obj/item/weapon/cloaking_device(get_turf(hostpda))*/
- if("thermal")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/clothing/glasses/thermal(get_turf(src))
- if("sword")
- if (uses >= 4)
- uses -= 4
- new /obj/item/weapon/melee/energy/sword(get_turf(hostpda))
- if("bomb")
- if (uses >= 2)
- uses -= 2
- new /obj/item/weapon/plastique(get_turf(hostpda))
- if("powersink")
- if (uses >= 5)
- uses -= 5
- new /obj/item/device/powersink(get_turf(hostpda))
- if("detomatix")
- if (uses >= 3)
- uses -= 3
- new /obj/item/weapon/cartridge/syndicate(get_turf(hostpda))
- if("space")
- if (uses >= 3)
- uses -= 3
- new /obj/item/clothing/suit/space/syndicate(get_turf(hostpda))
- new /obj/item/clothing/head/helmet/space/syndicate(get_turf(hostpda))
- if("lawmod")
- if (uses >= 7)
- uses -= 7
- new /obj/item/weapon/aiModule/syndicate(get_turf(hostpda))
- if("botchat")
- if (uses >= 3)
- uses -= 3
- new /obj/item/device/radio/headset/traitor(get_turf(hostpda))
- if("singubeacon")
- if(uses >= 7)
- uses -= 7
- new /obj/machinery/singularity_beacon/syndicate(get_turf(hostpda))
- if("toolbox")
- if(uses)
- uses--
- new /obj/item/weapon/storage/toolbox/syndicate(get_turf(hostpda))
- if("soap")
- if(uses)
- uses--
- new /obj/item/weapon/soap/syndie(get_turf(src))
- if("balloon")
- if(uses >= 10)
- uses -= 10
- new /obj/item/toy/syndicateballoon(get_turf(hostpda))
- if("bundle")
- if(uses >= 10)
- uses -= 10
- new /obj/item/weapon/storage/box/syndicate(get_turf(hostpda))
- if("eraser")
- if(uses >= 1)
- uses -= 1
- new /obj/item/weapon/stamperaser(get_turf(hostpda))
-
- generate_menu()
- print_to_host(menu_message)
- return
-
- return
-
-/obj/item/weapon/integrated_uplink/proc/shutdown_uplink()
- if (isnull(src.hostpda))
- return
- active = 0
- hostpda.note = orignote
- if (hostpda.mode==1)
- hostpda.mode = 0
- hostpda.updateDialog()
- return
\ 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 9283f50e04c..605ae867b53 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -38,12 +38,12 @@
desc = "Summon things."
var
activation_emote = "chuckle"
- obj/item/weapon/syndicate_uplink/uplink = null
+ obj/item/device/uplink/radio/uplink = null
New()
activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- uplink = new /obj/item/weapon/syndicate_uplink/implanted(src)
+ uplink = new /obj/item/device/uplink/radio/implanted(src)
..()
return
@@ -290,4 +290,38 @@ the implant may become unstable and either pre-maturely inject the subject or si
implanted(mob/source as mob)
mobname = source.real_name
- processing_objects.Add(src)
\ No newline at end of file
+ processing_objects.Add(src)
+
+/obj/item/weapon/implant/compressed
+ name = "compressed matter implant"
+ desc = "*fwooomp*"
+ var/activation_emote = "sigh"
+ var/obj/item/scanned = null
+
+ get_data()
+ var/dat = {"
+Implant Specifications:
+Name: NanoTrasen \"Profit Margin\" Class Employee Lifesign Sensor
+Life: Activates upon death.
+Important Notes: Alerts crew to crewmember death.
+
+Implant Details:
+Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
+Special Features: Alerts crew to crewmember death.
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+ return dat
+
+ trigger(emote, mob/source as mob)
+ if (src.scanned == null)
+ return 0
+
+ if (emote == src.activation_emote)
+ source << "The air glows as \the [src.scanned.name] uncompresses."
+ var/turf/t = get_turf(source)
+ src.scanned.loc = t
+ del src
+
+ implanted(mob/source as mob)
+ src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
+ source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
+ source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index 0d4d7543e7c..90dff280ec1 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -80,4 +80,39 @@
src.imp = new /obj/item/weapon/implant/explosive( src )
..()
update()
- return
\ No newline at end of file
+ return
+
+/obj/item/weapon/implanter/compressed
+ name = "implanter-compressed"
+ icon_state = "cimplanter0"
+
+ New()
+ src.imp = new /obj/item/weapon/implant/compressed( src )
+ ..()
+ update()
+ return
+
+ update()
+ if (src.imp)
+ var/obj/item/weapon/implant/compressed/c = src.imp
+ if(!c.scanned)
+ src.icon_state = "cimplanter0"
+ else
+ src.icon_state = "cimplanter1"
+ else
+ src.icon_state = "cimplanter2"
+ return
+
+ attack(mob/M as mob, mob/user as mob)
+ var/obj/item/weapon/implant/compressed/c = src.imp
+ if (c.scanned == null)
+ user << "Please scan an object with the implanter first."
+ return
+ ..()
+
+ afterattack(atom/A, mob/user as mob)
+ if(istype(A,/obj/item))
+ var/obj/item/weapon/implant/compressed/c = src.imp
+ c.scanned = A
+ A.loc.contents.Remove(A)
+ src.update()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/uplinks.dm b/code/game/objects/items/weapons/uplinks.dm
deleted file mode 100644
index 7d6d03fa972..00000000000
--- a/code/game/objects/items/weapons/uplinks.dm
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-CONTAINS:
-SYNDICATE UPLINK
-*/
-
-/obj/item/weapon/syndicate_uplink/implanted
- uses = 5
-
-/obj/item/weapon/syndicate_uplink/proc/explode()
- var/turf/location = get_turf(src.loc)
- if(location)
- location.hotspot_expose(700,125)
-
- explosion(location, 0, 0, 2, 4)
-
- del(src.master)
- del(src)
- return
-
-/obj/item/weapon/syndicate_uplink/attack_self(mob/user as mob)
- interact(user)
-
-/obj/item/weapon/syndicate_uplink/proc/interact(mob/user as mob)
- currentUser = user
- user.machine = src
- var/dat
- if (src.selfdestruct)
- dat = "Self Destructing..."
- else
- if (src.temp)
- dat = "[src.temp]
Clear"
- else
- dat = "Syndicate Uplink Access:
"
- dat += "Tele-Crystals left: [src.uses]
"
- dat += "
"
- dat += "Request item:
"
- dat += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
- dat += "
"
- dat += "Revolver (6)
"
- dat += "Ammo-357 for use with Revolver (2)
"
- dat += "Energy Crossbow (5)
"
- dat += "Energy Sword (4)
"
- dat += "
"
- dat += "Chameleon Jumpsuit (3)
"
- dat += "Syndicate Shoes (2)
"
- dat += "Syndicate Card (3)
"
- dat += "Voice-Changer (4)
"
- dat += "Thermal Glasses (4)
"
- dat += "Stamp Remover (1)
"
- dat += "
"
- dat += "Freedom Implant (with injector) (3)
"
-// dat += "Paralysis Pen (3)
" //Note that this goes to the updated sleepypen now.
- dat += "Sleepy Pen (4)
" //Terrible -Pete. //Reinstated -Skymarshal
- dat += "
"
- dat += "Explosive Implant (with injector) (6)
"
- dat += "Detomatix Cartridge (3)
"
- dat += "Plastic Explosives (2)
"
- dat += "Power Sink (5)
"
- dat += "Syndicate-made Space Suit (inludes a helmet) (3)
"
- dat += "
"
- dat += "Chameleon-projector (4)
"
-// dat += "Cloaking Device (4)
"
- dat += "Electromagnet Card (3)
"
- dat += "5 EMP Grenades (4)
"
- dat += "
"
- dat += "Binary Translator (3)
"
- dat += "Hacked AI Module (7)
"
- dat += "
"
- dat += "Syndicate Toolbox (Includes various tools) (1)
"
- dat += "Syndicate Soap (1)
"
- dat += "Syndicate Balloon (Useless) (10)
"
- dat += "
"
- if (src.origradio)
- dat += "Lock
"
- dat += "
"
- dat += "Self-Destruct"
- user << browse(dat, "window=radio")
- onclose(user, "radio")
- return
-
-/obj/item/weapon/syndicate_uplink/Topic(href, href_list)
- ..()
- if(!currentUser)
- return
- if (currentUser.stat || currentUser.restrained())
- return
- if (!( istype(currentUser, /mob/living/carbon/human)))
- return
- if ((currentUser.contents.Find(src) || (in_range(src, currentUser) && istype(src.loc, /turf))) || istype(src,/obj/item/weapon/syndicate_uplink/implanted))
- currentUser.machine = src
- if (href_list["buy_item"])
- switch(href_list["buy_item"])
- if("revolver")
- if (src.uses >= 6)
- src.uses -= 6
- new /obj/item/weapon/gun/projectile(get_turf(src))
- if("revolver_ammo")
- if (src.uses >= 2)
- src.uses -= 2
- new /obj/item/ammo_magazine/a357(get_turf(src))
- if("xbow")
- if (src.uses >= 5)
- src.uses -= 5
- new /obj/item/weapon/gun/energy/crossbow(get_turf(src))
- if("empbox")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/weapon/storage/emp_kit(get_turf(src))
- if("voice")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/clothing/mask/gas/voice(get_turf(src))
- if("jump")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/clothing/under/chameleon(get_turf(src))
- if("shoes")
- if (uses >= 2)
- uses -= 2
- new /obj/item/clothing/shoes/syndigaloshes(get_turf(src))
- if("card")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/weapon/card/id/syndicate(get_turf(src))
- if("emag")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/weapon/card/emag(get_turf(src))
- if("imp_freedom")
- if (src.uses >= 3)
- src.uses -= 3
- var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(get_turf(src))
- O.imp = new /obj/item/weapon/implant/freedom(O)
- if("imp_exp")
- if (src.uses >= 6)
- src.uses -= 6
- var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(get_turf(src))
- O.imp = new /obj/item/weapon/implant/explosive(O)
- O.name = "(BIO-HAZARD) BIO-detpack"
- O.update()
- if("sleepypen")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/weapon/pen/sleepypen(get_turf(src))
- if("paralysispen")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/weapon/pen/paralysis(get_turf(src))
- if("projector")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/device/chameleon(get_turf(src))
- if("lawmod")
- if (src.uses >= 7)
- src.uses -= 7
- new /obj/item/weapon/aiModule/syndicate(get_turf(src))
-/* if("cloak")
- if (src.uses >= 4)
- if (ticker.mode.config_tag!="nuclear" || \
- (input(currentUser,"Spawning a cloak in nuke is generally regarded as entirely dumb, are you sure?") in list("Confirm", "Abort")) == "Confirm" \
- )
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/weapon/cloaking_device(get_turf(src)) */
- if("sword")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/weapon/melee/energy/sword(get_turf(src))
- if("thermal")
- if (src.uses >= 4)
- src.uses -= 4
- new /obj/item/clothing/glasses/thermal(get_turf(src))
- if("bomb")
- if (src.uses >= 2)
- src.uses -= 2
- new /obj/item/weapon/plastique(get_turf(src))
- if("powersink")
- if (src.uses >= 5)
- src.uses -= 5
- new /obj/item/device/powersink(get_turf(src))
- if("detomatix")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/weapon/cartridge/syndicate(get_turf(src))
- if("space")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/clothing/suit/space/syndicate(get_turf(src))
- new /obj/item/clothing/head/helmet/space/syndicate(get_turf(src))
- if("botchat")
- if (src.uses >= 3)
- src.uses -= 3
- new /obj/item/device/radio/headset/traitor(get_turf(src))
- if("toolbox")
- if(uses)
- uses--
- new /obj/item/weapon/storage/toolbox/syndicate(get_turf(src))
- if("soap")
- if(uses)
- uses--
- new /obj/item/weapon/soap/syndie(get_turf(src))
- if("balloon")
- if (src.uses >= 10)
- uses -= 10
- new /obj/item/toy/syndicateballoon(get_turf(src))
- else if (href_list["lock"] && src.origradio)
- // presto chango, a regular radio again! (reset the freq too...)
- shutdown_uplink()
- return
- else if (href_list["selfdestruct"])
- src.temp = "Self-Destruct"
- else if (href_list["selfdestruct2"])
- src.selfdestruct = 1
- spawn (100)
- explode()
- return
- else
- if (href_list["temp"])
- src.temp = null
- if (istype(src.loc, /mob))
- interact(src.loc)
- else
- for(var/mob/M in viewers(1, src))
- if (M.client)
- interact(M)
- return
-
-/obj/item/weapon/syndicate_uplink/proc/shutdown_uplink()
- if (!src.origradio)
- return
- var/list/nearby = viewers(1, src)
- for(var/mob/M in nearby)
- if (M.client && M.machine == src)
- M << browse(null, "window=radio")
- M.machine = null
-
- var/obj/item/device/radio/T = src.origradio
- var/obj/item/weapon/syndicate_uplink/R = src
- var/mob/L = src.loc
- R.loc = T
- T.loc = L
- // R.layer = initial(R.layer)
- R.layer = 0
- if (istype(L))
- if (L.client)
- L.client.screen -= R
- if (L.r_hand == R)
- L.u_equip(R)
- L.r_hand = T
- else
- L.u_equip(R)
- L.l_hand = T
- T.layer = 20
- T.set_frequency(initial(T.frequency))
- return
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 56b126aa78a..7f7d75a6cf2 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -354,6 +354,41 @@
reset_view(C)
return 1
+/mob/living/silicon/ai/proc/triggerUnmarkedAlarm(var/class, area/A, var/O)
+ if(stat == 2) // stat = 2 = dead AI
+ return 1
+ var/obj/machinery/camera/C = null
+ var/list/CL = null
+ var/alarmtext = ""
+ if(class == "AirlockHacking") // In case more unmarked alerts would be added eventually;
+ alarmtext = "--- Unauthorized remote access detected"
+ if (O && istype(O, /list))
+ CL = O
+ if (CL.len == 1)
+ C = CL[1]
+ else if (O && istype(O, /obj/machinery/camera))
+ C = O
+ if (A)
+ alarmtext += " in " + A.name
+ if (O)
+ if (C && C.status)
+ alarmtext += text("! ([])", src, C, C.c_tag)
+ else if (CL && CL.len)
+ var/foo = 0
+ var/dat2 = ""
+ for (var/obj/machinery/camera/I in CL)
+ dat2 += text("[][]", (!foo) ? "" : " | ", src, I, I.c_tag)
+ foo = 1
+ alarmtext += text("! ([])", dat2)
+ else
+ alarmtext += "! (No Camera)"
+ else
+ alarmtext += "! (No Camera)"
+ else
+ alarmtext += "!"
+ src << alarmtext
+ return 1
+
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
if (stat == 2)
return 1
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 2f683a56bba..62331f82765 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -293,6 +293,17 @@
return
return
+/mob/living/silicon/robot/proc/triggerUnmarkedAlarm(var/class, area/A)
+ if(stat == 2) // stat = 2 = dead Cyborg
+ return 1
+ var/alarmtext = ""
+ if(class == "AirlockHacking") // In case more unmarked alerts would be added eventually;
+ alarmtext = "--- Unauthorized remote access detected"
+ if (A)
+ alarmtext += " in " + A.name
+ alarmtext += "!"
+ src << alarmtext
+ return 1
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
if (stat == 2)
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index f02a7f7ac26..fc8bfaa4f71 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index 9c324cb55c4..9d3778ef16b 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 7f568e027a8..64d4b0adc04 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index fdcfb9c2057..31cfc9428d2 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ