From a9ef2b61c08c331610c2e2a4ac0e131b8a09dc71 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Tue, 4 Nov 2014 14:19:42 +0100 Subject: [PATCH 01/16] Wiring Upgrade Continues the wiring upgrade. Now cameras, airlocks, robots, and air alarms also use the new wire datum system. Global wiring code is now removed but there are sneaky objects which didn't rely on them such as mulebots and autolathes. Fixes a few issues from the previous upgrade. --- baystation12.dme | 6 +- code/__HELPERS/mobs.dm | 18 + code/datums/wires/airlock.dm | 195 ++++++++++ code/datums/wires/alarm.dm | 93 +++++ code/datums/wires/apc.dm | 6 - code/datums/wires/camera.dm | 74 ++++ code/datums/wires/robot.dm | 103 +++++ code/datums/wires/smartfridge.dm | 9 +- code/datums/wires/suit_storage_unit.dm | 5 - code/datums/wires/wires.dm | 4 +- code/game/machinery/alarm.dm | 212 +---------- code/game/machinery/camera/camera.dm | 19 +- code/game/machinery/camera/wires.dm | 169 --------- code/game/machinery/doors/airlock.dm | 352 +----------------- code/game/machinery/kitchen/smartfridge.dm | 22 +- code/game/machinery/transformer.dm | 5 +- code/game/objects/items/robot/robot_parts.dm | 1 + .../objects/items/robot/robot_upgrades.dm | 5 + code/game/objects/structures/door_assembly.dm | 6 +- code/global.dm | 16 - code/modules/assembly/signaler.dm | 3 - code/modules/mob/living/silicon/robot/life.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 32 +- .../modules/mob/living/silicon/robot/wires.dm | 149 -------- code/modules/mob/mob.dm | 28 ++ code/modules/mob/transform_procs.dm | 2 +- code/modules/power/apc.dm | 1 - code/modules/projectiles/projectile/change.dm | 1 + nano/templates/smartfridge.tmpl | 39 -- 29 files changed, 606 insertions(+), 971 deletions(-) create mode 100644 code/datums/wires/airlock.dm create mode 100644 code/datums/wires/alarm.dm create mode 100644 code/datums/wires/camera.dm create mode 100644 code/datums/wires/robot.dm delete mode 100644 code/game/machinery/camera/wires.dm delete mode 100644 code/modules/mob/living/silicon/robot/wires.dm diff --git a/baystation12.dme b/baystation12.dme index 10529d45fa2..c7f6f1eaa7a 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 521f07c35e5..3c7582b8164 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 00000000000..e6cb473f590 --- /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 00000000000..e8d68d7ffe2 --- /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 7e48809af9a..0cd295258bb 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 00000000000..d03da5fa171 --- /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 00000000000..13e53164320 --- /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 0d0fb298706..b611497e796 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 8ef5ce63986..c2d1a130d79 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 6204c90325e..26feaefe47a 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 6ca98474f7e..7f3d04a0ebc 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 1c8298bd0ba..140659a0e51 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 785b33368a2..00000000000 --- 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 f542ff69943..5babdc6706a 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 ef62417b694..2350b8120cb 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 a817c2c3a55..7885a8b8e24 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 a5274598dd6..87a6fdc04ca 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 ce8056d46a7..f9d3e356ce6 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 8e63a00a1e4..da7549fe343 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 cf8bc91b546..2186af119d0 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 2c9c26fceba..9d79d678764 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 58ad85e2a0e..95d8ed9d57f 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 880de591c9c..b0c7acad233 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 9ed4320c844..00000000000 --- 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 9e8a8c65fa3..6a1bef3f6f7 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 515067da79b..d5d7a0791f1 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 bfedb92ed6c..059ec7f471f 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 72250fbf1a3..90157efd625 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 b371baaef32..cc25d760ce0 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}} From d9b420642a8020268fb5b61f3689418e47208587 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Tue, 4 Nov 2014 17:25:01 +0100 Subject: [PATCH 02/16] Manifest ghost visibility-toggle Ghosts which have been made visible by cultists can afterward turn themselves (in)visible at will, with a cooldown before being able to turn themselves visible after having faded from sight. --- code/game/gamemodes/cult/ritual.dm | 3 +- code/modules/mob/dead/observer/observer.dm | 39 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index e60795f5fd9..30737a71cb5 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -346,7 +346,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (JMP)") if(istype(M,/mob/dead)) - M.invisibility = 0 + var/mob/dead/D = M + D.manifest() user.visible_message( \ "\red [user] drags the ghost to our plan of reality!", \ "\red You drag the ghost to our plan of reality!" \ diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 5e6bd3cba1b..fd37fcae6b7 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -550,3 +550,42 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp W.message = message W.add_hiddenprint(src) W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...") + +/mob/dead/proc/manifest() + verbs += /mob/dead/proc/toggle_visibility + toggle_visibility() + +/mob/dead/proc/toggle_icon(var/icon) + if(!client) + return + + var/iconRemoved = 0 + for(var/image/I in client.images) + if(I.icon_state == icon) + iconRemoved = 1 + del(I) + + if(!iconRemoved) + var/image/J = image('icons/mob/mob.dmi', loc = src, icon_state = icon) + client.images += J + +/mob/dead/proc/toggle_visibility() + set category = "Ghost" + set name = "Toggle Visibility" + set desc = "Allows you to turn (in)visible (almost) at will." + + var/toggled_invisible + + if(invisibility && world.time < toggled_invisible + 600) + src << "You must gather strength before you can turn visible again..." + return + + if(invisibility == 0) + toggled_invisible = world.time + visible_message("It fades from sight...", "You are now invisible") + else + src << "You have pried the window into the frame." : "You have pried the window out of the frame.") + else if(istype(W, /obj/item/weapon/wrench) && !anchored && (!state || !reinf)) + if(!glasstype) + user << "You're not sure how to dismantle \the [src] properly." + else + visible_message("[user] dismantles \the [src].") + if(dir == SOUTHWEST) + var/index = null + index = 0 + while(index < 2) + new glasstype(loc) + index++ + else + new glasstype(loc) + del(src) else if(W.damtype == BRUTE || W.damtype == BURN) hit(W.force) @@ -373,6 +388,8 @@ desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it." icon_state = "window" basestate = "window" + glasstype = /obj/item/stack/sheet/glass + /obj/structure/window/phoronbasic name = "phoron window" @@ -380,6 +397,7 @@ basestate = "phoronwindow" icon_state = "phoronwindow" shardtype = /obj/item/weapon/shard/phoron + glasstype = /obj/item/stack/sheet/glass/phoronglass maxhealth = 120 /obj/structure/window/phoronbasic/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -393,6 +411,7 @@ basestate = "phoronrwindow" icon_state = "phoronrwindow" shardtype = /obj/item/weapon/shard/phoron + glasstype = /obj/item/stack/sheet/glass/phoronrglass reinf = 1 maxhealth = 160 @@ -406,6 +425,7 @@ basestate = "rwindow" maxhealth = 40 reinf = 1 + glasstype = /obj/item/stack/sheet/rglass /obj/structure/window/reinforced/tinted name = "tinted window" diff --git a/html/changelog.html b/html/changelog.html index bbc7657a9c1..2c0e9d05e87 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,15 @@ should be listed in the changelog upon commit though. Thanks. --> +
+

4 November 2014

+

TwistedAkai updated:

+
    +
  • Almost any window which has been fully unsecured can now be dismantled with a wrench.
  • +
+
+ +

1 november 2014

PsiOmegaDelta updated:

From e19a79a3404036f4c52a029a333c9c75933fc00d Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 5 Nov 2014 08:52:56 +0100 Subject: [PATCH 04/16] Ports verb-optimizations from /tg/ The examine, pull, and point verbs now below to the mob instead of all atoms. Based on discussion here: http://www.byond.com/forum/?post=1326139&page=2#comment8198716 As a bonus ghosts can now point. Ghost pointing should only be visible to other ghosts unless made visible by cult activities. --- baystation12.dme | 1 - code/_onclick/click.dm | 3 +- code/_onclick/observer.dm | 2 +- code/game/atoms.dm | 26 +++++++------ code/game/verbs/atom_verbs.dm | 32 ---------------- code/modules/mob/living/living.dm | 22 +++++++++++ .../mob/living/silicon/ai/freelook/eye.dm | 10 ++--- code/modules/mob/mob.dm | 38 ++++++++++++++++++- code/modules/mob/mob_helpers.dm | 7 ++++ 9 files changed, 86 insertions(+), 55 deletions(-) delete mode 100644 code/game/verbs/atom_verbs.dm diff --git a/baystation12.dme b/baystation12.dme index 10529d45fa2..fc754e1a5c1 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -685,7 +685,6 @@ #include "code\game\turfs\unsimulated\beach.dm" #include "code\game\turfs\unsimulated\floor.dm" #include "code\game\turfs\unsimulated\walls.dm" -#include "code\game\verbs\atom_verbs.dm" #include "code\game\verbs\ooc.dm" #include "code\game\verbs\suicide.dm" #include "code\game\verbs\who.dm" diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 569423ec015..053bd48b7ca 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -227,8 +227,7 @@ return /atom/proc/ShiftClick(var/mob/user) if(user.client && user.client.eye == user) - examine() - user.face_atom(src) + user.examinate(src) return /* diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 2b941562b05..aa135a66541 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -41,7 +41,7 @@ // Oh by the way this didn't work with old click code which is why clicking shit didn't spam you /atom/proc/attack_ghost(mob/dead/observer/user as mob) if(user.client && user.client.inquisitive_ghost) - examine() + examine(user) return // --------------------------------------- diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b1cfd18551d..bf86972fdc9 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -187,18 +187,22 @@ its easier to just keep the beam vertical. //All atoms -/atom/verb/examine() - set name = "Examine" - set category = "IC" - set src in view(usr.client) //If it can be seen, it can be examined. +/atom/proc/examine(mob/user, var/distance = -1) + //This reformat names to get a/an properly working on item descriptions when they are bloody + var/f_name = "\a [src]." + if(src.blood_DNA && !istype(src, /obj/effect/decal)) + if(gender == PLURAL) + f_name = "some " + else + f_name = "a " + f_name += "blood-stained [name]!" - if (!( usr )) - return - usr << "That's \a [src]." //changed to "That's" from "This is" because "This is some metal sheets" sounds dumb compared to "That's some metal sheets" ~Carn - usr << desc - // *****RM - //usr << "[name]: Dn:[density] dir:[dir] cont:[contents] icon:[icon] is:[icon_state] loc:[loc]" - return + user << "\icon[src] That's [f_name]" + + if(desc) + user << desc + + return distance == -1 || (get_dist(src, user) <= distance) // called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set. // see code/modules/mob/mob_movement.dm for more. diff --git a/code/game/verbs/atom_verbs.dm b/code/game/verbs/atom_verbs.dm deleted file mode 100644 index bac2d2b5f39..00000000000 --- a/code/game/verbs/atom_verbs.dm +++ /dev/null @@ -1,32 +0,0 @@ -/atom/movable/verb/pull() - set name = "Pull" - set category = "Object" - set src in oview(1) - - if(Adjacent(usr)) - usr.start_pulling(src) - return - -/atom/verb/point() - set name = "Point To" - set category = "Object" - set src in oview() - var/atom/this = src//detach proc from src - src = null - - if(!usr || !isturf(usr.loc)) - return - if(usr.stat || usr.restrained()) - return - if(usr.status_flags & FAKEDEATH) - return - - var/tile = get_turf(this) - if (!tile) - return - - var/P = new /obj/effect/decal/point(tile) - spawn (20) - if(P) del(P) - - usr.visible_message("[usr] points to [this]") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c1adb74feee..b4125f6f59d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,3 +1,25 @@ +//mob verbs are faster than object verbs. See mob/verb/examine. +/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1)) + set name = "Pull" + set category = "Object" + + if(AM.Adjacent(src)) + src.start_pulling(AM) + + return + +//mob verbs are faster than object verbs. See above. +/mob/living/pointed(atom/A as mob|obj|turf in view()) + if(src.stat || !src.canmove || src.restrained()) + return 0 + if(src.status_flags & FAKEDEATH) + return 0 + if(!..()) + return 0 + + usr.visible_message("[src] points to [A]") + return 1 + /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > -95.0)) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 08ca9d32b8a..17293f2b678 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -17,21 +17,17 @@ /mob/aiEye/Move() return 0 -// Hide popout menu verbs -/mob/aiEye/examine() +/mob/aiEye/examinate(atom/A as mob|obj|turf in view()) set popup_menu = 0 set src = usr.contents return 0 -/mob/aiEye/pull() +/mob/aiEye/pointed(atom/A as mob|obj|turf in view()) set popup_menu = 0 set src = usr.contents return 0 -/mob/aiEye/point() - set popup_menu = 0 - set src = usr.contents - return 0 +/mob/aiEye/examine(mob/user) // Use this when setting the aiEye's location. // It will also stream the chunk that the new loc is in. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9e8a8c65fa3..8253bf7c32e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -47,6 +47,8 @@ /mob/visible_message(var/message, var/self_message, var/blind_message) for(var/mob/M in viewers(src)) + if(M.see_invisible < invisibility) + continue // Cannot view the invisible var/msg = message if(self_message && M==src) msg = self_message @@ -183,6 +185,40 @@ var/list/slot_equipment_priority = list( \ onclose(user, "mob[name]") return +//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine() +/mob/verb/examinate(atom/A as mob|obj|turf in view()) + set name = "Examine" + set category = "IC" + + if(is_blind(src) || usr.stat) + src << "Something is there but you can't see it." + return + + face_atom(A) + A.examine(src) + +/mob/verb/pointed(atom/A as mob|obj|turf in view()) + set name = "Point To" + set category = "Object" + + if(!src || !isturf(src.loc) || !(A in view(src.loc))) + return 0 + if(istype(A, /obj/effect/decal/point)) + return 0 + + var/tile = get_turf(A) + if (!tile) + return 0 + + var/obj/P = new /obj/effect/decal/point(tile) + P.invisibility = invisibility + spawn (20) + if(P) + del(P) // qdel + + return 1 + + /mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag) if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) ))) if (!( L )) @@ -543,11 +579,11 @@ var/list/slot_equipment_priority = list( \ pulling = null /mob/proc/start_pulling(var/atom/movable/AM) - if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort! return if (AM.anchored) + usr << "It won't budge!" return var/mob/M = AM diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 7015f84b645..b44a56dc59e 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -426,6 +426,13 @@ var/list/intents = list("help","disarm","grab","hurt") else hud_used.action_intent.icon_state = "help" +proc/is_blind(A) + if(istype(A, /mob/living/carbon)) + var/mob/living/carbon/C = A + if(C.sdisabilities & BLIND || C.blinded) + return 1 + return 0 + /proc/broadcast_security_hud_message(var/message, var/broadcast_source) broadcast_hud_message(message, broadcast_source, sec_hud_users, /obj/item/clothing/glasses/hud/security) From bc438e21ad974d0e295534f08e26bd2093531d44 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 5 Nov 2014 08:57:27 +0100 Subject: [PATCH 05/16] All the relevant examine changes. --- .../components/binary_devices/dp_vent_pump.dm | 9 ++--- .../components/unary/cold_sink.dm | 6 +-- .../components/unary/heat_source.dm | 6 +-- .../components/unary/vent_pump.dm | 12 +++--- .../components/unary/vent_scrubber.dm | 10 ++--- code/WorkInProgress/Chinsky/guestpass.dm | 8 ++-- code/WorkInProgress/SkyMarshal/wardrobes.dm | 17 ++++----- .../Wrongnumber/weldbackpack.dm | 7 ++-- code/_onclick/click.dm | 6 +-- code/_onclick/observer.dm | 2 +- code/game/gamemodes/cult/ritual.dm | 35 +++++------------ code/game/gamemodes/cult/talisman.dm | 7 ---- code/game/gamemodes/events/ninja_equipment.dm | 19 ++++------ .../mutiny/emergency_authentication_device.dm | 4 +- code/game/gamemodes/mutiny/key_pinpointer.dm | 8 ++-- code/game/gamemodes/nuclear/pinpointer.dm | 6 +-- code/game/machinery/alarm.dm | 8 ++-- code/game/machinery/atmoalter/meter.dm | 8 ++-- code/game/machinery/bots/bots.dm | 9 ++--- code/game/machinery/bots/mulebot.dm | 1 - code/game/machinery/cell_charger.dm | 11 +++--- code/game/machinery/cloning.dm | 7 ++-- code/game/machinery/constructable_frame.dm | 6 +-- code/game/machinery/doors/firedoor.dm | 19 ++++------ code/game/machinery/iv_drip.dm | 9 ++--- code/game/machinery/lightswitch.dm | 7 ++-- code/game/machinery/rechargestation.dm | 5 ++- code/game/machinery/spaceheater.dm | 14 +++---- code/game/machinery/status_display.dm | 7 ++-- code/game/mecha/mecha.dm | 38 +++++++++---------- .../effects/decals/Cleanable/humans.dm | 6 +-- code/game/objects/effects/decals/crayon.dm | 6 --- code/game/objects/effects/decals/misc.dm | 6 +-- code/game/objects/items.dm | 8 ++-- code/game/objects/items/devices/PDA/PDA.dm | 7 ++-- .../objects/items/devices/floor_painter.dm | 6 +-- .../objects/items/devices/lightreplacer.dm | 7 ++-- code/game/objects/items/devices/modkit.dm | 6 +-- .../objects/items/devices/pipe_painter.dm | 6 +-- .../game/objects/items/devices/radio/radio.dm | 12 +++--- .../objects/items/devices/suit_cooling.dm | 21 +++++----- code/game/objects/items/stacks/stack.dm | 8 ++-- code/game/objects/items/toys.dm | 24 +++++------- code/game/objects/items/weapons/RSF.dm | 7 ++-- .../objects/items/weapons/extinguisher.dm | 8 ++-- .../objects/items/weapons/gift_wrappaper.dm | 9 ++--- .../items/weapons/grenades/chem_grenade.dm | 7 ++-- .../objects/items/weapons/grenades/grenade.dm | 13 +++---- .../objects/items/weapons/storage/fancy.dm | 14 +++---- .../objects/items/weapons/storage/secure.dm | 7 ++-- code/game/objects/items/weapons/stunbaton.dm | 11 +++--- .../objects/items/weapons/tanks/jetpack.dm | 22 ++++++----- .../objects/items/weapons/tanks/tank_types.dm | 38 ++++++++----------- .../game/objects/items/weapons/tanks/tanks.dm | 8 ++-- code/game/objects/items/weapons/tools.dm | 7 ++-- code/game/objects/structures/bedsheet_bin.dm | 11 +++--- code/game/objects/structures/janicart.dm | 17 +++++---- code/game/objects/structures/mop_bucket.dm | 7 ++-- .../structures/stool_bed_chair_nest/chairs.dm | 4 +- code/game/turfs/simulated/walls.dm | 14 +++---- code/modules/assembly/assembly.dm | 11 +++--- code/modules/assembly/bomb.dm | 6 +-- code/modules/assembly/holder.dm | 11 +++--- code/modules/assembly/mousetrap.dm | 6 +-- code/modules/clothing/clothing.dm | 20 ++++------ code/modules/clothing/shoes/magboots.dm | 7 ++-- code/modules/clothing/spacesuits/alien.dm | 7 ++-- code/modules/clothing/spacesuits/breaches.dm | 6 +-- code/modules/clothing/spacesuits/ert.dm | 7 ++-- code/modules/clothing/spacesuits/rig.dm | 7 ++-- code/modules/clothing/under/ties.dm | 9 ++--- code/modules/detectivework/evidence.dm | 6 +-- .../detectivework/footprints_and_rag.dm | 7 ---- code/modules/economy/cash.dm | 9 ++--- code/modules/games/cards.dm | 10 ++--- code/modules/hydroponics/seeds.dm | 6 +-- code/modules/mining/satchel_ore_boxdm.dm | 24 +++++------- code/modules/mob/dead/observer/observer.dm | 10 +++-- .../mob/living/carbon/brain/brain_item.dm | 12 ++---- .../mob/living/carbon/brain/posibrain.dm | 13 ++----- .../carbon/human/alien/alien_facehugger.dm | 10 ++--- code/modules/mob/living/carbon/human/emote.dm | 2 +- .../mob/living/carbon/human/examine.dm | 11 +----- code/modules/mob/living/carbon/human/human.dm | 4 +- .../mob/living/carbon/metroid/examine.dm | 14 ++----- .../mob/living/carbon/monkey/examine.dm | 14 ++----- code/modules/mob/living/silicon/ai/ai.dm | 5 +++ code/modules/mob/living/silicon/ai/examine.dm | 12 ++---- .../modules/mob/living/silicon/pai/examine.dm | 9 ++--- code/modules/mob/living/silicon/pai/pai.dm | 15 ++------ .../silicon/robot/drone/drone_manufacturer.dm | 8 ++-- .../mob/living/silicon/robot/examine.dm | 13 ++----- code/modules/mob/living/simple_animal/bees.dm | 1 - .../mob/living/simple_animal/constructs.dm | 9 ++--- .../simple_animal/friendly/spiderbot.dm | 6 +-- code/modules/mob/mob.dm | 3 +- code/modules/paperwork/paper.dm | 22 +++++------ code/modules/paperwork/paper_bundle.dm | 11 ++---- code/modules/paperwork/paperbin.dm | 13 +++---- code/modules/paperwork/photography.dm | 13 +++---- code/modules/power/antimatter/fuel.dm | 7 ++-- code/modules/power/apc.dm | 25 ++++++------ code/modules/power/breaker_box.dm | 8 ++-- code/modules/power/cable.dm | 11 +++--- code/modules/power/cell.dm | 17 +++++---- code/modules/power/lighting.dm | 36 +++++++++--------- code/modules/power/pacman2.dm | 8 ++-- code/modules/power/port_gen.dm | 15 ++++---- code/modules/power/singularity/collector.dm | 7 ++-- .../particle_accelerator.dm | 4 +- code/modules/projectiles/guns/alien.dm | 6 +-- code/modules/projectiles/guns/projectile.dm | 10 ++--- .../projectiles/guns/projectile/crossbow.dm | 14 +++---- .../projectiles/guns/projectile/pneumatic.dm | 27 +++++++------ .../projectiles/guns/projectile/rocket.dm | 9 ++--- code/modules/reagents/dartgun.dm | 10 ++--- code/modules/reagents/grenade_launcher.dm | 9 ++--- .../reagents/reagent_containers/borghydro.dm | 11 +++--- .../reagents/reagent_containers/food/cans.dm | 17 ++++----- .../reagent_containers/food/drinks.dm | 17 ++++----- .../reagent_containers/food/sandwich.dm | 6 +-- .../reagent_containers/food/snacks.dm | 13 +++---- .../reagents/reagent_containers/glass.dm | 13 +++---- .../reagents/reagent_containers/hypospray.dm | 8 ++-- .../reagents/reagent_containers/spray.dm | 14 +++---- code/modules/reagents/reagent_dispenser.dm | 24 ++++++------ code/modules/reagents/syringe_gun.dm | 8 ++-- code/modules/recycling/sortingmachinery.dm | 26 ++++++------- .../tools/tools_coresampler.dm | 12 ++---- code/modules/vehicles/cargo_train.dm | 36 ++++++++---------- code/modules/virus2/items_devices.dm | 8 ++-- code/unused/Agouri_stuff.dm | 6 +-- code/unused/assemblies.dm | 18 ++++----- code/unused/hivebot/examine.dm | 20 +++++----- code/unused/pipe.dm | 34 ++++++++--------- 135 files changed, 665 insertions(+), 876 deletions(-) diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index c31f6f92b78..43cab4f6ec7 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -200,12 +200,9 @@ if(frequency) set_frequency(frequency) -/obj/machinery/atmospherics/binary/dp_vent_pump/examine() - set src in oview(1) - ..() - - if (get_dist(usr, src) <= 1) - usr << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" +/obj/machinery/atmospherics/binary/dp_vent_pump/examine(mob/user) + if(..(user, 1)) + user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" /obj/machinery/atmospherics/unary/vent_pump/power_change() var/old_stat = stat diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index bd3c3b17965..b48e1c5cbe9 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -201,7 +201,7 @@ ..() -/obj/machinery/atmospherics/unary/freezer/examine() - ..() +/obj/machinery/atmospherics/unary/freezer/examine(mob/user) + ..(user) if (opened) - usr << "The maintenance hatch is open." \ No newline at end of file + user << "The maintenance hatch is open." diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 15d416fff0f..db193cc2dd2 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -184,7 +184,7 @@ ..() -/obj/machinery/atmospherics/unary/heater/examine() - ..() +/obj/machinery/atmospherics/unary/heater/examine(mob/user) + ..(user) if (opened) - usr << "The maintenance hatch is open." \ No newline at end of file + user << "The maintenance hatch is open." diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 925994546ee..ff43e913857 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -375,15 +375,13 @@ else ..() -/obj/machinery/atmospherics/unary/vent_pump/examine() - set src in oview(1) - ..() - if (get_dist(usr, src) <= 1) - usr << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" +/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user) + if(..(user, 1)) + user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" else - usr << "You are too far away to read the gauge." + user << "You are too far away to read the gauge." if(welded) - usr << "It seems welded shut." + user << "It seems welded shut." /obj/machinery/atmospherics/unary/vent_pump/power_change() var/old_stat = stat diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 2bad9230e52..fdae89d97e0 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -260,13 +260,11 @@ new /obj/item/pipe(loc, make_from=src) del(src) -/obj/machinery/atmospherics/unary/vent_scrubber/examine() - set src in oview(1) - ..() - if (get_dist(usr, src) <= 1) - usr << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" +/obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user) + if(..(user, 1)) + user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" else - usr << "You are too far away to read the gauge." + user << "You are too far away to read the gauge." /obj/machinery/atmospherics/unary/vent_scrubber/Del() if(initial_loc) diff --git a/code/WorkInProgress/Chinsky/guestpass.dm b/code/WorkInProgress/Chinsky/guestpass.dm index 5f798fa61af..2fc9c700bcc 100644 --- a/code/WorkInProgress/Chinsky/guestpass.dm +++ b/code/WorkInProgress/Chinsky/guestpass.dm @@ -16,12 +16,12 @@ else return temp_access -/obj/item/weapon/card/id/guest/examine() - ..() +/obj/item/weapon/card/id/guest/examine(mob/user) + ..(user) if (world.time < expiration_time) - usr << "This pass expires at [worldtime2text(expiration_time)]." + user << "This pass expires at [worldtime2text(expiration_time)]." else - usr << "It expired at [worldtime2text(expiration_time)]." + user << "It expired at [worldtime2text(expiration_time)]." /obj/item/weapon/card/id/guest/read() if (world.time > expiration_time) diff --git a/code/WorkInProgress/SkyMarshal/wardrobes.dm b/code/WorkInProgress/SkyMarshal/wardrobes.dm index 420345214f0..ffbf4d69837 100755 --- a/code/WorkInProgress/SkyMarshal/wardrobes.dm +++ b/code/WorkInProgress/SkyMarshal/wardrobes.dm @@ -63,16 +63,13 @@ user.visible_message("\blue [user] gathers up[could_fill ? " " : " most of "]the pile of items and puts it into [src].") update_icon() - examine() - set src in view() - ..() - if(src in usr) - usr << "It claims to contain [contents.len ? descriptor : descriptor + "... but it looks empty"]." - if(seal_torn && !contents.len) - usr << "The seal on the bag is broken." - else - usr << "The seal on the bag is[seal_torn ? ", however, not intact" : " intact"]." - return + examine(mob/user) + ..(user) + user << "It claims to contain [contents.len ? descriptor : descriptor + "... but it looks empty"]." + if(seal_torn && !contents.len) + user << "The seal on the bag is broken." + else + user << "The seal on the bag is[seal_torn ? ", however, not intact" : " intact"]." update_icon() if(contents.len) diff --git a/code/WorkInProgress/Wrongnumber/weldbackpack.dm b/code/WorkInProgress/Wrongnumber/weldbackpack.dm index 18899745c9a..f1c786d3e11 100644 --- a/code/WorkInProgress/Wrongnumber/weldbackpack.dm +++ b/code/WorkInProgress/Wrongnumber/weldbackpack.dm @@ -46,8 +46,7 @@ user << "\blue The pack is already full!" return -/obj/item/weapon/weldpack/examine() - set src in usr - usr << text("\icon[] [] units of fuel left!", src, src.reagents.total_volume) - ..() +/obj/item/weapon/weldpack/examine(mob/user) + ..(user) + user << text("\icon[] [] units of fuel left!", src, src.reagents.total_volume) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 053bd48b7ca..586b2622593 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -303,7 +303,6 @@ // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(var/atom/A) - // Snowflake for space vines. var/is_buckled = 0 if(buckled) @@ -312,8 +311,7 @@ is_buckled = 1 else is_buckled = 0 - - if( stat || is_buckled || !A || !x || !y || !A.x || !A.y ) return + if( is_buckled || !A || !x || !y || !A.x || !A.y || (stat && !isobserver(src))) return var/dx = A.x - x var/dy = A.y - y if(!dx && !dy) return @@ -325,7 +323,7 @@ else if(dx > 0) direction = EAST else direction = WEST - usr.dir = direction + dir = direction if(buckled && buckled.movable) buckled.dir = direction buckled.handle_rotation() \ No newline at end of file diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index aa135a66541..337a0442355 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -41,7 +41,7 @@ // Oh by the way this didn't work with old click code which is why clicking shit didn't spam you /atom/proc/attack_ghost(mob/dead/observer/user as mob) if(user.client && user.client.inquisitive_ghost) - examine(user) + user.examinate(src) return // --------------------------------------- diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index e60795f5fd9..ba12a7478aa 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -20,7 +20,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", runewords-=cultwords[word] /obj/effect/rune - desc = "" + desc = "A strange collection of symbols drawn in blood." anchored = 1 icon = 'icons/obj/rune.dmi' icon_state = "1" @@ -68,26 +68,10 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", for(var/mob/living/silicon/ai/AI in player_list) AI.client.images += blood - examine() - set src in view(2) - - if(!iscultist(usr)) - usr << "A strange collection of symbols drawn in blood." - return - /* Explosions... really? - if(desc && !usr.stat) - usr << "It reads: [desc]." - sleep(30) - explosion(src.loc, 0, 2, 5, 5) - if(src) - del(src) - */ - if(!desc) - usr << "A spell circle drawn in blood. It reads: [word1] [word2] [word3]." - else - usr << "Explosive Runes inscription in blood. It reads: [desc]." - - return + examine(mob/user) + ..() + if(iscultist(user)) + user << "This spell circle reads: [word1] [word2] [word3]." attackby(I as obj, user as mob) @@ -510,12 +494,11 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", user << "You copy the translation notes from your tome." - examine() - set src in usr - if(!iscultist(usr)) - usr << "An old, dusty tome with frayed edges and a sinister looking cover." + examine(mob/user) + if(!iscultist(user)) + user << "An old, dusty tome with frayed edges and a sinister looking cover." else - usr << "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though." + user << "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though." /obj/item/weapon/book/tome/imbued //admin tome, spawns working runes without waiting w_class = 2.0 diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index a319e83421e..961f38fc0d9 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -3,13 +3,6 @@ var/imbue = null var/uses = 0 - - examine() - set src in view(2) - ..() - return - - attack_self(mob/living/user as mob) if(iscultist(user)) var/delete = 1 diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm index 48b99580fdd..99b127ec1be 100644 --- a/code/game/gamemodes/events/ninja_equipment.dm +++ b/code/game/gamemodes/events/ninja_equipment.dm @@ -911,9 +911,8 @@ ________________________________________________________________________________ U.drop_item() return 0 -/obj/item/clothing/suit/space/space_ninja/examine() - set src in view() - ..() +/obj/item/clothing/suit/space/space_ninja/examine(mob/user) + ..(user) if(s_initialized) var/mob/living/carbon/human/U = affecting if(s_control) @@ -1168,9 +1167,8 @@ ________________________________________________________________________________ U << "You [candrain?"disable":"enable"] special interaction." candrain=!candrain -/obj/item/clothing/gloves/space_ninja/examine() - set src in view() - ..() +/obj/item/clothing/gloves/space_ninja/examine(mob/user) + ..(user) if(!canremove) var/mob/living/carbon/human/U = loc U << "The energy drain mechanism is: [candrain?"active":"inactive"]." @@ -1306,12 +1304,11 @@ ________________________________________________________________________________ var/mob/U = loc U << "Switching mode to [ninja_vision.mode]." -/obj/item/clothing/mask/gas/voice/space_ninja/examine() - set src in view() - ..() +/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user) + ..(user) - usr << "[ninja_vision.mode] is active."//Leaving usr here since it may be on the floor or on a person. - usr << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." + user << "[ninja_vision.mode] is active." + user << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." /* =================================================================================== diff --git a/code/game/gamemodes/mutiny/emergency_authentication_device.dm b/code/game/gamemodes/mutiny/emergency_authentication_device.dm index 5bdcf27576e..bedd67e64cf 100644 --- a/code/game/gamemodes/mutiny/emergency_authentication_device.dm +++ b/code/game/gamemodes/mutiny/emergency_authentication_device.dm @@ -99,7 +99,7 @@ return ..() -/obj/machinery/emergency_authentication_device/examine() - usr << {" +/obj/machinery/emergency_authentication_device/examine(mob/user) + user << {" This is a specialized communications device that is able to instantly send a message to NanoTrasen High Command via quantum entanglement with a sister device at CentCom. The EAD's status is [get_status()]."} diff --git a/code/game/gamemodes/mutiny/key_pinpointer.dm b/code/game/gamemodes/mutiny/key_pinpointer.dm index c481fd5bbc8..7e8d628d85b 100644 --- a/code/game/gamemodes/mutiny/key_pinpointer.dm +++ b/code/game/gamemodes/mutiny/key_pinpointer.dm @@ -25,14 +25,14 @@ icon_state = "pinoff" usr << "\blue You switch \the [src] off." -/obj/item/weapon/pinpointer/advpinpointer/auth_key/examine() +/obj/item/weapon/pinpointer/advpinpointer/auth_key/examine(mob/user) switch(mode) if (1) - usr << "Is is calibrated for the Captain's Authentication Key." + user << "Is is calibrated for the Captain's Authentication Key." if (2) - usr << "It is calibrated for the Emergency Secondary Authentication Key." + user << "It is calibrated for the Emergency Secondary Authentication Key." else - usr << "It is switched off." + user << "It is switched off." /datum/supply_packs/key_pinpointer name = "Authentication Key Pinpointer crate" diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 9b49e37fae1..36137a74a93 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -42,11 +42,11 @@ icon_state = "pinonfar" spawn(5) .() - examine() - ..() + examine(mob/user) + ..(user) for(var/obj/machinery/nuclearbomb/bomb in world) if(bomb.timing) - usr << "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]" + user << "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]" /obj/item/weapon/pinpointer/advpinpointer diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 6ca98474f7e..41cb13ec08e 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -1168,12 +1168,12 @@ table tr:first-child th:first-child { border: none;} spawn(rand(0,15)) update_icon() -/obj/machinery/alarm/examine() - ..() +/obj/machinery/alarm/examine(mob/user) + ..(user) if (buildstage < 2) - usr << "It is not wired." + user << "It is not wired." if (buildstage < 1) - usr << "The circuit is missing." + user << "The circuit is missing." /* AIR ALARM CIRCUIT Just a object used in constructing air alarms diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 1c99ff73448..ad7d55c2aa5 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -65,10 +65,10 @@ ) radio_connection.post_signal(src, signal) -/obj/machinery/meter/examine() +/obj/machinery/meter/examine(mob/user) var/t = "A gas flow meter. " - if(get_dist(usr, src) > 3 && !(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))) + if(get_dist(user, src) > 3 && !(istype(user, /mob/living/silicon/ai) || istype(user, /mob/dead))) t += "\blue You are too far away to read it." else if(stat & (NOPOWER|BROKEN)) @@ -83,12 +83,12 @@ else t += "The connect error light is blinking." - usr << t + user << t /obj/machinery/meter/Click() if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine - examine() + usr.examinate(src) return 1 return ..() diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 9289c438e90..d41405aed36 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -43,14 +43,13 @@ emagged = 2 log_and_message_admins("emagged [src]'s inner circuits") -/obj/machinery/bot/examine() - set src in view() - ..() +/obj/machinery/bot/examine(mob/user) + ..(user) if (src.health < maxhealth) if (src.health > maxhealth/3) - usr << "[src]'s parts look loose." + user << "[src]'s parts look loose." else - usr << "[src]'s parts look very loose!" + user << "[src]'s parts look very loose!" return /obj/machinery/bot/attack_animal(var/mob/living/simple_animal/M as mob) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index ce76680b0d9..0ff1bec2775 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -93,7 +93,6 @@ suffix = "#[count]" name = "Mulebot ([suffix])" - verbs -= /atom/movable/verb/pull // set up the wire colours in random order diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 4608944b5f2..171646c4b15 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -28,12 +28,13 @@ else overlays.Cut() -/obj/machinery/cell_charger/examine() - set src in oview(5) - ..() - usr << "There's [charging ? "a" : "no"] cell in the charger." +/obj/machinery/cell_charger/examine(mob/user) + if(!..(user, 5)) + return + + user << "There's [charging ? "a" : "no"] cell in the charger." if(charging) - usr << "Current charge: [charging.charge]" + user << "Current charge: [charging.charge]" /obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user) if(stat & BROKEN) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 8084ab09ff0..dc1ee050aa8 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -96,10 +96,9 @@ src.read_only = !src.read_only user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]." -/obj/item/weapon/disk/data/examine() - set src in oview(5) - ..() - usr << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") +/obj/item/weapon/disk/data/examine(mob/user) + ..(user) + user << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") return //Health Tracker Implant diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 106cd2bbad2..4e5b64c631b 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -288,9 +288,9 @@ obj/item/weapon/circuitboard/rdserver user.visible_message("\blue \The [user] adjusts the jumper on the [src]'s port configuration pins.", "\blue You adjust the jumper on the port configuration pins. Now set to [dir2text(machine_dir)].") return -/obj/item/weapon/circuitboard/unary_atmos/examine() - ..() - usr << "The jumper is connecting the [dir2text(machine_dir)] pins." +/obj/item/weapon/circuitboard/unary_atmos/examine(mob/user) + ..(user) + user << "The jumper is connecting the [dir2text(machine_dir)] pins." /obj/item/weapon/circuitboard/unary_atmos/construct(var/obj/machinery/atmospherics/unary/U) //TODO: Move this stuff into the relevant constructor when pipe/construction.dm is cleaned up. diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 88c97b9bf44..1335f4c2f80 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -2,7 +2,7 @@ /var/const/CLOSED = 2 #define FIREDOOR_MAX_PRESSURE_DIFF 25 // kPa -#define FIREDOOR_MAX_TEMP 50 // °C +#define FIREDOOR_MAX_TEMP 50 // °C #define FIREDOOR_MIN_TEMP 0 // Bitflags @@ -72,17 +72,14 @@ . = ..() -/obj/machinery/door/firedoor/examine() - set src in view() - . = ..() - - if(get_dist(src, usr) > 1 && !isAI(usr)) +/obj/machinery/door/firedoor/examine(mob/user) + if(!..(user, 1) && !isAI(user)) return if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF) - usr << "WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!" + user << "WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!" - usr << "Sensor readings:" + user << "Sensor readings:" for(var/index = 1; index <= tile_info.len; index++) var/o = "  " switch(index) @@ -96,7 +93,7 @@ o += "WEST: " if(tile_info[index] == null) o += "DATA UNAVAILABLE" - usr << o + user << o continue var/celsius = convert_k2c(tile_info[index][1]) var/pressure = tile_info[index][2] @@ -107,14 +104,14 @@ o += "[celsius]°C " o += "" o += "[pressure]kPa" - usr << o + user << o if(islist(users_to_open) && users_to_open.len) var/users_to_open_string = users_to_open[1] if(users_to_open.len >= 2) for(var/i = 2 to users_to_open.len) users_to_open_string += ", [users_to_open[i]]" - usr << "These people have opened \the [src] during an alert: [users_to_open_string]." + user << "These people have opened \the [src] during an alert: [users_to_open_string]." /obj/machinery/door/firedoor/Bumped(atom/AM) if(p_open || operating) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index e677e6e8be9..63ad92f017d 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -146,12 +146,11 @@ mode = !mode usr << "The IV drip is now [mode ? "injecting" : "taking blood"]." -/obj/machinery/iv_drip/examine() - set src in view() - ..() - if (!(usr in view(2)) && usr!=src.loc) return +/obj/machinery/iv_drip/examine(mob/user) + ..(user) + if (!(user in view(2)) && user!=src.loc) return - usr << "The IV drip is [mode ? "injecting" : "taking blood"]." + user << "The IV drip is [mode ? "injecting" : "taking blood"]." if(beaker) if(beaker.reagents && beaker.reagents.reagent_list.len) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index f75ebc4171c..f7c1bcfa8f3 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -37,10 +37,9 @@ else icon_state = "light0" -/obj/machinery/light_switch/examine() - set src in oview(1) - if(usr && !usr.stat) - usr << "A light switch. It is [on? "on" : "off"]." +/obj/machinery/light_switch/examine(mob/user) + if(..(user, 1)) + user << "A light switch. It is [on? "on" : "off"]." /obj/machinery/light_switch/attack_paw(mob/user) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index d4b5f90d681..3049a6f6943 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -70,8 +70,9 @@ allow_drop() return 0 - examine() - usr << "The charge meter reads: [round(chargepercentage())]%" + examine(mob/user) + ..(user) + user << "The charge meter reads: [round(chargepercentage())]%" proc/chargepercentage() return ((current_internal_charge / max_internal_charge) * 100) diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index f6a1455e78c..bc65e08eb43 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -25,18 +25,14 @@ if(open) overlays += "sheater-open" -/obj/machinery/space_heater/examine() - set src in oview(12) - if (!( usr )) - return - usr << "This is \icon[src] \an [src.name]." - usr << src.desc +/obj/machinery/space_heater/examine(mob/user) + ..(user) - usr << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." + user << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." if(open) - usr << "The power cell is [cell ? "installed" : "missing"]." + user << "The power cell is [cell ? "installed" : "missing"]." else - usr << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" + user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" return /obj/machinery/space_heater/emp_act(severity) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index a652cd50f0d..8d7ed7fccc4 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -124,11 +124,10 @@ return 1 return 0 -/obj/machinery/status_display/examine() - set src in view() - . = ..() +/obj/machinery/status_display/examine(mob/user) + . = ..(user) if(mode != STATUS_DISPLAY_BLANK && mode != STATUS_DISPLAY_ALERT) - usr << "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]" + user << "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]" /obj/machinery/status_display/proc/set_message(m1, m2) if(m1) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 51352e3afb9..2a33539bc86 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -83,7 +83,6 @@ add_cell() add_iterators() removeVerb(/obj/mecha/verb/disconnect_from_port) - removeVerb(/atom/movable/verb/pull) log_message("[src.name] created.") loc.Entered(src) mechas_list += src //global mech list @@ -165,25 +164,24 @@ else return 0 -/obj/mecha/examine() - set src in view() - ..() +/obj/mecha/examine(mob/user) + ..(user) var/integrity = health/initial(health)*100 switch(integrity) if(85 to 100) - usr << "It's fully intact." + user << "It's fully intact." if(65 to 85) - usr << "It's slightly damaged." + user << "It's slightly damaged." if(45 to 65) - usr << "It's badly damaged." + user << "It's badly damaged." if(25 to 45) - usr << "It's heavily damaged." + user << "It's heavily damaged." else - usr << "It's falling apart." + user << "It's falling apart." if(equipment && equipment.len) - usr << "It's equipped with:" + user << "It's equipped with:" for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - usr << "\icon[ME] [ME]" + user << "\icon[ME] [ME]" return @@ -1406,11 +1404,11 @@ /obj/mecha/proc/output_maintenance_dialog(obj/item/weapon/card/id/id_card,mob/user) if(!id_card || !user) return - + var/maint_options = "Set Cabin Air Pressure" if (locate(/obj/item/mecha_parts/mecha_equipment/tool/passenger) in contents) - maint_options += "Remove Passenger" - + maint_options += "Remove Passenger" + var/output = {"