diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm index eceda53ecbe..e9f6258fa24 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm @@ -661,9 +661,7 @@ }, /area/ruin/plasma_facility/commons) "kA" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/ore/plasma, /obj/item/stack/ore/plasma, /obj/item/stack/ore/plasma, @@ -1129,9 +1127,7 @@ /area/ruin/plasma_facility/commons) "rS" = ( /obj/effect/turf_decal/bot/left, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/mineral/plasma/thirty, /turf/open/floor/iron/smooth_half{ initial_gas_mix = "ICEMOON_ATMOS" @@ -1148,9 +1144,7 @@ /obj/structure/railing{ dir = 5 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/mineral/silver, /obj/item/stack/sheet/mineral/silver, /obj/item/stack/sheet/mineral/silver, @@ -1760,9 +1754,7 @@ "FD" = ( /obj/structure/lattice/catwalk, /obj/structure/railing/corner, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/mineral/uranium/five, /obj/item/stack/sheet/mineral/uranium/five, /obj/item/stack/sheet/mineral/uranium/five, diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm index 64c6856d76c..6211bd0ef6d 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm @@ -104,9 +104,7 @@ /turf/open/floor/iron/smooth_large, /area/ruin/powered/mailroom) "jm" = ( -/obj/structure/closet/crate/mail{ - icon_state = "mailopen" - }, +/obj/structure/closet/crate/mail/preopen, /obj/item/mail/junkmail, /obj/item/mail/junkmail, /obj/item/mail/junkmail, @@ -165,9 +163,7 @@ /turf/open/floor/plating/snowed/smoothed/icemoon, /area/ruin/powered/mailroom) "oU" = ( -/obj/structure/closet/crate/mail{ - icon_state = "mailopen" - }, +/obj/structure/closet/crate/mail/preopen, /obj/item/mail/junkmail, /obj/item/mail/junkmail, /turf/open/floor/plating/snowed/smoothed/icemoon, @@ -317,9 +313,7 @@ }, /area/ruin/powered/mailroom) "Jd" = ( -/obj/structure/closet/crate/mail{ - icon_state = "mailopen" - }, +/obj/structure/closet/crate/mail/preopen, /obj/effect/turf_decal/siding/yellow, /obj/item/mail/junkmail, /obj/item/mail/junkmail, @@ -413,9 +407,7 @@ /turf/open/misc/grass, /area/ruin/powered/mailroom) "Qb" = ( -/obj/structure/closet/crate/mail{ - icon_state = "mailopen" - }, +/obj/structure/closet/crate/mail/preopen, /obj/effect/turf_decal/stripes{ dir = 8 }, @@ -494,9 +486,7 @@ /turf/open/floor/iron/white, /area/ruin/powered/mailroom) "Wr" = ( -/obj/structure/closet/crate/mail{ - icon_state = "mailopen" - }, +/obj/structure/closet/crate/mail/preopen, /obj/effect/turf_decal/siding/yellow, /obj/item/mail/junkmail, /obj/item/mail/junkmail, diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index 315eb923063..b750d66535a 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -165,9 +165,7 @@ /turf/open/floor/plating, /area/ruin/space/has_grav/derelictoutpost/powerstorage) "aN" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargobay) @@ -636,9 +634,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargobay) "cH" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/structure/cable, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargobay) @@ -965,9 +961,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) "dY" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/plasteel/twenty, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -1020,9 +1014,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) "ek" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/cardboard/fifty, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -1048,9 +1040,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) "eq" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/exotic/tool, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) @@ -1106,9 +1096,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) "eB" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/machinery/light/directional/south, /obj/effect/turf_decal/delivery, /obj/effect/spawner/random/exotic/technology, diff --git a/_maps/RandomRuins/SpaceRuins/crashedclownship.dmm b/_maps/RandomRuins/SpaceRuins/crashedclownship.dmm index f2a0595751b..128deda9e35 100644 --- a/_maps/RandomRuins/SpaceRuins/crashedclownship.dmm +++ b/_maps/RandomRuins/SpaceRuins/crashedclownship.dmm @@ -35,9 +35,7 @@ /turf/open/floor/mineral/bananium/airless, /area/ruin/space/has_grav) "j" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/ore/bananium, /turf/open/floor/mineral/bananium/airless, /area/ruin/space/has_grav) diff --git a/_maps/RandomRuins/SpaceRuins/hellfactory.dmm b/_maps/RandomRuins/SpaceRuins/hellfactory.dmm index 438e36acb59..511614db103 100644 --- a/_maps/RandomRuins/SpaceRuins/hellfactory.dmm +++ b/_maps/RandomRuins/SpaceRuins/hellfactory.dmm @@ -103,9 +103,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/hellfactory) "at" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/reagent_containers/cup/beaker/large, /obj/item/reagent_containers/cup/beaker/large, /turf/open/floor/plating, diff --git a/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm b/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm index fd4bf0a5ab1..f0ea8b833d9 100644 --- a/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm +++ b/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm @@ -25,9 +25,7 @@ /area/ruin) "hG" = ( /obj/effect/mob_spawn/corpse/human/clown, -/obj/structure/closet/secure_closet/freezer/fridge/open{ - opened = 1 - }, +/obj/structure/closet/secure_closet/freezer/fridge/preopen, /obj/item/food/burger/mime, /obj/item/food/burger/mime, /obj/item/food/pie/mimetart, @@ -61,9 +59,7 @@ /area/ruin) "ox" = ( /obj/machinery/light/small/broken/directional/east, -/obj/structure/closet{ - opened = 1 - }, +/obj/structure/closet/preopen, /obj/item/clothing/mask/gas/mime, /obj/item/clothing/mask/gas/mime, /obj/item/clothing/under/rank/civilian/mime, diff --git a/_maps/RandomRuins/SpaceRuins/waystation.dmm b/_maps/RandomRuins/SpaceRuins/waystation.dmm index a6d83df4974..8e0dde4e171 100644 --- a/_maps/RandomRuins/SpaceRuins/waystation.dmm +++ b/_maps/RandomRuins/SpaceRuins/waystation.dmm @@ -431,9 +431,7 @@ /area/ruin/space/has_grav/waystation/cargobay) "ib" = ( /obj/effect/turf_decal/delivery, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/iron, /area/ruin/space/has_grav/waystation/cargobay) "ic" = ( diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/caves.dmm index e777584ee9b..7f0c4a2e386 100644 --- a/_maps/RandomZLevels/caves.dmm +++ b/_maps/RandomZLevels/caves.dmm @@ -1258,9 +1258,7 @@ }, /area/awaymission/caves/bmp_asteroid/level_two) "ki" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/paper/fluff/awaymissions/caves/shipment_receipt, /obj/item/organ/internal/eyes/robotic/thermals, /obj/item/gun/energy/laser/captain/scattershot, diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index bc6878f0953..d1806afb8ee 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -3866,9 +3866,7 @@ /turf/open/floor/iron/white, /area/awaymission/research/interior/security) "Re" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/awaymission/research/interior/maint) diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm index 8eaedce940f..5363f08f0d2 100644 --- a/_maps/RandomZLevels/snowdin.dmm +++ b/_maps/RandomZLevels/snowdin.dmm @@ -623,9 +623,7 @@ "ce" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/directional/north, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/iron, /area/awaymission/snowdin/post/kitchen) "ch" = ( @@ -785,9 +783,7 @@ /turf/open/floor/plating, /area/awaymission/snowdin/post/research) "cD" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/awaymission/snowdin/post/mining_dock) @@ -1203,8 +1199,7 @@ /area/awaymission/snowdin/cave) "dy" = ( /obj/effect/turf_decal/weather/snow, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "explosives ordinance" }, /turf/open/floor/iron/dark/snowdin, @@ -1967,9 +1962,7 @@ /area/awaymission/snowdin/cave) "gk" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/crowbar, /obj/item/crowbar, /obj/item/pickaxe/mini, @@ -2289,9 +2282,7 @@ pixel_x = 5; pixel_y = 5 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/clothing/shoes/winterboots, /obj/item/clothing/shoes/winterboots, /turf/open/floor/plating, @@ -3492,9 +3483,7 @@ /obj/structure/sign/poster/contraband/tools{ pixel_x = 32 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/tank/internals/plasma, /obj/item/tank/internals/plasma, /turf/open/floor/plating, @@ -8253,8 +8242,7 @@ /area/awaymission/snowdin/cave) "Ca" = ( /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "explosives ordinance" }, /turf/open/floor/plating/snowed, @@ -9721,9 +9709,7 @@ /turf/open/floor/iron, /area/awaymission/snowdin/post/mining_main) "IX" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/mineral/plasma{ amount = 10 }, @@ -9815,9 +9801,7 @@ /turf/open/floor/plating, /area/awaymission/snowdin/post/mining_dock) "Jp" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/storage/toolbox/emergency, /obj/item/clothing/suit/hooded/wintercoat, /obj/item/clothing/suit/hooded/wintercoat, @@ -9830,9 +9814,7 @@ /turf/open/floor/plating/snowed/cavern, /area/awaymission/snowdin/cave/cavern) "Jt" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/storage/toolbox/emergency, /turf/open/floor/plating, /area/awaymission/snowdin/post/mining_main) @@ -9904,9 +9886,7 @@ /turf/open/floor/iron, /area/awaymission/snowdin/post/mining_dock) "JE" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/storage/toolbox/emergency, /obj/item/clothing/suit/hooded/wintercoat, /turf/open/floor/plating, @@ -9958,9 +9938,7 @@ /turf/open/floor/iron, /area/awaymission/snowdin/post/mining_main) "JN" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/clothing/suit/hooded/wintercoat, /obj/item/clothing/suit/hooded/wintercoat, /obj/item/clothing/suit/hooded/wintercoat, @@ -12674,8 +12652,7 @@ /area/awaymission/snowdin/post/research) "YR" = ( /obj/effect/turf_decal/weather/snow, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "explosives ordinance" }, /obj/machinery/light/small/directional/east, diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 4d7fe494a2b..c850f6f24f5 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -2503,9 +2503,7 @@ /area/station/cargo/storage) "aDg" = ( /obj/effect/turf_decal/delivery, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/iron, /area/station/cargo/storage) "aDt" = ( @@ -17227,9 +17225,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/clothing/head/cone, /obj/item/clothing/head/cone, /obj/item/clothing/head/cone, @@ -17726,9 +17722,7 @@ "etg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/two, /obj/effect/turf_decal/bot, /turf/open/floor/iron, @@ -23913,9 +23907,7 @@ /area/station/command/heads_quarters/hos) "fXt" = ( /obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/cargo/storage) @@ -59945,9 +59937,7 @@ /turf/open/floor/iron, /area/station/cargo/storage) "pdF" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/structure/sign/nanotrasen{ pixel_x = 32 }, @@ -72660,9 +72650,7 @@ /turf/open/floor/plating/airless, /area/space/nearstation) "sji" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance, /obj/effect/turf_decal/bot, /obj/item/electronics/apc, diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 67fab5b0c47..0502955ffb3 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -35594,9 +35594,7 @@ }, /area/station/service/chapel) "lnx" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) "lnC" = ( @@ -55811,9 +55809,7 @@ }, /obj/machinery/light/directional/west, /obj/structure/cable, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/mineral/plasma/five, /obj/effect/turf_decal/tile/dark/half/contrasted{ dir = 8 @@ -68273,9 +68269,7 @@ /area/icemoon/underground/explored) "vNT" = ( /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/machinery/light/small/directional/north, /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron, @@ -73804,9 +73798,7 @@ /obj/machinery/power/terminal{ dir = 8 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/machinery/light/directional/south, /obj/item/stack/sheet/mineral/plasma/thirty, /turf/open/floor/iron/smooth, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index f3517537536..4facd02335f 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -2158,9 +2158,7 @@ /turf/open/floor/iron/white, /area/station/medical/treatment_center) "aPk" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/plating, /area/station/maintenance/port/fore) "aPm" = ( @@ -2405,9 +2403,7 @@ /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/ai) "aUj" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/package_wrap, /obj/item/stack/package_wrap{ pixel_y = 2 @@ -5692,9 +5688,7 @@ /area/station/medical/morgue) "cfv" = ( /obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/cargo/warehouse) @@ -17078,9 +17072,7 @@ /obj/item/storage/toolbox/mechanical, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/wrench, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -44353,9 +44345,7 @@ "pVi" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light_switch/directional/north, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/iron, /area/station/cargo/warehouse) "pVM" = ( @@ -58010,9 +58000,7 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "uHa" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/rglass{ amount = 50 }, diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index b738e49895c..cc78fbc71e7 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -31128,9 +31128,7 @@ /area/station/maintenance/floor1/port/aft) "ioM" = ( /obj/effect/spawner/random/maintenance/two, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/pod/light, /area/station/maintenance/floor4/starboard/fore) @@ -34626,9 +34624,7 @@ /turf/open/floor/iron/kitchen/herringbone, /area/station/service/kitchen/diner) "jnv" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/two, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/pod/light, @@ -44792,9 +44788,7 @@ /area/station/commons/fitness/recreation) "lRc" = ( /obj/item/reagent_containers/dropper, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/pod/light, /area/station/maintenance/floor4/starboard/fore) @@ -66779,9 +66773,7 @@ "rBB" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/entertainment/drugs, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/plating, /area/station/maintenance/floor1/port/fore) "rBC" = ( @@ -74980,9 +74972,7 @@ /area/station/science/cytology) "tSf" = ( /obj/effect/spawner/random/maintenance/two, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/mop, /obj/effect/spawner/random/engineering/flashlight, /obj/effect/decal/cleanable/dirt/dust, @@ -83030,9 +83020,7 @@ /turf/open/floor/iron/dark, /area/station/commons/storage/tools) "wcR" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/engineering/material_cheap, /obj/effect/spawner/random/engineering/flashlight, /obj/effect/spawner/random/engineering/tool, diff --git a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm index e2845b4169b..ebfe88aed6b 100644 --- a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm @@ -49,9 +49,7 @@ "cZ" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/mapping_helpers/broken_floor, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/two, /turf/open/floor/plating/airless, /area/station/maintenance/department/crew_quarters/dorms) diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index e1d6c55cc0b..4128880f615 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -4468,9 +4468,7 @@ /area/station/cargo/storage) "axI" = ( /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/iron, /area/station/cargo/storage) "axJ" = ( @@ -4561,9 +4559,7 @@ "ayG" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/cardboard{ amount = 23 }, @@ -25125,9 +25121,7 @@ dir = 4 }, /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stock_parts/cell/empty, /obj/effect/spawner/random/engineering/flashlight, /turf/open/floor/iron, @@ -29475,9 +29469,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/two, /obj/effect/spawner/random/engineering/flashlight, /turf/open/floor/iron, @@ -50976,9 +50968,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/package_wrap, /obj/item/stack/package_wrap, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, diff --git a/_maps/shuttles/emergency_luxury.dmm b/_maps/shuttles/emergency_luxury.dmm index e13338b4c59..eeb25b19cca 100644 --- a/_maps/shuttles/emergency_luxury.dmm +++ b/_maps/shuttles/emergency_luxury.dmm @@ -616,9 +616,7 @@ /area/shuttle/escape/luxury) "Av" = ( /obj/effect/spawner/random/maintenance/eight, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/turf_decal/delivery, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/vomit/old, @@ -832,9 +830,7 @@ /area/shuttle/escape/luxury) "In" = ( /obj/effect/spawner/random/maintenance/eight, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/decal/cleanable/robot_debris, /obj/effect/turf_decal/delivery, /obj/effect/decal/cleanable/oil, diff --git a/_maps/shuttles/emergency_pubby.dmm b/_maps/shuttles/emergency_pubby.dmm index 919d07003ef..7fefead21ed 100644 --- a/_maps/shuttles/emergency_pubby.dmm +++ b/_maps/shuttles/emergency_pubby.dmm @@ -424,9 +424,7 @@ /turf/open/floor/plating, /area/shuttle/escape) "bn" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/machinery/light/directional/south, /obj/item/storage/toolbox/mechanical, /turf/open/floor/plating, diff --git a/_maps/shuttles/hunter_russian.dmm b/_maps/shuttles/hunter_russian.dmm index ed48ece46eb..10100224aed 100644 --- a/_maps/shuttles/hunter_russian.dmm +++ b/_maps/shuttles/hunter_russian.dmm @@ -433,9 +433,7 @@ /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, /obj/machinery/firealarm/directional/south, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /turf/open/floor/mineral/plastitanium, /area/shuttle/hunter/russian) "Gh" = ( diff --git a/_maps/shuttles/ruin_caravan_victim.dmm b/_maps/shuttles/ruin_caravan_victim.dmm index 90344acccd1..868c62c7b9c 100644 --- a/_maps/shuttles/ruin_caravan_victim.dmm +++ b/_maps/shuttles/ruin_caravan_victim.dmm @@ -146,9 +146,7 @@ /turf/open/floor/plating/airless, /area/shuttle/ruin/caravan/freighter1) "lD" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/stack/sheet/iron/fifty, /turf/open/floor/iron/dark/airless, /area/shuttle/ruin/caravan/freighter1) diff --git a/_maps/shuttles/ruin_cyborg_mothership.dmm b/_maps/shuttles/ruin_cyborg_mothership.dmm index 15b35e6de97..9cbca717c44 100644 --- a/_maps/shuttles/ruin_cyborg_mothership.dmm +++ b/_maps/shuttles/ruin_cyborg_mothership.dmm @@ -242,9 +242,7 @@ /obj/structure/window/reinforced/spawner/directional/north{ layer = 2.9 }, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/turf_decal/stripes/asteroid/line{ dir = 8 }, diff --git a/_maps/shuttles/whiteship_birdshot.dmm b/_maps/shuttles/whiteship_birdshot.dmm index aa5daf0e34a..2b4929d0101 100644 --- a/_maps/shuttles/whiteship_birdshot.dmm +++ b/_maps/shuttles/whiteship_birdshot.dmm @@ -43,9 +43,7 @@ "bo" = ( /obj/effect/turf_decal/box/white/corners, /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/three, /turf/open/floor/iron/dark/textured_large, /area/shuttle/abandoned/cargo) diff --git a/_maps/shuttles/whiteship_cere.dmm b/_maps/shuttles/whiteship_cere.dmm index 884478f50c2..acb3270965f 100644 --- a/_maps/shuttles/whiteship_cere.dmm +++ b/_maps/shuttles/whiteship_cere.dmm @@ -138,8 +138,7 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "spare equipment crate" }, /turf/open/floor/mineral/titanium/yellow, @@ -156,8 +155,7 @@ /obj/effect/turf_decal/delivery{ dir = 1 }, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "spare equipment crate" }, /obj/item/pickaxe, @@ -192,8 +190,7 @@ /obj/effect/turf_decal/delivery{ dir = 1 }, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "spare equipment crate" }, /obj/item/storage/bag/ore, @@ -270,8 +267,7 @@ }, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen"; +/obj/structure/closet/crate/preopen{ name = "spare equipment crate" }, /obj/machinery/light/directional/south, diff --git a/_maps/shuttles/whiteship_delta.dmm b/_maps/shuttles/whiteship_delta.dmm index 5280dd4f226..e3b7925447c 100644 --- a/_maps/shuttles/whiteship_delta.dmm +++ b/_maps/shuttles/whiteship_delta.dmm @@ -1917,9 +1917,7 @@ /area/shuttle/abandoned/cargo) "Ps" = ( /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/three, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -1927,9 +1925,7 @@ "Pt" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/turf_decal/box/white/corners, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/three, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, diff --git a/_maps/shuttles/whiteship_meta.dmm b/_maps/shuttles/whiteship_meta.dmm index cb58a85b76f..f2c1c0bdbbc 100644 --- a/_maps/shuttles/whiteship_meta.dmm +++ b/_maps/shuttles/whiteship_meta.dmm @@ -2026,18 +2026,14 @@ }, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/three, /turf/open/floor/iron/dark, /area/shuttle/abandoned/cargo) "Sm" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt/dust, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/effect/spawner/random/maintenance/three, /turf/open/floor/iron/dark, /area/shuttle/abandoned/cargo) diff --git a/_maps/templates/lazy_templates/wizard_den.dmm b/_maps/templates/lazy_templates/wizard_den.dmm index 025f9e8cdd0..efe2d455c23 100644 --- a/_maps/templates/lazy_templates/wizard_den.dmm +++ b/_maps/templates/lazy_templates/wizard_den.dmm @@ -455,9 +455,7 @@ /turf/open/floor/iron/white, /area/centcom/wizard_station) "Uu" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, +/obj/structure/closet/crate/preopen, /obj/item/clothing/suit/wizrobe/red, /obj/item/clothing/head/wizard/red, /obj/item/staff, diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 9f6d20023f5..b278dfb6e0e 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -187,6 +187,12 @@ ///From open: (forced) #define COMSIG_CLOSET_POST_OPEN "closet_post_open" +///From close +#define COMSIG_CLOSET_PRE_CLOSE "closet_pre_close" + #define BLOCK_CLOSE (1<<1) +///From close +#define COMSIG_CLOSET_POST_CLOSE "closet_post_close" + ///a deliver_first element closet was successfully delivered #define COMSIG_CLOSET_DELIVERED "crate_delivered" diff --git a/code/datums/components/crafting/equipment.dm b/code/datums/components/crafting/equipment.dm index 9724e07da49..e5c66b2ac56 100644 --- a/code/datums/components/crafting/equipment.dm +++ b/code/datums/components/crafting/equipment.dm @@ -57,12 +57,29 @@ time = 20 SECONDS category = CAT_EQUIPMENT -/datum/crafting_recipe/freezer_cabinat - name = "Freezer Cabinet" +/datum/crafting_recipe/secured_freezer_cabinet + name = "Secure Freezer Cabinet" result = /obj/structure/closet/secure_closet/freezer/empty reqs = list( - /obj/item/stack/sheet/iron = 2, + /obj/item/stack/sheet/iron = 5, /obj/item/assembly/igniter/condenser = 1, + /obj/item/electronics/airlock = 1, + ) + parts = list( + /obj/item/electronics/airlock = 1, + ) + time = 5 SECONDS + category = CAT_EQUIPMENT + +/datum/crafting_recipe/secure_closet + name = "Secure Closet" + result = /obj/structure/closet/secure_closet + reqs = list( + /obj/item/stack/sheet/iron = 5, + /obj/item/electronics/airlock = 1, + ) + parts = list( + /obj/item/electronics/airlock = 1, ) time = 5 SECONDS category = CAT_EQUIPMENT diff --git a/code/datums/elements/deliver_first.dm b/code/datums/elements/deliver_first.dm index 7c674bf9c71..9633a376107 100644 --- a/code/datums/elements/deliver_first.dm +++ b/code/datums/elements/deliver_first.dm @@ -85,7 +85,7 @@ return BLOCK_OPEN ///signal called by successfully opening target -/datum/element/deliver_first/proc/on_post_open(obj/structure/closet/target, force) +/datum/element/deliver_first/proc/on_post_open(obj/structure/closet/target, mob/living/user, force) SIGNAL_HANDLER if(area_check(target)) //noice, delivered! diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 9179d0fdd6a..47d4aa17154 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -9,6 +9,9 @@ density = TRUE obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the unit is open max_integrity = 250 + req_access = list() + state_open = FALSE + panel_open = FALSE circuit = /obj/item/circuitboard/machine/suit_storage_unit var/obj/item/clothing/suit/space/suit = null @@ -29,10 +32,10 @@ /// What type of additional item the unit starts with when spawned. var/storage_type = null - state_open = FALSE + /// If the SSU's doors are locked closed. Can be toggled manually via the UI, but is also locked automatically when the UV decontamination sequence is running. var/locked = FALSE - panel_open = FALSE + /// If the safety wire is cut/pulsed, the SSU can run the decontamination sequence while occupied by a mob. The mob will be burned during every cycle of cook(). var/safeties = TRUE @@ -53,9 +56,14 @@ var/breakout_time = 300 /// Power contributed by this machine to charge the mod suits cell without any capacitors var/base_charge_rate = 200 - // Final charge rate which is base_charge_rate + contribution by capacitors + /// Final charge rate which is base_charge_rate + contribution by capacitors var/final_charge_rate = 250 - + /// is the card reader installed in this machine + var/card_reader_installed = FALSE + /// physical reference of the players id card to check for PERSONAL access level + var/datum/weakref/id_card = null + /// should we prevent furthur access change + var/access_locked = FALSE /obj/machinery/suit_storage_unit/standard_unit suit_type = /obj/item/clothing/suit/space/eva @@ -158,6 +166,8 @@ /obj/machinery/suit_storage_unit/Initialize(mapload) . = ..() + + set_access() wires = new /datum/wires/suit_storage_unit(src) if(suit_type) suit = new suit_type(src) @@ -171,14 +181,39 @@ storage = new storage_type(src) update_appearance() + register_context() + /obj/machinery/suit_storage_unit/Destroy() QDEL_NULL(suit) QDEL_NULL(helmet) QDEL_NULL(mask) QDEL_NULL(mod) QDEL_NULL(storage) + id_card = null return ..() +/obj/machinery/suit_storage_unit/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + if(isnull(held_item)) + return NONE + + var/screentip_change = FALSE + if(istype(held_item, /obj/item/stock_parts/card_reader) && !locked && can_install_card_reader(user)) + context[SCREENTIP_CONTEXT_LMB] ="Install Reader" + screentip_change = TRUE + + if(held_item.tool_behaviour == TOOL_MULTITOOL && !locked && !panel_open && !state_open && card_reader_installed) + context[SCREENTIP_CONTEXT_LMB] ="[access_locked ? "Unlock" : "Lock"] Access Panel" + screentip_change = TRUE + + if(!state_open && is_operational && card_reader_installed && !isnull((held_item.GetID()))) + context[SCREENTIP_CONTEXT_LMB] ="Change Access" + screentip_change = TRUE + + return screentip_change ? CONTEXTUAL_SCREENTIP_SET : NONE + + /obj/machinery/suit_storage_unit/update_overlays() . = ..() //if things arent powered, these show anyways @@ -213,11 +248,37 @@ else . += "[base_icon_state]_ready" +/obj/machinery/suit_storage_unit/examine(mob/user) + . = ..() + if(card_reader_installed) + . += span_notice("Swipe your ID to change access levels.") + . += span_notice("Use a multitool to [access_locked ? "unlock" : "lock"] access panel after opening panel.") + else + . += span_notice("A card reader can be installed for further control access after opening its panel.") + +/// copy over access of electronics +/obj/machinery/suit_storage_unit/proc/set_access(list/accesses) + var/obj/item/electronics/airlock/electronics = locate() in component_parts + if(QDELETED(electronics)) + return + + if(!isnull(accesses)) + electronics.accesses = accesses + if(electronics.one_access) + req_one_access = electronics.accesses + req_access = null + else + req_access = electronics.accesses + req_one_access = null + /obj/machinery/suit_storage_unit/RefreshParts() . = ..() + for(var/datum/stock_part/capacitor/capacitor in component_parts) final_charge_rate = base_charge_rate + (capacitor.tier * 50) + set_access() + /obj/machinery/suit_storage_unit/power_change() . = ..() if(!is_operational && state_open) @@ -238,8 +299,31 @@ if(!(flags_1 & NODECONSTRUCT_1)) open_machine() dump_inventory_contents() + if(card_reader_installed) + new /obj/item/stock_parts/card_reader(loc) return ..() +/obj/machinery/suit_storage_unit/proc/access_check(mob/living/user) + if(!isnull(id_card)) + var/obj/item/card/id/id = id_card?.resolve() + if(!id) // reset to defaults + name = initial(name) + desc = initial(desc) + id_card = null + req_access = list() + req_one_access = null + set_access(list()) + return TRUE + if(user.get_idcard() != id) + balloon_alert(user, "not your unit!") + return FALSE + + if(!allowed(user)) + balloon_alert(user, "access denied!") + return FALSE + + return TRUE + /obj/machinery/suit_storage_unit/interact(mob/living/user) var/static/list/items @@ -292,6 +376,8 @@ switch (choice) if ("open") if (!state_open) + if(!access_check(user)) + return open_machine(drop = FALSE) if (occupant) dump_inventory_contents() @@ -299,6 +385,8 @@ if (state_open) close_machine() if ("disinfect") + if(!access_check(user)) + return if (occupant && safeties) say("Alert: safeties triggered, occupant detected!") return @@ -311,6 +399,8 @@ to_chat(mob_occupant, span_userdanger("[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!")) cook() if ("lock", "unlock") + if(locked && !access_check(user)) + return if (!state_open) locked = !locked update_icon() @@ -516,60 +606,171 @@ span_notice("You escape the cramped confines of [src]!")) open_machine() -/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) +/obj/machinery/suit_storage_unit/multitool_act(mob/living/user, obj/item/tool) + if(!card_reader_installed || state_open) + return + + if(locked) + balloon_alert(user, "unlock first!") + return + + access_locked = !access_locked + balloon_alert(user, "access panel [access_locked ? "locked" : "unlocked"]") + return TRUE + +/obj/machinery/suit_storage_unit/proc/can_install_card_reader(mob/user) + if(card_reader_installed || !panel_open || state_open || !is_operational) + return FALSE + + if(locked) + balloon_alert(user, "unlock first!") + return FALSE + + return TRUE + +/obj/machinery/suit_storage_unit/attackby(obj/item/weapon, mob/user, params) + . = TRUE + var/obj/item/card/id/id = null + if(istype(weapon, /obj/item/stock_parts/card_reader) && can_install_card_reader(user)) + user.visible_message(span_notice("[user] is installing a card reader."), + span_notice("You begin installing the card reader.")) + + if(!do_after(user, 4 SECONDS, target = src, extra_checks = CALLBACK(src, PROC_REF(can_install_card_reader), user))) + return + + qdel(weapon) + card_reader_installed = TRUE + + balloon_alert(user, "card reader installed") + + else if(!state_open && is_operational && card_reader_installed && !isnull((id = weapon.GetID()))) + if(panel_open) + balloon_alert(user, "close panel!") + return + + if(locked) + balloon_alert(user, "unlock first!") + return + + if(access_locked) + balloon_alert(user, "access panel locked!") + return + + //change the access type + var/static/list/choices = list( + "Personal", + "Departmental", + "None" + ) + var/choice = tgui_input_list(user, "Set Access Type", "Access Type", choices) + if(isnull(choice)) + return + + id_card = null + switch(choice) + if("Personal") //only the player who swiped their id has access. + id_card = WEAKREF(id) + name = "[id.registered_name] Suit Storage Unit" + desc = "Owned by [id.registered_name]. [initial(desc)]" + if("Departmental") //anyone who has the same access permissions as this id has access + name = "[id.assignment] Suit Storage Unit" + desc = "Its a [id.assignment] Suit Storage Unit. [initial(desc)]" + set_access(id.GetAccess()) + if("None") //free for all + name = initial(name) + desc = initial(desc) + req_access = list() + req_one_access = null + set_access(list()) + + if(!isnull(id_card)) + balloon_alert(user, "now owned by [id.registered_name]") + else + balloon_alert(user, "set to [choice]") + + else if(!state_open && istype(weapon, /obj/item/pen)) + if(locked) + balloon_alert(user, "unlock first!") + return + + if(isnull(id_card)) + balloon_alert(user, "not yours to rename!") + return + + var/name_set = FALSE + var/desc_set = FALSE + + var/str = tgui_input_text(user, "Personal Unit Name", "Unit Name") + if(!isnull(str)) + name = str + name_set = TRUE + + str = tgui_input_text(user, "Personal Unit Description", "Unit Description") + if(!isnull(str)) + desc = str + desc_set = TRUE + + var/bit_flag = NONE + if(name_set) + bit_flag |= UPDATE_NAME + if(desc_set) + bit_flag |= UPDATE_DESC + if(bit_flag) + update_appearance(bit_flag) + if(state_open && is_operational) - if(istype(I, /obj/item/clothing/suit)) + if(istype(weapon, /obj/item/clothing/suit)) if(suit) to_chat(user, span_warning("The unit already contains a suit!.")) return - if(!user.transferItemToLoc(I, src)) + if(!user.transferItemToLoc(weapon, src)) return - suit = I - else if(istype(I, /obj/item/clothing/head)) + suit = weapon + else if(istype(weapon, /obj/item/clothing/head)) if(helmet) to_chat(user, span_warning("The unit already contains a helmet!")) return - if(!user.transferItemToLoc(I, src)) + if(!user.transferItemToLoc(weapon, src)) return - helmet = I - else if(istype(I, /obj/item/clothing/mask)) + helmet = weapon + else if(istype(weapon, /obj/item/clothing/mask)) if(mask) to_chat(user, span_warning("The unit already contains a mask!")) return - if(!user.transferItemToLoc(I, src)) + if(!user.transferItemToLoc(weapon, src)) return - mask = I - else if(istype(I, /obj/item/mod/control)) + mask = weapon + else if(istype(weapon, /obj/item/mod/control)) if(mod) to_chat(user, span_warning("The unit already contains a MOD!")) return - if(!user.transferItemToLoc(I, src)) + if(!user.transferItemToLoc(weapon, src)) return - mod = I + mod = weapon else if(storage) to_chat(user, span_warning("The auxiliary storage compartment is full!")) return - if(!user.transferItemToLoc(I, src)) + if(!user.transferItemToLoc(weapon, src)) return - storage = I + storage = weapon - visible_message(span_notice("[user] inserts [I] into [src]"), span_notice("You load [I] into [src].")) + visible_message(span_notice("[user] inserts [weapon] into [src]"), span_notice("You load [weapon] into [src].")) update_appearance() return if(panel_open) - if(is_wire_tool(I)) + if(is_wire_tool(weapon)) wires.interact(user) return - else if(I.tool_behaviour == TOOL_CROWBAR) - default_deconstruction_crowbar(I) + else if(weapon.tool_behaviour == TOOL_CROWBAR) + default_deconstruction_crowbar(weapon) return if(!state_open) - if(default_deconstruction_screwdriver(user, "[base_icon_state]", "[base_icon_state]", I)) //Set to base_icon_state because the panels for this are overlays + if(default_deconstruction_screwdriver(user, "[base_icon_state]", "[base_icon_state]", weapon)) //Set to base_icon_state because the panels for this are overlays update_appearance() return - if(default_pry_open(I)) + if(default_pry_open(weapon)) dump_inventory_contents() return @@ -579,16 +780,21 @@ screwdriving it open while it's running a decontamination sequence without closing the panel prior to finish causes the SSU to break due to state_open being set to TRUE at the end, and the panel becoming inaccessible. */ -/obj/machinery/suit_storage_unit/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_SCREWDRIVER && uv) - to_chat(user, span_warning("It might not be wise to fiddle with [src] while it's running...")) +/obj/machinery/suit_storage_unit/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/screwdriver) + if(!(flags_1 & NODECONSTRUCT_1) && screwdriver.tool_behaviour == TOOL_SCREWDRIVER && (uv || locked)) + to_chat(user, span_warning("You cant open the panel while its [locked ? "locked" : "decontaminating"]")) return TRUE return ..() -/obj/machinery/suit_storage_unit/default_pry_open(obj/item/I)//needs to check if the storage is locked. - . = !(state_open || panel_open || is_operational || locked || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR +/obj/machinery/suit_storage_unit/default_pry_open(obj/item/crowbar)//needs to check if the storage is locked. + . = !(state_open || panel_open || is_operational || locked || (flags_1 & NODECONSTRUCT_1)) && crowbar.tool_behaviour == TOOL_CROWBAR if(.) - I.play_tool_sound(src, 50) + crowbar.play_tool_sound(src, 50) visible_message(span_notice("[usr] pries open \the [src]."), span_notice("You pry open \the [src].")) open_machine() + +/obj/machinery/suit_storage_unit/default_deconstruction_crowbar(obj/item/crowbar, ignore_panel, custom_deconstruct) + . = (!locked && panel_open && !(flags_1 & NODECONSTRUCT_1) && crowbar.tool_behaviour == TOOL_CROWBAR) + if(.) + return ..() diff --git a/code/game/objects/effects/spawners/random/structure.dm b/code/game/objects/effects/spawners/random/structure.dm index 2d65d944dfc..580f7ff1b9b 100644 --- a/code/game/objects/effects/spawners/random/structure.dm +++ b/code/game/objects/effects/spawners/random/structure.dm @@ -93,9 +93,8 @@ /obj/effect/spawner/random/structure/crate_empty/make_item(spawn_loc, type_path_to_make) var/obj/structure/closet/crate/peek_a_boo = ..() - if(istype(peek_a_boo)) - peek_a_boo.opened = prob(50) - peek_a_boo.update_appearance() + if(istype(peek_a_boo) && prob(50)) + peek_a_boo.open(special_effects = FALSE) //the crate appears immediatly out of thin air so no need to animate anything return peek_a_boo @@ -127,9 +126,8 @@ /obj/effect/spawner/random/structure/closet_empty/make_item(spawn_loc, type_path_to_make) var/obj/structure/closet/peek_a_boo = ..() - if(istype(peek_a_boo)) - peek_a_boo.opened = prob(50) - peek_a_boo.update_appearance() + if(istype(peek_a_boo) && prob(50)) + peek_a_boo.open(special_effects = FALSE) //the crate appears immediatly out of thin air so no need to animate anything return peek_a_boo diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index db1c9612f99..b71c3aff611 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -53,7 +53,8 @@ req_components = list( /obj/item/stack/sheet/glass = 2, /obj/item/stack/cable_coil = 5, - /datum/stock_part/capacitor = 1) + /datum/stock_part/capacitor = 1, + /obj/item/electronics/airlock = 1) /obj/item/circuitboard/machine/autolathe name = "Autolathe" diff --git a/code/game/objects/items/implants/implant_stealth.dm b/code/game/objects/items/implants/implant_stealth.dm index 00751d5f945..9a5a1f1c87a 100644 --- a/code/game/objects/items/implants/implant_stealth.dm +++ b/code/game/objects/items/implants/implant_stealth.dm @@ -17,19 +17,15 @@ move_speed_multiplier = 0.5 enable_door_overlay = FALSE -/obj/structure/closet/cardboard/agent/proc/go_invisible() - animate(src, , alpha = 0, time = 20) - /obj/structure/closet/cardboard/agent/Initialize(mapload) . = ..() go_invisible() -/obj/structure/closet/cardboard/agent/open(mob/living/user, force = FALSE) +/obj/structure/closet/cardboard/agent/proc/go_invisible() + animate(src, alpha = 0, time = 20) + +/obj/structure/closet/cardboard/agent/after_open(mob/living/user) . = ..() - - if(!.) - return - qdel(src) /obj/structure/closet/cardboard/agent/process() diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm index 8d4ef47c0ec..149e4968402 100644 --- a/code/game/objects/items/mail.dm +++ b/code/game/objects/items/mail.dm @@ -215,19 +215,21 @@ name = "mail crate" desc = "A certified post crate from CentCom." icon_state = "mail" + base_icon_state = "mail" can_install_electronics = FALSE lid_icon_state = "maillid" lid_x = -26 lid_y = 2 + paint_jobs = null /obj/structure/closet/crate/mail/update_icon_state() . = ..() if(opened) - icon_state = "[initial(icon_state)]open" + icon_state = "[base_icon_state]open" if(locate(/obj/item/mail) in src) - icon_state = initial(icon_state) + icon_state = base_icon_state else - icon_state = "[initial(icon_state)]sealed" + icon_state = "[base_icon_state]sealed" /// Fills this mail crate with N pieces of mail, where N is the lower of the amount var passed, and the maximum capacity of this crate. If N is larger than the number of alive human players, the excess will be junkmail. /obj/structure/closet/crate/mail/proc/populate(amount) @@ -275,6 +277,11 @@ populate(INFINITY) +/// Opened mail crate +/obj/structure/closet/crate/mail/preopen + opened = TRUE + icon_state = "mailopen" + /// Mailbag. /obj/item/storage/bag/mail name = "mail bag" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 2fada65d116..93460ba0f64 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -11,6 +11,10 @@ integrity_failure = 0.25 armor_type = /datum/armor/structure_closet blocks_emissive = EMISSIVE_BLOCK_GENERIC + /// How close being inside of the thing provides complete pressure safety. Must be between 0 and 1! + contents_pressure_protection = 0 + /// How insulated the thing is, for the purposes of calculating body temperature. Must be between 0 and 1! + contents_thermal_insulation = 0 /// The overlay for the closet's door var/obj/effect/overlay/closet_door/door_obj @@ -24,13 +28,13 @@ var/door_hinge_x = -6.5 /// Amount of time it takes for the door animation to play var/door_anim_time = 1.5 // set to 0 to make the door not animate at all - + /// Paint jobs for this closet, crates are a subtype of closet so they override these values + var/list/paint_jobs = TRUE /// Controls whether a door overlay should be applied using the icon_door value as the icon state var/enable_door_overlay = TRUE var/has_opened_overlay = TRUE var/has_closed_overlay = TRUE var/icon_door = null - var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights var/opened = FALSE var/welded = FALSE var/locked = FALSE @@ -56,19 +60,23 @@ var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable. var/anchorable = TRUE var/icon_welded = "welded" - /// How close being inside of the thing provides complete pressure safety. Must be between 0 and 1! - contents_pressure_protection = 0 - /// How insulated the thing is, for the purposes of calculating body temperature. Must be between 0 and 1! - contents_thermal_insulation = 0 /// Whether a skittish person can dive inside this closet. Disable if opening the closet causes "bad things" to happen or that it leads to a logical inconsistency. var/divable = TRUE /// true whenever someone with the strong pull component (or magnet modsuit module) is dragging this, preventing opening var/strong_grab = FALSE - ///electronics for access - var/obj/item/electronics/airlock/electronics + /// secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights + var/secure = FALSE var/can_install_electronics = TRUE var/contents_initialized = FALSE + /// is this closet locked by an exclusive id, i.e. your own personal locker + var/datum/weakref/id_card = null + /// should we prevent furthur access change + var/access_locked = FALSE + /// is the card reader installed in this machine + var/card_reader_installed = FALSE + /// access types for card reader + var/list/access_choices = TRUE /datum/armor/structure_closet melee = 20 @@ -81,11 +89,32 @@ /obj/structure/closet/Initialize(mapload) . = ..() + var/static/list/closet_paint_jobs = list( + "Cargo" = list("icon_state" = "qm"), + "Engineering" = list("icon_state" = "ce"), + "Engineering Secure" = list("icon_state" = "eng_secure"), + "Radiation" = list("icon_state" = "eng", "icon_door" = "eng_rad"), + "Tool Storage" = list("icon_state" = "eng", "icon_door" = "eng_tool"), + "Fire Equipment" = list("icon_state" = "fire"), + "Emergency" = list("icon_state" = "emergency"), + "Hydroponics" = list("icon_state" = "hydro"), + "Medical" = list("icon_state" = "med"), + "Science" = list("icon_state" = "rd"), + "Security" = list("icon_state" = "cap"), + "Mining" = list("icon_state" = "mining"), + "Virology" = list("icon_state" = "bio_viro"), + ) + if(paint_jobs) + paint_jobs = closet_paint_jobs + + if(access_choices) + var/static/list/choices = list("Personal", "Departmental", "None") + access_choices = choices + // if closed, any item at the crate's loc is put in the contents if (mapload && !opened) . = INITIALIZE_HINT_LATELOAD - update_appearance() populate_contents_immediate() var/static/list/loc_connections = list( COMSIG_CARBON_DISARM_COLLIDE = PROC_REF(locker_carbon), @@ -94,10 +123,16 @@ AddElement(/datum/element/connect_loc, loc_connections) register_context() + if(opened) + opened = FALSE //nessassary because open() proc will early return if its true + if(open(special_effects = FALSE)) //closets which are meant to be open by default dont need to be animated open + return + update_appearance() + /obj/structure/closet/LateInitialize() . = ..() - - take_contents() + if(!opened) + take_contents() //USE THIS TO FILL IT, NOT INITIALIZE OR NEW /obj/structure/closet/proc/PopulateContents() @@ -109,8 +144,8 @@ return /obj/structure/closet/Destroy() + id_card = null QDEL_NULL(door_obj) - QDEL_NULL(electronics) return ..() /obj/structure/closet/update_appearance(updates=ALL) @@ -124,7 +159,6 @@ . = ..() if(issupplypod(src)) return - layer = opened ? BELOW_OBJ_LAYER : OBJ_LAYER /obj/structure/closet/update_overlays() @@ -134,12 +168,13 @@ /obj/structure/closet/proc/closet_update_overlays(list/new_overlays) . = new_overlays if(enable_door_overlay && !is_animating_door) + var/overlay_state = isnull(base_icon_state) ? initial(icon_state) : base_icon_state if(opened && has_opened_overlay) - var/mutable_appearance/door_overlay = mutable_appearance(icon, "[icon_state]_open", alpha = src.alpha) + var/mutable_appearance/door_overlay = mutable_appearance(icon, "[overlay_state]_open", alpha = src.alpha) . += door_overlay door_overlay.overlays += emissive_blocker(door_overlay.icon, door_overlay.icon_state, src, alpha = door_overlay.alpha) // If we don't do this the door doesn't block emissives and it looks weird. else if(has_closed_overlay) - . += "[icon_door || icon_state]_door" + . += "[icon_door || overlay_state]_door" if(opened) return @@ -157,10 +192,10 @@ if(vname == NAMEOF(src, opened)) if(vval == opened) return FALSE - if(vval && !opened && open(null, TRUE)) + if(vval && !opened && open(force = TRUE)) datum_flags |= DF_VAR_EDITED return TRUE - else if(!vval && opened && close(null)) + else if(!vval && opened && close()) datum_flags |= DF_VAR_EDITED return TRUE return FALSE @@ -188,6 +223,7 @@ for(var/step in 0 to num_steps) var/angle = door_anim_angle * (closing ? 1 - (step/num_steps) : (step/num_steps)) + var/matrix/door_transform = get_door_transform(angle) var/door_state var/door_layer @@ -225,13 +261,33 @@ /obj/structure/closet/examine(mob/user) . = ..() - - . += span_notice("It can be [EXAMINE_HINT("welded")] apart.") - . += span_notice("It can be [EXAMINE_HINT("bolted")] to the ground.") - + if(id_card) + . += span_notice("It can be [EXAMINE_HINT("marked")] with a pen.") + if(can_weld_shut && !welded) + . += span_notice("Its can be [EXAMINE_HINT("welded")] shut.") + if(welded) + . += span_notice("Its [EXAMINE_HINT("welded")] shut.") + if(anchorable && !anchored) + . += span_notice("It can be [EXAMINE_HINT("bolted")] to the ground.") + if(anchored) + . += span_notice("Its [EXAMINE_HINT("bolted")] to the ground.") + if(length(paint_jobs)) + . += span_notice("It can be [EXAMINE_HINT("painted")] another texture.") if(HAS_TRAIT(user, TRAIT_SKITTISH) && divable) . += span_notice("If you bump into [p_them()] while running, you will jump inside.") + if(can_install_electronics) + if(!secure) + . += span_notice("You can install airlock electronics for access control.") + else + . += span_notice("Its airlock electronics are [EXAMINE_HINT("screwed")] in place.") + if(!card_reader_installed && length(access_choices)) + . += span_notice("You can install a card reader for furthur access control.") + else if(card_reader_installed) + . += span_notice("The card reader could be [EXAMINE_HINT("pried")] out.") + . += span_notice("Swipe your PDA with an ID card/Just ID to change access levels.") + . += span_notice("Use multitool to [access_locked ? "unlock" : "lock"] the access panel.") + /obj/structure/closet/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() var/screentip_change = FALSE @@ -247,13 +303,45 @@ if(opened) context[SCREENTIP_CONTEXT_LMB] = "Deconstruct" else - context[SCREENTIP_CONTEXT_LMB] = welded ? "Unweld" : "Weld" - screentip_change = TRUE + if(!welded && can_weld_shut) + context[SCREENTIP_CONTEXT_LMB] = "Weld" + screentip_change = TRUE + else if(welded) + context[SCREENTIP_CONTEXT_LMB] = "Unweld" + screentip_change = TRUE if(istype(held_item) && held_item.tool_behaviour == TOOL_WRENCH) context[SCREENTIP_CONTEXT_RMB] = anchored ? "Unanchor" : "Anchor" screentip_change = TRUE + if(!locked && (welded || !can_weld_shut)) + if(!secure) + if(!broken && can_install_electronics && istype(held_item, /obj/item/electronics/airlock)) + context[SCREENTIP_CONTEXT_LMB] = "Install Electronics" + screentip_change = TRUE + else + if(istype(held_item) && held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "Remove Electronics" + screentip_change = TRUE + if(!card_reader_installed && length(access_choices) && !broken && can_install_electronics && istype(held_item, /obj/item/stock_parts/card_reader)) + context[SCREENTIP_CONTEXT_LMB] = "Install Reader" + screentip_change = TRUE + if(card_reader_installed && istype(held_item) && held_item.tool_behaviour == TOOL_CROWBAR) + context[SCREENTIP_CONTEXT_LMB] = "Remove Reader" + screentip_change = TRUE + + if(!locked && !opened) + if(id_card && istype(held_item, /obj/item/pen)) + context[SCREENTIP_CONTEXT_LMB] = "Rename" + screentip_change = TRUE + if(secure && card_reader_installed && !broken) + if(!access_locked && istype(held_item) && !isnull(held_item.GetID())) + context[SCREENTIP_CONTEXT_LMB] = "Change Access" + screentip_change = TRUE + if(istype(held_item) && istype(held_item) && held_item.tool_behaviour == TOOL_MULTITOOL) + context[SCREENTIP_CONTEXT_LMB] = "[access_locked ? "Unlock" : "Lock"] Access Panel" + screentip_change = TRUE + return screentip_change ? CONTEXTUAL_SCREENTIP_SET : NONE /obj/structure/closet/CanAllowThrough(atom/movable/mover, border_dir) @@ -267,7 +355,8 @@ if(welded || locked) return FALSE if(strong_grab) - to_chat(user, span_danger("[pulledby] has an incredibly strong grip on [src], preventing it from opening.")) + if(user) + to_chat(user, span_danger("[pulledby] has an incredibly strong grip on [src], preventing it from opening.")) return FALSE var/turf/T = get_turf(src) for(var/mob/living/L in T) @@ -317,25 +406,28 @@ var/atom/movable/thing = i thing.atom_storage?.close_all() -/obj/structure/closet/proc/open(mob/living/user, force = FALSE) - if(!can_open(user, force)) +///Proc to write checks before opening a door +/obj/structure/closet/proc/before_open(mob/living/user, force) + return TRUE + +/obj/structure/closet/proc/open(mob/living/user, force = FALSE, special_effects = TRUE) + if(opened || !can_open(user, force)) return FALSE - if(opened) - return FALSE - if(SEND_SIGNAL(src, COMSIG_CLOSET_PRE_OPEN, user, force) & BLOCK_OPEN) + if(!before_open(user, force) || (SEND_SIGNAL(src, COMSIG_CLOSET_PRE_OPEN, user, force) & BLOCK_OPEN)) return FALSE welded = FALSE locked = FALSE - playsound(loc, open_sound, open_sound_volume, TRUE, -3) + if(special_effects) + playsound(loc, open_sound, open_sound_volume, TRUE, -3) opened = TRUE if(!dense_when_open) set_density(FALSE) dump_contents() - animate_door(FALSE) + if(special_effects) + animate_door(FALSE) update_appearance() - after_open(user, force) - SEND_SIGNAL(src, COMSIG_CLOSET_POST_OPEN, force) + SEND_SIGNAL(src, COMSIG_CLOSET_POST_OPEN, user, force) return TRUE ///Proc to override for effects after opening a door @@ -388,9 +480,15 @@ return TRUE +///Proc to write checks before closing a door +/obj/structure/closet/proc/before_close(mob/living/user) + return TRUE + /obj/structure/closet/proc/close(mob/living/user) if(!opened || !can_close(user)) return FALSE + if(!before_close(user) || (SEND_SIGNAL(src, COMSIG_CLOSET_PRE_CLOSE, user) & BLOCK_CLOSE)) + return FALSE take_contents() playsound(loc, close_sound, close_sound_volume, TRUE, -3) opened = FALSE @@ -398,9 +496,10 @@ animate_door(TRUE) update_appearance() after_close(user) + SEND_SIGNAL(src, COMSIG_CLOSET_POST_CLOSE, user) return TRUE -///Proc to override for effects after closing a door +///Proc to do effects after closet has closed /obj/structure/closet/proc/after_close(mob/living/user) return @@ -417,10 +516,15 @@ if (!(flags_1 & NODECONSTRUCT_1)) if(ispath(material_drop) && material_drop_amount) new material_drop(loc, material_drop_amount) - if (electronics) - var/obj/item/electronics/airlock/electronics_ref = electronics - electronics = null - electronics_ref.forceMove(drop_location()) + if (secure) + var/obj/item/electronics/airlock/electronics = new(drop_location()) + if(length(req_one_access)) + electronics.one_access = TRUE + electronics.accesses = req_one_access + else + electronics.accesses = req_access + if(card_reader_installed) + new /obj/item/stock_parts/card_reader(drop_location()) dump_contents() qdel(src) @@ -429,6 +533,38 @@ if(!broken && !(flags_1 & NODECONSTRUCT_1)) bust_open() +/obj/structure/closet/CheckParts(list/parts_list) + var/obj/item/electronics/airlock/access_control = locate() in parts_list + if(QDELETED(access_control)) + return + + if (access_control.one_access) + req_one_access = access_control.accesses + req_access = null + else + req_access = access_control.accesses + req_one_access = null + access_control.moveToNullspace() + + parts_list -= access_control + qdel(access_control) + +/obj/structure/closet/multitool_act(mob/living/user, obj/item/tool) + if(!secure || !card_reader_installed || broken || locked || opened) + return + access_locked = !access_locked + balloon_alert(user, "access panel [access_locked ? "locked" : "unlocked"]") + return TRUE + +/// sets the access for the closets from the swiped ID card +/obj/structure/closet/proc/set_access(list/accesses) + if(length(req_one_access)) + req_one_access = accesses + req_access = null + else + req_access = accesses + req_one_access = null + /obj/structure/closet/attackby(obj/item/W, mob/user, params) if(user in src) return @@ -437,94 +573,253 @@ else return ..() -/obj/structure/closet/proc/tool_interact(obj/item/W, mob/living/user)//returns TRUE if attackBy call shouldn't be continued (because tool was used/closet was of wrong type), FALSE if otherwise +/// check if we can install airlock electronics in this closet +/obj/structure/closet/proc/can_install_airlock_electronics(mob/user) + if(secure || !can_install_electronics || !(welded || !can_weld_shut)) + return FALSE + + if(broken) + balloon_alert(user, "its broken!") + return FALSE + + if(locked) + balloon_alert(user, "unlock first!") + return FALSE + + return TRUE + +/// check if we can unscrew airlock electronics from this closet +/obj/structure/closet/proc/can_unscrew_airlock_electronics(mob/user) + if(!secure || !(welded || !can_weld_shut)) + return FALSE + + if(locked) + balloon_alert(user, "unlock first!") + return FALSE + + return TRUE + +/// check if we can install card reader in this closet +/obj/structure/closet/proc/can_install_card_reader(mob/user) + if(card_reader_installed || !can_install_electronics || !length(access_choices) || !(welded || !can_weld_shut)) + return FALSE + + if(broken) + balloon_alert(user, "its broken!") + return FALSE + + if(!secure) + balloon_alert(user, "no electronics inside!") + return FALSE + + if(locked) + balloon_alert(user, "unlock first!") + return FALSE + + return TRUE + +/// check if we can pry out the card reader from this closet +/obj/structure/closet/proc/can_pryout_card_reader(mob/user) + if(!card_reader_installed || !(welded || !can_weld_shut)) + return FALSE + + if(locked) + balloon_alert(user, "unlock first!") + return FALSE + + return TRUE + +/// returns TRUE if attackBy call shouldn't be continued (because tool weaponas used/closet weaponas of weaponrong type), FALSE if otherweaponise +/obj/structure/closet/proc/tool_interact(obj/item/weapon, mob/living/user) . = TRUE - if(opened) - if(istype(W, cutting_tool)) - if(W.tool_behaviour == TOOL_WELDER) - if(!W.tool_start_check(user, amount=0)) + var/obj/item/card/id/id = null + if(!opened && istype(weapon, /obj/item/airlock_painter)) + if(!length(paint_jobs)) + return + var/choice = tgui_input_list(user, "Set Closet Paintjob", "Paintjob", paint_jobs) + if(isnull(choice)) + return + + var/obj/item/airlock_painter/painter = weapon + if(!painter.use_paint(user)) + return + var/list/paint_job = paint_jobs[choice] + icon_state = paint_job["icon_state"] + base_icon_state = icon_state + icon_door = paint_job["icon_door"] + + update_appearance() + + else if(istype(weapon, /obj/item/electronics/airlock) && can_install_airlock_electronics(user)) + user.visible_message(span_notice("[user] installs the electronics into the [src]."),\ + span_notice("You start to install electronics into the [src]...")) + + if(!do_after(user, 4 SECONDS, target = src, extra_checks = CALLBACK(src, PROC_REF(can_install_airlock_electronics), user))) + return + if(!user.transferItemToLoc(weapon, src)) + return + + CheckParts(list(weapon)) + secure = TRUE + balloon_alert(user, "electronics installed") + + update_appearance() + + else if(weapon.tool_behaviour == TOOL_SCREWDRIVER && can_unscrew_airlock_electronics(user)) + user.visible_message(span_notice("[user] begins to remove the electronics from the [src]."),\ + span_notice("You begin to remove the electronics from the [src]...")) + + if (!weapon.use_tool(src, user, 40, volume = 50, extra_checks = CALLBACK(src, PROC_REF(can_unscrew_airlock_electronics), user))) + return + + var/obj/item/electronics/airlock/airlock_electronics = new(drop_location()) + if(length(req_one_access)) + airlock_electronics.one_access = TRUE + airlock_electronics.accesses = req_one_access + else + airlock_electronics.accesses = req_access + + req_access = list() + req_one_access = null + id_card = null + secure = FALSE + balloon_alert(user, "electronics removed") + + update_appearance() + + else if(istype(weapon, /obj/item/stock_parts/card_reader) && can_install_card_reader(user)) + user.visible_message(span_notice("[user] is installing a card reader."), + span_notice("You begin installing the card reader.")) + + if(!do_after(user, 4 SECONDS, target = src, extra_checks = CALLBACK(src, PROC_REF(can_install_card_reader), user))) + return + + qdel(weapon) + card_reader_installed = TRUE + + balloon_alert(user, "card reader installed") + + else if(weapon.tool_behaviour == TOOL_CROWBAR && can_pryout_card_reader(user)) + user.visible_message(span_notice("[user] begins to pry the card reader out from [src]."),\ + span_notice("You begin to pry the card reader out from [src]...")) + + if(!weapon.use_tool(src, user, 4 SECONDS, extra_checks = CALLBACK(src, PROC_REF(can_pryout_card_reader), user))) + return + + new /obj/item/stock_parts/card_reader(drop_location()) + card_reader_installed = FALSE + + balloon_alert(user, "card reader removed") + + else if(secure && !broken && card_reader_installed && !locked && !opened && !access_locked && !isnull((id = weapon.GetID()))) + var/num_choices = length(access_choices) + if(!num_choices) + return + + var/choice + if(num_choices == 1) + choice = access_choices[1] + else + choice = tgui_input_list(user, "Set Access Type", "Access Type", access_choices) + if(isnull(choice)) + return + + id_card = null + switch(choice) + if("Personal") //only the player weaponho sweaponiped their id has access. + id_card = WEAKREF(id) + name = "[id.registered_name] locker" + desc = "now owned by [id.registered_name]. [initial(desc)]" + if("Departmental") //anyone weaponho has the same access permissions as this id has access + name = "[id.assignment] closet" + desc = "Its a [id.assignment] closet. [initial(desc)]" + set_access(id.GetAccess()) + if("None") //free for all + name = initial(name) + desc = initial(desc) + req_access = list() + req_one_access = null + set_access(list()) + + if(!isnull(id_card)) + balloon_alert(user, "now owned by [id.registered_name]") + else + balloon_alert(user, "set to [choice]") + + else if(!opened && istype(weapon, /obj/item/pen)) + if(locked) + balloon_alert(user, "unlock first!") + return + + if(isnull(id_card)) + balloon_alert(user, "not yours to rename!") + return + + var/name_set = FALSE + var/desc_set = FALSE + + var/str = tgui_input_text(user, "Personal Locker Name", "Locker Name") + if(!isnull(str)) + name = str + name_set = TRUE + + str = tgui_input_text(user, "Personal Locker Description", "Locker Description") + if(!isnull(str)) + desc = str + desc_set = TRUE + + var/bit_flag = NONE + if(name_set) + bit_flag |= UPDATE_NAME + if(desc_set) + bit_flag |= UPDATE_DESC + if(bit_flag) + update_appearance(bit_flag) + + else if(opened) + if(istype(weapon, cutting_tool)) + if(weapon.tool_behaviour == TOOL_WELDER) + if(!weapon.tool_start_check(user, amount=0)) return to_chat(user, span_notice("You begin cutting \the [src] apart...")) - if(W.use_tool(src, user, 40, volume=50)) + if(weapon.use_tool(src, user, 40, volume=50)) if(!opened) return user.visible_message(span_notice("[user] slices apart \the [src]."), - span_notice("You cut \the [src] apart with \the [W]."), - span_hear("You hear welding.")) + span_notice("You cut \the [src] apart weaponith \the [weapon]."), + span_hear("You hear weaponelding.")) deconstruct(TRUE) return - else // for example cardboard box is cut with wirecutters + else // for example cardboard box is cut weaponith weaponirecutters user.visible_message(span_notice("[user] cut apart \the [src]."), \ - span_notice("You cut \the [src] apart with \the [W].")) + span_notice("You cut \the [src] apart weaponith \the [weapon].")) deconstruct(TRUE) return if (user.combat_mode) - return FALSE - if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too return - else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut) - if(!W.tool_start_check(user, amount=0)) + if(user.transferItemToLoc(weapon, drop_location())) // so weapone put in unlit weaponelder too return - to_chat(user, span_notice("You begin [welded ? "unwelding":"welding"] \the [src]...")) - if(W.use_tool(src, user, 40, volume=50)) + else if(weapon.tool_behaviour == TOOL_WELDER && can_weld_shut) + if(!weapon.tool_start_check(user, amount=0)) + return + + if(weapon.use_tool(src, user, 40, volume=50)) if(opened) return welded = !welded after_weld(welded) user.visible_message(span_notice("[user] [welded ? "welds shut" : "unwelded"] \the [src]."), - span_notice("You [welded ? "weld" : "unwelded"] \the [src] with \the [W]."), + span_notice("You [welded ? "weld" : "unwelded"] \the [src] with \the [weapon]."), span_hear("You hear welding.")) - user.log_message("[welded ? "welded":"unwelded"] closet [src] with [W]", LOG_GAME) + user.log_message("[welded ? "welded":"unwelded"] closet [src] with [weapon]", LOG_GAME) update_appearance() - else if (can_install_electronics && istype(W, /obj/item/electronics/airlock)\ - && !secure && !electronics && !locked && (welded || !can_weld_shut) && !broken) - user.visible_message(span_notice("[user] installs the electronics into the [src]."),\ - span_notice("You start to install electronics into the [src]...")) - if (!do_after(user, 4 SECONDS, target = src)) - return FALSE - if (electronics || secure) - return FALSE - if (!user.transferItemToLoc(W, src)) - return FALSE - W.moveToNullspace() - to_chat(user, span_notice("You install the electronics.")) - electronics = W - if (electronics.one_access) - req_one_access = electronics.accesses - else - req_access = electronics.accesses - secure = TRUE - update_appearance() - else if (can_install_electronics && W.tool_behaviour == TOOL_SCREWDRIVER\ - && (secure || electronics) && !locked && (welded || !can_weld_shut)) - user.visible_message(span_notice("[user] begins to remove the electronics from the [src]."),\ - span_notice("You begin to remove the electronics from the [src]...")) - var/had_electronics = !!electronics - var/was_secure = secure - if (!do_after(user, 4 SECONDS, target = src)) - return FALSE - if ((had_electronics && !electronics) || (was_secure && !secure)) - return FALSE - var/obj/item/electronics/airlock/electronics_ref - if (!electronics) - electronics_ref = new /obj/item/electronics/airlock(loc) - if (req_one_access.len) - electronics_ref.one_access = 1 - electronics_ref.accesses = req_one_access - else - electronics_ref.accesses = req_access - else - electronics_ref = electronics - electronics = null - electronics_ref.forceMove(drop_location()) - secure = FALSE - update_appearance() + else if(!user.combat_mode) - var/item_is_id = W.GetID() + var/item_is_id = weapon.GetID() if(!item_is_id) - return FALSE + return if((item_is_id || !toggle(user)) && !opened) togglelock(user) else @@ -692,7 +987,7 @@ welded = FALSE //applies to all lockers locked = FALSE //applies to critter crates and secure lockers only broken = TRUE //applies to secure lockers only - open() + open(force = TRUE, special_effects = FALSE) /obj/structure/closet/attack_hand_secondary(mob/user, modifiers) . = ..() @@ -705,19 +1000,37 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/structure/closet/proc/togglelock(mob/living/user, silent) - if(secure && !broken) - if(allowed(user)) - if(iscarbon(user)) - add_fingerprint(user) - balloon_alert_to_viewers(locked ? "unlocked" : "locked") - locked = !locked - user.visible_message(span_notice("[user] [locked ? null : "un"]locks [src]."), - span_notice("You [locked ? null : "un"]lock [src].")) - update_appearance() - else if(!silent) - balloon_alert(user, "access denied!") - else if(secure && broken) - balloon_alert(user, "broken!") + if(!secure || broken) + return + + if(locked) //only apply checks while unlocking else allow anyone to lock it + var/error_msg = "" + if(!isnull(id_card)) + var/obj/item/card/id/advanced/prisoner/registered_id = id_card.resolve() + if(!registered_id) //id was deleted at some point. make this closet public access again + name = initial(name) + desc = initial(desc) + id_card = null + req_access = list() + req_one_access = null + togglelock(user, silent) + return + if(registered_id != user.get_idcard()) + error_msg = "not your locker!" + else if(!allowed(user)) //allow anyone to lock the closet for safe keeping but apply checks only when unlocking + error_msg = "access denied!" + if(error_msg) + if(!silent) + balloon_alert(user, error_msg) + return + + if(iscarbon(user)) + add_fingerprint(user) + locked = !locked + user.visible_message(span_notice("[user] [locked ? "locks" : "unlocks"][src]."), + span_notice("You [locked ? "locked" : "unlocked"] [src].")) + update_appearance() + /obj/structure/closet/emag_act(mob/user) if(secure && !broken) @@ -805,4 +1118,7 @@ locked = FALSE INVOKE_ASYNC(src, PROC_REF(open)) +/obj/structure/closet/preopen + opened = TRUE + #undef LOCKER_FULL diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 5e5cee3d276..50cd91fc56b 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -1,4 +1,3 @@ - /obj/structure/closet/body_bag name = "body bag" desc = "A plastic bag designed for the storage and transportation of cadavers." @@ -18,11 +17,13 @@ drag_slowdown = 0 has_closed_overlay = FALSE can_install_electronics = FALSE + paint_jobs = null - ///The tagged name of the bodybag, also used to check if the bodybag IS tagged. - var/tag_name var/foldedbag_path = /obj/item/bodybag var/obj/item/bodybag/foldedbag_instance = null + /// The tagged name of the bodybag, also used to check if the bodybag IS tagged. + var/tag_name + /obj/structure/closet/body_bag/Initialize(mapload) . = ..() @@ -72,10 +73,9 @@ if(tag_name) . += "bodybag_label" -/obj/structure/closet/body_bag/close(mob/living/user) +/obj/structure/closet/body_bag/after_close(mob/living/user) . = ..() - if(.) - set_density(FALSE) + set_density(FALSE) /obj/structure/closet/body_bag/attack_hand_secondary(mob/user, list/modifiers) . = ..() @@ -257,6 +257,18 @@ to_chat(the_folder, span_warning("You wrestle with [src], but it won't fold while its straps are fastened.")) return ..() +/obj/structure/closet/body_bag/environmental/prisoner/before_open(mob/living/user, force) + . = ..() + if(!.) + return FALSE + + if(sinched && !force) + to_chat(user, span_danger("The buckles on [src] are sinched down, preventing it from opening.")) + return FALSE + + sinched = FALSE //in case it was forced open unsinch it + return TRUE + /obj/structure/closet/body_bag/environmental/prisoner/update_icon() . = ..() if(sinched) @@ -264,22 +276,6 @@ else icon_state = initial(icon_state) -/obj/structure/closet/body_bag/environmental/prisoner/open(mob/living/user, force = FALSE) - if(sinched && !force) - to_chat(user, span_danger("The buckles on [src] are sinched down, preventing it from opening.")) - return TRUE - if(opened) - return FALSE - sinched = FALSE - playsound(loc, open_sound, open_sound_volume, TRUE, -3) - opened = TRUE - if(!dense_when_open) - set_density(FALSE) - dump_contents() - update_appearance() - after_open(user, force) - return TRUE - /obj/structure/closet/body_bag/environmental/prisoner/container_resist_act(mob/living/user) /// copy-pasted with changes because flavor text as well as some other misc stuff if(opened) @@ -291,7 +287,7 @@ location.relay_container_resist_act(user, src) return if(!sinched) - open() + open(user) return user.changeNext_move(CLICK_CD_BREAKOUT) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index c25b4b27cf0..e2b16478bb0 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -17,15 +17,19 @@ close_sound_volume = 35 has_closed_overlay = FALSE door_anim_time = 0 // no animation - var/move_speed_multiplier = 1 - var/move_delay = FALSE can_install_electronics = FALSE - + paint_jobs = null /// Cooldown controlling when the box can trigger the Metal Gear Solid-style '!' alert. COOLDOWN_DECLARE(alert_cooldown) /// How much time must pass before the box can trigger the next Metal Gear Solid-style '!' alert. var/time_between_alerts = 60 SECONDS + /// List of viewers around the box + var/list/alerted + /// How fast a mob can move inside this box + var/move_speed_multiplier = 1 + /// If the speed multiplier should be applied to mobs inside this box + var/move_delay = FALSE /obj/structure/closet/cardboard/relaymove(mob/living/user, direction) if(opened || move_delay || user.incapacitated() || !isturf(loc) || !has_gravity(loc)) @@ -41,32 +45,34 @@ /obj/structure/closet/cardboard/proc/ResetMoveDelay() move_delay = FALSE -/obj/structure/closet/cardboard/open(mob/living/user, force = FALSE) - var/do_alert = (COOLDOWN_FINISHED(src, alert_cooldown) && (locate(/mob/living) in contents)) - - if(!do_alert) - return ..() - - // Get mobs in view before we open the box. - var/list/alerted = list() - for(var/mob/living/alerted_mob in viewers(7, src)) - if(alerted_mob.stat != CONSCIOUS || alerted_mob.is_blind()) - continue - alerted += alerted_mob - - // There are no mobs to alert? - if(!length(alerted)) - return ..() - +/obj/structure/closet/cardboard/before_open(mob/living/user, force) . = ..() - - // Box didn't open? if(!.) + return FALSE + + alerted = null + var/do_alert = (COOLDOWN_FINISHED(src, alert_cooldown) && (locate(/mob/living) in contents)) + if(!do_alert) + + return TRUE + // Cache the list before we open the box. + alerted = viewers(7, src) + // There are no mobs to alert? clear the list & prevent furthur action after opening the box + if(!(locate(/mob/living) in alerted)) + alerted = null + + return TRUE + +/obj/structure/closet/cardboard/after_open(mob/living/user, force) + . = ..() + if(!length(alerted)) return COOLDOWN_START(src, alert_cooldown, time_between_alerts) for(var/mob/living/alerted_mob as anything in alerted) + if(alerted_mob.stat != CONSCIOUS || alerted_mob.is_blind()) + continue if(!alerted_mob.incapacitated(IGNORE_RESTRAINTS)) alerted_mob.face_atom(src) alerted_mob.do_alert_animation() diff --git a/code/game/objects/structures/crates_lockers/closets/infinite.dm b/code/game/objects/structures/crates_lockers/closets/infinite.dm index 9afab3ddd20..7bd25e54b46 100644 --- a/code/game/objects/structures/crates_lockers/closets/infinite.dm +++ b/code/game/objects/structures/crates_lockers/closets/infinite.dm @@ -23,9 +23,9 @@ if(replicating_type && !opened && (length(contents) < stop_replicating_at)) new replicating_type(src) -/obj/structure/closet/infinite/open(mob/living/user, force = FALSE) +/obj/structure/closet/infinite/after_close(mob/living/user, force) . = ..() - if(. && auto_close_time) + if(auto_close_time) addtimer(CALLBACK(src, PROC_REF(close_on_my_own)), auto_close_time, TIMER_OVERRIDE | TIMER_UNIQUE) /obj/structure/closet/infinite/proc/close_on_my_own() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm index eabfae7ab15..cb5a70e8440 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm @@ -9,6 +9,7 @@ open_sound_volume = 25 close_sound_volume = 50 door_anim_time = 0 // no animation + paint_jobs = null /obj/structure/closet/secure_closet/bar/PopulateContents() ..() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index ae076da40cd..5091c01eacc 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -1,11 +1,25 @@ /obj/structure/closet/secure_closet/freezer icon_state = "freezer" + base_icon_state = "freezer" flags_1 = PREVENT_CONTENTS_EXPLOSION_1 door_anim_squish = 0.22 door_anim_angle = 123 door_anim_time = 4 /// If FALSE, we will protect the first person in the freezer from an explosion / nuclear blast. var/jones = FALSE + paint_jobs = null + +/obj/structure/closet/secure_closet/freezer/before_open(mob/living/user, force) + . = ..() + if(!.) + return FALSE + + toggle_organ_decay(src) + return TRUE + +/obj/structure/closet/secure_closet/freezer/after_close(mob/living/user) + . = ..() + toggle_organ_decay(src) /obj/structure/closet/secure_closet/freezer/Destroy() toggle_organ_decay(src) @@ -15,17 +29,6 @@ . = ..() toggle_organ_decay(src) -/obj/structure/closet/secure_closet/freezer/open(mob/living/user, force = FALSE) - if(opened || !can_open(user, force)) //dupe check just so we don't let the organs decay when someone fails to open the locker - return FALSE - toggle_organ_decay(src) - return ..() - -/obj/structure/closet/secure_closet/freezer/close(mob/living/user) - if(..()) //if we actually closed the locker - toggle_organ_decay(src) - return TRUE - /obj/structure/closet/secure_closet/freezer/ex_act() if(jones) return ..() @@ -33,27 +36,11 @@ flags_1 &= ~PREVENT_CONTENTS_EXPLOSION_1 return FALSE -/obj/structure/closet/secure_closet/freezer/atom_destruction(damage_flag) - new /obj/item/stack/sheet/iron(drop_location(), 1) - new /obj/item/assembly/igniter/condenser(drop_location()) - return ..() - -/obj/structure/closet/secure_closet/freezer/welder_act(mob/living/user, obj/item/tool) +/obj/structure/closet/secure_closet/freezer/deconstruct(disassembled) + if (!(flags_1 & NODECONSTRUCT_1)) + new /obj/item/assembly/igniter/condenser(drop_location()) . = ..() - if(!opened) - balloon_alert(user, "open it first!") - return TRUE - - if(!tool.use_tool(src, user, 40, volume=50)) - return TRUE - - new /obj/item/stack/sheet/iron(drop_location(), 2) - new /obj/item/assembly/igniter/condenser(drop_location()) - qdel(src) - - return TRUE - /obj/structure/closet/secure_closet/freezer/empty name = "freezer" @@ -98,8 +85,8 @@ new /obj/item/food/meat/slab/monkey(src) /obj/structure/closet/secure_closet/freezer/meat/open - req_access = list() locked = FALSE + req_access = list() /obj/structure/closet/secure_closet/freezer/gulag_fridge name = "refrigerator" @@ -125,6 +112,11 @@ req_access = null locked = FALSE +/obj/structure/closet/secure_closet/freezer/fridge/preopen + req_access = null + locked = FALSE + opened = TRUE + /obj/structure/closet/secure_closet/freezer/money name = "freezer" desc = "This contains cold hard cash." diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index d85f5f26d37..93fea8a2343 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -1,8 +1,13 @@ /obj/structure/closet/secure_closet/personal - desc = "It's a secure locker for personnel. The first card swiped gains control." + desc = "It's a secure locker for personnel. The first person to open this closet gains control." name = "personal closet" req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) - var/registered_name = null + card_reader_installed = TRUE + +/obj/structure/closet/secure_closet/personal/Initialize(mapload) + . = ..() + var/static/list/choices = list("Personal") + access_choices = choices /obj/structure/closet/secure_closet/personal/PopulateContents() ..() @@ -34,33 +39,3 @@ new /obj/item/storage/backpack/satchel/leather/withwallet( src ) new /obj/item/instrument/piano_synth(src) new /obj/item/radio/headset( src ) - -/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) - var/obj/item/card/id/I = W.GetID() - if(istype(I)) - if(broken) - to_chat(user, span_danger("It appears to be broken.")) - return - if(!I || !I.registered_name) - return - if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) - //they can open all lockers, or nobody owns this, or they own this locker - locked = !locked - update_appearance() - - if(!registered_name) - registered_name = I.registered_name - desc = "Owned by [I.registered_name]." - else - to_chat(user, span_danger("Access Denied.")) - else - return ..() - -/obj/structure/closet/secure_closet/personal/allowed(mob/mob_to_check) - . = ..() - if (. || !ishuman(mob_to_check)) - return - var/mob/living/carbon/human/human_to_check = mob_to_check - var/obj/item/card/id/id_card = human_to_check.wear_id?.GetID() - if (istype(id_card) && id_card.registered_name == registered_name) - return TRUE diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 87058f0b5d7..1fad4a1c902 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -7,6 +7,7 @@ armor_type = /datum/armor/closet_secure_closet secure = TRUE damage_deflection = 20 + material_drop_amount = 5 /datum/armor/closet_secure_closet melee = 30 diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 9657de5cf24..86be18f5357 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -1,7 +1,7 @@ /obj/structure/closet/secure_closet/captains name = "captain's locker" - req_access = list(ACCESS_CAPTAIN) icon_state = "cap" + req_access = list(ACCESS_CAPTAIN) /obj/structure/closet/secure_closet/captains/PopulateContents() ..() @@ -23,8 +23,8 @@ /obj/structure/closet/secure_closet/hop name = "head of personnel's locker" - req_access = list(ACCESS_HOP) icon_state = "hop" + req_access = list(ACCESS_HOP) /obj/structure/closet/secure_closet/hop/PopulateContents() ..() @@ -47,8 +47,8 @@ /obj/structure/closet/secure_closet/hos name = "head of security's locker" - req_access = list(ACCESS_HOS) icon_state = "hos" + req_access = list(ACCESS_HOS) /obj/structure/closet/secure_closet/hos/PopulateContents() ..() @@ -75,8 +75,8 @@ /obj/structure/closet/secure_closet/warden name = "warden's locker" - req_access = list(ACCESS_ARMORY) icon_state = "warden" + req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/warden/PopulateContents() ..() @@ -101,8 +101,8 @@ /obj/structure/closet/secure_closet/security name = "security officer's locker" - req_access = list(ACCESS_BRIG) icon_state = "sec" + req_access = list(ACCESS_BRIG) /obj/structure/closet/secure_closet/security/PopulateContents() ..() @@ -150,13 +150,13 @@ /obj/structure/closet/secure_closet/detective name = "\improper detective's cabinet" - req_access = list(ACCESS_DETECTIVE) icon_state = "cabinet" resistance_flags = FLAMMABLE max_integrity = 70 door_anim_time = 0 // no animation open_sound = 'sound/machines/wooden_closet_open.ogg' close_sound = 'sound/machines/wooden_closet_close.ogg' + req_access = list(ACCESS_DETECTIVE) /obj/structure/closet/secure_closet/detective/PopulateContents() ..() @@ -183,62 +183,54 @@ /obj/structure/closet/secure_closet/brig name = "brig locker" - req_one_access = list(ACCESS_BRIG) anchored = TRUE + req_one_access = list(ACCESS_BRIG) var/id = null /obj/structure/closet/secure_closet/brig/genpop name = "genpop storage locker" desc = "Used for storing the belongings of genpop's tourists visiting the locals." - - ///Reference to the ID linked to the locker, done by swiping a prisoner ID on it - var/datum/weakref/assigned_id_ref = null - -/obj/structure/closet/secure_closet/brig/genpop/Destroy() - assigned_id_ref = null - return ..() + access_choices = FALSE + paint_jobs = null /obj/structure/closet/secure_closet/brig/genpop/examine(mob/user) . = ..() . += span_notice("Right-click with a Security-level ID to reset [src]'s registered ID.") -/obj/structure/closet/secure_closet/brig/genpop/attackby(obj/item/card/id/advanced/prisoner/used_id, mob/user, params) - . = ..() - if(!istype(used_id, /obj/item/card/id/advanced/prisoner)) - return +/obj/structure/closet/secure_closet/brig/genpop/attackby(obj/item/card/id/advanced/prisoner/user_id, mob/user, params) + if(!secure || !istype(user_id)) + return ..() - if(!assigned_id_ref) + if(isnull(id_card)) say("Prisoner ID linked to locker.") - assigned_id_ref = WEAKREF(used_id) - name = "genpop storage locker - [used_id.registered_name]" - return - var/obj/item/card/id/advanced/prisoner/registered_id = assigned_id_ref.resolve() - if(used_id == registered_id) - say("Authorized ID detected. Unlocking locker and resetting ID.") - locked = FALSE - assigned_id_ref = null - name = initial(name) - update_appearance() + id_card = WEAKREF(user_id) + name = "genpop storage locker - [user_id.registered_name]" + +/obj/structure/closet/secure_closet/brig/genpop/proc/clear_access() + say("Authorized ID detected. Unlocking locker and resetting ID.") + locked = FALSE + id_card = null + name = initial(name) + update_appearance() /obj/structure/closet/secure_closet/brig/genpop/attackby_secondary(obj/item/card/id/advanced/used_id, mob/user, params) - . = ..() + if(!secure || !istype(used_id)) + return ..() var/list/id_access = used_id.GetAccess() - if(assigned_id_ref && (ACCESS_BRIG in id_access)) - say("Authorized ID detected. Unlocking locker and resetting ID.") - locked = FALSE - assigned_id_ref = null - name = initial(name) - update_appearance() + if(!isnull(id_card) && (ACCESS_BRIG in id_access)) + clear_access() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/structure/closet/secure_closet/evidence anchored = TRUE name = "secure evidence closet" - req_one_access = list("armory","detective") + req_one_access = list(ACCESS_ARMORY, ACCESS_DETECTIVE) /obj/structure/closet/secure_closet/brig/PopulateContents() ..() + new /obj/item/clothing/under/rank/prisoner( src ) new /obj/item/clothing/under/rank/prisoner/skirt( src ) new /obj/item/clothing/shoes/sneakers/orange( src ) @@ -265,14 +257,14 @@ req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/contraband/heads - anchored = TRUE name = "contraband locker" req_access = list(ACCESS_COMMAND) + anchored = TRUE /obj/structure/closet/secure_closet/armory1 name = "armory armor locker" - req_access = list(ACCESS_ARMORY) icon_state = "armory" + req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/armory1/PopulateContents() ..() @@ -291,8 +283,8 @@ /obj/structure/closet/secure_closet/armory2 name = "armory ballistics locker" - req_access = list(ACCESS_ARMORY) icon_state = "armory" + req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/armory2/PopulateContents() ..() @@ -304,8 +296,8 @@ /obj/structure/closet/secure_closet/armory3 name = "armory energy gun locker" - req_access = list(ACCESS_ARMORY) icon_state = "armory" + req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/armory3/PopulateContents() ..() @@ -320,8 +312,8 @@ /obj/structure/closet/secure_closet/tac name = "armory tac locker" - req_access = list(ACCESS_ARMORY) icon_state = "tac" + req_access = list(ACCESS_ARMORY) /obj/structure/closet/secure_closet/tac/PopulateContents() ..() @@ -332,8 +324,8 @@ /obj/structure/closet/secure_closet/labor_camp_security name = "labor camp security locker" - req_access = list(ACCESS_SECURITY) icon_state = "sec" + req_access = list(ACCESS_SECURITY) /obj/structure/closet/secure_closet/labor_camp_security/PopulateContents() ..() diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 9ee9f0e1473..eae92151cab 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -2,6 +2,8 @@ name = "armory closet" desc = "Why is this here?" icon_state = "syndicate" + armor_type = /datum/armor/closet_syndicate + paint_jobs = null /datum/armor/closet_syndicate melee = 70 diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index c46c9d06fbe..cd7c701baef 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -3,6 +3,7 @@ desc = "A rectangular steel crate." icon = 'icons/obj/storage/crates.dmi' icon_state = "crate" + base_icon_state = "crate" req_access = null can_weld_shut = FALSE horizontal = TRUE @@ -29,13 +30,20 @@ var/lid_y = 0 /obj/structure/closet/crate/Initialize(mapload) + AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) //add element in closed state before parent init opens it(if it does) . = ..() - if(icon_state == "[initial(icon_state)]open") - opened = TRUE - AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) - else - AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) - update_appearance() + + var/static/list/crate_paint_jobs = list( + "Internals" = list("icon_state" = "o2crate"), + "Medical" = list("icon_state" = "medicalcrate"), + "Radiation" = list("icon_state" = "radiation"), + "Hydrophonics" = list("icon_state" = "hydrocrate"), + "Science" = list("icon_state" = "scicrate"), + "Solar" = list("icon_state" = "engi_e_crate"), + "Engineering" = list("icon_state" = "engi_crate") + ) + if(!isnull(paint_jobs)) + paint_jobs = crate_paint_jobs /obj/structure/closet/crate/Destroy() QDEL_NULL(manifest) @@ -52,7 +60,7 @@ return TRUE /obj/structure/closet/crate/update_icon_state() - icon_state = "[initial(icon_state)][opened ? "open" : ""]" + icon_state = "[isnull(base_icon_state) ? initial(icon_state) : base_icon_state][opened ? "open" : ""]" return ..() /obj/structure/closet/crate/closet_update_overlays(list/new_overlays) @@ -65,6 +73,12 @@ . += "securecrater" else if(secure) . += "securecrateg" + if(opened && lid_icon_state) + var/mutable_appearance/lid = mutable_appearance(icon = lid_icon, icon_state = lid_icon_state) + lid.pixel_x = lid_x + lid.pixel_y = lid_y + lid.layer = layer + . += lid /obj/structure/closet/crate/attack_hand(mob/user, list/modifiers) . = ..() @@ -77,22 +91,17 @@ . = ..() RemoveElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) - -/obj/structure/closet/crate/after_close(mob/living/user, force) - . = ..() - RemoveElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) - AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) - - -/obj/structure/closet/crate/open(mob/living/user, force = FALSE) - . = ..() - if(. && !QDELETED(manifest)) - to_chat(user, span_notice("The manifest is torn off [src].")) + if(!QDELETED(manifest)) playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE) manifest.forceMove(get_turf(src)) manifest = null update_appearance() +/obj/structure/closet/crate/after_close(mob/living/user) + . = ..() + RemoveElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) + AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) + /obj/structure/closet/crate/proc/tear_manifest(mob/user) to_chat(user, span_notice("You tear the manifest off of [src].")) playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE) @@ -103,20 +112,15 @@ manifest = null update_appearance() -/obj/structure/closet/crate/closet_update_overlays(list/new_overlays) - . = new_overlays - if(opened && lid_icon_state) - var/mutable_appearance/lid = mutable_appearance(icon = lid_icon, icon_state = lid_icon_state) - lid.pixel_x = lid_x - lid.pixel_y = lid_y - lid.layer = layer - . += lid - . += ..() +/obj/structure/closet/crate/preopen + opened = TRUE + icon_state = "crateopen" /obj/structure/closet/crate/coffin name = "coffin" desc = "It's a burial receptacle for the dearly departed." icon_state = "coffin" + base_icon_state = "coffin" resistance_flags = FLAMMABLE max_integrity = 70 material_drop = /obj/item/stack/sheet/mineral/wood @@ -126,6 +130,7 @@ open_sound_volume = 25 close_sound_volume = 50 can_install_electronics = FALSE + paint_jobs = null /obj/structure/closet/crate/maint @@ -135,12 +140,10 @@ var/static/list/possible_crates = RANDOM_CRATE_LOOT var/crate_path = pick_weight(possible_crates) - - var/obj/structure/closet/crate = new crate_path(loc) - crate.RegisterSignal(crate, COMSIG_CLOSET_POPULATE_CONTENTS, TYPE_PROC_REF(/obj/structure/closet/, populate_with_random_maint_loot)) + var/obj/structure/closet/crate/random_crate = new crate_path(loc) + random_crate.RegisterSignal(random_crate, COMSIG_CLOSET_POPULATE_CONTENTS, TYPE_PROC_REF(/obj/structure/closet/, populate_with_random_maint_loot)) if (prob(50)) - crate.opened = TRUE - crate.update_appearance() + random_crate.open(null, special_effects = FALSE) //crates spawned as immediatly opened don't need to animate into being opened return INITIALIZE_HINT_QDEL @@ -172,12 +175,15 @@ desc = "An internals crate." name = "internals crate" icon_state = "o2crate" + base_icon_state = "o2crate" /obj/structure/closet/crate/trashcart //please make this a generic cart path later after things calm down a little desc = "A heavy, metal trashcart with wheels." name = "trash cart" icon_state = "trashcart" + base_icon_state = "trashcart" can_install_electronics = FALSE + paint_jobs = null /obj/structure/closet/crate/trashcart/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() @@ -188,36 +194,37 @@ name = "laundry cart" desc = "A large cart for hauling around large amounts of laundry." icon_state = "laundry" + base_icon_state = "laundry" /obj/structure/closet/crate/medical desc = "A medical crate." name = "medical crate" icon_state = "medicalcrate" + base_icon_state = "medicalcrate" /obj/structure/closet/crate/freezer desc = "A freezer." name = "freezer" icon_state = "freezer" + base_icon_state = "freezer" + paint_jobs = null -//Snowflake organ freezer code -//Order is important, since we check source, we need to do the check whenever we have all the organs in the crate +/obj/structure/closet/crate/freezer/before_open(mob/living/user, force) + . = ..() + if(!.) + return FALSE -/obj/structure/closet/crate/freezer/open(mob/living/user, force = FALSE) toggle_organ_decay(src) - ..() + return TRUE -/obj/structure/closet/crate/freezer/close() - ..() +/obj/structure/closet/crate/freezer/after_close(mob/living/user) + . = ..() toggle_organ_decay(src) /obj/structure/closet/crate/freezer/Destroy() toggle_organ_decay(src) return ..() -/obj/structure/closet/crate/freezer/Initialize(mapload) - . = ..() - toggle_organ_decay(src) - /obj/structure/closet/crate/freezer/blood name = "blood freezer" desc = "A freezer containing packs of blood." @@ -255,23 +262,28 @@ desc = "A crate with a radiation sign on it." name = "radiation crate" icon_state = "radiation" + base_icon_state = "radiation" /obj/structure/closet/crate/hydroponics name = "hydroponics crate" desc = "All you need to destroy those pesky weeds and pests." icon_state = "hydrocrate" + base_icon_state = "hydrocrate" /obj/structure/closet/crate/engineering name = "engineering crate" icon_state = "engi_crate" + base_icon_state = "engi_crate" /obj/structure/closet/crate/engineering/electrical icon_state = "engi_e_crate" + base_icon_state = "engi_e_crate" /obj/structure/closet/crate/rcd desc = "A crate for the storage of an RCD." name = "\improper RCD crate" icon_state = "engi_crate" + base_icon_state = "engi_crate" /obj/structure/closet/crate/rcd/PopulateContents() ..() @@ -283,10 +295,12 @@ name = "science crate" desc = "A science crate." icon_state = "scicrate" + base_icon_state = "scicrate" /obj/structure/closet/crate/solarpanel_small name = "budget solar panel crate" icon_state = "engi_e_crate" + base_icon_state = "engi_e_crate" /obj/structure/closet/crate/solarpanel_small/PopulateContents() ..() @@ -319,6 +333,7 @@ /obj/structure/closet/crate/decorations icon_state = "engi_crate" + base_icon_state = "engi_crate" /obj/structure/closet/crate/decorations/PopulateContents() . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm index 867ede6d88d..e13c671e1a3 100644 --- a/code/game/objects/structures/crates_lockers/crates/bins.dm +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -2,12 +2,14 @@ desc = "A trash bin, place your trash here for the janitor to collect." name = "trash bin" icon_state = "largebins" + base_icon_state = "largebins" open_sound = 'sound/effects/bin_open.ogg' close_sound = 'sound/effects/bin_close.ogg' anchored = TRUE horizontal = FALSE delivery_icon = null can_install_electronics = FALSE + paint_jobs = null /obj/structure/closet/crate/bin/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates/cardboard.dm b/code/game/objects/structures/crates_lockers/crates/cardboard.dm index b29b8f9138e..b4d14751a65 100644 --- a/code/game/objects/structures/crates_lockers/crates/cardboard.dm +++ b/code/game/objects/structures/crates_lockers/crates/cardboard.dm @@ -5,17 +5,21 @@ material_drop = /obj/item/stack/sheet/cardboard material_drop_amount = 4 icon_state = "cardboard" + base_icon_state = "cardboard" open_sound = 'sound/items/poster_ripped.ogg' close_sound = 'sound/machines/cardboard_box.ogg' open_sound_volume = 25 close_sound_volume = 25 + paint_jobs = null /obj/structure/closet/crate/cardboard/mothic name = "\improper Mothic Fleet box" desc = "For holding moths, presumably." icon_state = "cardboard_moth" + base_icon_state = "cardboard_moth" /obj/structure/closet/crate/cardboard/tiziran name = "\improper Tiziran shipment box" desc = "For holding lizards, presumably." icon_state = "cardboard_tiziran" + base_icon_state = "cardboard_tiziran" diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm index 6f27595b8d8..a89d82ea0ea 100644 --- a/code/game/objects/structures/crates_lockers/crates/critter.dm +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -2,6 +2,7 @@ name = "critter crate" desc = "A crate designed for safe transport of animals. It has an oxygen tank for safe transport in space." icon_state = "crittercrate" + base_icon_state = "crittercrate" horizontal = FALSE allow_objects = FALSE breakout_time = 600 @@ -13,9 +14,10 @@ open_sound_volume = 25 close_sound_volume = 50 contents_pressure_protection = 0.8 - var/obj/item/tank/internals/emergency_oxygen/tank can_install_electronics = FALSE + var/obj/item/tank/internals/emergency_oxygen/tank + /obj/structure/closet/crate/critter/Initialize(mapload) . = ..() tank = new diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 22340400b3b..ef6e25d343c 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -2,6 +2,7 @@ name = "large crate" desc = "A hefty wooden crate. You'll need a crowbar to get it open." icon_state = "largecrate" + base_icon_state = "largecrate" density = TRUE pass_flags_self = PASSSTRUCTURE material_drop = /obj/item/stack/sheet/mineral/wood diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index 4698c8469d2..aa6284e298e 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -2,13 +2,15 @@ desc = "A secure crate." name = "secure crate" icon_state = "securecrate" + base_icon_state = "securecrate" secure = TRUE locked = TRUE max_integrity = 500 armor_type = /datum/armor/crate_secure - var/tamperproof = 0 damage_deflection = 25 + var/tamperproof = 0 + /datum/armor/crate_secure melee = 30 bullet = 50 @@ -39,32 +41,38 @@ desc = "A secure weapons crate." name = "weapons crate" icon_state = "weaponcrate" + base_icon_state = "weaponcrate" /obj/structure/closet/crate/secure/plasma desc = "A secure plasma crate." name = "plasma crate" icon_state = "plasmacrate" + base_icon_state = "plasmacrate" /obj/structure/closet/crate/secure/gear desc = "A secure gear crate." name = "gear crate" icon_state = "secgearcrate" + base_icon_state = "secgearcrate" /obj/structure/closet/crate/secure/hydroponics desc = "A crate with a lock on it, painted in the scheme of the station's botanists." name = "secure hydroponics crate" icon_state = "hydrosecurecrate" + base_icon_state = "hydrosecurecrate" /obj/structure/closet/crate/secure/freezer //for consistency with other "freezer" closets/crates desc = "An insulated crate with a lock on it, used to secure perishables." name = "secure kitchen crate" icon_state = "kitchen_secure_crate" + base_icon_state = "kitchen_secure_crate" + paint_jobs = null /obj/structure/closet/crate/secure/freezer/pizza name = "secure pizza crate" desc = "An insulated crate with a lock on it, used to secure pizza." - req_access = list(ACCESS_KITCHEN) tamperproof = 10 + req_access = list(ACCESS_KITCHEN) /obj/structure/closet/crate/secure/freezer/pizza/PopulateContents() . = ..() @@ -74,16 +82,19 @@ desc = "A crate with a lock on it, painted in the scheme of the station's engineers." name = "secure engineering crate" icon_state = "engi_secure_crate" + base_icon_state = "engi_secure_crate" /obj/structure/closet/crate/secure/science name = "secure science crate" desc = "A crate with a lock on it, painted in the scheme of the station's scientists." icon_state = "scisecurecrate" + base_icon_state = "scisecurecrate" /obj/structure/closet/crate/secure/owned name = "private crate" desc = "A crate cover designed to only open for who purchased its contents." icon_state = "privatecrate" + base_icon_state = "privatecrate" ///Account of the person buying the crate if private purchasing. var/datum/bank_account/buyer_account ///Department of the person buying the crate if buying via the NIRN app. diff --git a/code/game/objects/structures/crates_lockers/crates/syndicrate.dm b/code/game/objects/structures/crates_lockers/crates/syndicrate.dm index b18321338c4..b58686cc343 100644 --- a/code/game/objects/structures/crates_lockers/crates/syndicrate.dm +++ b/code/game/objects/structures/crates_lockers/crates/syndicrate.dm @@ -2,10 +2,12 @@ name = "surplus syndicrate" desc = "A conspicuous crate with the Syndicate logo on it. You don't know how to open it." icon_state = "syndicrate" + base_icon_state = "syndicrate" max_integrity = 500 armor_type = /datum/armor/crate_syndicrate resistance_flags = FIRE_PROOF | ACID_PROOF integrity_failure = 0 //prevents bust_open from activating + paint_jobs = null /// variable that only lets the crate open if opened by a key from the uplink var/created_items = FALSE /// this is what will spawn when it is opened with a syndicrate key @@ -18,6 +20,17 @@ laser = 50 energy = 100 +/obj/structure/closet/crate/syndicrate/before_open(mob/living/user, force) + . = ..() + if(!.) + return FALSE + + if(!broken && !force && !created_items) + balloon_alert(user, "locked!") + return FALSE + + return TRUE + /obj/structure/closet/crate/syndicrate/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) if(created_items) return ..() @@ -46,13 +59,6 @@ /obj/structure/closet/crate/syndicrate/attackby_secondary(obj/item/weapon, mob/user, params) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -///overwrites default opening behavior until it is unlocked via the syndicrate key -/obj/structure/closet/crate/syndicrate/can_open(mob/living/user, force = FALSE) - if(!created_items) - balloon_alert(user, "locked!") - return FALSE - return ..() - ///syndicrate has a unique overlay for being unlocked /obj/structure/closet/crate/syndicrate/closet_update_overlays(list/new_overlays) . = new_overlays @@ -70,7 +76,7 @@ . = ..() register_item_context() -/obj/item/add_item_context(obj/item/source, list/context, atom/target, mob/living/user,) +/obj/item/syndicrate_key/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) . = ..() var/obj/structure/closet/crate/syndicrate/target_structure = target diff --git a/code/game/objects/structures/crates_lockers/crates/wooden.dm b/code/game/objects/structures/crates_lockers/crates/wooden.dm index 544662f9cc1..a5e0b78cadb 100644 --- a/code/game/objects/structures/crates_lockers/crates/wooden.dm +++ b/code/game/objects/structures/crates_lockers/crates/wooden.dm @@ -4,10 +4,12 @@ material_drop = /obj/item/stack/sheet/mineral/wood material_drop_amount = 6 icon_state = "wooden" + base_icon_state = "wooden" open_sound = 'sound/machines/wooden_closet_open.ogg' close_sound = 'sound/machines/wooden_closet_close.ogg' open_sound_volume = 25 close_sound_volume = 50 + paint_jobs = null /obj/structure/closet/crate/wooden/toy name = "toy box" diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index c76a10ee9ae..e2df91c342a 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -210,7 +210,7 @@ /obj/structure/closet/supplypod/toggle(mob/living/user) return -/obj/structure/closet/supplypod/open(mob/living/user, force = FALSE) +/obj/structure/closet/supplypod/open(mob/living/user, force = FALSE, special_effects = TRUE) return /obj/structure/closet/supplypod/proc/handleReturnAfterDeparting(atom/movable/holder = src) @@ -434,16 +434,19 @@ opened = TRUE set_density(FALSE) update_appearance() + after_open(null, FALSE) /obj/structure/closet/supplypod/extractionpod/setOpened() opened = TRUE set_density(TRUE) update_appearance() + after_open(null, FALSE) /obj/structure/closet/supplypod/setClosed() //Ditto opened = FALSE set_density(TRUE) update_appearance() + after_close(null, FALSE) /obj/structure/closet/supplypod/proc/tryMakeRubble(turf/T) //Ditto if (rubble_type == RUBBLE_NONE) diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index 8b29d83c941..021e5812d1e 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -29,15 +29,10 @@ //If the mob is holding a valid ID, we let them in. get_active_held_item() is on the mob level, so no need to copypasta everywhere. else if(check_access(accessor.get_active_held_item())) return TRUE - //if they are wearing a card that has access, that works - else if(ishuman(accessor)) - var/mob/living/carbon/human/human_accessor = accessor - if(check_access(human_accessor.wear_id)) - return TRUE - //if they have a hacky abstract animal ID with the required access, let them in i guess... - else if(isanimal(accessor)) - var/mob/living/simple_animal/animal = accessor - if(check_access(animal.access_card)) + //if they are carying a card that has access, that works + else if(isliving(accessor)) + var/mob/living/being = accessor + if(check_access(being.get_idcard(TRUE))) return TRUE else if(isbrain(accessor) && istype(accessor.loc, /obj/item/mmi)) var/obj/item/mmi/brain_mmi = accessor.loc diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index b9668c1f83b..fc52a488b87 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -128,20 +128,42 @@ desc = "A marked patch of soil, showing signs of a burial long ago. You wouldn't disturb a grave... right?" icon = 'icons/obj/storage/crates.dmi' icon_state = "grave" + base_icon_state = "grave" dense_when_open = TRUE material_drop = /obj/item/stack/ore/glass/basalt material_drop_amount = 5 anchorable = FALSE anchored = TRUE - locked = TRUE divable = FALSE //As funny as it may be, it would make little sense how you got yourself inside it in first place. breakout_time = 90 SECONDS open_sound = 'sound/effects/shovel_dig.ogg' close_sound = 'sound/effects/shovel_dig.ogg' cutting_tool = /obj/item/shovel + can_install_electronics = FALSE + paint_jobs = null + var/lead_tomb = FALSE var/first_open = FALSE - can_install_electronics = FALSE + var/grave_dug_open = FALSE + +/obj/structure/closet/crate/grave/before_open(mob/living/user, force) + . = ..() + if(!.) + return FALSE + + if(!force && !grave_dug_open) + balloon_alert(user, "use a shovel!") + return FALSE + + return TRUE + +/obj/structure/closet/crate/grave/before_close(mob/living/user) + . = ..() + if(!.) + return FALSE + + balloon_alert(user, "already open!") + return FALSE /obj/structure/closet/crate/grave/filled/PopulateContents() //GRAVEROBBING IS NOW A FEATURE ..() @@ -172,12 +194,6 @@ //empty grave return -/obj/structure/closet/crate/grave/open(mob/living/user, obj/item/S, force = FALSE) - if(!opened) - to_chat(user, span_notice("The ground here is too hard to dig up with your bare hands. You'll need a shovel.")) - else - to_chat(user, span_notice("The grave has already been dug up.")) - /obj/structure/closet/crate/grave/closet_update_overlays(list/new_overlays) return @@ -187,10 +203,8 @@ if(istype(S,cutting_tool) && S.tool_behaviour == TOOL_SHOVEL) to_chat(user, span_notice("You start start to dig open \the [src] with \the [S]...")) if (do_after(user,20, target = src)) - opened = TRUE - locked = TRUE - dump_contents() - update_appearance() + grave_dug_open = TRUE + open(user, force = TRUE) user.add_mood_event("graverobbing", /datum/mood_event/graverobbing) if(lead_tomb == TRUE && first_open == TRUE) user.gain_trauma(/datum/brain_trauma/magic/stalker) @@ -215,13 +229,6 @@ return 1 return -/obj/structure/closet/crate/grave/bust_open() - ..() - opened = TRUE - update_appearance() - dump_contents() - return - /obj/structure/closet/crate/grave/filled/lead_researcher name = "ominous burial mound" desc = "Even in a place filled to the brim with graves, this one shows a level of preperation and planning that fills you with dread." diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 99ed31e5c40..f0f95b4d64e 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -4,6 +4,7 @@ name = "abandoned crate" desc = "What could be inside?" icon_state = "securecrate" + base_icon_state = "securecrate" integrity_failure = 0 //no breaking open the crate var/code = null var/lastattempt = null @@ -124,7 +125,7 @@ return return ..() -/obj/structure/closet/crate/secure/loot/open(mob/living/user, force = FALSE) +/obj/structure/closet/crate/secure/loot/after_open(mob/living/user, force) . = ..() if(qdel_on_open) qdel(src) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index de4a7e924f6..6d422157a24 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -4,8 +4,10 @@ name = "necropolis chest" desc = "It's watching you closely." icon_state = "necrocrate" + base_icon_state = "necrocrate" resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF can_install_electronics = FALSE + paint_jobs = null /obj/structure/closet/crate/necropolis/tendril desc = "It's watching you suspiciously. You need a skeleton key to open it." @@ -76,10 +78,16 @@ qdel(item) to_chat(user, span_notice("You disable the magic lock, revealing the loot.")) -/obj/structure/closet/crate/necropolis/tendril/can_open(mob/living/user, force = FALSE) - if(!spawned_loot) +/obj/structure/closet/crate/necropolis/tendril/before_open(mob/living/user, force) + . = ..() + if(!.) return FALSE - return ..() + + if(!broken && !force && !spawned_loot) + balloon_alert(user, "its locked!") + return FALSE + + return TRUE //Megafauna chests diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 411d8ac238a..e115bd9af01 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -129,3 +129,4 @@ desc = "A mining car. This one doesn't work on rails, but has to be dragged." name = "Mining car (not for rails)" icon_state = "miningcar" + base_icon_state = "miningcar" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index bbea6b6fe00..fcf792da957 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -580,6 +580,7 @@ density = TRUE anchored = TRUE resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE + paint_jobs = null var/mob/living/simple_animal/holder_animal /obj/structure/closet/stasis/process() diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 9957c802c79..f3e45dd8f44 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -276,6 +276,7 @@ breakout_time = 600 icon_welded = null icon_state = "cursed" + paint_jobs = null var/weakened_icon = "decursed" var/auto_destroy = TRUE @@ -284,15 +285,14 @@ if(auto_destroy) addtimer(CALLBACK(src, PROC_REF(bust_open)), 5 MINUTES) +/obj/structure/closet/decay/after_open(mob/living/user, force) + . = ..() + unmagify() + /obj/structure/closet/decay/after_weld(weld_state) if(weld_state) unmagify() -/obj/structure/closet/decay/open(mob/living/user, force = FALSE) - . = ..() - if(.) - unmagify() - ///Give it the lesser magic icon and tell it to delete itself /obj/structure/closet/decay/proc/unmagify() icon_state = weakened_icon