diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 3122f089bd6..800cdd8341a 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -42,6 +42,9 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return + if(modifiers["shift"] && modifiers["alt"]) + AltShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -99,6 +102,8 @@ /mob/living/silicon/ai/CtrlShiftClickOn(var/atom/A) A.AICtrlShiftClick(src) +/mob/living/silicon/ai/AltShiftClickOn(var/atom/A) + A.AIAltShiftClick(src) /mob/living/silicon/ai/ShiftClickOn(var/atom/A) A.AIShiftClick(src) /mob/living/silicon/ai/CtrlClickOn(var/atom/A) @@ -118,6 +123,18 @@ examine() return +/atom/proc/AIAltShiftClick() + return + +/obj/machinery/door/airlock/AIAltShiftClick() // Sets/Unsets Emergency Access Override + if(emagged) + return + if(!emergency) + Topic("aiEnable=11", list("aiEnable"="11"), 1) // 1 meaning no window (consistency!) + else + Topic("aiDisable=11", list("aiDisable"="11"), 1) + return + /atom/proc/AIShiftClick() return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 533a6d26c84..bb288fc7d48 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -46,6 +46,9 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return + if(modifiers["shift"] && modifiers["alt"]) + AltShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -262,7 +265,7 @@ return T.Adjacent(src) /* - Control+Shift click + Control+Shift/Alt+Shift click Unused except for AI */ /mob/proc/CtrlShiftClickOn(var/atom/A) @@ -271,6 +274,14 @@ /atom/proc/CtrlShiftClick(var/mob/user) return + +/mob/proc/AltShiftClickOn(var/atom/A) + A.AltShiftClick(src) + return + +/atom/proc/AltShiftClick(var/mob/user) + return + /* Misc helpers diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index fc32220b6d4..4e20ef9ec32 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -19,6 +19,9 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return + if(modifiers["shift"] && modifiers["alt"]) + AltShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -117,6 +120,8 @@ // for non-doors/apcs /mob/living/silicon/robot/CtrlShiftClickOn(var/atom/A) A.BorgCtrlShiftClick(src) +/mob/living/silicon/robot/AltShiftClickOn(var/atom/A) + A.BorgAltShiftClick(src) /mob/living/silicon/robot/ShiftClickOn(var/atom/A) A.BorgShiftClick(src) /mob/living/silicon/robot/CtrlClickOn(var/atom/A) @@ -129,9 +134,15 @@ examine() user.face_atom(src) return + +/atom/proc/BorgAltShiftClick() + return + +/obj/machinery/door/airlock/BorgAltShiftClick() // Enables emergency override on doors! Forwards to AI code. + AIAltShiftClick() /atom/proc/BorgShiftClick() - return + return /obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code. AIShiftClick() diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index f53c822a027..3b6d009a5ff 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -34,12 +34,13 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 /datum/wires/airlock/GetInteractWindow() var/obj/machinery/door/airlock/A = holder . += ..() - . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), + . += 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.arePowerSystemsOn() && !(A.stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (A.aiControlDisabled==0 ? "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.normalspeed==0 ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), + (A.emergency==0 ? "The emergency lights are off." : "The emergency lights are on.")) /datum/wires/airlock/UpdateCut(var/index, var/mended) @@ -123,9 +124,12 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 var/obj/machinery/door/airlock/A = holder switch(index) if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). + //Sending a pulse through this disables emergency access and flashes the red light on the door (if the door has power). if((A.arePowerSystemsOn()) && (!(A.stat & NOPOWER))) A.door_animate("deny") + if(A.emergency) + A.emergency = 0 + A.update_icon() 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() diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm index f5c63e381bd..017b88f9364 100644 --- a/code/game/gamemodes/events/power_failure.dm +++ b/code/game/gamemodes/events/power_failure.dm @@ -5,7 +5,7 @@ for(var/mob/M in player_list) M << sound('sound/AI/poweroff.ogg') - var/list/skipped_areas = list(/area/turret_protected/ai) + var/list/skipped_areas = list(/area/turret_protected/ai,/area/engine/engineering) for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) @@ -23,7 +23,7 @@ C.cell.charge = 0 /proc/power_restore(var/announce = 1) - var/list/skipped_areas = list(/area/turret_protected/ai) + var/list/skipped_areas = list(/area/turret_protected/ai,/area/engine/engineering) if(announce) command_alert("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal") diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 324a9ce53d9..ea15a1bf730 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -414,13 +414,13 @@ obj/machinery/bot/proc/bot_move(var/dest, var/move_speed) obj/machinery/bot/proc/bot_step(var/dest) if(path && path.len > 1) - step_to(src, path[1]) + step_towards(src, path[1]) if(get_turf(src) == path[1]) //Successful move path -= path[1] else return 0 else if(path.len == 1) - step_to(src, dest) + step_towards(src, dest) path = list() return 1 @@ -777,7 +777,7 @@ obj/machinery/bot/proc/bot_summon() /obj/machinery/bot/Bump(M as mob|obj) //Leave no door unopened! - if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(botcard))) + if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(botcard))) var/obj/machinery/door/D = M if(D.check_access(botcard)) D.open() @@ -786,4 +786,5 @@ obj/machinery/bot/proc/bot_summon() var/mob/living/Mb = M loc = Mb.loc frustration = 0 - return \ No newline at end of file + return + \ No newline at end of file diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index d5b5566d677..6bcc05dfd92 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -113,6 +113,7 @@ . = ..() if (.) return + usr.set_machine(src) var/dat dat += hack(user) dat += text({" @@ -400,25 +401,6 @@ Auto Patrol[]"}, return 1 return 0 -/obj/machinery/bot/ed209/Bump(M as mob|obj) //Leave no door unopened! - if ((istype(M, /obj/machinery/door)) && (!isnull(botcard))) - var/obj/machinery/door/D = M - if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(botcard)) - D.open() - frustration = 0 - else if ((istype(M, /mob/living/)) && (!anchored)) - loc = M:loc - frustration = 0 - return - -/* terrible -/obj/machinery/bot/ed209/Bumped(atom/movable/M as mob|obj) - spawn(0) - if (M) - var/turf/T = get_turf(src) - M:loc = T -*/ - /obj/machinery/bot/ed209/explode() walk_to(src,0) visible_message("[src] blows apart!") diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 2c437492097..eb79c59f304 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -136,6 +136,7 @@ . = ..() if (.) return + usr.set_machine(src) var/dat dat += hack(user) dat += "Medical Unit Controls v1.1

" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 196cea60241..24076937260 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -435,13 +435,14 @@ About the new airlock wires panel: /obj/machinery/door/airlock/update_icon() if(overlays) overlays.Cut() + overlays = list() + if(emergency) overlays += image('icons/obj/doors/doorint.dmi', "elights") if(density) if(locked && lights) icon_state = "door_locked" else icon_state = "door_closed" if(p_open || welded || frozen) - overlays = list() if(p_open) overlays += image(icon, "panel_open") if(welded) @@ -508,6 +509,11 @@ About the new airlock wires panel: else t1 += text("IdScan enabled. Disable?
\n", src) + if(src.emergency) + t1 += text("Emergency Access Override is enabled. Disable?
\n", src) + else + t1 += text("Emergency Access Override is disabled. Enable?
\n", src) + if(src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) t1 += text("Main Power Input wire is cut.
\n") if(src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) @@ -686,8 +692,9 @@ About the new airlock wires panel: return 1 /obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0) - // If you add an if(..()) check you must first remove the var/nowindow parameter. - // Otherwise it will runtime with this kind of error: null.Topic() + //AI + //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 door safties, 9 door speed, 11 emergency access + //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 door safties, 9 door speed, 11 emergency access if(!nowindow) ..() if(usr.stat || usr.restrained()|| usr.small) @@ -826,6 +833,13 @@ About the new airlock wires panel: usr << "The door bolt lights have been disabled." else usr << "The door bolt lights are already disabled!" + if(11) + // Emergency access + if (src.emergency) + emergency = 0 + else + usr << text("Emergency access is already disabled!") + else if(href_list["aiEnable"]) var/code = text2num(href_list["aiEnable"]) @@ -917,6 +931,13 @@ About the new airlock wires panel: usr << "The door bolt lights have been enabled" else usr << "The door bolt lights are already enabled!" + if(11) + // Emergency access + if (!src.emergency) + emergency = 1 + else + usr << text("Emergency access is already enabled!") + add_fingerprint(usr) update_icon() @@ -1209,3 +1230,8 @@ About the new airlock wires panel: return else return + + +/obj/machinery/door/airlock/CanAStarPass(var/obj/item/weapon/card/id/ID) +//Airlock is passable if it is open (!density), bot has access, and is not bolted shut) + return !density || (check_access(ID) && !locked) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index f7410d589f0..e8023a62e8c 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -18,6 +18,7 @@ var/glass = 0 var/normalspeed = 1 var/heat_proof = 0 // For glass airlocks/opacity firedoors + var/emergency = 0 var/air_properties_vary_with_direction = 0 //Multi-tile doors @@ -68,7 +69,7 @@ if(istype(AM, /obj/machinery/bot)) var/obj/machinery/bot/bot = AM - if(src.check_access(bot.botcard)) + if(src.check_access(bot.botcard) || emergency == 1) if(density) open() return @@ -76,7 +77,7 @@ if(istype(AM, /obj/mecha)) var/obj/mecha/mecha = AM if(density) - if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) + if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access) || emergency == 1)) open() else flick("door_deny", src) @@ -101,7 +102,7 @@ //used in the AStar algorithm to determinate if the turf the door is on is passable /obj/machinery/door/proc/CanAStarPass(var/obj/item/weapon/card/id/ID) - return !density || check_access(ID) + return !density /obj/machinery/door/proc/bumpopen(mob/user as mob) if(operating) return @@ -113,8 +114,10 @@ user = null if(density) - if(allowed(user)) open() - else flick("door_deny", src) + if(allowed(user) || src.emergency == 1) + open() + else + flick("door_deny", src) return /obj/machinery/door/meteorhit(obj/M as obj) @@ -153,7 +156,7 @@ open() operating = -1 return 1 - if(src.allowed(user)) + if(src.allowed(user) || src.emergency == 1) if(src.density) open() else diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 4cc8e45d6a2..a6609c03ec1 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -468,7 +468,3 @@ /obj/machinery/door/firedoor/multi_tile/triple icon = 'icons/obj/doors/DoorHazard3x1.dmi' width = 3 - -//used in the AStar algorithm to determinate if the turf the door is on is passable -/obj/machinery/door/firedoor/CanAStarPass() - return !density diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 81633dd25f2..0c0d793c34e 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -208,6 +208,41 @@ see_invisible = 45 nightvision = 0 usr.hud_used.nightvisionicon.icon_state = "nightvision0" + + +/mob/living/carbon/alien/assess_threat(var/obj/machinery/bot/secbot/judgebot, var/lasercolor) + if(judgebot.emagged == 2) + return 10 //Everyone is a criminal! + var/threatcount = 0 + + //Securitrons can't identify aliens + if(!lasercolor && judgebot.idcheck) + threatcount += 4 + + //Lasertag bullshit + if(lasercolor) + if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve + if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag))) + threatcount += 4 + + if(lasercolor == "r") + if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag))) + threatcount += 4 + + return threatcount + + //Check for weapons + if(judgebot.weaponscheck) + if(judgebot.check_for_weapons(l_hand)) + threatcount += 4 + if(judgebot.check_for_weapons(r_hand)) + threatcount += 4 + + //Loyalty implants imply trustworthyness + if(isloyal(src)) + threatcount -= 1 + + return threatcount /*---------------------------------------- Proc: AddInfectionImages() diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm index 4ff8db96a62..9d94725adf6 100644 --- a/code/modules/security levels/keycard authentication.dm +++ b/code/modules/security levels/keycard authentication.dm @@ -160,16 +160,19 @@ var/global/maint_all_access = 0 /proc/make_maint_all_access() - maint_all_access = 1 + for(var/area/maintenance/A in world) + for(var/obj/machinery/door/airlock/D in A) + D.emergency = 1 + D.update_icon(0) world << "Attention!" world << "The maintenance access requirement has been revoked on all airlocks." - + maint_all_access = 1 + /proc/revoke_maint_all_access() - maint_all_access = 0 + for(var/area/maintenance/A in world) + for(var/obj/machinery/door/airlock/D in A) + D.emergency = 0 + D.update_icon(0) world << "Attention!" world << "The maintenance access requirement has been readded on all maintenance airlocks." - -/obj/machinery/door/airlock/allowed(mob/M) - if(maint_all_access && src.check_access_list(list(access_maint_tunnels))) - return 1 - return ..(M) + maint_all_access = 0 \ No newline at end of file diff --git a/icons/obj/doors/doorint.dmi b/icons/obj/doors/doorint.dmi index 68fdd16a566..1938f24e5f8 100644 Binary files a/icons/obj/doors/doorint.dmi and b/icons/obj/doors/doorint.dmi differ