diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index a089f57f31b..244484d8a84 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -161,6 +161,13 @@ var/insecure = TRUE var/securitylock = FALSE + /// Override access by code level. This is an associative list that should only be set through /obj/effect/map_effect/door_helper/level_access. + /// Structure example: "red" -> list(1, 2) + /// Uses standard access if the current level is not on the list. + var/list/access_by_level + /// As above, but with req_one_access. Note that only one of these lists should ever be set. + var/list/req_one_access_by_level + /obj/machinery/door/airlock/Initialize(mapload, dir, populate_components, obj/structure/door_assembly/assembly = null) var/on_admin_z = FALSE //wires & hatch - this needs to be done up here so the hatch isn't generated by the parent Initialize(). @@ -2064,6 +2071,8 @@ About the new airlock wires panel: to_chat(user, bracer.health) if(p_open) to_chat(user, "\The [src]'s maintenance panel has been unscrewed and is hanging open.") + if(islist(access_by_level) || islist(req_one_access_by_level)) + to_chat(user, SPAN_NOTICE("This airlock changes access requirements depending on the level.")) /obj/machinery/door/airlock/emag_act(var/remaining_charges) . = ..() diff --git a/code/modules/effects/map_effects/door_helper.dm b/code/modules/effects/map_effects/door_helper.dm index b886a5315d9..40568594e25 100644 --- a/code/modules/effects/map_effects/door_helper.dm +++ b/code/modules/effects/map_effects/door_helper.dm @@ -1,13 +1,44 @@ /obj/effect/map_effect/door_helper layer = DOOR_CLOSED_LAYER + 0.1 -/obj/effect/map_effect/door_helper/unres - icon_state = "unres_door" - -/obj/effect/map_effect/door_helper/unres/Initialize(mapload, ...) +/obj/effect/map_effect/door_helper/Initialize(mapload, ...) ..() for(var/obj/machinery/door/D in loc) if(istype(D, /obj/machinery/door/blast) || istype(D, /obj/machinery/door/firedoor)) continue - D.unres_dir ^= dir + modify_door(D) return INITIALIZE_HINT_QDEL + +/obj/effect/map_effect/door_helper/proc/modify_door(obj/machinery/door/D) + return + +/obj/effect/map_effect/door_helper/unres + icon_state = "unres_door" + +/obj/effect/map_effect/door_helper/unres/modify_door(obj/machinery/door/D) + D.unres_dir ^= dir + +/obj/effect/map_effect/door_helper/level_access + icon_state = "level_door" + + /// Sets access_by_level (access override based on security level) on the airlock this is spawned on. + /// For more information check the access_by_level variable on the airlock. + /// Example of an appropriate way to set this: list("red" = list(1, 2)) + /// Alternatively, for a door that is free access on a certain code: list("green" = null) + var/list/access_by_level + /// As above, but with req_one_access. Note that only one of these lists should ever be set. + var/list/req_one_access_by_level + +/obj/effect/map_effect/door_helper/level_access/modify_door(obj/machinery/door/D) + if(length(access_by_level) && length(req_one_access_by_level)) + crash_with("Airlock access level modifier at [x] [y] [z] spawned with both access lists set.") + if(isairlock(D)) + var/obj/machinery/door/airlock/A = D + A.access_by_level = access_by_level + A.req_one_access_by_level = req_one_access_by_level + +/obj/effect/map_effect/door_helper/level_access/test1 + access_by_level = list("green" = list(access_security)) + +/obj/effect/map_effect/door_helper/level_access/test2 + req_one_access_by_level = list("green" = list(access_security, access_heads)) diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm index bc72bf02b05..7028615d914 100644 --- a/code/modules/security levels/keycard authentication.dm +++ b/code/modules/security levels/keycard authentication.dm @@ -221,4 +221,16 @@ var/global/maint_all_access = 0 var/exceptional_circumstances = maint_all_access || maint_sec_access if(exceptional_circumstances && src.check_access_list(list(access_maint_tunnels))) return 1 + if(access_by_level || req_one_access_by_level) + var/sec_level = get_security_level() + if(sec_level in (req_one_access_by_level ? req_one_access_by_level : access_by_level)) + var/access_to_use = req_one_access_by_level ? req_one_access_by_level[sec_level] : access_by_level[sec_level] + if(!access_to_use) + return TRUE + if(req_one_access_by_level) + if(has_access(req_one_access = access_to_use, accesses = A)) + return TRUE + else + if(has_access(access_to_use, accesses = A)) + return TRUE return ..(M) diff --git a/html/changelogs/mattatlas-doorsbylevel.yml b/html/changelogs/mattatlas-doorsbylevel.yml new file mode 100644 index 00000000000..0ce60b38c2e --- /dev/null +++ b/html/changelogs/mattatlas-doorsbylevel.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: MattAtlas + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added a changelog editing system that should cause fewer conflicts and more accurate timestamps." + - rscdel: "Killed innocent kittens." diff --git a/icons/effects/map_effects.dmi b/icons/effects/map_effects.dmi index 9080a1fc9f4..bcfe5c600b8 100644 Binary files a/icons/effects/map_effects.dmi and b/icons/effects/map_effects.dmi differ