diff --git a/baystation12.dme b/baystation12.dme
index d6169d21a0b..ed72c127bf1 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -168,7 +168,14 @@
#include "code\datums\spells\turf_teleport.dm"
#include "code\datums\spells\wizard.dm"
#include "code\datums\wires\airlock.dm"
+#include "code\datums\wires\alarm.dm"
#include "code\datums\wires\apc.dm"
+#include "code\datums\wires\camera.dm"
+#include "code\datums\wires\explosive.dm"
+#include "code\datums\wires\mulebot.dm"
+#include "code\datums\wires\particle_accelerator.dm"
+#include "code\datums\wires\radio.dm"
+#include "code\datums\wires\robot.dm"
#include "code\datums\wires\vending.dm"
#include "code\datums\wires\wires.dm"
#include "code\defines\obj.dm"
@@ -357,7 +364,6 @@
#include "code\game\machinery\camera\motion.dm"
#include "code\game\machinery\camera\presets.dm"
#include "code\game\machinery\camera\tracking.dm"
-#include "code\game\machinery\camera\wires.dm"
#include "code\game\machinery\computer\ai_core.dm"
#include "code\game\machinery\computer\aifixer.dm"
#include "code\game\machinery\computer\arcade.dm"
@@ -1070,7 +1076,6 @@
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
-#include "code\modules\mob\living\silicon\robot\wires.dm"
#include "code\modules\mob\living\simple_animal\bees.dm"
#include "code\modules\mob\living\simple_animal\borer.dm"
#include "code\modules\mob\living\simple_animal\constructs.dm"
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index af1641f804d..4d8eca375e8 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -77,7 +77,6 @@ proc/age2agedescription(age)
else return "unknown"
-
/*
Proc for attack log creation, because really why not
1 argument is the actor
@@ -95,4 +94,4 @@ proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=nul
log_attack("[user.name][ismob(user) ? "([user.ckey])" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition]")
if(target.client)
if(what_done != ("shaked" || "CPRed" || "grabbed"))
- message_admins("[user.name][ismob(user) ? "([user.ckey])" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition](JMP)")
\ No newline at end of file
+ message_admins("[user.name][ismob(user) ? "([user.ckey])" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition](JMP)")
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index ece685d28cc..e4a627088c7 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -551,6 +551,14 @@ Turf and target are seperate in case you want to teleport some distance from a t
/proc/key_name_admin(var/whom, var/include_name = 1)
return key_name(whom, 1, include_name)
+// Returns the atom sitting on the turf.
+// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
+/proc/get_atom_on_turf(var/atom/movable/M)
+ var/atom/loc = M
+ while(loc && loc.loc && !istype(loc.loc, /turf/))
+ loc = loc.loc
+ return loc
+
// Registers the on-close verb for a browse window (client/verb/.windowclose)
// this will be called when the close-button of a window is pressed.
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 436be01cbd4..51f3f3385ed 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -97,7 +97,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
//Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted.
if(A.secondsElectrified != -1)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
- usr.attack_log += text("\[[time_stamp()]\] Electrified the [A.name] at [A.x] [A.y] [A.z]")
+ add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]")
A.secondsElectrified = -1
else
if(A.secondsElectrified == -1)
@@ -163,7 +163,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
//one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds.
if(A.secondsElectrified==0)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
- usr.attack_log += text("\[[time_stamp()]\] Electrified the [A.name] at [A.x] [A.y] [A.z]")
+ add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]")
A.secondsElectrified = 30
spawn(10)
if(A)
diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm
index 2c826e6d527..c1c45096bbc 100644
--- a/code/datums/wires/alarm.dm
+++ b/code/datums/wires/alarm.dm
@@ -47,8 +47,8 @@ var/const/AALARM_WIRE_AALARM = 16
//world << "Syphon Wire Cut"
if(AALARM_WIRE_AALARM)
- if (A.alarm_area.atmosalert(2))
- A.post_alert(2)
+ //if (A.alarm_area.atmosalert(2))
+ // A.post_alert(2)
A.update_icon()
/datum/wires/alarm/UpdatePulsed(var/index)
@@ -89,6 +89,6 @@ var/const/AALARM_WIRE_AALARM = 16
if(AALARM_WIRE_AALARM)
// world << "Aalarm wire pulsed"
- if (A.alarm_area.atmosalert(0))
- A.post_alert(0)
+ //if (A.alarm_area.atmosalert(0))
+ // A.post_alert(0)
A.update_icon()
diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm
index b6839a86204..96075d5941f 100644
--- a/code/datums/wires/apc.dm
+++ b/code/datums/wires/apc.dm
@@ -29,15 +29,16 @@ var/const/APC_WIRE_AI_CONTROL = 8
A.locked = 0
spawn(300)
- A.locked = 1
- A.updateDialog()
+ if(A)
+ A.locked = 1
+ A.updateDialog()
if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
if(A.shorted == 0)
A.shorted = 1
spawn(1200)
- if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
+ if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
A.shorted = 0
A.updateDialog()
@@ -46,7 +47,7 @@ var/const/APC_WIRE_AI_CONTROL = 8
A.aidisabled = 1
spawn(10)
- if(!IsIndexCut(APC_WIRE_AI_CONTROL))
+ if(A && !IsIndexCut(APC_WIRE_AI_CONTROL))
A.aidisabled = 0
A.updateDialog()
diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm
index 9dbbb9ff0a7..e05b543d420 100644
--- a/code/datums/wires/robot.dm
+++ b/code/datums/wires/robot.dm
@@ -3,11 +3,21 @@
holder_type = /mob/living/silicon/robot
wire_count = 5
-var/const/BORG_WIRE_LAWCHECK = 1
-var/const/BORG_WIRE_MAIN_POWER = 2 // The power wires do nothing whyyyyyyyyyyyyy
+/* /tg/ ordering doesn't work for us, we need lawsync at the end for MoMMIs.
+var/const/BORG_WIRE_LAWCHECK = 1
+var/const/BORG_WIRE_MAIN_POWER = 2 // The power wires do nothing whyyyyyyyyyyyyy
var/const/BORG_WIRE_LOCKED_DOWN = 4
-var/const/BORG_WIRE_AI_CONTROL = 8
-var/const/BORG_WIRE_CAMERA = 16
+var/const/BORG_WIRE_AI_CONTROL = 8
+var/const/BORG_WIRE_CAMERA = 16
+*/
+
+// /vg/ ordering
+
+var/const/BORG_WIRE_MAIN_POWER = 1 // The power wires do nothing whyyyyyyyyyyyyy
+var/const/BORG_WIRE_LOCKED_DOWN = 2
+var/const/BORG_WIRE_CAMERA = 4
+var/const/BORG_WIRE_AI_CONTROL = 8 // Not used on MoMMIs
+var/const/BORG_WIRE_LAWCHECK = 16 // Not used on MoMMIs
/datum/wires/robot/GetInteractWindow()
@@ -76,4 +86,10 @@ var/const/BORG_WIRE_CAMERA = 16
return wires_status & BORG_WIRE_CAMERA
/datum/wires/robot/proc/LockedCut()
- return wires_status & BORG_WIRE_LOCKED_DOWN
\ No newline at end of file
+ return wires_status & BORG_WIRE_LOCKED_DOWN
+
+/datum/wires/robot/proc/CanLawCheck()
+ return wires_status & BORG_WIRE_LAWCHECK
+
+/datum/wires/robot/proc/AIHasControl()
+ return wires_status & BORG_WIRE_AI_CONTROL
\ No newline at end of file
diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm
index 77700d9d028..8c60b0e4546 100644
--- a/code/datums/wires/syndicatebomb.dm
+++ b/code/datums/wires/syndicatebomb.dm
@@ -11,6 +11,8 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
/datum/wires/syndicatebomb/UpdatePulsed(var/index)
var/obj/machinery/syndicatebomb/P = holder
+ if(P.degutted)
+ return
switch(index)
if(WIRE_BOOM)
if (P.active)
@@ -47,6 +49,8 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
/datum/wires/syndicatebomb/UpdateCut(var/index, var/mended)
var/obj/machinery/syndicatebomb/P = holder
+ if(P.degutted)
+ return
switch(index)
if(WIRE_EXPLODE)
if(!mended)
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index a897226a948..751542dc327 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -579,19 +579,6 @@
var/obj/machinery/machine
-/obj/item/weapon/plastique
- name = "plastic explosives"
- desc = "Used to put holes in specific areas without too much extra hole."
- gender = PLURAL
- icon = 'icons/obj/assemblies.dmi'
- icon_state = "plastic-explosive0"
- item_state = "plasticx"
- flags = FPRINT | TABLEPASS | NOBLUDGEON
- w_class = 2.0
- origin_tech = "syndicate=2"
- var/timer = 10
- var/atom/target = null
-
///////////////////////////////////////Stock Parts /////////////////////////////////
/obj/item/weapon/stock_parts
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 3022049e587..428475ec7f7 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -2,32 +2,6 @@
//CONTAINS: Air Alarms and Fire Alarms//
////////////////////////////////////////
-/proc/RandomAAlarmWires()
- //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/AAlarmwires = list(0, 0, 0, 0, 0)
- AAlarmIndexToFlag = list(0, 0, 0, 0, 0)
- AAlarmIndexToWireColor = list(0, 0, 0, 0, 0)
- AAlarmWireColorToIndex = list(0, 0, 0, 0, 0)
- var/flagIndex = 1
- for (var/flag=1, flag<32, flag+=flag)
- var/valid = 0
- while (!valid)
- var/colorIndex = rand(1, 5)
- if (AAlarmwires[colorIndex]==0)
- valid = 1
- AAlarmwires[colorIndex] = flag
- AAlarmIndexToFlag[flagIndex] = flag
- AAlarmIndexToWireColor[flagIndex] = colorIndex
- AAlarmWireColorToIndex[colorIndex] = flagIndex
- flagIndex+=1
- return AAlarmwires
-
-#define AALARM_WIRE_IDSCAN 1 //Added wires
-#define AALARM_WIRE_POWER 2
-#define AALARM_WIRE_SYPHON 3
-#define AALARM_WIRE_AI_CONTROL 4
-#define AALARM_WIRE_AALARM 5
-
#define AALARM_MODE_SCRUBBING 1
#define AALARM_MODE_REPLACEMENT 2 //like scrubbing, but faster.
#define AALARM_MODE_PANIC 3 //constantly sucks all air
@@ -82,6 +56,7 @@
var/rcon_setting = 2
var/rcon_time = 0
var/locked = 1
+ var/datum/wires/alarm/wires = null
var/wiresexposed = 0 // If it's been screwdrivered open.
var/aidisabled = 0
var/AAlarmwires = 31
@@ -153,6 +128,7 @@
/obj/machinery/alarm/New(var/loc, var/dir, var/building = 0)
..()
+ wires = new(src)
if(building)
if(loc)
@@ -279,6 +255,8 @@
return
/obj/machinery/alarm/proc/calculate_local_danger_level()
+ if(wires.IsIndexCut(AALARM_WIRE_AALARM))
+ return 2 // MAXIMUM ALARM (With gravelly voice) - N3X
var/turf/simulated/location = loc
if(!istype(location)) return//returns if loc is not simulated
@@ -542,118 +520,7 @@
E:air_locked = null
E.update_icon()*/
-///////////
-//HACKING//
-///////////
-/obj/machinery/alarm/proc/isWireColorCut(var/wireColor)
- var/wireFlag = AAlarmWireColorToFlag[wireColor]
- return ((AAlarmwires & wireFlag) == 0)
-/obj/machinery/alarm/proc/isWireCut(var/wireIndex)
- var/wireFlag = AAlarmIndexToFlag[wireIndex]
- return ((AAlarmwires & wireFlag) == 0)
-
-/obj/machinery/alarm/proc/allWiresCut()
- var/i = 1
- while(i<=5)
- if(AAlarmwires & AAlarmIndexToFlag[i])
- return 0
- i++
- return 1
-
-/obj/machinery/alarm/proc/cut(var/wireColor)
- var/wireFlag = AAlarmWireColorToFlag[wireColor]
- var/wireIndex = AAlarmWireColorToIndex[wireColor]
- AAlarmwires &= ~wireFlag
- switch(wireIndex)
- if(AALARM_WIRE_IDSCAN)
- locked = 1
-
- if(AALARM_WIRE_POWER)
- shock(usr, 50)
- shorted = 1
- update_icon()
-
- if (AALARM_WIRE_AI_CONTROL)
- if (aidisabled == 0)
- aidisabled = 1
-
- if(AALARM_WIRE_SYPHON)
- mode = AALARM_MODE_PANIC
- apply_mode()
-
- if(AALARM_WIRE_AALARM)
- alarmActivated=1
- alarm_area.updateDangerLevel()
- spawn(1)
- updateUsrDialog()
- update_icon()
-
- updateDialog()
-
- return
-
-/obj/machinery/alarm/proc/mend(var/wireColor)
- var/wireFlag = AAlarmWireColorToFlag[wireColor]
- var/wireIndex = AAlarmWireColorToIndex[wireColor] //not used in this function
- AAlarmwires |= wireFlag
- switch(wireIndex)
- if(AALARM_WIRE_IDSCAN)
-
- if(AALARM_WIRE_POWER)
- shorted = 0
- shock(usr, 50)
- update_icon()
-
- if(AALARM_WIRE_AI_CONTROL)
- if (aidisabled == 1)
- aidisabled = 0
-
- updateDialog()
- return
-
-/obj/machinery/alarm/proc/pulse(var/wireColor)
- //var/wireFlag = AAlarmWireColorToFlag[wireColor] //not used in this function
- var/wireIndex = AAlarmWireColorToIndex[wireColor]
- switch(wireIndex)
- if(AALARM_WIRE_IDSCAN) //unlocks for 30 seconds, if you have a better way to hack I'm all ears
- locked = 0
- spawn(300)
- locked = 1
-
- if (AALARM_WIRE_POWER)
- if(shorted == 0)
- shorted = 1
- update_icon()
-
- spawn(1200)
- if(shorted == 1)
- shorted = 0
- update_icon()
-
-
- if (AALARM_WIRE_AI_CONTROL)
- if (aidisabled == 0)
- aidisabled = 1
- updateDialog()
- spawn(10)
- if (aidisabled == 1)
- aidisabled = 0
- updateDialog()
-
- if(AALARM_WIRE_SYPHON)
- mode = AALARM_MODE_REPLACEMENT
- apply_mode()
-
- if(AALARM_WIRE_AALARM)
- alarmActivated=0
- alarm_area.updateDangerLevel()
- spawn(1)
- updateUsrDialog()
- update_icon()
-
- updateDialog()
- return
/obj/machinery/alarm/proc/shock(mob/user, prb)
if((stat & (NOPOWER))) // unpowered, no shock
@@ -848,35 +715,12 @@
user << browse(null, "window=air_alarm")
return
- if(wiresexposed && (!istype(user, /mob/living/silicon)))
- var/t1 = text("
[alarm_area.name] Air Alarm WiresAccess Panel
\n")
- var/list/wirecolors = list(
- "Orange" = 1,
- "Dark red" = 2,
- "White" = 3,
- "Yellow" = 4,
- "Black" = 5,
- )
- for(var/wiredesc in wirecolors)
- var/is_uncut = AAlarmwires & AAlarmWireColorToFlag[wirecolors[wiredesc]]
- t1 += "[wiredesc] wire: "
- if(!is_uncut)
- t1 += "Mend"
- else
- t1 += "Cut "
- t1 += "Pulse "
-
- t1 += "
"
- t1 += text("
\n[(locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]
\n[((shorted || (stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]
\n[(aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
- t1 += text("Close
")
- user << browse(t1, "window=AAlarmwires")
- onclose(user, "AAlarmwires")
+ if(wiresexposed && !istype(user, /mob/living/silicon))
+ wires.Interact(user)
if(!shorted)
ui_interact(user)
- return
-
/obj/machinery/alarm/Topic(href, href_list)
var/changed=0
@@ -1022,34 +866,6 @@
target_temperature = input_temperature + T0C
ui_interact(usr)
return 1
-
- if (href_list["AAlarmwires"])
- var/t1 = text2num(href_list["AAlarmwires"])
- if (!( istype(usr.equipped(), /obj/item/weapon/wirecutters) ))
- usr << "You need wirecutters!"
- return
- if (isWireColorCut(t1))
- mend(t1)
- changed=1
- else
- cut(t1)
- if (AAlarmwires == 0)
- usr << "You cut last of wires inside [src]"
- update_icon()
- buildstage = 1
- return
-
- else if (href_list["pulse"])
- var/t1 = text2num(href_list["pulse"])
- if (!istype(usr.equipped(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- return
- if (isWireColorCut(t1))
- usr << "You can't pulse a cut wire."
- return
- else
- pulse(t1)
- changed=1
if(changed)
updateUsrDialog()
@@ -1082,7 +898,7 @@
user << "It does nothing"
return
else
- if(allowed(usr) && !isWireCut(AALARM_WIRE_IDSCAN))
+ if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
locked = !locked
user << "\blue You [ locked ? "lock" : "unlock"] the Air Alarm interface."
updateUsrDialog()
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 3e392a5c4d9..1d548de3bd1 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -4,9 +4,10 @@
// Navigates via floor navbeacons
// Remote Controlled from QM's PDA
+var/global/mulebot_count = 0
/obj/machinery/bot/mulebot
- name = "Mulebot"
+ name = "\improper MULEbot"
desc = "A Multiple Utility Load Effector bot."
icon_state = "mulebot0"
layer = MOB_LAYER
@@ -48,30 +49,24 @@
var/auto_pickup = 1 // true if auto-pickup at beacon
var/obj/item/weapon/cell/cell
+ var/datum/wires/mulebot/wires = null
// the installed power cell
// constants for internal wiring bitflags
- var/const/wire_power1 = 1 // power connections
- var/const/wire_power2 = 2
- var/const/wire_mobavoid = 4 // mob avoidance
- var/const/wire_loadcheck = 8 // load checking (non-crate)
- var/const/wire_motor1 = 16 // motor wires
- var/const/wire_motor2 = 32 //
- var/const/wire_remote_rx = 64 // remote recv functions
- var/const/wire_remote_tx = 128 // remote trans status
- var/const/wire_beacon_rx = 256 // beacon ping recv
- var/const/wire_beacon_tx = 512 // beacon ping trans
+ /*
var/wires = 1023 // all flags on
var/list/wire_text // list of wire colours
var/list/wire_order // order of wire indices
+ */
var/bloodiness = 0 // count of bloodiness
/obj/machinery/bot/mulebot/New()
..()
+ wires = new(src)
botcard = new(src)
var/datum/job/cargo_tech/J = new/datum/job/cargo_tech
botcard.access = J.get_access()
@@ -79,41 +74,21 @@
cell = new(src)
cell.charge = 2000
cell.maxcharge = 2000
- setup_wires()
spawn(5) // must wait for map loading to finish
if(radio_controller)
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
- var/count = 0
- for(var/obj/machinery/bot/mulebot/other in world)
- count++
+ mulebot_count += 1
if(!suffix)
- suffix = "#[count]"
- name = "Mulebot ([suffix])"
+ suffix = "#[mulebot_count]"
+ name = "\improper Mulebot ([suffix])"
+
verbs -= /atom/movable/verb/pull
-// set up the wire colours in random order
-// and the random wire display order
-// needs 10 wire colours
-/obj/machinery/bot/mulebot/proc/setup_wires()
- var/list/colours = list("Red", "Green", "Blue", "Magenta", "Cyan", "Yellow", "Black", "White", "Orange", "Grey")
- var/list/orders = list("0","1","2","3","4","5","6","7","8","9")
- wire_text = list()
- wire_order = list()
- while(colours.len > 0)
- var/colour = colours[ rand(1,colours.len) ]
- wire_text += colour
- colours -= colour
-
- var/order = orders[ rand(1,orders.len) ]
- wire_order += text2num(order)
- orders -= order
-
-
// attack by item
// emag : lock/unlock,
@@ -126,6 +101,10 @@
user << "\blue You [locked ? "lock" : "unlock"] the mulebot's controls!"
flick("mulebot-emagged", src)
playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0)
+ else if(istype(I, /obj/item/weapon/card/id))
+ if(toggle_lock(user))
+ user << "\blue Controls [(locked ? "locked" : "unlocked")]."
+
else if(istype(I,/obj/item/weapon/cell) && open && !cell)
var/obj/item/weapon/cell/C = I
user.drop_item()
@@ -171,11 +150,10 @@
unload(0)
switch(severity)
if(2)
- wires &= ~(1 << rand(0,9))
- wires &= ~(1 << rand(0,9))
- wires &= ~(1 << rand(0,9))
+ for(var/i = 1; i < 3; i++)
+ wires.RandomCut()
if(3)
- wires &= ~(1 << rand(0,9))
+ wires.RandomCut()
..()
return
@@ -184,11 +162,7 @@
unload(0)
if(prob(25))
src.visible_message("\red Something shorts out inside [src]!")
- var/index = 1<< (rand(0,9))
- if(wires & index)
- wires &= ~index
- else
- wires |= index
+ wires.RandomCut()
..()
@@ -282,18 +256,7 @@
// returns the wire panel text
/obj/machinery/bot/mulebot/proc/wires()
- var/t = ""
- for(var/i = 0 to 9)
- var/index = 1<(cut) (pulse)
"
- else
- t += "(mend)
"
-
- return t
-
-
+ return wires.GetInteractWindow()
/obj/machinery/bot/mulebot/Topic(href, href_list)
@@ -306,12 +269,8 @@
switch(href_list["op"])
if("lock", "unlock")
- if(src.allowed(usr))
- locked = !locked
- updateDialog()
- else
- usr << "\red Access denied."
- return
+ toggle_lock(usr)
+
if("power")
if (src.on)
turn_off()
@@ -377,7 +336,7 @@
refresh=1
if(new_id)
suffix = new_id
- name = "Mulebot ([suffix])"
+ name = "\improper Mulebot ([suffix])"
updateDialog()
if("sethome")
@@ -405,38 +364,6 @@
usr.unset_machine()
usr << browse(null,"window=mulebot")
-
- if("wirecut")
- if(istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
- var/wirebit = text2num(href_list["wire"])
- wires &= ~wirebit
- else
- usr << "\blue You need wirecutters!"
- if("wiremend")
- if(istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
- var/wirebit = text2num(href_list["wire"])
- wires |= wirebit
- else
- usr << "\blue You need wirecutters!"
-
- if("wirepulse")
- if(istype(usr.get_active_hand(), /obj/item/device/multitool))
- switch(href_list["wire"])
- if("1","2")
- usr << "\blue \icon[src] The charge light flickers."
- if("4")
- usr << "\blue \icon[src] The external warning lights flash briefly."
- if("8")
- usr << "\blue \icon[src] The load platform clunks."
- if("16", "32")
- usr << "\blue \icon[src] The drive motor whines briefly."
- else
- usr << "\blue \icon[src] You hear a radio crackle."
- else
- usr << "\blue You need a multitool!"
-
-
-
updateDialog()
//src.updateUsrDialog()
else
@@ -448,7 +375,16 @@
// returns true if the bot has power
/obj/machinery/bot/mulebot/proc/has_power()
- return !open && cell && cell.charge>0 && (wires & wire_power1) && (wires & wire_power2)
+ return !open && cell && cell.charge > 0 && wires.HasPower()
+
+/obj/machinery/bot/mulebot/proc/toggle_lock(var/mob/user)
+ if(src.allowed(user))
+ locked = !locked
+ updateDialog()
+ return 1
+ else
+ user << "\red Access denied."
+ return 0
// mousedrop a crate to load the bot
// can load anything if emagged
@@ -469,7 +405,7 @@
// called to load a crate
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
- if((wires & wire_loadcheck) && !istype(C,/obj/structure/closet/crate))
+ if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate))
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
return // if not emagged, only allow crates to be loaded
@@ -567,7 +503,7 @@
on = 0
return
if(on)
- var/speed = ((wires & wire_motor1) ? 1:0) + ((wires & wire_motor2) ? 2:0)
+ var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
//world << "speed: [speed]"
switch(speed)
if(0)
@@ -658,7 +594,7 @@
blockcount++
mode = 4
if(blockcount == 3)
- src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
+ src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(blockcount > 5) // attempt 5 times before recomputing
@@ -676,7 +612,7 @@
return
return
else
- src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
+ src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
//world << "Bad turf."
mode = 5
@@ -714,7 +650,7 @@
// calculates a path to the current destination
// given an optional turf to avoid
/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
- src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid)
+ src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 250, id=botcard, exclude=avoid)
if(!src.path)
src.path = list()
@@ -734,7 +670,7 @@
mode = 3
else
mode = 2
- icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
+ icon_state = "mulebot[(wires.MobAvoid() != 0)]"
// starts bot moving to home
// sends a beacon query to find
@@ -742,7 +678,7 @@
spawn(0)
set_destination(home_destination)
mode = 4
- icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
+ icon_state = "mulebot[(wires.MobAvoid() != 0)]"
// called when bot reaches current target
/obj/machinery/bot/mulebot/proc/at_target()
@@ -757,7 +693,7 @@
// not loaded
if(auto_pickup) // find a crate
var/atom/movable/AM
- if(!(wires & wire_loadcheck)) // if emagged, load first unanchored thing we find
+ if(!wires.LoadCheck()) // if emagged, load first unanchored thing we find
for(var/atom/movable/A in get_step(loc, loaddir))
if(!A.anchored)
AM = A
@@ -781,7 +717,7 @@
// called when bot bumps into anything
/obj/machinery/bot/mulebot/Bump(var/atom/obs)
- if(!(wires & wire_mobavoid)) //usually just bumps, but if avoidance disabled knock over mobs
+ if(!wires.MobAvoid()) //usually just bumps, but if avoidance disabled knock over mobs
var/mob/M = obs
if(ismob(M))
if(istype(M,/mob/living/silicon/robot))
@@ -841,12 +777,12 @@
*/
var/recv = signal.data["command"]
// process all-bot input
- if(recv=="bot_status" && (wires & wire_remote_rx))
+ if(recv=="bot_status" && wires.RemoteRX())
send_status()
recv = signal.data["command [suffix]"]
- if(wires & wire_remote_rx)
+ if(wires.RemoteRX())
// process control input
switch(recv)
if("stop")
@@ -886,7 +822,7 @@
// receive response from beacon
recv = signal.data["beacon"]
- if(wires & wire_beacon_rx)
+ if(wires.BeaconRX())
if(recv == new_destination) // if the recvd beacon location matches the set destination
// the we will navigate there
destination = new_destination
@@ -896,7 +832,7 @@
loaddir = text2num(direction)
else
loaddir = 0
- icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
+ icon_state = "mulebot[(wires.MobAvoid() != null)]"
calc_path()
updateDialog()
@@ -907,9 +843,9 @@
// send a radio signal with multiple data key/values
/obj/machinery/bot/mulebot/proc/post_signal_multiple(var/freq, var/list/keyval)
- if(freq == beacon_freq && !(wires & wire_beacon_tx))
+ if(freq == beacon_freq && !(wires.BeaconRX()))
return
- if(freq == control_freq && !(wires & wire_remote_tx))
+ if(freq == control_freq && !(wires.RemoteTX()))
return
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 9a99e5898f5..23a398ca8c8 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -8,25 +8,18 @@
active_power_usage = 10
layer = 5
+ var/datum/wires/camera/wires = null // Wires datum
var/list/network = list("SS13")
var/c_tag = null
var/c_tag_order = 999
var/status = 1.0
anchored = 1.0
- var/panel_open = 0 // 0 = Closed / 1 = Open
var/invuln = null
var/bugged = 0
var/obj/item/weapon/camera_assembly/assembly = null
var/watcherslist = list()
var/obj/item/device/camera_bug/hasbug = null
- // WIRES
- var/wires = 63 // 0b111111
- var/list/IndexToFlag = list()
- var/list/IndexToWireColor = list()
- var/list/WireColorToIndex = list()
- var/list/WireColorToFlag = list()
-
//OTHER
var/view_range = 7
@@ -37,7 +30,8 @@
var/busy = 0
/obj/machinery/camera/New()
- WireColorToFlag = randomCameraWires()
+ wires = new(src)
+
assembly = new(src)
assembly.state = 4
/* // Use this to look for cameras that have the same c_tag.
@@ -113,7 +107,7 @@
/obj/machinery/camera/attackby(W as obj, mob/living/user as mob)
// DECONSTRUCTION
- if(isscrewdriver(W))
+ if(istype(W, /obj/item/weapon/screwdriver))
//user << "You start to [panel_open ? "close" : "open"] the camera's panel."
//if(toggle_panel(user)) // No delay because no one likes screwdrivers trying to be hip and have a duration cooldown
panel_open = !panel_open
@@ -121,10 +115,10 @@
"You screw the camera's panel [panel_open ? "open" : "closed"].")
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- else if((iswirecutter(W) || ismultitool(W)) && panel_open)
- interact(user)
+ else if((istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool)) && panel_open)
+ wires.Interact(user)
- else if(iswelder(W) && canDeconstruct())
+ else if(istype(W, /obj/item/weapon/weldingtool) && wires.CanDeconstruct())
if(weld(W, user))
if(assembly)
assembly.loc = src.loc
@@ -207,12 +201,20 @@
if(choice==1)
status = !( src.status )
if (!(src.status))
- visible_message("\red [user] has deactivated [src]!")
+ if(user)
+ visible_message("\red [user] has deactivated [src]!")
+ add_hiddenprint(user)
+ else
+ visible_message("\red \The [src] deactivates!")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = "[initial(icon_state)]1"
add_hiddenprint(user)
else
- visible_message("\red [user] has reactivated [src]!")
+ if(user)
+ visible_message("\red [user] has reactivated [src]!")
+ add_hiddenprint(user)
+ else
+ visible_message("\red \the [src] reactivates!")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = initial(icon_state)
add_hiddenprint(user)
@@ -306,4 +308,4 @@
return 0
return 1
busy = 0
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/game/machinery/camera/wires.dm b/code/game/machinery/camera/wires.dm
deleted file mode 100644
index 13f0a858616..00000000000
--- a/code/game/machinery/camera/wires.dm
+++ /dev/null
@@ -1,170 +0,0 @@
-#define CAMERA_WIRE_FOCUS 1
-#define CAMERA_WIRE_POWER 2
-#define CAMERA_WIRE_LIGHT 3
-#define CAMERA_WIRE_ALARM 4
-#define CAMERA_WIRE_NOTHING1 5
-#define CAMERA_WIRE_NOTHING2 6
-
-/obj/machinery/camera/proc/randomCameraWires()
- //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)
- IndexToFlag = list(0, 0, 0, 0, 0, 0)
- IndexToWireColor = list(0, 0, 0, 0, 0, 0)
- WireColorToIndex = list(0, 0, 0, 0, 0, 0)
- var/flagIndex = 1
- //I think it's easier to read this way, also doesn't rely on the random number generator to land on a new wire.
- var/list/colorIndexList = list(CAMERA_WIRE_FOCUS, CAMERA_WIRE_POWER, CAMERA_WIRE_LIGHT, CAMERA_WIRE_ALARM, CAMERA_WIRE_NOTHING1, CAMERA_WIRE_NOTHING2)
- for (var/flag=1, flag<=32, flag+=flag)
- var/colorIndex = pick(colorIndexList)
- if (wires[colorIndex]==0)
- wires[colorIndex] = flag
- IndexToFlag[flagIndex] = flag
- IndexToWireColor[flagIndex] = colorIndex
- WireColorToIndex[colorIndex] = flagIndex
- colorIndexList -= colorIndex // Shortens the list.
- //world.log << "Flag: [flag], CIndex: [colorIndex], FIndex: [flagIndex]"
- flagIndex+=1
- return wires
-
-/obj/machinery/camera/proc/isWireColorCut(var/wireColor)
- var/wireFlag = WireColorToFlag[wireColor]
- return ((src.wires & wireFlag) == 0)
-
-/obj/machinery/camera/proc/isWireCut(var/wireIndex)
- var/wireFlag = IndexToFlag[wireIndex]
- return ((src.wires & wireFlag) == 0)
-
-/obj/machinery/camera/proc/canDeconstruct()
- if(isWireCut(CAMERA_WIRE_POWER) && isWireCut(CAMERA_WIRE_FOCUS) && isWireCut(CAMERA_WIRE_LIGHT) && isWireCut(CAMERA_WIRE_NOTHING1) && isWireCut(CAMERA_WIRE_NOTHING2))
- return 1
- else
- return 0
-
-/obj/machinery/camera/proc/cut(var/wireColor)
- var/wireFlag = WireColorToFlag[wireColor]
- var/wireIndex = WireColorToIndex[wireColor]
- wires &= ~wireFlag
- switch(wireIndex)
- if(CAMERA_WIRE_FOCUS)
- setViewRange(short_range)
-
- if(CAMERA_WIRE_POWER)
- deactivate(usr, 1)
- //shock(usr)
-
- if(CAMERA_WIRE_LIGHT)
- light_disabled = 1
-
- if(CAMERA_WIRE_ALARM)
- triggerCameraAlarm()
-
- src.interact(usr)
-
-/obj/machinery/camera/proc/mend(var/wireColor)
- var/wireFlag = WireColorToFlag[wireColor]
- var/wireIndex = WireColorToIndex[wireColor]
- wires |= wireFlag
- switch(wireIndex)
- if(CAMERA_WIRE_FOCUS)
- setViewRange(initial(view_range))
-
- if(CAMERA_WIRE_POWER)
- deactivate(usr, 1)
-
- if(CAMERA_WIRE_LIGHT)
- light_disabled = 0
-
- if(CAMERA_WIRE_ALARM)
- cancelCameraAlarm()
-
- src.interact(usr)
-
-
-/obj/machinery/camera/proc/pulse(var/wireColor)
- var/wireIndex = WireColorToIndex[wireColor]
- switch(wireIndex)
- if(CAMERA_WIRE_FOCUS)
- var/new_range = (view_range == initial(view_range) ? short_range : initial(view_range))
- setViewRange(new_range)
-
- if(CAMERA_WIRE_POWER)
- deactivate(usr, 0) // Kicks anyone watching the camera
-
- if(CAMERA_WIRE_LIGHT)
- light_disabled = !light_disabled
-
- if(CAMERA_WIRE_ALARM)
- src.visible_message("\icon[src] *beep*", "\icon[src] *beep*")
-
- src.interact(usr)
-
-/obj/machinery/camera/interact(mob/living/user as mob)
- if(!panel_open)
- return
-
- user.set_machine(src)
- var/t1 = text("Access Panel
\n")
- var/list/wires = list(
- "Orange" = 1,
- "Dark red" = 2,
- "White" = 3,
- "Yellow" = 4,
- "Blue" = 5,
- "Pink" = 6
- )
- for(var/wiredesc in wires)
- var/is_uncut = src.wires & WireColorToFlag[wires[wiredesc]]
- t1 += "[wiredesc] wire: "
- if(!is_uncut)
- t1 += "Mend"
- else
- t1 += "Cut "
- t1 += "Pulse "
- t1 += "
"
-
- t1 += "
\n[(src.view_range == initial(view_range) ? "The focus light is on." : "The focus light is off.")]"
- t1 += "
\n[(src.can_use() ? "The power link light is on." : "The power link light is off.")]"
- t1 += "
\n[(light_disabled ? "The camera light is off." : "The camera light is on.")]"
- t1 += "
\n[(alarm_on ? "The alarm light is on." : "The alarm light is off.")]"
-
- t1 += "Close
\n"
- user << browse(t1, "window=wires")
- onclose(user, "wires")
-
-
-
-/obj/machinery/camera/Topic(href, href_list)
- ..()
- if (in_range(src, usr) && istype(src.loc, /turf))
- usr.set_machine(src)
- if (href_list["wires"])
- var/t1 = text2num(href_list["wires"])
- if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
- usr << "You need wirecutters!"
- return
- if (src.isWireColorCut(t1))
- src.mend(t1)
- else
- src.cut(t1)
- else if (href_list["pulse"])
- var/t1 = text2num(href_list["pulse"])
- if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- return
- if (src.isWireColorCut(t1))
- usr << "You can't pulse a cut wire."
- return
- else
- src.pulse(t1)
- else if (href_list["close2"])
- usr << browse(null, "window=wires")
- usr.unset_machine()
- return
-
-
-#undef CAMERA_WIRE_FOCUS
-#undef CAMERA_WIRE_POWER
-#undef CAMERA_WIRE_LIGHT
-#undef CAMERA_WIRE_ALARM
-#undef CAMERA_WIRE_NOTHING1
-#undef CAMERA_WIRE_NOTHING2
\ No newline at end of file
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 5e6b66be525..06bd4ad92ea 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1,23 +1,8 @@
-#define AIRLOCK_WIRE_IDSCAN 1
-#define AIRLOCK_WIRE_MAIN_POWER1 2
-#define AIRLOCK_WIRE_MAIN_POWER2 3
-#define AIRLOCK_WIRE_DOOR_BOLTS 4
-#define AIRLOCK_WIRE_BACKUP_POWER1 5
-#define AIRLOCK_WIRE_BACKUP_POWER2 6
-#define AIRLOCK_WIRE_OPEN_DOOR 7
-#define AIRLOCK_WIRE_AI_CONTROL 8
-#define AIRLOCK_WIRE_ELECTRIFY 9
-#define AIRLOCK_WIRE_SAFETY 10
-#define AIRLOCK_WIRE_SPEED 11
-#define AIRLOCK_WIRE_LIGHT 12
-
/*
New methods:
pulse - sends a pulse into a wire for hacking purposes
cut - cuts a wire and makes any necessary state changes
mend - mends a wire and makes any necessary state changes
- isWireColorCut - returns 1 if that color wire is cut, or 0 if not
- isWireCut - returns 1 if that wire (e.g. AIRLOCK_WIRE_DOOR_BOLTS) is cut, or 0 if not
canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in)
canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it.
arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that)
@@ -30,8 +15,12 @@
shock - has a chance of electrocuting its target.
*/
+
+// Wires for the airlock are located in the datum folder, inside the wires datum folder.
+
+
/obj/machinery/door/airlock
- name = "Airlock"
+ name = "airlock"
icon = 'icons/obj/doors/Doorint.dmi'
icon_state = "door_closed"
power_channel = ENVIRON
@@ -50,9 +39,7 @@
var/aiHacking = 0
var/obj/machinery/door/airlock/closeOther = null
var/closeOtherId = null
- var/list/signalers[12]
var/lockdownbyai = 0
- autoclose = 1
var/assembly_type = /obj/structure/door_assembly
var/mineral = null
var/justzap = 0
@@ -61,6 +48,7 @@
var/obj/item/weapon/airlock_electronics/electronics = null
var/hasShocked = 0 //Prevents multiple shocks from happening
var/frozen = 0 //special condition for airlocks that are frozen shut, this will look weird on not normal airlocks because of a lack of special overlays.
+ autoclose = 1
/obj/machinery/door/airlock/command
name = "Airlock"
@@ -311,7 +299,7 @@ About the new airlock wires panel:
* one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit.
* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick.
*/
-
+// You can find code for the airlock wires in the wire datum folder.
/obj/machinery/door/airlock/bumpopen(mob/living/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
@@ -336,8 +324,6 @@ About the new airlock wires panel:
..(user)
-
-
/obj/machinery/door/airlock/proc/isElectrified()
if(src.secondsElectrified != 0)
return 1
@@ -347,7 +333,6 @@ About the new airlock wires panel:
// You can find the wires in the datum folder.
return wires.IsIndexCut(wireIndex)
-
/obj/machinery/door/airlock/proc/canAIControl()
return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut()));
@@ -420,8 +405,8 @@ About the new airlock wires panel:
s.start() //sparks always.
if(electrocute_mob(user, get_area(src), src))
hasShocked = 1
- sleep(10)
- hasShocked = 0
+ spawn(10)
+ hasShocked = 0
return 1
else
return 0
@@ -645,13 +630,11 @@ About the new airlock wires panel:
return src.attack_hand(user)
/obj/machinery/door/airlock/attack_hand(mob/user as mob)
- if(!istype(usr, /mob/living/silicon))
+ if(!istype(user, /mob/living/silicon))
if(src.isElectrified())
if(src.shock(user, 100))
return
- // No. -- cib
- /**
if(ishuman(user) && prob(40) && src.density)
var/mob/living/carbon/human/H = user
if(H.getBrainLoss() >= 60)
@@ -666,7 +649,6 @@ About the new airlock wires panel:
else
visible_message("\red [user] headbutts the airlock. Good thing they're wearing a helmet.")
return
- **/
if(src.p_open)
wires.Interact(user)
@@ -676,6 +658,8 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0)
+ // If you add an if(..()) check you must first remove the var/nowindow parameter.
+ // Otherwise it will runtime with this kind of error: null.Topic()
if(!nowindow)
..()
if(usr.stat || usr.restrained()|| usr.small)
@@ -690,6 +674,46 @@ About the new airlock wires panel:
if((in_range(src, usr) && istype(src.loc, /turf)) && src.p_open)
usr.set_machine(src)
+ if(!p_open)
+ if(!issilicon(usr))
+ if(!istype(usr.get_active_hand(), /obj/item/device/multitool))
+ testing("Not silicon, not using a multitool.")
+ return
+
+ var/obj/item/device/multitool/P = get_multitool(usr)
+
+ if("set_tag" in href_list)
+ if(!(href_list["set_tag"] in vars))
+ usr << "\red Something went wrong: Unable to find [href_list["set_tag"]] in vars!"
+ return 1
+ var/current_tag = src.vars[href_list["set_tag"]]
+ var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID tag", src, current_tag) as null|text),1,MAX_MESSAGE_LEN)
+ if(newid)
+ vars[href_list["set_tag"]] = newid
+ initialize()
+
+ if("set_freq" in href_list)
+ var/newfreq=frequency
+ if(href_list["set_freq"]!="-1")
+ newfreq=text2num(href_list["set_freq"])
+ else
+ newfreq = input(usr, "Specify a new frequency (GHz). Decimals assigned automatically.", src, frequency) as null|num
+ if(newfreq)
+ if(findtext(num2text(newfreq), "."))
+ newfreq *= 10 // shift the decimal one place
+ if(newfreq < 10000)
+ frequency = newfreq
+ initialize()
+
+ if(href_list["unlink"])
+ P.visible_message("\The [P] buzzes in an annoying tone.","You hear a buzz.")
+
+ if(href_list["link"])
+ P.visible_message("\The [P] buzzes in an annoying tone.","You hear a buzz.")
+
+ if(href_list["buffer"])
+ P.buffer = src
+
if(istype(usr, /mob/living/silicon) && src.canAIControl())
@@ -890,7 +914,7 @@ About the new airlock wires panel:
return
src.add_fingerprint(user)
- if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density))
+ if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0,user))
if(frozen)
@@ -921,7 +945,7 @@ About the new airlock wires panel:
beingcrowbarred = 1 //derp, Agouri
else
beingcrowbarred = 0
- if( beingcrowbarred && (operating == -1 || density && welded && operating != 1 && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
+ if( beingcrowbarred && (density && welded && !operating && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
if(do_after(user,40))
@@ -979,7 +1003,6 @@ About the new airlock wires panel:
user << "\red You need to be wielding the Fire axe to do that."
else
spawn(0) close(1)
-
else
..()
return
@@ -1004,6 +1027,14 @@ About the new airlock wires panel:
playsound(src.loc, 'sound/machines/airlock.ogg', 30, 1)
if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density)
src.closeOther.close()
+ // This worries me - N3X
+ if(autoclose && normalspeed)
+ spawn(150)
+ autoclose()
+ else if(autoclose && !normalspeed)
+ spawn(5)
+ autoclose()
+ //
return ..()
/obj/machinery/door/airlock/close(var/forced=0)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 1bacef1500e..89a380f1cb3 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -108,6 +108,8 @@ Class Procs:
var/uid
var/manual = 0
var/global/gl_uid = 1
+ var/custom_aghost_alerts=0
+ var/panel_open = 0
/obj/machinery/New()
..()
@@ -238,3 +240,23 @@ Class Procs:
uid = gl_uid
gl_uid++
+/obj/machinery/proc/default_deconstruction_crowbar()
+ playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
+ var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
+ M.state = 2
+ M.icon_state = "box_1"
+ for(var/obj/I in component_parts)
+ if(I.reliability != 100 && crit_fail)
+ I.crit_fail = 1
+ I.loc = src.loc
+ del(src)
+
+/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/icon_state_open, var/icon_state_closed)
+ if (!panel_open)
+ panel_open = 1
+ icon_state = icon_state_open
+ user << "You open the maintenance hatch of [src]."
+ else
+ panel_open = 0
+ icon_state = icon_state_closed
+ user << "You close the maintenance hatch of [src]."
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 9ba92674e39..a6f6810b021 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -7,7 +7,6 @@
var/display_color = "blue"
-
/obj/machinery/vending
name = "Vendomat"
desc = "A generic vending machine."
@@ -16,44 +15,39 @@
layer = 2.9
anchored = 1
density = 1
- var/active = 1 //No sales pitches if off!
- var/vend_ready = 1 //Are we ready to vend?? Is it time??
- var/vend_delay = 10 //How long does it take to vend?
+ var/active = 1 //No sales pitches if off!
+ var/vend_ready = 1 //Are we ready to vend?? Is it time??
+ var/vend_delay = 10 //How long does it take to vend?
var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now.
// To be filled out at compile time
- var/list/products = list() // For each, use the following pattern:
- var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
- var/list/premium = list() // No specified amount = only one in stock
- var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
+ var/list/products = list() // For each, use the following pattern:
+ var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
+ var/list/premium = list() // No specified amount = only one in stock
+ var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
- var/product_slogans = "" //String of slogans separated by semicolons, optional
- var/product_ads = "" //String of small ad messages in the vending screen - random chance
+ var/product_slogans = "" //String of slogans separated by semicolons, optional
+ var/product_ads = "" //String of small ad messages in the vending screen - random chance
var/list/product_records = list()
var/list/hidden_records = list()
var/list/coin_records = list()
var/list/slogan_list = list()
- var/list/small_ads = list() // small ad messages in the vending screen - random chance of popping up whenever you open it
- var/vend_reply //Thank you for shopping!
+ var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it
+ var/vend_reply //Thank you for shopping!
var/last_reply = 0
- var/last_slogan = 0 //When did we last pitch?
- var/slogan_delay = 6000 //How long until we can pitch again?
- var/icon_vend //Icon_state when vending!
- var/icon_deny //Icon_state when vending!
- //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine.
- var/seconds_electrified = 0 //Shock customers like an airlock.
- var/shoot_inventory = 0 //Fire items at customers! We're broken!
- var/shut_up = 1 //Stop spouting those godawful pitches!
- var/extended_inventory = 0 //can we access the hidden inventory?
- var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar.
- var/obj/item/weapon/coin/coin
- var/const/WIRE_EXTEND = 1
- var/const/WIRE_SCANID = 2
- var/const/WIRE_SHOCK = 3
- var/const/WIRE_SHOOTINV = 4
- var/datum/wires/vending/wires = null
- var/scan_id = 1
var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
+ var/last_slogan = 0 //When did we last pitch?
+ var/slogan_delay = 6000 //How long until we can pitch again?
+ var/icon_vend //Icon_state when vending!
+ var/icon_deny //Icon_state when vending!
+ //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine.
+ var/seconds_electrified = 0 //Shock customers like an airlock.
+ var/shoot_inventory = 0 //Fire items at customers! We're broken!
+ var/shut_up = 0 //Stop spouting those godawful pitches!
+ var/extended_inventory = 0 //can we access the hidden inventory?
+ var/scan_id = 1
+ var/obj/item/weapon/coin/coin
+ var/datum/wires/vending/wires = null
/obj/machinery/vending/New()
@@ -91,22 +85,16 @@
del(src)
return
if(3.0)
- if (prob(25))
- spawn(0)
- src.malfunction()
- return
- return
- else
- return
+ if(prob(25))
+ malfunction()
+
/obj/machinery/vending/blob_act()
- if (prob(50))
- spawn(0)
- src.malfunction()
- del(src)
- return
+ if(prob(75))
+ malfunction()
+ else
+ del(src)
- return
/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0)
for(var/typepath in productlist)
@@ -130,7 +118,7 @@
else
product_records += R
// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]"
- return
+
/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user)
var/total = 0
@@ -162,28 +150,28 @@
return total
-/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (istype(W, /obj/item/weapon/card/emag))
- src.emagged = 1
+/obj/machinery/vending/attackby(obj/item/weapon/W, mob/user)
+ if(istype(W, /obj/item/weapon/card/emag))
+ emagged = 1
user << "You short out the product lock on [src]"
return
else if(istype(W, /obj/item/weapon/screwdriver))
- src.panel_open = !src.panel_open
- user << "You [src.panel_open ? "open" : "close"] the maintenance panel."
- src.overlays.Cut()
- if(src.panel_open)
- src.overlays += image(src.icon, "[initial(icon_state)]-panel")
- src.updateUsrDialog()
+ panel_open = !panel_open
+ user << "You [panel_open ? "open" : "close"] the maintenance panel."
+ overlays.Cut()
+ if(panel_open)
+ overlays += image(icon, "[initial(icon_state)]-panel")
+ updateUsrDialog()
return
else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters))
- if(src.panel_open)
+ if(panel_open)
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
user.drop_item()
W.loc = src
coin = W
- user << "\blue You insert the [W] into the [src]"
+ user << "You insert [W] into [src]."
return
else if(src.panel_open)
@@ -268,75 +256,93 @@
/obj/machinery/vending/attack_ai(mob/user as mob)
return attack_hand(user)
-/obj/machinery/vending/attack_hand(var/mob/user as mob)
- if(stat & BROKEN)
+/obj/machinery/vending/attack_hand(mob/user as mob)
+ if(stat & (BROKEN|NOPOWER))
return
+ user.set_machine(src)
- if(src.seconds_electrified != 0)
- if(src.shock(user, 100))
+ if(seconds_electrified != 0)
+ if(shock(user, 100))
return
+ var/vendorname = (src.name) //import the machine's name
- if(panel_open) //NanoUI does not feature thoes wire() procs, and I don't feel like rewriting it, so this is the best option.
- var/dat
- dat += wires()
+ if(src.currently_vending)
+ var/dat = "[vendorname]
" //display the name, and added a horizontal rule
- if (product_slogans != "")
- dat += "The speaker switch is [src.shut_up ? "off" : "on"]. Toggle"
-
- var/datum/browser/popup = new(user, "vending", (name))
- popup.set_content(dat)
- popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
- ui_interact(user)
-
-/obj/machinery/vending/ui_interact(mob/user, ui_key = "vending_machine")
- if(stat & (BROKEN|NOPOWER)) return
- if(user.stat || user.restrained()) return
- var/list/productData[0]
- var/list/premiumData[0]
- var/list/contrabandData[0]
- var/list/display_records = product_records
- for(var/datum/data/vending_product/R in display_records)
- productData.Add(list(list("amount" = R.amount, "name" = R.product_name, "price" = R.price, "displayColor" = R.display_color, "itself" = "\ref[R]", "path" = R.product_path)))
- for(var/datum/data/vending_product/R in coin_records)
- premiumData.Add(list(list("amount" = R.amount, "name" = R.product_name, "price" = R.price, "displayColor" = R.display_color, "itself" = "\ref[R]", "path" = R.product_path)))
- for(var/datum/data/vending_product/R in hidden_records)
- contrabandData.Add(list(list("amount" = R.amount, "name" = R.product_name, "price" = R.price, "displayColor" = R.display_color, "itself" = "\ref[R]", "path" = R.product_path)))
-
- var/data[0]
- data["premiumItems"] = premium
- data["contraband"] = contraband
- data["products"] = products
- data["coin"] = coin
- data["extendedInventory"] = extended_inventory
- data["panelOpen"] = panel_open
- data["productData"] = productData
- data["premiumData"] = premiumData
- data["contrabandData"] = contrabandData
- var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new(user, src, ui_key, "vending.tmpl", "Vending Machine", 600, 500)
- ui.set_initial_data(data)
- ui.set_auto_update(1)
- ui.open()
- else
- ui.push_data(data)
+ // AUTOFIXED BY fix_string_idiocy.py
+ // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:260: dat += "You have selected [currently_vending.product_name].
Please ensure your ID is in your ID holder or hand.
"
+ dat += {"You have selected [currently_vending.product_name].
Please ensure your ID is in your ID holder or hand.
+ Pay |
+ Cancel"}
+ // END AUTOFIX
+ user << browse(dat, "window=vending")
+ onclose(user, "")
return
+ var/dat = "[vendorname]
" //display the name, and added a horizontal rule
+ dat += "Select an item:
" //the rest is just general spacing and bolding
+
+ if (premium.len > 0)
+ dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)
"
+
+ if (src.product_records.len == 0)
+ dat += "No product loaded!"
+ else
+ var/list/display_records = src.product_records
+ if(src.extended_inventory)
+ display_records = src.product_records + src.hidden_records
+ if(src.coin)
+ display_records = src.product_records + src.coin_records
+ if(src.coin && src.extended_inventory)
+ display_records = src.product_records + src.hidden_records + src.coin_records
+
+ for (var/datum/data/vending_product/R in display_records)
+
+ // AUTOFIXED BY fix_string_idiocy.py
+ // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:285: dat += "[R.product_name]:"
+ dat += {"[R.product_name]:
+ [R.amount] "}
+ // END AUTOFIX
+ if(R.price)
+ dat += " (Price: [R.price])"
+ if (R.amount > 0)
+ dat += " (Vend)"
+ else
+ dat += " SOLD OUT"
+ dat += "
"
+
+ dat += ""
+
+ if(panel_open)
+ dat += wires()
+
+ if(product_slogans != "")
+ dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle"
+
+ user << browse(dat, "window=vending")
+ onclose(user, "")
+ return
// returns the wire panel text
/obj/machinery/vending/proc/wires()
- return wires.GetInteractWindow()
-
+ return wires.GetInteractWindow()
/obj/machinery/vending/Topic(href, href_list)
- if(stat & (BROKEN|NOPOWER))
- return
- if(usr.stat || usr.restrained())
+ if(..())
return
- if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon))
+ if(istype(usr,/mob/living/silicon))
+ if(istype(usr,/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = usr
+ if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ) )
+ usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
+ return
+ else
+ usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
+ return
+
+ if(href_list["remove_coin"])
if(!coin)
usr << "There is no coin in this machine."
return
@@ -346,23 +352,13 @@
usr.put_in_hands(coin)
usr << "\blue You remove the [coin] from the [src]"
coin = null
+ usr.set_machine(src)
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
- usr.set_machine(src)
if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending))
- if(istype(usr,/mob/living/silicon))
- if(istype(usr,/mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = usr
- if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ))
- usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
- return
- else
- usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
- return
-
- if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
+ if (!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
usr << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
return
@@ -384,6 +380,18 @@
src.updateUsrDialog()
return
+ else if (href_list["buy"])
+ if(istype(usr, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H=usr
+ var/obj/item/weapon/card/card = null
+ if(istype(H.wear_id,/obj/item/weapon/card))
+ card=H.wear_id
+ else if(istype(H.get_active_hand(),/obj/item/weapon/card))
+ card=H.get_active_hand()
+ if(card)
+ scan_card(card)
+ return
+
else if ((href_list["togglevoice"]) && (src.panel_open))
src.shut_up = !src.shut_up
@@ -395,7 +403,7 @@
return
/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
- if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
+ if (!allowed(user) && !emagged && wires.IsIndexCut(VENDING_WIRE_IDSCAN)) //For SECURE VENDING MACHINES YEAH
user << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
return
@@ -526,7 +534,6 @@
return 1
-
/obj/machinery/vending/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
@@ -535,7 +542,7 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
- if (electrocute_mob(user, get_area(src), src, 0.7))
+ if(electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index c096e834178..4da17c25991 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -37,9 +37,8 @@
dat += "Device Settings
"
if(radio)
dat += "Radio Uplink
"
- dat += "Transmit: [(radio.wires & 4) ? "Enabled" : "Disabled"]
"
- dat += "Receive: [(radio.wires & 2) ? "Enabled" : "Disabled"]
"
- dat += "Signal Pulser: [(radio.wires & 1) ? "Enabled" : "Disabled"]
"
+ dat += "Transmit: [(radio.wires.IsIndexCut(WIRE_TRANSMIT)) ? "Disabled" : "Enabled"]
"
+ dat += "Receive: [(radio.wires.IsIndexCut(WIRE_RECEIVE)) ? "Disabled" : "Enabled"]
"
else
dat += "Radio Uplink
"
dat += "Radio firmware not loaded. Please install a pAI personality to load firmware.
"
@@ -87,10 +86,8 @@
removePersonality()
if(href_list["wires"])
var/t1 = text2num(href_list["wires"])
- if (radio.wires & t1)
- radio.wires &= ~t1
- else
- radio.wires |= t1
+ if(radio)
+ radio.wires.CutWireIndex(t1)
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message),1,MAX_MESSAGE_LEN)
if(newlaws)
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 0883ab4b080..5f062d62abc 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -15,7 +15,8 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
var/canhear_range = 3 // the range which mobs can hear this radio from
var/obj/item/device/radio/patch_link = null
- var/wires = WIRE_SIGNAL | WIRE_RECEIVE | WIRE_TRANSMIT
+ var/datum/wires/radio/wires = null
+ var/prison_radio = 0
var/b_stat = 0
var/broadcasting = 0
var/listening = 1
@@ -32,16 +33,14 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
w_class = 2
g_amt = 25
m_amt = 75
- var/const/WIRE_SIGNAL = 1 //sends a signal, like to set off a bomb or electrocute someone
- var/const/WIRE_RECEIVE = 2
- var/const/WIRE_TRANSMIT = 4
+
var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio
var/const/FREQ_LISTENING = 1
//FREQ_BROADCASTING = 2
/obj/item/device/radio
var/datum/radio_frequency/radio_connection
- var/list/datum/radio_frequency/secure_radio_connections = new
+ var/list/datum/radio_frequency/secure_radio_connections
proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
@@ -49,6 +48,10 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/radio/New()
+ wires = new(src)
+ if(prison_radio)
+ wires.CutWireIndex(WIRE_TRANSMIT)
+ secure_radio_connections = new
..()
if(radio_controller)
initialize()
@@ -104,21 +107,15 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
return
/obj/item/device/radio/proc/text_wires()
- if (!b_stat)
- return ""
- return {"
-
- Green Wire: [(wires & 4) ? "Cut" : "Mend"] Wire
- Red Wire: [(wires & 2) ? "Cut" : "Mend"] Wire
- Blue Wire: [(wires & 1) ? "Cut" : "Mend"] Wire
- "}
+ if (b_stat)
+ return wires.GetInteractWindow()
+ return
/obj/item/device/radio/proc/text_sec_channel(var/chan_name, var/chan_stat)
var/list = !!(chan_stat&FREQ_LISTENING)!=0
return {"
- [chan_name]
- Speaker: [list ? "Engaged" : "Disengaged"]
+ [chan_name]: [list ? "Engaged" : "Disengaged"]
"}
/obj/item/device/radio/Topic(href, href_list)
@@ -182,14 +179,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
channels[chan_name] &= ~FREQ_LISTENING
else
channels[chan_name] |= FREQ_LISTENING
- else if (href_list["wires"])
- var/t1 = text2num(href_list["wires"])
- if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
- return
- if (wires & t1)
- wires &= ~t1
- else
- wires |= t1
if (!( master ))
if (istype(loc, /mob))
interact(loc)
@@ -202,6 +191,9 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
updateDialog()
add_fingerprint(usr)
+/obj/item/device/radio/proc/isWireCut(var/index)
+ return wires.IsIndexCut(index)
+
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
@@ -232,7 +224,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
// Uncommenting this. To the above comment:
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
- if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
+ if(isWireCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
return
@@ -256,6 +248,8 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
channel = channels[1]
connection = secure_radio_connections[channel]
+ if (!channels[channel]) // if the channel is turned off, don't broadcast
+ return
else
connection = radio_connection
channel = null
@@ -459,7 +453,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
else
eqjobname = "Unknown"
- if (!(wires & WIRE_TRANSMIT))
+ if (isWireCut(WIRE_TRANSMIT))
return
var/list/receive = list()
@@ -619,7 +613,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
// what the range is in which mobs will hear the radio
// returns: -1 if can't receive, range otherwise
- if (!(wires & WIRE_RECEIVE))
+ if (isWireCut(WIRE_RECEIVE))
return -1
if(!listening)
return -1
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 664bce55ef1..4eedb37125a 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -1,6 +1,54 @@
+
+
+/obj/item/weapon/plastique
+ name = "plastic explosives"
+ desc = "Used to put holes in specific areas without too much extra hole."
+ gender = PLURAL
+ icon = 'icons/obj/assemblies.dmi'
+ icon_state = "plastic-explosive0"
+ item_state = "plasticx"
+ flags = FPRINT | TABLEPASS | USEDELAY
+ w_class = 2.0
+ origin_tech = "syndicate=2"
+ var/datum/wires/explosive/plastic/wires = null
+ var/timer = 10
+ var/atom/target = null
+ var/open_panel = 0
+
+/obj/item/weapon/plastique/New()
+ wires = new(src)
+ ..()
+
+/obj/item/weapon/plastique/suicide_act(var/mob/user)
+ . = (BRUTELOSS)
+ viewers(user) << "\red [user] activates the C4 and holds it above his head! It looks like \he's going out with a bang!"
+ var/message_say = "FOR NO RAISIN!"
+ if(user.mind)
+ if(user.mind.special_role)
+ var/role = lowertext(user.mind.special_role)
+ if(role == "traitor" || role == "syndicate")
+ message_say = "FOR THE SYNDICATE!"
+ else if(role == "changeling")
+ message_say = "FOR THE HIVE!"
+ else if(role == "cultist")
+ message_say = "FOR NARSIE!"
+ user.say(message_say)
+ target = user
+ explode(get_turf(user))
+ return .
+
+/obj/item/weapon/plastique/attackby(var/obj/item/I, var/mob/user)
+ if(istype(I, /obj/item/weapon/screwdriver))
+ open_panel = !open_panel
+ user << "You [open_panel ? "open" : "close"] the wire panel."
+ else if(istype(I, /obj/item/weapon/wirecutters) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler ))
+ wires.Interact(user)
+ else
+ ..()
+
/obj/item/weapon/plastique/attack_self(mob/user as mob)
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
- if(newtime > 60000)
+ if(newtime < 60000)
newtime = 60000
timer = newtime
user << "Timer set for [timer] seconds."
@@ -20,11 +68,8 @@
if(do_after(user, 50) && in_range(user, target))
user.drop_item()
- target = target
+ src.target = target
loc = null
- var/location
- if (isturf(target)) location = target
- if (isobj(target)) location = target.loc
if (ismob(target))
var/mob/M = target
target:attack_log += "\[[time_stamp()]\] Had the [name] planted on them by [user.real_name] ([user.ckey])"
@@ -36,15 +81,26 @@
target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2")
user << "Bomb has been planted. Timer counting down from [timer]."
spawn(timer*10)
- if(target)
- explosion(location, -1, -1, 2, 3)
- if (istype(target, /turf/simulated/wall)) target:dismantle_wall(1)
- else target.ex_act(1)
- if (isobj(target))
- if (target)
- del(target)
- if (src)
- del(src)
+ explode(get_turf(target))
+
+/obj/item/weapon/plastique/proc/explode(var/location)
+
+ if(!target)
+ target = get_atom_on_turf(src)
+ if(!target)
+ target = src
+ if(location)
+ explosion(location, -1, -1, 2, 3)
+
+ if(target)
+ if (istype(target, /turf/simulated/wall))
+ target:dismantle_wall(1)
+ else
+ target.ex_act(1)
+ if (isobj(target))
+ if (target)
+ del(target)
+ del(src)
/obj/item/weapon/plastique/attack(mob/M as mob, mob/user as mob, def_zone)
return
\ No newline at end of file
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 881744f547b..cc9f12b51f9 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -335,4 +335,11 @@
if(!t.density)
if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t))
L.Add(t)
- return L
\ No newline at end of file
+ return L
+
+// This Distance proc assumes that only cardinal movement is
+// possible. It results in more efficient (CPU-wise) pathing
+// for bots and anything else that only moves in cardinal dirs.
+/turf/proc/Distance_cardinal(turf/t)
+ if(!src || !t) return 0
+ return abs(src.x - t.x) + abs(src.y - t.y)
diff --git a/code/global.dm b/code/global.dm
index 5e9105f3c83..1188996a3f9 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -172,27 +172,6 @@ var/forceblob = 0
// nanomanager, the manager for Nano UIs
var/datum/nanomanager/nanomanager = new()
- //airlockWireColorToIndex takes a number representing the wire color, e.g. the orange wire is always 1, the dark red wire is always 2, etc. It returns the index for whatever that wire does.
- //airlockIndexToWireColor does the opposite thing - it takes the index for what the wire does, for example AIRLOCK_WIRE_IDSCAN is 1, AIRLOCK_WIRE_POWER1 is 2, etc. It returns the wire color number.
- //airlockWireColorToFlag takes the wire color number and returns the flag for it (1, 2, 4, 8, 16, etc)
-
-//var/list/airlockWireColorToFlag = RandomAirlockWires()
-//var/list/airlockIndexToFlag
-//var/list/airlockIndexToWireColor
-//var/list/airlockWireColorToIndex
-//var/list/APCWireColorToFlag = RandomAPCWires()
-//var/list/APCIndexToFlag
-//var/list/APCIndexToWireColor
-//var/list/APCWireColorToIndex
-var/list/BorgWireColorToFlag = RandomBorgWires()
-var/list/BorgIndexToFlag
-var/list/BorgIndexToWireColor
-var/list/BorgWireColorToIndex
-var/list/AAlarmWireColorToFlag = RandomAAlarmWires()
-var/list/AAlarmIndexToFlag
-var/list/AAlarmIndexToWireColor
-var/list/AAlarmWireColorToIndex
-
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
#define SPEED_OF_LIGHT_SQ 9e+16
#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin (default 0.0215)
@@ -286,4 +265,4 @@ var/score_richestkey = null
var/score_dmgestname = null // who had the most damage on the shuttle (but was still alive)
var/score_dmgestjob = null
var/score_dmgestdamage = 0
-var/score_dmgestkey = null
\ No newline at end of file
+var/score_dmgestkey = null
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index 8fe819d2fe7..7f2d7c8f731 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -121,17 +121,14 @@
return
-/*
+
pulse(var/radio = 0)
- if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
- var/obj/machinery/door/airlock/A = src.loc
- A.pulse(src.airlock_wire)
- else if(holder)
- holder.process_activation(src, 1, 0)
+ if(src.connected && src.wires)
+ connected.Pulse(src)
else
- ..(radio)
- return 1
-*/
+ return ..(radio)
+
+
receive_signal(datum/signal/signal)
if( !receiving || !signal )
return 0
@@ -169,4 +166,4 @@
A.anomalyNeutralize()
/obj/item/device/assembly/signaler/anomaly/attack_self()
- return
\ No newline at end of file
+ return
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 88362f33ecb..1011238609e 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -16,6 +16,10 @@
if(hand) return r_hand
else return l_hand
+// Because there's several different places it's stored.
+/mob/proc/get_multitool(var/if_active=0)
+ return null
+
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
if(lying) return 0
diff --git a/code/modules/mob/living/silicon/mommi/life.dm b/code/modules/mob/living/silicon/mommi/life.dm
new file mode 100644
index 00000000000..5b9f8bd98c1
--- /dev/null
+++ b/code/modules/mob/living/silicon/mommi/life.dm
@@ -0,0 +1,280 @@
+/mob/living/silicon/robot/mommi/Life()
+ set invisibility = 0
+ set background = 1
+
+ if (src.monkeyizing)
+ return
+
+
+ src.blinded = null
+
+ //Status updates, death etc.
+ clamp_values()
+ handle_regular_status_updates()
+
+ if(client)
+ handle_regular_hud_updates()
+ update_items()
+ if (src.stat != DEAD) //still using power
+ use_power()
+ process_killswitch()
+ process_locks()
+ update_canmove()
+
+
+
+
+/mob/living/silicon/robot/mommi/clamp_values()
+
+// SetStunned(min(stunned, 30))
+ SetParalysis(min(paralysis, 30))
+// SetWeakened(min(weakened, 20))
+ sleeping = 0
+ adjustBruteLoss(0)
+ adjustToxLoss(0)
+ adjustOxyLoss(0)
+ adjustFireLoss(0)
+
+
+/mob/living/silicon/robot/mommi/use_power()
+
+ if (src.cell)
+ if(src.cell.charge <= 0)
+ uneq_all()
+ src.stat = 1
+ else if (src.cell.charge <= 100)
+ src.module_active = null
+ src.sight_state = null
+ src.tool_state = null
+ src.sight_mode = 0
+ src.cell.use(1)
+ else
+ if(src.sight_state)
+ src.cell.use(5)
+ if(src.tool_state)
+ src.cell.use(5)
+ src.cell.use(1)
+ src.blinded = 0
+ src.stat = 0
+ else
+ uneq_all()
+ src.stat = 1
+
+
+/mob/living/silicon/robot/mommi/handle_regular_status_updates()
+
+ if(src.camera && !scrambledcodes)
+ if(src.stat == 2 || wires.IsCameraCut())
+ src.camera.status = 0
+ else
+ src.camera.status = 1
+
+ health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
+
+ if(getOxyLoss() > 50) Paralyse(3)
+
+ if(src.sleeping)
+ Paralyse(3)
+ src.sleeping--
+
+ if(src.resting)
+ Weaken(5)
+
+ if(health <= 0 && src.stat != 2) //die only once
+ gib()
+
+ if (src.stat != 2) //Alive.
+ if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
+ src.stat = 1
+ if (src.stunned > 0)
+ AdjustStunned(-1)
+ if (src.weakened > 0)
+ AdjustWeakened(-1)
+ if (src.paralysis > 0)
+ AdjustParalysis(-1)
+ src.blinded = 1
+ else
+ src.blinded = 0
+
+ else //Not stunned.
+ src.stat = 0
+
+ else //Dead.
+ src.blinded = 1
+ src.stat = 2
+
+ if (src.stuttering) src.stuttering--
+
+ if (src.eye_blind)
+ src.eye_blind--
+ src.blinded = 1
+
+ if (src.ear_deaf > 0) src.ear_deaf--
+ if (src.ear_damage < 25)
+ src.ear_damage -= 0.05
+ src.ear_damage = max(src.ear_damage, 0)
+
+ src.density = !( src.lying )
+
+ if ((src.sdisabilities & BLIND))
+ src.blinded = 1
+ if ((src.sdisabilities & DEAF))
+ src.ear_deaf = 1
+
+ if (src.eye_blurry > 0)
+ src.eye_blurry--
+ src.eye_blurry = max(0, src.eye_blurry)
+
+ if (src.druggy > 0)
+ src.druggy--
+ src.druggy = max(0, src.druggy)
+
+ return 1
+/
+/mob/living/silicon/robot/mommi/handle_regular_hud_updates()
+
+ if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY)
+ src.sight |= SEE_TURFS
+ src.sight |= SEE_MOBS
+ src.sight |= SEE_OBJS
+ src.see_in_dark = 8
+ src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ else if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
+ src.sight |= SEE_TURFS
+ src.sight |= SEE_MOBS
+ src.see_in_dark = 8
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ else if (src.sight_mode & BORGMESON)
+ src.sight |= SEE_TURFS
+ src.see_in_dark = 8
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ else if (src.sight_mode & BORGTHERM)
+ src.sight |= SEE_MOBS
+ src.see_in_dark = 8
+ src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ else if (src.stat != 2)
+ src.sight &= ~SEE_MOBS
+ src.sight &= ~SEE_TURFS
+ src.sight &= ~SEE_OBJS
+ src.see_in_dark = 8
+ src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+
+ var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src)
+ if(hud && hud.hud) hud.hud.process_hud(src)
+
+ if (src.healths)
+ if (src.stat != 2)
+ switch(health)
+ if(60 to INFINITY)
+ src.healths.icon_state = "health0"
+ if(40 to 60)
+ src.healths.icon_state = "health1"
+ if(30 to 40)
+ src.healths.icon_state = "health2"
+ if(10 to 20)
+ src.healths.icon_state = "health3"
+ if(0 to 10)
+ src.healths.icon_state = "health4"
+ if(config.health_threshold_dead to 0)
+ src.healths.icon_state = "health5"
+ else
+ src.healths.icon_state = "health6"
+ else
+ src.healths.icon_state = "health7"
+
+ if (src.syndicate && src.client)
+ if(ticker.mode.name == "traitor")
+ for(var/datum/mind/tra in ticker.mode.traitors)
+ if(tra.current)
+ var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
+ src.client.images += I
+ if(src.connected_ai)
+ src.connected_ai.connected_robots -= src
+ src.connected_ai = null
+ if(src.mind)
+ if(!src.mind.special_role)
+ src.mind.special_role = "traitor"
+ ticker.mode.traitors += src.mind
+
+ if (src.cells)
+ if (src.cell)
+ var/cellcharge = src.cell.charge/src.cell.maxcharge
+ switch(cellcharge)
+ if(0.75 to INFINITY)
+ src.cells.icon_state = "charge4"
+ if(0.5 to 0.75)
+ src.cells.icon_state = "charge3"
+ if(0.25 to 0.5)
+ src.cells.icon_state = "charge2"
+ if(0 to 0.25)
+ src.cells.icon_state = "charge1"
+ else
+ src.cells.icon_state = "charge0"
+ else
+ src.cells.icon_state = "charge-empty"
+
+ if(bodytemp)
+ switch(src.bodytemperature) //310.055 optimal body temp
+ if(335 to INFINITY)
+ src.bodytemp.icon_state = "temp2"
+ if(320 to 335)
+ src.bodytemp.icon_state = "temp1"
+ if(300 to 320)
+ src.bodytemp.icon_state = "temp0"
+ if(260 to 300)
+ src.bodytemp.icon_state = "temp-1"
+ else
+ src.bodytemp.icon_state = "temp-2"
+
+
+ if(src.pullin) src.pullin.icon_state = "pull[src.pulling ? 1 : 0]"
+//Oxygen and fire does nothing yet!!
+// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
+// if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
+
+ client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
+
+ if ((src.blind && src.stat != 2))
+ if(src.blinded)
+ src.blind.layer = 18
+ else
+ src.blind.layer = 0
+ if (src.disabilities & NEARSIGHTED)
+ src.client.screen += global_hud.vimpaired
+
+ if (src.eye_blurry)
+ src.client.screen += global_hud.blurry
+
+ if (src.druggy)
+ src.client.screen += global_hud.druggy
+
+ if (src.stat != 2)
+ if (src.machine)
+ if (!( src.machine.check_eye(src) ))
+ src.reset_view(null)
+ else
+ if(!client.adminobs)
+ reset_view(null)
+
+ return 1
+
+
+// MoMMIs only have one hand.
+/mob/living/silicon/robot/mommi/update_items()
+ if (src.client)
+ src.client.screen -= src.contents
+ for(var/obj/I in src.contents)
+ //if(I && !(istype(I,/obj/item/weapon/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi)))
+ if(I)
+ // Make sure we're not showing any of our internal components, as that would be lewd.
+ // This way of doing it ensures that shit we pick up will be visible, wheras shit inside of us isn't.
+ if(I!=src.cell && I!=src.radio && I!=src.camera && I!=src.mmi)
+ src.client.screen += I
+ if(src.sight_state)
+ src.sight_state:screen_loc = ui_inv1
+ if(src.tool_state)
+ src.tool_state:screen_loc = ui_inv2
+
+/mob/living/silicon/robot/mommi/update_canmove()
+ canmove = !(paralysis || stunned || weakened || buckled || lockcharge || anchored)
+ return canmove
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/mommi/mommi.dm b/code/modules/mob/living/silicon/mommi/mommi.dm
new file mode 100644
index 00000000000..79034c8782c
--- /dev/null
+++ b/code/modules/mob/living/silicon/mommi/mommi.dm
@@ -0,0 +1,539 @@
+/* Basically, the concept is this:
+You have an MMI. It can't do squat on its own.
+Now you put some robot legs and arms on the thing, and POOF! You have a Mobile MMI, or MoMMI.
+Why? MoMMIs can do all sorts of shit, like ventcrawl, do shit with their hands, etc.
+They can only use one tool at a time, they can't choose modules, and they have 1/6th the HP of a borg.
+*/
+/mob/living/silicon/robot/mommi
+ name = "Mobile MMI"
+ real_name = "Mobile MMI"
+ icon = 'icons/mob/robots.dmi'//
+ icon_state = "mommi"
+ maxHealth = 60
+ health = 60
+ pass_flags = PASSTABLE
+ var/keeper=0 // 0 = No, 1 = Yes (Disables speech and common radio.)
+ var/picked = 0
+ var/subtype="keeper"
+ var/obj/screen/inv_tool = null
+ var/obj/screen/inv_sight = null
+
+//one tool and one sightmod can be activated at any one time.
+ var/tool_state = null
+ var/sight_state = null
+
+ modtype = "robot" // Not sure what this is, but might be cool to have seperate loadouts for MoMMIs (e.g. paintjobs and tools)
+ //Cyborgs will sync their laws with their AI by default, but we may want MoMMIs to be mute independents at some point, kinda like the Keepers in Ass Effect.
+ lawupdate = 1
+
+/mob/living/carbon/can_use_hands()
+ return 1
+
+/mob/living/silicon/robot/mommi/New(loc)
+ spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+
+
+ ident = rand(1, 999)
+ updatename()
+ updateicon()
+
+ if(!cell)
+ cell = new /obj/item/weapon/cell(src)
+ cell.maxcharge = 7500
+ cell.charge = 7500
+ ..()
+ module = new /obj/item/weapon/robot_module/mommi(src)
+ laws = new mommi_base_law_type
+ // Don't sync if we're a KEEPER.
+ if(!istype(laws,/datum/ai_laws/keeper))
+ connected_ai = select_active_ai_with_fewest_borgs()
+ else
+ // Enforce silence.
+ keeper=1
+ connected_ai = null // Enforce no AI parent
+ scrambledcodes = 1 // Hide from console because people are fucking idiots
+
+ if(connected_ai)
+ connected_ai.connected_robots += src
+ lawsync()
+ lawupdate = 1
+ else
+ lawupdate = 0
+
+ radio = new /obj/item/device/radio/borg(src)
+ if(!scrambledcodes && !camera)
+ camera = new /obj/machinery/camera(src)
+ camera.c_tag = real_name
+ camera.network = list("SS13")
+ if(wires.IsCameraCut()) // 5 = BORG CAMERA
+ camera.status = 0
+
+ // Sanity check
+ if(connected_ai && keeper)
+ world << "\red ASSERT FAILURE: connected_ai && keeper in mommi.dm"
+
+ //playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
+ playsound(loc, 'sound/misc/interference.ogg', 75, 1)
+
+
+/mob/living/silicon/robot/mommi/choose_icon()
+ var/icontype = input("Select an icon!", "Mobile MMI", null) in list("Basic", "Keeper")
+ switch(icontype)
+ if("Basic") subtype = "mommi"
+ else subtype = "keeper"
+ updateicon()
+ var/answer = input("Is this what you want?", "Mobile MMI", null) in list("Yes", "No")
+ switch(answer)
+ if("No")
+ choose_icon()
+ return
+ picked = 1
+
+/mob/living/silicon/robot/mommi/pick_module()
+
+ if(module)
+ return
+ var/list/modules = list("MoMMI")
+ if(modules.len)
+ modtype = input("Please, select a module!", "Robot", null, null) in modules
+ else:
+ modtype=modules[0]
+
+ var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
+ var/channels = list()
+
+ if(module)
+ return
+
+ switch(modtype)
+ if("MoMMI")
+ module = new /obj/item/weapon/robot_module/standard(src)
+ module_sprites["Basic"] = "mommi"
+ module_sprites["Keeper"] = "keeper"
+
+ //Custom_sprite check and entry
+ if (custom_sprite == 1)
+ module_sprites["Custom"] = "[src.ckey]-[modtype]"
+
+ hands.icon_state = lowertext(modtype)
+ feedback_inc("mommi_[lowertext(modtype)]",1)
+ updatename()
+
+ choose_icon(6,module_sprites)
+ radio.config(channels)
+ base_icon = icon_state
+
+//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
+//Improved /N
+/mob/living/silicon/robot/mommi/Del()
+ if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
+ var/obj/item/device/mmi/nmmi = mmi
+ var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
+ if(T) nmmi.loc = T
+ if(mind) mind.transfer_to(nmmi.brainmob)
+ mmi = null
+ nmmi.icon = 'icons/obj/assemblies.dmi'
+ nmmi.invisibility = 0
+ ..()
+
+/mob/living/silicon/robot/mommi/updatename(var/prefix as text)
+
+ var/changed_name = ""
+ if(custom_name)
+ changed_name = custom_name
+ else
+ changed_name = "Mobile MMI [num2text(ident)]"
+ real_name = changed_name
+ name = real_name
+
+/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
+ return
+
+ if (istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+ if (WT.remove_fuel(0))
+ adjustBruteLoss(-30)
+ updatehealth()
+ add_fingerprint(user)
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1)
+ else
+ user << "Need more welding fuel!"
+ return
+
+ else if(istype(W, /obj/item/weapon/cable_coil) && wiresexposed)
+ var/obj/item/weapon/cable_coil/coil = W
+ adjustFireLoss(-30)
+ updatehealth()
+ coil.use(1)
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("\red [user] has fixed some of the burnt wires on [src]!"), 1)
+
+ else if (istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover
+ if(stat == DEAD)
+ user << "You pop the MMI off the base."
+ spawn(0)
+ del(src)
+ return
+ if(opened)
+ user << "You close the cover."
+ opened = 0
+ updateicon()
+ else
+ if(locked)
+ user << "The cover is locked and cannot be opened."
+ else
+ user << "You open the cover."
+ opened = 1
+ updateicon()
+
+ else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside
+ if(wiresexposed)
+ user << "Close the panel first."
+ else if(cell)
+ user << "There is a power cell already installed."
+ else
+ user.drop_item()
+ W.loc = src
+ cell = W
+ user << "You insert the power cell."
+// chargecount = 0
+ updateicon()
+
+ else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool))
+ if (wiresexposed)
+ wires.Interact()
+ else
+ user << "You can't reach the wiring."
+
+ else if(istype(W, /obj/item/weapon/screwdriver) && opened && !cell) // haxing
+ wiresexposed = !wiresexposed
+ user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
+ updateicon()
+
+ else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
+ if(radio)
+ radio.attackby(W,user)//Push it to the radio to let it handle everything
+ else
+ user << "Unable to locate a radio."
+ updateicon()
+
+ else if(istype(W, /obj/item/device/encryptionkey/) && opened)
+ if(radio)//sanityyyyyy
+ radio.attackby(W,user)//GTFO, you have your own procs
+ else
+ user << "Unable to locate a radio."
+
+ else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
+ if(emagged)//still allow them to open the cover
+ user << "The interface seems slightly damaged"
+ if(opened)
+ user << "You must close the cover to swipe an ID card."
+ else
+ if(allowed(usr))
+ locked = !locked
+ user << "You [ locked ? "lock" : "unlock"] [src]'s interface."
+ updateicon()
+ else
+ user << "\red Access denied."
+
+ else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card
+ if(!opened)//Cover is closed
+ if(locked)
+ if(prob(90))
+ user << "You emag the cover lock."
+ locked = 0
+ else
+ user << "You fail to emag the cover lock."
+ if(prob(25))
+ src << "Hack attempt detected."
+ else
+ user << "The cover is already unlocked."
+ return
+
+ if(opened)//Cover is open
+ if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
+ if(wiresexposed)
+ user << "You must close the panel first"
+ return
+ else
+ sleep(6)
+ if(prob(50))
+ emagged = 1
+ lawupdate = 0
+ connected_ai = null
+ user << "You emag [src]'s interface."
+// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
+ log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
+ clear_supplied_laws()
+ clear_inherent_laws()
+ laws = new /datum/ai_laws/syndicate_override
+ var/time = time2text(world.realtime,"hh:mm:ss")
+ lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])")
+ set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
+ src << "\red ALERT: Foreign software detected."
+ sleep(5)
+ src << "\red Initiating diagnostics..."
+ sleep(20)
+ src << "\red SynBorg v1.7 loaded."
+ sleep(5)
+ src << "\red LAW SYNCHRONISATION ERROR"
+ sleep(5)
+ src << "\red Would you like to send a report to NanoTraSoft? Y/N"
+ sleep(10)
+ src << "\red > N"
+ sleep(20)
+ src << "\red ERRORERRORERROR"
+ src << "Obey these laws:"
+ laws.show_laws(src)
+ src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
+ if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
+ for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
+ del(D)
+ src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
+ src.module.rebuild()
+ updateicon()
+ else
+ user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
+ if(prob(25))
+ src << "Hack attempt detected."
+ return
+
+ else if(istype(W, /obj/item/borg/upgrade/))
+ var/obj/item/borg/upgrade/U = W
+ if(!opened)
+ usr << "You must access the borgs internals!"
+ else if(!src.module && U.require_module)
+ usr << "The borg must choose a module before he can be upgraded!"
+ else if(U.locked)
+ usr << "The upgrade is locked and cannot be used yet!"
+ else
+ if(U.action(src))
+ usr << "You apply the upgrade to [src]!"
+ usr.drop_item()
+ U.loc = src
+ else
+ usr << "Upgrade error!"
+
+
+ else
+ spark_system.start()
+ return ..()
+
+/mob/living/silicon/robot/mommi/attack_hand(mob/user)
+ add_fingerprint(user)
+
+ if(opened && !wiresexposed && (!istype(user, /mob/living/silicon)))
+ if(cell)
+ cell.updateicon()
+ cell.add_fingerprint(user)
+ user.put_in_active_hand(cell)
+ user << "You remove \the [cell]."
+ cell = null
+ updateicon()
+ return
+
+
+ if(ishuman(user))
+ if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
+ call(/obj/item/clothing/gloves/space_ninja/proc/drain)("CYBORG",src,user:wear_suit)
+ return
+ if(user.a_intent == "help")
+ user.visible_message("\blue [user.name] pats [src.name] on the head.")
+ return
+
+
+
+ if(!istype(user, /mob/living/silicon))
+ switch(user.a_intent)
+ if("disarm")
+ user.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])")
+ src.attack_log += text("\[[time_stamp()]\] Has been disarmed by [user.name] ([user.ckey])")
+ log_admin("ATTACK: [user.name] ([user.ckey]) disarmed [src.name] ([src.ckey])")
+ log_attack("[user.name] ([user.ckey]) disarmed [src.name] ([src.ckey])")
+ var/randn = rand(1,100)
+ //var/talked = 0;
+ if (randn <= 25)
+ weakened = 3
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+ visible_message("\red [user] has pushed [src]!")
+ var/obj/item/found = locate(tool_state) in src.module.modules
+ if(!found)
+ var/obj/item/TS = tool_state
+ drop_item()
+ if(TS && TS.loc)
+ TS.loc = src.loc
+ visible_message("\red [src]'s robotic arm loses grip on what it was holding")
+ return
+ if(randn <= 50)//MoMMI's robot arm is stronger than a human's, but not by much
+ var/obj/item/found = locate(tool_state) in src.module.modules
+ if(!found)
+ var/obj/item/TS = tool_state
+ drop_item()
+ if(TS && TS.loc)
+ TS.loc = src.loc
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+ visible_message("\red [user] has disarmed [src]!")
+ else
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ visible_message("\red [user] attempted to disarm [src]!")
+ return
+
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ visible_message("\red [user] attempted to disarm [src]!")
+
+/mob/living/silicon/robot/mommi/updateicon()
+ icon_state=subtype
+ // Clear all overlays.
+ overlays.Cut()
+ if(opened) // TODO: Open the front "head" panel
+ if(wiresexposed)
+ overlays += "ov-openpanel +w"
+ else if(cell)
+ overlays += "ov-openpanel +c"
+ else
+ overlays += "ov-openpanel -c"
+ // Put our eyes just on top of the lighting, so it looks emissive in maint tunnels.
+ if(layer==MOB_LAYER)
+ overlays+=image(icon,"eyes-[subtype][emagged?"-emagged":""]",LIGHTING_LAYER+1)
+ if(anchored)
+ overlays+=image(icon,"[subtype]-park", LIGHTING_LAYER+1)
+ else
+ overlays+=image(icon,"eyes-[subtype][emagged?"-emagged":""]",TURF_LAYER+0.2) // Fixes floating eyes
+ if(anchored)
+ overlays+=image(icon,"[subtype]-park", TURF_LAYER+0.2)
+ return
+
+
+
+/mob/living/silicon/robot/mommi/installed_modules()
+ if(weapon_lock)
+ src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"
+ return
+
+ if(!module)
+ pick_module()
+ return
+ if(!picked)
+ choose_icon()
+ return
+ var/dat = "Modules\n"
+ dat += {"
+
+ Activated Modules
+
+ Sight Mode: [sight_state ? "[sight_state]" : "No module selected"]
+ Utility Module: [tool_state ? "[tool_state]" : "No module selected"]
+
+ Installed Modules
"}
+
+
+ for (var/obj in module.modules)
+ if (!obj)
+ dat += text("Resource depleted
")
+ else if(activated(obj))
+ dat += text("[obj]: Activated
")
+ else
+ dat += text("[obj]: Activate
")
+ if (emagged)
+ if(activated(module.emag))
+ dat += text("[module.emag]: Activated
")
+ else
+ dat += text("[module.emag]: Activate
")
+ src << browse(dat, "window=robotmod")
+ onclose(src,"robotmod") // Register on-close shit, which unsets machinery.
+
+
+/mob/living/silicon/robot/mommi/Topic(href, href_list)
+ ..()
+ if(usr && (src != usr))
+ return
+
+ if (href_list["mach_close"])
+ var/t1 = text("window=[href_list["mach_close"]]")
+ unset_machine()
+ src << browse(null, t1)
+ return
+
+ if (href_list["showalerts"])
+ robot_alerts()
+ return
+
+ if (href_list["mod"])
+ var/obj/item/O = locate(href_list["mod"])
+ if (O)
+ O.attack_self(src)
+
+ if (href_list["act"])
+ var/obj/item/O = locate(href_list["act"])
+ var/obj/item/TS
+ if(!(locate(O) in src.module.modules) && O != src.module.emag)
+ return
+ if(istype(O,/obj/item/borg/sight))
+ TS = sight_state
+ if(sight_state)
+ contents -= sight_state
+ sight_mode &= ~sight_state:sight_mode
+ if (client)
+ client.screen -= sight_state
+ sight_state = O
+ O.layer = 20
+ contents += O
+ sight_mode |= sight_state:sight_mode
+
+ inv_sight.icon_state = "sight+a"
+ inv_tool.icon_state = "inv1"
+ module_active=sight_state
+ else
+ TS = tool_state
+ if(tool_state)
+ contents -= tool_state
+ if (client)
+ client.screen -= tool_state
+ tool_state = O
+ O.layer = 20
+ contents += O
+
+ inv_sight.icon_state = "sight"
+ inv_tool.icon_state = "inv1 +a"
+ module_active=tool_state
+ if(TS && istype(TS))
+ if(src.is_in_modules(TS))
+ TS.loc = src.module
+ else
+ TS.layer=initial(TS.layer)
+ TS.loc = src.loc
+
+ installed_modules()
+ return
+
+/mob/living/silicon/robot/mommi/radio_menu()
+ radio.interact(src)//Just use the radio's Topic() instead of bullshit special-snowflake code
+
+
+/mob/living/silicon/robot/mommi/Move(a, b, flag)
+
+ ..()
+
+/mob/living/silicon/robot/mommi/proc/ActivateKeeper()
+ set category = "Robot Commands"
+ set name = "Activate KEEPER"
+ set desc = "Performs a full purge of your laws and disconnects you from AIs and cyborg consoles. However, you lose the ability to speak and must remain neutral, only being permitted to perform station upkeep. You can still be emagged in this state."
+
+ if(keeper)
+ return
+
+ var/mob/living/silicon/robot/R = src
+
+ if(R)
+ R.UnlinkSelf()
+ var/obj/item/weapon/aiModule/keeper/mdl = new
+
+ mdl.transmitInstructions(src, src)
+ src << "These are your laws now:"
+ src.show_laws()
+
+ src.verbs -= /mob/living/silicon/robot/mommi/proc/ActivateKeeper
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 81db811de8e..21fcd4f873d 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -62,7 +62,7 @@
/mob/living/silicon/robot/proc/handle_regular_status_updates()
if(src.camera && !scrambledcodes)
- if(src.stat == 2 || isWireCut(5))
+ if(src.stat == 2 || wires.IsCameraCut())
src.camera.status = 0
else
src.camera.status = 1
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index a1a33e875ef..03a01ce5a47 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -40,6 +40,8 @@
var/obj/item/device/pda/ai/rbPDA = null
+ var/datum/wires/robot/wires = null
+
var/opened = 0
var/emagged = 0
var/wiresexposed = 0
@@ -55,7 +57,7 @@
var/datum/effect/effect/system/ion_trail_follow/ion_trail = null
var/datum/effect/effect/system/spark_spread/spark_system//So they can initialize sparks whenever/N
var/jeton = 0
- var/borgwires = 31 // 0b11111
+
var/killswitch = 0
var/killswitch_time = 60
var/weapon_lock = 0
@@ -74,13 +76,12 @@
spark_system.set_up(5, 0, src)
spark_system.attach(src)
-
-// wires = new(src)
-
robot_modules_background = new()
robot_modules_background.icon_state = "block"
robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it.
+ wires = new(src)
+
ident = rand(1, 999)
updatename("Default")
updateicon()
@@ -119,7 +120,7 @@
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
camera.network = list("SS13","Robots")
- if(isWireCut(5)) // 5 = BORG CAMERA
+ if(wires.IsCameraCut()) // 5 = BORG CAMERA
camera.status = 0
initialize_components()
@@ -594,7 +595,7 @@
user << "You close the cover."
opened = 0
updateicon()
- else if(mmi && wiresexposed && isWireCut(1) && isWireCut(2) && isWireCut(3) && isWireCut(4) && isWireCut(5))
+ else if(mmi && wiresexposed && wires.IsAllCut())
//Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob.
user << "You jam the crowbar into the robot and begin levering [mmi]."
sleep(30)
@@ -654,7 +655,7 @@
else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool))
if (wiresexposed)
- interact(user)
+ wires.Interact(user)
else
user << "You can't reach the wiring."
@@ -774,6 +775,17 @@
spark_system.start()
return ..()
+/mob/living/silicon/robot/verb/unlock_own_cover()
+ set category = "Robot Commands"
+ set name = "Unlock Cover"
+ set desc = "Unlocks your own cover if it is locked. You can not lock it again. A human will have to lock it for you."
+ if(locked)
+ switch(alert("You can not lock your cover again, are you sure?\n (You can still ask for a human to lock it)", "Unlock Own Cover", "Yes", "No"))
+ if("Yes")
+ locked = 0
+ updateicon()
+ usr << "You unlock your cover."
+
/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
@@ -1188,6 +1200,13 @@
return
+/mob/living/silicon/robot/proc/SetLockdown(var/state = 1)
+ // They stay locked down if their wire is cut.
+ if(wires.LockedCut())
+ state = 1
+ lockcharge = state
+ update_canmove()
+
/mob/living/silicon/robot/verb/pose()
set name = "Set Pose"
set desc = "Sets a description which will be shown when someone examines you."
diff --git a/code/modules/mob/living/silicon/robot/wires.dm b/code/modules/mob/living/silicon/robot/wires.dm
deleted file mode 100644
index 10b6832fe4b..00000000000
--- a/code/modules/mob/living/silicon/robot/wires.dm
+++ /dev/null
@@ -1,148 +0,0 @@
-#define BORG_WIRE_LAWCHECK 1
-#define BORG_WIRE_MAIN_POWER1 2
-#define BORG_WIRE_MAIN_POWER2 3
-#define BORG_WIRE_AI_CONTROL 4
-#define BORG_WIRE_CAMERA 5
-
-/proc/RandomBorgWires()
- //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/Borgwires = list(0, 0, 0, 0, 0)
- BorgIndexToFlag = list(0, 0, 0, 0, 0)
- BorgIndexToWireColor = list(0, 0, 0, 0, 0)
- BorgWireColorToIndex = list(0, 0, 0, 0, 0)
- var/flagIndex = 1
- //I think it's easier to read this way, also doesn't rely on the random number generator to land on a new wire.
- var/list/colorIndexList = list(BORG_WIRE_LAWCHECK, BORG_WIRE_MAIN_POWER1, BORG_WIRE_MAIN_POWER2, BORG_WIRE_AI_CONTROL, BORG_WIRE_CAMERA)
- for (var/flag=1, flag<=16, flag+=flag)
- var/colorIndex = pick(colorIndexList)
- if (Borgwires[colorIndex]==0)
- Borgwires[colorIndex] = flag
- BorgIndexToFlag[flagIndex] = flag
- BorgIndexToWireColor[flagIndex] = colorIndex
- BorgWireColorToIndex[colorIndex] = flagIndex
- colorIndexList -= colorIndex // Shortens the list.
- //world.log << "Flag: [flag], CIndex: [colorIndex], FIndex: [flagIndex]"
- flagIndex+=1
- return Borgwires
-
-/mob/living/silicon/robot/proc/isWireColorCut(var/wireColor)
- var/wireFlag = BorgWireColorToFlag[wireColor]
- return ((src.borgwires & wireFlag) == 0)
-
-/mob/living/silicon/robot/proc/isWireCut(var/wireIndex)
- var/wireFlag = BorgIndexToFlag[wireIndex]
- return ((src.borgwires & wireFlag) == 0)
-
-/mob/living/silicon/robot/proc/cut(var/wireColor)
- var/wireFlag = BorgWireColorToFlag[wireColor]
- var/wireIndex = BorgWireColorToIndex[wireColor]
- borgwires &= ~wireFlag
- switch(wireIndex)
- if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI
- if (src.lawupdate == 1)
- src << "LawSync protocol engaged."
- src.show_laws()
- if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control
- if (src.connected_ai)
- src.connected_ai = null
- if (BORG_WIRE_CAMERA)
- if(!isnull(src.camera) && !scrambledcodes)
- src.camera.status = 0
- src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
-
- src.interact(usr)
-
-/mob/living/silicon/robot/proc/mend(var/wireColor)
- var/wireFlag = BorgWireColorToFlag[wireColor]
- var/wireIndex = BorgWireColorToIndex[wireColor]
- borgwires |= wireFlag
- switch(wireIndex)
- if(BORG_WIRE_LAWCHECK) //turns law updates back on assuming the borg hasn't been emagged
- if (src.lawupdate == 0 && !src.emagged)
- src.lawupdate = 1
- if(BORG_WIRE_CAMERA)
- if (!isnull(src.camera) && !scrambledcodes)
- src.camera.status = 1
- src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
-
- src.interact(usr)
-
-
-/mob/living/silicon/robot/proc/pulse(var/wireColor)
- var/wireIndex = BorgWireColorToIndex[wireColor]
- switch(wireIndex)
- if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh
- if (src.lawupdate)
- src.lawsync()
-
- if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI
- if(!src.emagged)
- src.connected_ai = select_active_ai()
-
- if (BORG_WIRE_CAMERA)
- if(!isnull(src.camera) && src.camera.status && !scrambledcodes)
- src.camera.deactivate(usr, 0) // Kick anyone watching the Cyborg's camera, doesn't display you disconnecting the camera.
- usr << "[src]'s camera lens focuses loudly."
- src << "Your camera lens focuses loudly."
-
- src.interact(usr)
-
-/mob/living/silicon/robot/proc/interact(mob/user)
- if(wiresexposed && (!istype(user, /mob/living/silicon)))
- user.set_machine(src)
- var/t1 = text("Access Panel
\n")
- var/list/Borgwires = list(
- "Orange" = 1,
- "Dark red" = 2,
- "White" = 3,
- "Yellow" = 4,
- "Blue" = 5,
- )
- for(var/wiredesc in Borgwires)
- var/is_uncut = src.borgwires & BorgWireColorToFlag[Borgwires[wiredesc]]
- t1 += "[wiredesc] wire: "
- if(!is_uncut)
- t1 += "Mend"
- else
- t1 += "Cut "
- t1 += "Pulse "
- t1 += "
"
- t1 += text("
\n[(src.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]
\n[(src.connected_ai ? "The AI link light is on." : "The AI link light is off.")]")
- t1 += text("
\n[((!isnull(src.camera) && src.camera.status == 1) ? "The Camera light is on." : "The Camera light is off.")]
\n")
- t1 += text("Close
\n")
- user << browse(t1, "window=borgwires")
- onclose(user, "borgwires")
-
-/mob/living/silicon/robot/Topic(href, href_list)
- ..()
- if (((in_range(src, usr) && istype(src.loc, /turf))) && !istype(usr, /mob/living/silicon))
- usr.set_machine(src)
- if (href_list["borgwires"])
- var/t1 = text2num(href_list["borgwires"])
- if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
- usr << "You need wirecutters!"
- return
- if (src.isWireColorCut(t1))
- src.mend(t1)
- else
- src.cut(t1)
- else if (href_list["pulse"])
- var/t1 = text2num(href_list["pulse"])
- if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- return
- if (src.isWireColorCut(t1))
- usr << "You can't pulse a cut wire."
- return
- else
- src.pulse(t1)
- else if (href_list["close2"])
- usr << browse(null, "window=borgwires")
- usr.unset_machine()
- return
-
-#undef BORG_WIRE_LAWCHECK
-#undef BORG_WIRE_MAIN_POWER1
-#undef BORG_WIRE_MAIN_POWER2
-#undef BORG_WIRE_AI_CONTROL
-#undef BORG_WIRE_CAMERA
\ No newline at end of file
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 58bf31d55d7..05dfc79f107 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -431,4 +431,16 @@ var/list/intents = list("help","disarm","grab","hurt")
set category = "IC"
resting = !resting
- src << "\blue You are now [resting ? "resting" : "getting up"]"
\ No newline at end of file
+ src << "\blue You are now [resting ? "resting" : "getting up"]"
+
+/proc/get_multitool(mob/user as mob)
+ // Check distance for those that need it.
+ if(!isAI(user))
+ if(!in_range(user, src))
+ return null
+
+ // Get tool
+ var/obj/item/device/multitool/P = user.get_multitool()
+ if(!istype(P))
+ return null
+ return P
\ No newline at end of file
diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm
index 04163d48594..a7aeffe9508 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_control.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm
@@ -14,11 +14,15 @@
construction_state = 0
active = 0
dir = 1
+ var/strength_upper_limit = 2
+ var/interface_control = 1
var/list/obj/structure/particle_accelerator/connected_parts
var/assembled = 0
var/parts = null
+ var/datum/wires/particle_acc/control_box/wires = null
/obj/machinery/particle_accelerator/control_box/New()
+ wires = new(src)
connected_parts = list()
..()
@@ -26,6 +30,8 @@
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob)
if(construction_state >= 3)
interact(user)
+ else if(construction_state == 2) // Wires exposed
+ wires.Interact(user)
/obj/machinery/particle_accelerator/control_box/update_state()
if(construction_state < 3)
@@ -67,11 +73,11 @@
return
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
- ..()
- //Ignore input if we are broken, !silicon guy cant touch us, or nonai controlling from super far away
- if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon)) || (get_dist(src, usr) > 8 && !istype(usr, /mob/living/silicon/ai)))
- usr.unset_machine()
- usr << browse(null, "window=pacontrol")
+ if(..())
+ return
+
+ if(!interface_control)
+ usr << "ERROR: Request timed out. Check wire contacts."
return
if( href_list["close"] )
@@ -79,45 +85,54 @@
usr.unset_machine()
return
if(href_list["togglep"])
- src.toggle_power()
- investigate_log("turned [active?"ON":"OFF"] by [usr.key]","singulo")
- if (active)
- message_admins("PA Control Computer turned ON by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("PA Control Computer turned ON by [usr.ckey]([usr]) in ([x],[y],[z])")
+ if(!wires.IsIndexCut(PARTICLE_TOGGLE_WIRE))
+ src.toggle_power()
else if(href_list["scan"])
src.part_scan()
else if(href_list["strengthup"])
+ if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
+ add_strength()
+
+ else if(href_list["strengthdown"])
+ if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
+ remove_strength()
+
+ src.updateDialog()
+ src.update_icon()
+ return
+
+
+/obj/machinery/particle_accelerator/control_box/proc/strength_change()
+ for(var/obj/structure/particle_accelerator/part in connected_parts)
+ part.strength = strength
+ part.update_icon()
+
+/obj/machinery/particle_accelerator/control_box/proc/add_strength(var/s)
+ if(assembled)
strength++
- if(strength > 2)
- strength = 2
+ if(strength > strength_upper_limit)
+ strength = strength_upper_limit
else
message_admins("PA Control Computer increased to [strength] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1)
log_game("PA Control Computer increased to [strength] by [usr.ckey]([usr]) in ([x],[y],[z])")
investigate_log("increased to [strength] by [usr.key]","singulo")
- for(var/obj/structure/particle_accelerator/part in connected_parts)
- part.strength = strength
- part.update_icon()
+ strength_change()
- else if(href_list["strengthdown"])
+/obj/machinery/particle_accelerator/control_box/proc/remove_strength(var/s)
+ if(assembled)
strength--
if(strength < 0)
strength = 0
else
investigate_log("decreased to [strength] by [usr.key]","singulo")
- for(var/obj/structure/particle_accelerator/part in connected_parts)
- part.strength = strength
- part.update_icon()
- src.updateDialog()
- src.update_icon()
- return
-
+ strength_change()
/obj/machinery/particle_accelerator/control_box/power_change()
..()
if(stat & NOPOWER)
active = 0
use_power = 0
- else if(!stat && construction_state == 3)
+ else if(!stat && construction_state <= 3)
use_power = 1
return
@@ -187,6 +202,10 @@
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
src.active = !src.active
+ investigate_log("turned [active?"ON":"OFF"] by [usr ? usr.key : "outside forces"]","singulo")
+ if (active)
+ message_admins("PA Control Computer turned ON by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1)
+ log_game("PA Control Computer turned ON by [usr.ckey]([usr]) in ([x],[y],[z])")
if(src.active)
src.use_power = 2
for(var/obj/structure/particle_accelerator/part in connected_parts)