diff --git a/baystation12.dme b/baystation12.dme index 10529d45fa..c7f6f1eaa7 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -164,7 +164,11 @@ #include "code\datums\spells\trigger.dm" #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\robot.dm" #include "code\datums\wires\smartfridge.dm" #include "code\datums\wires\suit_storage_unit.dm" #include "code\datums\wires\vending.dm" @@ -357,7 +361,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" @@ -1061,7 +1064,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\silicon\robot\drone\drone.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_console.dm" diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 521f07c35e..3c7582b816 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -97,3 +97,21 @@ proc/RoundHealth(health) else return "health-100" return "0" + +/* +Proc for attack log creation, because really why not +1 argument is the actor +2 argument is the target of action +3 is the description of action(like punched, throwed, or any other verb) +4 should it make adminlog note or not +5 is the tool with which the action was made(usually item) 5 and 6 are very similar(5 have "by " before it, that it) and are separated just to keep things in a bit more in order +6 is additional information, anything that needs to be added +*/ + +/proc/add_logs(mob/user, mob/target, what_done, var/admin=1, var/object=null, var/addition=null) + if(user && ismob(user)) + user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") + if(target && ismob(target)) + target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") + if(admin) + log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm new file mode 100644 index 0000000000..e6cb473f59 --- /dev/null +++ b/code/datums/wires/airlock.dm @@ -0,0 +1,195 @@ +// Wires for airlocks + +/datum/wires/airlock/secure + random = 1 + wire_count = 14 + +/datum/wires/airlock + holder_type = /obj/machinery/door/airlock + wire_count = 12 + window_y = 570 + +var/const/AIRLOCK_WIRE_IDSCAN = 1 +var/const/AIRLOCK_WIRE_MAIN_POWER1 = 2 +var/const/AIRLOCK_WIRE_MAIN_POWER2 = 4 +var/const/AIRLOCK_WIRE_DOOR_BOLTS = 8 +var/const/AIRLOCK_WIRE_BACKUP_POWER1 = 16 +var/const/AIRLOCK_WIRE_BACKUP_POWER2 = 32 +var/const/AIRLOCK_WIRE_OPEN_DOOR = 64 +var/const/AIRLOCK_WIRE_AI_CONTROL = 128 +var/const/AIRLOCK_WIRE_ELECTRIFY = 256 +var/const/AIRLOCK_WIRE_SAFETY = 512 +var/const/AIRLOCK_WIRE_SPEED = 1024 +var/const/AIRLOCK_WIRE_LIGHT = 2048 + +/datum/wires/airlock/CanUse(var/mob/living/L) + var/obj/machinery/door/airlock/A = holder + if(!istype(L, /mob/living/silicon)) + if(A.isElectrified()) + if(A.shock(L, 100)) + return 0 + if(A.p_open) + return 1 + return 0 + +/datum/wires/airlock/GetInteractWindow() + var/obj/machinery/door/airlock/A = holder + . += ..() + . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), + (A.lights ? "The door bolt lights are on." : "The door bolt lights are off!"), + ((A.hasPower()) ? "The test light is on." : "The test light is off!"), + ((A.aiControlDisabled==0 && !A.emagged) ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), + (A.safe==0 ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), + (A.normalspeed==0 ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), + (A.aiDisabledIdScanner==0 ? "The IDScan light is on." : "The IDScan light is off.")) + +/datum/wires/airlock/UpdateCut(var/index, var/mended) + + var/obj/machinery/door/airlock/A = holder + switch(index) + if(AIRLOCK_WIRE_IDSCAN) + A.aiDisabledIdScanner = !mended + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + + if(!mended) + //Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + A.loseMainPower() + A.shock(usr, 50) + else + if((!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER2))) + A.regainMainPower() + A.shock(usr, 50) + + if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + + if(!mended) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + A.loseBackupPower() + A.shock(usr, 50) + else + if((!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER2))) + A.regainBackupPower() + A.shock(usr, 50) + + if(AIRLOCK_WIRE_DOOR_BOLTS) + + if(!mended) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if(A.locked!=1) + A.locked = 1 + A.update_icon() + + if(AIRLOCK_WIRE_AI_CONTROL) + + if(!mended) + //one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. + //aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. + if(A.aiControlDisabled == 0) + A.aiControlDisabled = 1 + else if(A.aiControlDisabled == -1) + A.aiControlDisabled = 2 + else + if(A.aiControlDisabled == 1) + A.aiControlDisabled = 0 + else if(A.aiControlDisabled == 2) + A.aiControlDisabled = -1 + + if(AIRLOCK_WIRE_ELECTRIFY) + + if(!mended) + //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])") + add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]") + A.secondsElectrified = -1 + else + if(A.secondsElectrified == -1) + A.secondsElectrified = 0 + return // Don't update the dialog. + + if (AIRLOCK_WIRE_SAFETY) + A.safe = mended + + if(AIRLOCK_WIRE_SPEED) + A.autoclose = mended + if(mended) + if(!A.density) + A.close() + + if(AIRLOCK_WIRE_LIGHT) + A.lights = mended + A.update_icon() + + +/datum/wires/airlock/UpdatePulsed(var/index) + + var/obj/machinery/door/airlock/A = holder + switch(index) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through flashes the red light on the door (if the door has power). + if(A.hasPower() && A.density) + A.do_animate("deny") + if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) + //Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). + A.loseMainPower() + if(AIRLOCK_WIRE_DOOR_BOLTS) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if(!A.locked) + A.locked = 1 + A.audible_message("You hear a click from the bottom of the door.", null, 1) + else + if(A.hasPower()) //only can raise bolts if power's on + A.locked = 0 + A.audible_message("You hear a click from the bottom of the door.", null, 1) + A.update_icon() + + if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) + //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). + A.loseBackupPower() + if(AIRLOCK_WIRE_AI_CONTROL) + if(A.aiControlDisabled == 0) + A.aiControlDisabled = 1 + else if(A.aiControlDisabled == -1) + A.aiControlDisabled = 2 + + spawn(10) + if(A) + if(A.aiControlDisabled == 1) + A.aiControlDisabled = 0 + else if(A.aiControlDisabled == 2) + A.aiControlDisabled = -1 + + if(AIRLOCK_WIRE_ELECTRIFY) + //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])") + add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]") + A.secondsElectrified = 30 + spawn(10) + if(A) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (A.secondsElectrified>0) + A.secondsElectrified-=1 + if(A.secondsElectrified<0) + A.secondsElectrified = 0 + sleep(10) + return + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access and it's not emagged + if(A.emagged) return + if(!A.requiresID() || A.check_access(null)) + if(A.density) A.open() + else A.close() + if(AIRLOCK_WIRE_SAFETY) + A.safe = !A.safe + if(!A.density) + A.close() + + if(AIRLOCK_WIRE_SPEED) + A.normalspeed = !A.normalspeed + + if(AIRLOCK_WIRE_LIGHT) + A.lights = !A.lights + A.update_icon() diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm new file mode 100644 index 0000000000..e8d68d7ffe --- /dev/null +++ b/code/datums/wires/alarm.dm @@ -0,0 +1,93 @@ +/datum/wires/alarm + holder_type = /obj/machinery/alarm + wire_count = 5 + +var/const/AALARM_WIRE_IDSCAN = 1 +var/const/AALARM_WIRE_POWER = 2 +var/const/AALARM_WIRE_SYPHON = 4 +var/const/AALARM_WIRE_AI_CONTROL = 8 +var/const/AALARM_WIRE_AALARM = 16 + + +/datum/wires/alarm/CanUse(var/mob/living/L) + var/obj/machinery/alarm/A = holder + if(A.wiresexposed) + return 1 + return 0 + +/datum/wires/alarm/GetInteractWindow() + var/obj/machinery/alarm/A = holder + . += ..() + . += text("
\n[(A.locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]
\n[((A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]
\n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]") + +/datum/wires/alarm/UpdateCut(var/index, var/mended) + var/obj/machinery/alarm/A = holder + switch(index) + if(AALARM_WIRE_IDSCAN) + if(!mended) + A.locked = 1 + //world << "Idscan wire cut" + + if(AALARM_WIRE_POWER) + A.shock(usr, 50) + A.shorted = !mended + A.update_icon() + //world << "Power wire cut" + + if (AALARM_WIRE_AI_CONTROL) + if (A.aidisabled == !mended) + A.aidisabled = mended + //world << "AI Control Wire Cut" + + if(AALARM_WIRE_SYPHON) + if(!mended) + A.mode = 3 // AALARM_MODE_PANIC + A.apply_mode() + //world << "Syphon Wire Cut" + + if(AALARM_WIRE_AALARM) + if (A.alarm_area.atmosalert(2)) + A.post_alert(2) + A.update_icon() + +/datum/wires/alarm/UpdatePulsed(var/index) + var/obj/machinery/alarm/A = holder + switch(index) + if(AALARM_WIRE_IDSCAN) + A.locked = !A.locked + // world << "Idscan wire pulsed" + + if (AALARM_WIRE_POWER) + // world << "Power wire pulsed" + if(A.shorted == 0) + A.shorted = 1 + A.update_icon() + + spawn(12000) + if(A.shorted == 1) + A.shorted = 0 + A.update_icon() + + + if (AALARM_WIRE_AI_CONTROL) + // world << "AI Control wire pulsed" + if (A.aidisabled == 0) + A.aidisabled = 1 + A.updateDialog() + spawn(100) + if (A.aidisabled == 1) + A.aidisabled = 0 + + if(AALARM_WIRE_SYPHON) + // world << "Syphon wire pulsed" + if(A.mode == 1) // AALARM_MODE_SCRUB + A.mode = 3 // AALARM_MODE_PANIC + else + A.mode = 1 // AALARM_MODE_SCRUB + A.apply_mode() + + if(AALARM_WIRE_AALARM) + // world << "Aalarm wire pulsed" + 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 7e48809af9..0cd295258b 100644 --- a/code/datums/wires/apc.dm +++ b/code/datums/wires/apc.dm @@ -31,7 +31,6 @@ var/const/APC_WIRE_AI_CONTROL = 8 spawn(300) if(A) A.locked = 1 - A.updateDialog() if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2) if(A.shorted == 0) @@ -40,7 +39,6 @@ var/const/APC_WIRE_AI_CONTROL = 8 spawn(1200) if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2)) A.shorted = 0 - A.updateDialog() if (APC_WIRE_AI_CONTROL) if (A.aidisabled == 0) @@ -49,9 +47,6 @@ var/const/APC_WIRE_AI_CONTROL = 8 spawn(10) if(A && !IsIndexCut(APC_WIRE_AI_CONTROL)) A.aidisabled = 0 - A.updateDialog() - - A.updateDialog() /datum/wires/apc/UpdateCut(var/index, var/mended) var/obj/machinery/power/apc/A = holder @@ -75,4 +70,3 @@ var/const/APC_WIRE_AI_CONTROL = 8 else if (A.aidisabled == 1) A.aidisabled = 0 - A.updateDialog() diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm new file mode 100644 index 0000000000..d03da5fa17 --- /dev/null +++ b/code/datums/wires/camera.dm @@ -0,0 +1,74 @@ +// Wires for cameras. + +/datum/wires/camera + random = 1 + holder_type = /obj/machinery/camera + wire_count = 6 + +/datum/wires/camera/GetInteractWindow() + + . = ..() + var/obj/machinery/camera/C = holder + . += "
\n[(C.view_range == initial(C.view_range) ? "The focus light is on." : "The focus light is off.")]" + . += "
\n[(C.can_use() ? "The power link light is on." : "The power link light is off.")]" + . += "
\n[(C.light_disabled ? "The camera light is off." : "The camera light is on.")]" + . += "
\n[(C.alarm_on ? "The alarm light is on." : "The alarm light is off.")]" + return . + +/datum/wires/camera/CanUse(var/mob/living/L) + var/obj/machinery/camera/C = holder + return C.panel_open + +var/const/CAMERA_WIRE_FOCUS = 1 +var/const/CAMERA_WIRE_POWER = 2 +var/const/CAMERA_WIRE_LIGHT = 4 +var/const/CAMERA_WIRE_ALARM = 8 +var/const/CAMERA_WIRE_NOTHING1 = 16 +var/const/CAMERA_WIRE_NOTHING2 = 32 + +/datum/wires/camera/UpdateCut(var/index, var/mended) + var/obj/machinery/camera/C = holder + + switch(index) + if(CAMERA_WIRE_FOCUS) + var/range = (mended ? initial(C.view_range) : C.short_range) + C.setViewRange(range) + + if(CAMERA_WIRE_POWER) + if(C.status && !mended || !C.status && mended) + C.deactivate(usr, 1) + + if(CAMERA_WIRE_LIGHT) + C.light_disabled = !mended + + if(CAMERA_WIRE_ALARM) + if(!mended) + C.triggerCameraAlarm() + else + C.cancelCameraAlarm() + return + +/datum/wires/camera/UpdatePulsed(var/index) + var/obj/machinery/camera/C = holder + if(IsIndexCut(index)) + return + switch(index) + if(CAMERA_WIRE_FOCUS) + var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range)) + C.setViewRange(new_range) + + if(CAMERA_WIRE_POWER) + C.deactivate(null) // Deactivate the camera + + if(CAMERA_WIRE_LIGHT) + C.light_disabled = !C.light_disabled + + if(CAMERA_WIRE_ALARM) + C.visible_message("\icon[C] *beep*", "\icon[C] *beep*") + return + +/datum/wires/camera/proc/CanDeconstruct() + if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS) && IsIndexCut(CAMERA_WIRE_LIGHT) && IsIndexCut(CAMERA_WIRE_NOTHING1) && IsIndexCut(CAMERA_WIRE_NOTHING2)) + return 1 + else + return 0 diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm new file mode 100644 index 0000000000..13e5316432 --- /dev/null +++ b/code/datums/wires/robot.dm @@ -0,0 +1,103 @@ +/datum/wires/robot + random = 1 + 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 +var/const/BORG_WIRE_LOCKED_DOWN = 4 +var/const/BORG_WIRE_AI_CONTROL = 8 +var/const/BORG_WIRE_CAMERA = 16 + +/datum/wires/robot/GetInteractWindow() + + . = ..() + var/mob/living/silicon/robot/R = holder + . += text("
\n[(R.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]") + . += text("
\n[(R.connected_ai ? "The AI link light is on." : "The AI link light is off.")]") + . += text("
\n[((!isnull(R.camera) && R.camera.status == 1) ? "The Camera light is on." : "The Camera light is off.")]") + . += text("
\n[(R.lockcharge ? "The lockdown light is on." : "The lockdown light is off.")]") + return . + +/datum/wires/robot/UpdateCut(var/index, var/mended) + + var/mob/living/silicon/robot/R = holder + switch(index) + if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI + if(!mended) + if (R.lawupdate == 1) + R << "LawSync protocol engaged." + R.show_laws() + else + if (R.lawupdate == 0 && !R.emagged) + R.lawupdate = 1 + + if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control + if(!mended) + if (R.connected_ai) + R.connected_ai = null + + if (BORG_WIRE_CAMERA) + if(!isnull(R.camera) && !R.scrambledcodes) + R.camera.status = mended + R.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera. + + 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 (R.lawupdate) + R.lawsync() + + if(BORG_WIRE_LOCKED_DOWN) + R.SetLockdown(!mended) + + +/datum/wires/robot/UpdatePulsed(var/index) + + var/mob/living/silicon/robot/R = holder + switch(index) + if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI + if(!R.emagged) + var/new_ai = select_active_ai(R) + if(new_ai && (new_ai != R.connected_ai)) + R.connected_ai = new_ai + R.notify_ai(1) + var/numberer = 1 // Send images the Cyborg has taken to the AI's album upon sync. + for(var/datum/picture/z in R.aiCamera.aipictures) + if(R.connected_ai.aiCamera.aipictures.len == 0) + var/datum/picture/p = new/datum/picture() + p = z + p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" + R.connected_ai.aiCamera.aipictures += p + numberer++ + continue + for(var/datum/picture/t in R.connected_ai.aiCamera.aipictures) //Hopefully to prevent someone spamming images to silicons, by spamming this wire + if((z.fields["pixel_y"] != t.fields["pixel_y"]) && (z.fields["pixel_x"] != t.fields["pixel_x"])) //~2.26 out of 1000 chance this will stop something it shouldn't + var/datum/picture/p = new/datum/picture() + p = z + p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" + R.connected_ai.aiCamera.aipictures += p + else + continue + numberer++ + if(R.aiCamera.aipictures.len > 0) + R << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI." + + if (BORG_WIRE_CAMERA) + if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) + R.camera.deactivate(usr, 0) // Kick anyone watching the Cyborg's camera, doesn't display you disconnecting the camera. + R.visible_message("[R]'s camera lense focuses loudly.") + R << "Your camera lense focuses loudly." + + if(BORG_WIRE_LOCKED_DOWN) + R.SetLockdown(!R.lockcharge) // Toggle + +/datum/wires/robot/CanUse(var/mob/living/L) + var/mob/living/silicon/robot/R = holder + if(R.wiresexposed) + return 1 + return 0 + +/datum/wires/robot/proc/IsCameraCut() + return wires_status & BORG_WIRE_CAMERA + +/datum/wires/robot/proc/LockedCut() + return wires_status & BORG_WIRE_LOCKED_DOWN diff --git a/code/datums/wires/smartfridge.dm b/code/datums/wires/smartfridge.dm index 0d0fb29870..b611497e79 100644 --- a/code/datums/wires/smartfridge.dm +++ b/code/datums/wires/smartfridge.dm @@ -2,6 +2,10 @@ holder_type = /obj/machinery/smartfridge wire_count = 3 +/datum/wires/smartfridge/secure + random = 1 + wire_count = 4 + var/const/SMARTFRIDGE_WIRE_ELECTRIFY = 1 var/const/SMARTFRIDGE_WIRE_THROW = 2 var/const/SMARTFRIDGE_WIRE_IDSCAN = 4 @@ -16,11 +20,6 @@ var/const/SMARTFRIDGE_WIRE_IDSCAN = 4 return 1 return 0 -/datum/wires/smartfridge/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/smartfridge/S = holder - S.attack_hand(user) - /datum/wires/smartfridge/GetInteractWindow() var/obj/machinery/smartfridge/S = holder . += ..() diff --git a/code/datums/wires/suit_storage_unit.dm b/code/datums/wires/suit_storage_unit.dm index 8ef5ce6398..c2d1a130d7 100644 --- a/code/datums/wires/suit_storage_unit.dm +++ b/code/datums/wires/suit_storage_unit.dm @@ -16,11 +16,6 @@ var/const/SUIT_STORAGE_WIRE_LOCKED = 4 return 1 return 0 -/datum/wires/suit_storage_unit/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/suit_cycler/S = holder - S.attack_hand(user) - /datum/wires/suit_storage_unit/GetInteractWindow() var/obj/machinery/suit_cycler/S = holder . += ..() diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 6204c90325..26feaefe47 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -6,8 +6,8 @@ #define MAX_FLAG 65535 var/list/same_wires = list() -// 12 colours, if you're adding more than 12 wires then add more colours here -var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink") +// 14 colours, if you're adding more than 14 wires then add more colours here +var/list/wireColours = list("red", "blue", "green", "white", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink", "black", "yellow") /datum/wires diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 6ca98474f7..7f3d04a0eb 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 @@ -79,9 +53,10 @@ var/locked = 1 var/wiresexposed = 0 // If it's been screwdrivered open. var/aidisabled = 0 - var/AAlarmwires = 31 var/shorted = 0 + var/datum/wires/alarm/wires + var/mode = AALARM_MODE_SCRUBBING var/screen = AALARM_SCREEN_MAIN var/area_uid @@ -153,6 +128,9 @@ if (name == "alarm") name = "[alarm_area.name] Air Alarm" + if(!wires) + wires = new(src) + // breathable air according to human/Life() TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa @@ -482,125 +460,6 @@ frequency.post_signal(src, alert_signal) - -/////////// -//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) - - if (alarm_area.atmosalert(2)) - apply_danger_level(2) - 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) - if (alarm_area.atmosalert(0)) - apply_danger_level(0) - spawn(1) - updateUsrDialog() - update_icon() - - updateDialog() - return - -/////////////// -//END HACKING// -/////////////// - /obj/machinery/alarm/attack_ai(mob/user) return interact(user) @@ -616,7 +475,7 @@ if(buildstage!=2) return - if ( (get_dist(src, user) > 1 )) + if((get_dist(src, user) > 1 )) if (!istype(user, /mob/living/silicon)) user.machine = null user << browse(null, "window=air_alarm") @@ -629,30 +488,8 @@ 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/ai))) + wires.Interact(user) if(!shorted) user << browse(return_text(user),"window=air_alarm") @@ -1055,35 +892,6 @@ table tr:first-child th:first-child { border: none;} mode = text2num(href_list["mode"]) apply_mode() - // hrefs that need the AA wires exposed, note that borgs should be in range here too -walter0o - if(wiresexposed && Adjacent(usr)) - - 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) - 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) - updateUsrDialog() @@ -1115,7 +923,7 @@ table tr:first-child th:first-child { border: none;} 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() @@ -1488,7 +1296,7 @@ FIRE ALARM wiresexposed = 1 pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 - + /obj/machinery/firealarm/initialize() if(z in config.contact_levels) if(security_level) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1c8298bd0b..140659a0e5 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -19,11 +19,7 @@ var/obj/item/weapon/camera_assembly/assembly = null // WIRES - var/wires = 63 // 0b111111 - var/list/IndexToFlag = list() - var/list/IndexToWireColor = list() - var/list/WireColorToIndex = list() - var/list/WireColorToFlag = list() + var/datum/wires/camera/wires = null // Wires datum //OTHER @@ -35,7 +31,7 @@ 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. @@ -115,7 +111,7 @@ else if((iswirecutter(W) || ismultitool(W)) && panel_open) interact(user) - else if(iswelder(W) && canDeconstruct()) + else if(iswelder(W) && wires.CanDeconstruct()) if(weld(W, user)) if(assembly) assembly.loc = src.loc @@ -283,4 +279,11 @@ return 0 return 1 busy = 0 - return 0 \ No newline at end of file + return 0 + +/obj/machinery/camera/interact(mob/living/user as mob) + if(!panel_open || istype(user, /mob/living/silicon/ai)) + return + + user.set_machine(src) + wires.Interact(user) diff --git a/code/game/machinery/camera/wires.dm b/code/game/machinery/camera/wires.dm deleted file mode 100644 index 785b33368a..0000000000 --- a/code/game/machinery/camera/wires.dm +++ /dev/null @@ -1,169 +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) - - 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 f542ff6994..5babdc6706 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1,76 +1,3 @@ -#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) - requiresIDs - 1 if the airlock is requiring IDs, 0 if not - isAllPowerCut - 1 if the main and backup power both have cut wires. - regainMainPower - handles the effect of main power coming back on. - loseMainPower - handles the effect of main power going offline. Usually (if one isn't already running) spawn a thread to count down how long it will be offline - counting down won't happen if main power was completely cut along with backup power, though, the thread will just sleep. - loseBackupPower - handles the effect of backup power going offline. - regainBackupPower - handles the effect of main power coming back on. - shock - has a chance of electrocuting its target. -*/ - -//This generates the randomized airlock wire assignments for the game. -/proc/RandomAirlockWires() - var/list/wire_assignments = CreateRandomAirlockWires() - - globalAirlockIndexToFlag = wire_assignments[2] - globalAirlockIndexToWireColor = wire_assignments[3] - globalAirlockWireColorToIndex = wire_assignments[4] - return wire_assignments[1] - -/proc/CreateRandomAirlockWires() - //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/flagIndex = 1 - for (var/flag=1, flag<4096, flag+=flag) - var/valid = 0 - var/list/colorList = list(AIRLOCK_WIRE_IDSCAN, AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2, AIRLOCK_WIRE_DOOR_BOLTS, - AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2, AIRLOCK_WIRE_OPEN_DOOR, AIRLOCK_WIRE_AI_CONTROL, AIRLOCK_WIRE_ELECTRIFY, - AIRLOCK_WIRE_SAFETY, AIRLOCK_WIRE_SPEED, AIRLOCK_WIRE_LIGHT) - - while (!valid) - var/colorIndex = pick(colorList) - if(wires[colorIndex]==0) - valid = 1 - wires[colorIndex] = flag - airlockIndexToFlag[flagIndex] = flag - airlockIndexToWireColor[flagIndex] = colorIndex - airlockWireColorToIndex[colorIndex] = flagIndex - colorList -= colorIndex - flagIndex+=1 - return list(wires, airlockIndexToFlag, airlockIndexToWireColor, airlockWireColorToIndex) - -/* Example: -Airlock wires color -> flag are { 64, 128, 256, 2, 16, 4, 8, 32, 1 }. -Airlock wires color -> index are { 7, 8, 9, 2, 5, 3, 4, 6, 1 }. -Airlock index -> flag are { 1, 2, 4, 8, 16, 32, 64, 128, 256 }. -Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. -*/ - /obj/machinery/door/airlock name = "Airlock" icon = 'icons/obj/doors/Doorint.dmi' @@ -86,13 +13,11 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. var/welded = null var/locked = 0 var/lights = 1 // bolt lights show by default - var/wires = 4095 secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. var/aiDisabledIdScanner = 0 var/aiHacking = 0 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 @@ -104,10 +29,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. var/hasShocked = 0 //Prevents multiple shocks from happening var/secured_wires = 0 //for mapping use var/security_bolts = 0 //if 1, door bolts when broken - var/list/airlockIndexToFlag - var/list/airlockWireColorToFlag - var/list/airlockIndexToWireColor - var/list/airlockWireColorToIndex + var/datum/wires/airlock/wires = null /obj/machinery/door/airlock/command name = "Airlock" @@ -379,176 +301,14 @@ About the new airlock wires panel: /obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user as mob) ..(user) - -/obj/machinery/door/airlock/proc/pulse(var/wireColor) - //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function - var/wireIndex = airlockWireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - do_animate("deny") - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). - src.loseMainPower() - if(AIRLOCK_WIRE_DOOR_BOLTS) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if(!src.locked) - src.lock() - else - src.unlock() - src.updateUsrDialog() - - if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). - src.loseBackupPower() - if(AIRLOCK_WIRE_AI_CONTROL) - if(src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if(src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if(src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if(src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if(AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if(src.secondsElectrified==0) - shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if(src.secondsElectrified<0) - src.secondsElectrified = 0 -// src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if(!src.requiresID() || src.check_access(null)) - if(density) open() - else close() - if(AIRLOCK_WIRE_SAFETY) - safe = !safe - if(!src.density) - close() - src.updateUsrDialog() - - if(AIRLOCK_WIRE_SPEED) - normalspeed = !normalspeed - src.updateUsrDialog() - - if(AIRLOCK_WIRE_LIGHT) - lights = !lights - src.updateUsrDialog() - - -/obj/machinery/door/airlock/proc/cut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if(AIRLOCK_WIRE_DOOR_BOLTS) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - src.lock() - src.updateUsrDialog() - if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if(AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. - //aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. - if(src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if(src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if(AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if(src.secondsElectrified != -1) - shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") - src.secondsElectrified = -1 - if (AIRLOCK_WIRE_SAFETY) - safe = 0 - src.updateUsrDialog() - - if(AIRLOCK_WIRE_SPEED) - autoclose = 0 - src.updateUsrDialog() - - if(AIRLOCK_WIRE_LIGHT) - lights = 0 - src.updateUsrDialog() - -/obj/machinery/door/airlock/proc/mend(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - if((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - if((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if(AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. - //aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. - if(src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if(src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if(AIRLOCK_WIRE_ELECTRIFY) - if(src.secondsElectrified == -1) - src.secondsElectrified = 0 - - if (AIRLOCK_WIRE_SAFETY) - safe = 1 - src.updateUsrDialog() - - if(AIRLOCK_WIRE_SPEED) - autoclose = 1 - if(!src.density) - close() - src.updateUsrDialog() - - if(AIRLOCK_WIRE_LIGHT) - lights = 1 - src.updateUsrDialog() - - /obj/machinery/door/airlock/proc/isElectrified() if(src.secondsElectrified != 0) return 1 return 0 -/obj/machinery/door/airlock/proc/isWireColorCut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - /obj/machinery/door/airlock/proc/isWireCut(var/wireIndex) - var/wireFlag = airlockIndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) + // You can find the wires in the datum folder. + return wires.IsIndexCut(wireIndex) /obj/machinery/door/airlock/proc/canAIControl() return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); @@ -874,46 +634,8 @@ About the new airlock wires panel: **/ if(src.p_open) - user.set_machine(src) - var/t1 = text("Access Panel
\n") - - //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) - var/list/wires = list( - "Orange" = 1, - "Dark red" = 2, - "White" = 3, - "Yellow" = 4, - "Red" = 5, - "Blue" = 6, - "Green" = 7, - "Grey" = 8, - "Black" = 9, - "Gold" = 10, - "Aqua" = 11, - "Pink" = 12 - ) - for(var/wiredesc in wires) - var/is_uncut = src.wires & airlockWireColorToFlag[wires[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wires[wiredesc]]) - t1 += "Detach signaler" - else - t1 += "Attach signaler" - t1 += "
" - - t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), (src.lights ? "The door bolt lights are on." : "The door bolt lights are off!"), ((src.arePowerSystemsOn()) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.safe==0 ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), (src.normalspeed==0 ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off.")) - - t1 += text("

Close

\n", src) - - user << browse(t1, "window=airlock") - onclose(user, "airlock") - + wires.Interact(user) else ..(user) return @@ -947,52 +669,6 @@ About the new airlock wires panel: if((in_range(src, usr) && istype(src.loc, /turf)) && src.p_open) 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["signaler"]) - var/wirenum = text2num(href_list["signaler"]) - if(!istype(usr.get_active_hand(), /obj/item/device/assembly/signaler)) - usr << "You need a signaller!" - return - if(src.isWireColorCut(wirenum)) - usr << "You can't attach a signaller to a cut wire." - return - var/obj/item/device/assembly/signaler/R = usr.get_active_hand() - if(R.secured) - usr << "This radio can't be attached!" - return - var/mob/M = usr - M.drop_item() - R.loc = src - R.airlock_wire = wirenum - src.signalers[wirenum] = R - else if(href_list["remove-signaler"]) - var/wirenum = text2num(href_list["remove-signaler"]) - if(!(src.signalers[wirenum])) - usr << "There's no signaller attached to that wire!" - return - var/obj/item/device/assembly/signaler/R = src.signalers[wirenum] - R.loc = usr.loc - R.airlock_wire = null - src.signalers[wirenum] = null - if(istype(usr, /mob/living/silicon)) if (!check_synth_access(usr)) @@ -1394,13 +1070,10 @@ About the new airlock wires panel: ..() //wires - if (!secured_wires) - airlockWireColorToFlag = globalAirlockWireColorToFlag - airlockIndexToFlag = globalAirlockIndexToFlag - airlockIndexToWireColor = globalAirlockIndexToWireColor - airlockWireColorToIndex = globalAirlockWireColorToIndex + if (secured_wires) + wires = new/datum/wires/airlock/secure(src) else - randomize_wires() + wires = new/datum/wires/airlock(src) if(src.closeOtherId != null) spawn (5) @@ -1409,18 +1082,13 @@ About the new airlock wires panel: src.closeOther = A break -/obj/machinery/door/airlock/proc/randomize_wires() - var/wire_assignments = CreateRandomAirlockWires() - airlockWireColorToFlag = wire_assignments[1] - airlockIndexToFlag = wire_assignments[2] - airlockIndexToWireColor = wire_assignments[3] - airlockWireColorToIndex = wire_assignments[4] - - /obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason ..() update_icon() +/obj/machinery/door/airlock/proc/hasPower() + return ((src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) && !(stat & NOPOWER)) + /obj/machinery/door/airlock/proc/prison_open() src.unlock() src.open() diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index ef62417b69..2350b8120c 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -23,13 +23,22 @@ var/locked = 0 var/panel_open = 0 //Hacking a smartfridge var/scan_id = 1 + var/is_secure = 0 var/datum/wires/smartfridge/wires = null +/obj/machinery/smartfridge/secure/ + is_secure = 1 + /obj/machinery/smartfridge/New() - wires = new(src) + ..() + if(is_secure) + wires = new/datum/wires/smartfridge/secure(src) + else + wires = new/datum/wires/smartfridge(src) /obj/machinery/smartfridge/Del() del(wires) // qdel + ..() /obj/machinery/smartfridge/proc/accept_check(var/obj/item/O as obj) if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/)) @@ -217,12 +226,7 @@ /obj/machinery/smartfridge/attack_hand(mob/user as mob) if(!ispowered) return - if(seconds_electrified != 0) - if(shock(user, 100)) - return - if(panel_open) - wires.Interact(user) - + wires.Interact(user) ui_interact(user) /******************* @@ -232,12 +236,8 @@ /obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/is_secure = istype(src,/obj/machinery/smartfridge/secure) - var/data[0] data["contents"] = null - data["wires"] = null - data["panel_open"] = panel_open data["electrified"] = seconds_electrified > 0 data["shoot_inventory"] = shoot_inventory data["locked"] = locked diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index a817c2c3a5..7885a8b8e2 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -33,11 +33,12 @@ playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) use_power(5000) // Use a lot of power. var/mob/living/silicon/robot = H.Robotize() - robot.lying = 1 + robot.SetLockDown() spawn(50) // So he can't jump out the gate right away. playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) if(robot) - robot.lying = 0 + robot.SetLockDown(0) + robot.notify_ai(1) /obj/machinery/transformer/conveyor/New() ..() diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index a5274598dd..87a6fdc04c 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -226,6 +226,7 @@ feedback_inc("cyborg_birth",1) callHook("borgify", list(O)) + O.notify_ai(1) O.Namepick() del(src) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index ce8056d46a..f9d3e356ce 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -41,6 +41,7 @@ R.updatename("Default") R.status_flags |= CANPUSH R.updateicon() + R.notify_ai(2) return 1 @@ -56,6 +57,7 @@ /obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R) if(..()) return 0 + R.notify_ai(3, R.name, heldname) R.name = heldname R.custom_name = heldname R.real_name = heldname @@ -80,6 +82,9 @@ R.key = ghost.key R.stat = CONSCIOUS + dead_mob_list -= R + living_mob_list |= R + R.notify_ai(1) return 1 diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 8e63a00a1e..da7549fe34 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -270,13 +270,13 @@ obj/structure/door_assembly path = text2path("/obj/machinery/door/airlock[glass_type]") else path = text2path("/obj/machinery/door/airlock[airlock_type]") - + var/obj/machinery/door/airlock/door = new path(src.loc) - + door.assembly_type = type door.electronics = src.electronics if (istype(electronics, /obj/item/weapon/airlock_electronics/secure)) - door.randomize_wires() + door.wires = new/datum/wires/airlock/secure(src) if(src.electronics.one_access) door.req_access = null door.req_one_access = src.electronics.conf_access diff --git a/code/global.dm b/code/global.dm index cf8bc91b54..2186af119d 100644 --- a/code/global.dm +++ b/code/global.dm @@ -179,22 +179,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/globalAirlockWireColorToFlag = RandomAirlockWires() -var/list/globalAirlockIndexToFlag -var/list/globalAirlockIndexToWireColor -var/list/globalAirlockWireColorToIndex -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) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 2c9c26fceb..9d79d67876 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -121,9 +121,6 @@ pulse(var/radio = 0) if(src.connected && src.wires) connected.Pulse(src) - else 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) else diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 58ad85e2a0..95d8ed9d57 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.IsIndexCut(BORG_WIRE_CAMERA)) 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 880de591c9..b0c7acad23 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -21,6 +21,7 @@ var/list/robot_verbs_default = list( var/crisis //Admin-settable for combat module use. var/crisis_override = 0 var/integrated_light_power = 6 + var/datum/wires/robot/wires //Hud stuff @@ -81,6 +82,8 @@ var/list/robot_verbs_default = list( add_language("Robot Talk", 1) + wires = new(src) + ident = rand(1, 999) updatename("Default") updateicon() @@ -106,7 +109,7 @@ var/list/robot_verbs_default = list( camera = new /obj/machinery/camera(src) camera.c_tag = real_name camera.network = list("SS13","Robots") - if(isWireCut(5)) // 5 = BORG CAMERA + if(wires.IsIndexCut(BORG_WIRE_CAMERA)) camera.status = 0 initialize_components() @@ -303,6 +306,7 @@ var/list/robot_verbs_default = list( choose_icon(6,module_sprites) radio.config(module.channels) + notify_ai(2) /mob/living/silicon/robot/proc/updatename(var/prefix as text) if(prefix) @@ -320,6 +324,8 @@ var/list/robot_verbs_default = list( changed_name = custom_name else changed_name = "[modtype] [braintype]-[num2text(ident)]" + + notify_ai(3, real_name, changed_name) real_name = changed_name name = real_name @@ -672,7 +678,7 @@ var/list/robot_verbs_default = list( user << "You close the cover." opened = 0 updateicon() - else if(wiresexposed && isWireCut(1) && isWireCut(2) && isWireCut(3) && isWireCut(4) && isWireCut(5)) + else if(wiresexposed && wires.IsAllCut()) //Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob. if(!mmi) user << "\The [src] has no brain to remove." @@ -743,7 +749,7 @@ var/list/robot_verbs_default = list( 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." @@ -1231,6 +1237,13 @@ var/list/robot_verbs_default = list( R << "Buffers flushed and reset. Camera system shutdown. All systems operational." src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes +/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/mode() set name = "Activate Held Object" set category = "IC" @@ -1310,4 +1323,15 @@ var/list/robot_verbs_default = list( var/datum/robot_component/RC = get_component("comms") use_power(RC.active_usage) return 1 - return 0 \ No newline at end of file + return 0 + +/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) + if(!connected_ai) + return + switch(notifytype) + if(1) //New Cyborg + connected_ai << "

NOTICE - New cyborg connection detected: [name]
" + if(2) //New Module + connected_ai << "

NOTICE - Cyborg module change detected: [name] has loaded the [module.name] module.
" + if(3) //New Name + connected_ai << "

NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
" 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 9ed4320c84..0000000000 --- a/code/modules/mob/living/silicon/robot/wires.dm +++ /dev/null @@ -1,149 +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() - src.photosync() - - 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.dm b/code/modules/mob/mob.dm index 9e8a8c65fa..6a1bef3f6f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -60,6 +60,34 @@ for(var/mob/M in viewers(src)) M.show_message( message, 1, blind_message, 2) +// Show a message to all mobs in earshot of this one +// This would be for audible actions by the src mob +// message is the message output to anyone who can hear. +// self_message (optional) is what the src mob hears. +// deaf_message (optional) is what deaf people will see. +// hearing_distance (optional) is the range, how many tiles away the message can be heard. +/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message) + var/range = 7 + if(hearing_distance) + range = hearing_distance + var/msg = message + for(var/mob/M in get_mobs_in_view(range, src)) + if(self_message && M==src) + msg = self_message + M.show_message( msg, 2, deaf_message, 1) + +// Show a message to all mobs in earshot of this atom +// Use for objects performing audible actions +// message is the message output to anyone who can hear. +// deaf_message (optional) is what deaf people will see. +// hearing_distance (optional) is the range, how many tiles away the message can be heard. +/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance) + var/range = 7 + if(hearing_distance) + range = hearing_distance + for(var/mob/M in get_mobs_in_view(range, src)) + M.show_message( message, 2, deaf_message, 1) + /mob/proc/findname(msg) for(var/mob/M in mob_list) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 515067da79..d5d7a0791f 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -168,7 +168,7 @@ O.mmi.transfer_identity(src) callHook("borgify", list(O)) - + O.notify_ai(1) O.Namepick() spawn(0)//To prevent the proc from returning null. diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index bfedb92ed6..059ec7f471 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1228,7 +1228,6 @@ update() else if (last_ch != charging) queue_icon_update() - src.updateDialog() // val 0=off, 1=off(auto) 2=on 3=on(auto) // on 0=off, 1=on, 2=autooff diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 72250fbf1a..90157efd62 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -24,6 +24,7 @@ if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/Robot = M if(Robot.mmi) del(Robot.mmi) + Robot.notify_ai(1) else for(var/obj/item/W in M) if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something diff --git a/nano/templates/smartfridge.tmpl b/nano/templates/smartfridge.tmpl index b371baaef3..cc25d760ce 100644 --- a/nano/templates/smartfridge.tmpl +++ b/nano/templates/smartfridge.tmpl @@ -34,42 +34,3 @@ No products loaded. {{/if}} - -{{if data.panel_open}} -
-

Access Panel

-
-
-
- Wires: -
-
- {{for data.wires}} -
-
- {{:value.wire}} wire: -
-
- {{if value.cut}} - {{:helper.link('Mend', 'plus', {'cutwire' : value.index})}} - {{else}} - {{:helper.link('Cut', 'minus', {'cutwire' : value.index})}} - {{:helper.link('Pulse', 'signal-diag', {'pulsewire' : value.index})}} - {{/if}} -
-
- {{/for}} -
-
- -
- The orange light is {{:data.electrified ? "on" : "off"}}.
- The red light is {{:data.shoot_inventory ? "on" : "off"}}.
- {{if data.secure}} - The green light is - - {{:data.locked == 1 ? "off" : data.locked == -1 ? "blinking" : "on"}} - .
- {{/if}} -
-{{/if}}