Merge remote-tracking branch 'upstream/master' into SPIN_ME_RIGHT_ROUND

# Conflicts:
#	paradise.dme
This commit is contained in:
tigercat2000
2018-10-24 23:43:25 -07:00
88 changed files with 4393 additions and 2448 deletions
+11 -11
View File
@@ -8188,12 +8188,12 @@
"dbx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/maintenance/starboard)
"dby" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/maintenance/starboard)
"dbz" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/gambling_den)
"dbA" = (/turf/space,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/auxsolarstarboard)
"dbA" = (/obj/item/hemostat,/obj/effect/decal/cleanable/dirt,/obj/machinery/newscaster{pixel_y = -32},/obj/structure/table/tray,/turf/simulated/floor/plating,/area/medical/surgery1)
"dbB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/gambling_den)
"dbC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/gambling_den)
"dbD" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/gambling_den)
"dbE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/gambling_den)
"dbF" = (/turf/space,/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/auxsolarstarboard)
"dbF" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/item/surgicaldrill,/obj/item/circular_saw,/obj/item/FixOVein,/obj/structure/table/tray,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery)
"dbG" = (/obj/item/twohanded/required/kirbyplants,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/gambling_den)
"dbH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/gambling_den)
"dbI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/gambling_den)
@@ -10005,7 +10005,7 @@
"dKu" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/shuttle/escape)
"dKv" = (/obj/item/twohanded/required/kirbyplants,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"dKw" = (/obj/machinery/status_display,/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape)
"dKx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/table/reinforced,/obj/item/surgicaldrill,/obj/item/circular_saw,/obj/item/FixOVein,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery)
"dKx" = (/turf/space,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/auxsolarstarboard)
"dKy" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "16"},/turf/simulated/floor/plating,/area/shuttle/escape)
"dKz" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/medical/virology)
"dKA" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 2; icon_state = "0-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/medical/virology)
@@ -10255,7 +10255,7 @@
"dPk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/structure/table,/obj/item/crowbar,/obj/item/wrench,/obj/item/restraints/handcuffs/cable,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology)
"dPl" = (/obj/structure/table,/obj/item/storage/box/masks,/obj/item/storage/box/gloves,/obj/structure/sign/vacuum{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitegreencorner"},/area/medical/virology)
"dPm" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/medical/virology)
"dPn" = (/turf/space,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "sw_maint2_airlock"; name = "exterior access button"; pixel_x = 24; pixel_y = 24; req_access_txt = "0"},/turf/simulated/floor/plating/airless/catwalk,/area/space)
"dPn" = (/turf/space,/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/auxsolarstarboard)
"dPo" = (/obj/structure/bed/roller,/obj/effect/decal/warning_stripes/yellow/hollow,/mob/living/carbon/human/monkey,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreencorner"},/area/medical/virology)
"dPp" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/portsolar)
"dPq" = (/turf/simulated/wall/r_wall,/area/maintenance/portsolar)
@@ -10707,7 +10707,7 @@
"dXU" = (/obj/structure/table/reinforced,/obj/item/storage/firstaid/regular,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/machinery/status_display{pixel_y = -32},/turf/simulated/floor/plasteel,/area/medical/surgery1)
"dXV" = (/obj/structure/table/wood,/obj/item/soulstone/anybody/chaplain,/obj/item/nullrod,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
"dXW" = (/obj/machinery/light/small{dir = 4; pixel_y = 8},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "arrival_south_airlock"; name = "interior access button"; pixel_x = -24; pixel_y = -24; req_access_txt = "10;13"},/obj/structure/sign/vacuum{pixel_x = -32},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit)
"dXX" = (/obj/structure/table/reinforced,/obj/item/hemostat,/obj/effect/decal/cleanable/dirt,/obj/machinery/newscaster{pixel_y = -32},/turf/simulated/floor/plating,/area/medical/surgery1)
"dXX" = (/turf/space,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "sw_maint2_airlock"; name = "exterior access button"; pixel_x = 24; pixel_y = 24; req_access_txt = "0"},/turf/simulated/floor/plating/airless/catwalk,/area/space)
"dXY" = (/obj/structure/table/reinforced,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/syringe/epinephrine,/obj/item/reagent_containers/syringe,/obj/item/clothing/accessory/stethoscope,/obj/effect/decal/cleanable/dirt,/obj/machinery/status_display{pixel_y = -32},/turf/simulated/floor/plasteel,/area/medical/surgery1)
"dXZ" = (/obj/structure/table/reinforced,/obj/structure/bedsheetbin,/obj/item/gun/syringe,/obj/machinery/light/small,/turf/simulated/floor/plasteel,/area/medical/surgery1)
"dYa" = (/obj/effect/spawner/random_spawners/wall_rusted_maybe,/turf/simulated/wall,/area/medical/surgery1)
@@ -10920,19 +10920,19 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabiabjcCxcCxcCxbYhbYhcJKbYhbYhbYhcCxcLzcLzcLzbYhbYhbYhbYhcwCcZkcZlcLzcLzcfncLPcXWczDczDcZmdHkcFUcKecZncFUcFUcZocEzcIMcKocIMdaDcIMcKncIMcILcIMcKocIMcIHdtodtHdhSdvNcKrcKrcKrcYscYtcYucZtcYvcYzcYAcZtcZtcYBcKIcZrcZxcTRcZscZzcZAcZBcWZddrcTRcTQcVAcKKcYCcXecXecZDdgodlWdoCdoEddVcXecKYcZHcZIcJgcKYcKYcZJcSHcRocMxcPOcZKcZLcMxcZMcZNcZPdbscUrdbtdbucXldbvcWdcWddbwdcDcUrcWdcWdcqCcZTdcFdcGdcHdcIddRdemdeodepdeqctudadcqJabjaaaabjaaaabjabjabjabjabjabjabjabjabjabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabjabjabjaaaabjabjabjabjabjabjaMWdaeaUpdbGdagdahdaiaOsdajdakdalddddanaOscfndaockbdapdaqdapdapckcdaqdaqdaqdardascEzcIMdoQcIMcILcIMdpPcIMcILcIMdpZcIMcIHcNDdaudaudavdawdqqdaydazdaAdaBcZucNLdaCdaydtSdaydaEdaFdaGcNLcZvdaIdaJdaKdaLcWZdaMcVzdaNcVAcKKdaOdaPdaQdbddcgdaTdaUdaVdaWdaXdaYdaZcPGcPGcPGcPGdbadbbdbcdcidbedbfdbgcPGdbhdbidbjdbkdcAdebdbedbedbedbldbedbmdbcdbedbndbodbpdbqcXJderdlBduydxMdAXdemdGVcXJdbxdbybngbngcqJcqJcqJabjaaaaaaabiabiaaaabiabiaaaabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabiabjabiabiabiabjabiabiabiabjabjdbzaUpdfQdbBdbCdbDdbEdfTdbEdfUdhCdbHdbIdbJcZtdbKcZtdbLcZtdbLcZtcZtdbMcZtcZtcEGdbNcEzcEzddiddiddiddiddiddiddiddiddiddiddidbOcMmcMldbPdbQcMmcMldbRdbSdbTcZycMicMhcMidbVcMidbWdbRdbXdbYdaHdcacWZcWZdcbcWZdccdbUdcecVAcKKcYCdcfdcldchdcsdcjcXgcXkdckddLdcmdcndcodcpdcodcodcqdcrdcnddMdcodctdcudcpdcodcodcndcvdcqdcwdcodcpdcodcxdcodcqdcydcpdczdecdcBdcCcXJdHXdJOdMudNZdObdMudSCcXJcqCcMLbngdcJdcKdcLcqJabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaMWdcMdamdcNdcOdcPdcQdcRdcSdcTdcUdcVdcWdcXcZtdcYdcYdbZdcddcZcYAddcdkpddacZtcLAddfddgddhddiddbddoddpddqdxrdeKdeXdghdgiddscPnddtdduddvcPvcPvcPvddwddxddyddeddxddxddxddyddxddzddAddvddBddCddjddDddEddGddFddHcVzddJcVAcKKcYCddKcVDddZdfqddNddOddPddQdfwddSddTddUddUddUdlhddWddXddYdfrcNTcNTdeaddUddUdfEdfGdeddgAcNScNTdefcNTdegdXpdeedehdeicNTdejdekdelcXJdXSdXTdXUdXXdXYdXZdaSdYadetdmJdevdewdexdeybngabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaMWdcMdamdcNdcOdcPdcQdcRdcSdcTdcUdcVdcWdcXcZtdcYdcYdbZdcddcZcYAddcdkpddacZtcLAddfddgddhddiddbddoddpddqdxrdeKdeXdghdgiddscPnddtdduddvcPvcPvcPvddwddxddyddeddxddxddxddyddxddzddAddvddBddCddjddDddEddGddFddHcVzddJcVAcKKcYCddKcVDddZdfqddNddOddPddQdfwddSddTddUddUddUdlhddWddXddYdfrcNTcNTdeaddUddUdfEdfGdeddgAcNScNTdefcNTdegdXpdeedehdeicNTdejdekdelcXJdXSdXTdXUdbAdXYdXZdaSdYadetdmJdevdewdexdeybngabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbzdbzdbzdafdezaSPdeAdeBdeCdeDdeDdeDdeEdeFdcXdeGcZtddIdeHdeJdeIdeIdeIdeIdeLdeMcZtcIEdeNdeOdePddideQdeRdeSdeTdeUdeVdeWdeWdgjddscZxdeYdhXdfadfbcKrdfcdBDdfedffdffdfgdfhdfidfjdfkdflcMedfmdfndfodfodfpdfodfsdfodfodfodfodftdfBdgwdfvdgDdgDdgDdgDdgEdfxdfxdfxdfydfzdfzdfzdfydfAdgxdgydgzcKYcJgcKYcJgcKYcJgcKYcZPdgBdildfCdfDdfDdfDdfDdfDdwpdfFdxAdfDdfDcWadfHdfIdfIdfIdfIdfIdfIdfJdfJdfIcWacSWbngdfKdfKdfKbngabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbzaOsaUpaRmdkqaUpdfMdcXdcXdfNdfNaUpdfOdfPdcXdcXcZtdkwcAZdfSdeIcZwdkzdkAdfRdfXcZtcZtbYhdfYdfZddidgadgbdgcdgddgedgfdgcdggdgkddsdgldgmdeIdgndxEcKrdgpdgqdxPdffdgsdgtdhNdhOdhPdgudflcMfdgvdfndimdindiqdiqdirdiqdisditdfodgCcKKcSwdfvdgFdgGdgHdfvdgTdfydgIdgJdgKdgLdgMdgNdgOdfzdgPdgQdgRcJgdgSdgUdgVdiGdgScJgdgWdgXdgYdfDdgZdhadhbdfDdhcdhddhadhedhfdfDdhgdhhdhidhjdhkdhldhmdhndhodhpdfIdhqdmJdevdeudhsdhrbngabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMWdhuaRjdhvdfLdhwdfMdcXdnHdcXaUpaUpdfOdhxdcXaUpcZtdhycAZdovdpSdhBdkzdridfRdhJdhEcZtdhzdhGdhHdhAdjfdhKdhLdhMdhRdhTdhUdhQdhVdTedhWdhYdhZdibdhWdWjdicdiddiadfgdiedifdjpdjqdjrdigdihdiidijdikdivdjOdjPdiodipdjRdjSdjTdfodiudoZdiwdixdkYdiydizdjVdjWdfydiAdiBdiCdiCdiDdiEdiFdiHdiJdiIdlccZNcMpdiLdiKdkecMpcZNdldcXxdiMdfDdhadhadhadiNdhcdhcdhcdhcdiOdfDdiPcSWdfIdiQdiRdiSdiTdiSdiSdiUdfIcqCdiVbngboGdhtdiXcqJabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbzdhvduTduTdfLdiYdfMdfNaUpdiZdfNaUpdfOdjadcXaOscZtdjbdhDdpSdpSdeJdhFdhIdjgdjmdjmdjcdjddjjdjkdjldjndjodkxdjsdjtdjudjwdjxdjydjvdjzdjBdjCdjDdjzdjAdjEdjFdjJdjKdkLdjGdjHdjIdkQdkUdjLdjMdjNdfndmfdnxdnydjQdjQdjQdjSdnzdnBdnCdjUdledfvdkZdlfdmkdfvdmndfydjXdjYdjZdkadkbdkcdkddkidkfdkgdldcZNcMpdkkdkjdlkcMpcZNdldcVTdgYdfDdfFdkldfFdfCdfFdfFdfFdfFdfFdfDdiPdbydfIdkmdiSdiSdiSdiSdiTdkndfIdkodbybngdfKcqJcqJcqJabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMWdWwdYmdYmdfLdkrdfMdfNdksdfNdcXdcXdktdkudcXdkvcZtdYndYodkydhJdYpdkBdYqdYrdcYdmRcZtdhzcLAdbNddidkCdkDdkEdkFdkGdkGdkHdkFddidkIdkJdkKdlRdkKdkMdkIdkNdkOdkPdffdlVdkRdkSdkTdzSdffdkVdkWdkXdnFdoydnxdladladlbdladjSdnzdoRdoScKKcSwdnIdnJdpfdpgdfvdqtdfydlgdoFdlidljdlqdlldlmdfzdlndlodkhcJgdFEdlrdlsdmjdJEcJgcYKcXxdludlvdlwdlxdlydlzdlAdJMdKxdlDdlEdlzdlFdbydfIdlGdiSdiSdiRdiSdiSdlHdhicqCdbycqJabjaaaabjaaaabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMWdWwdYmdYmdfLdkrdfMdfNdksdfNdcXdcXdktdkudcXdkvcZtdYndYodkydhJdYpdkBdYqdYrdcYdmRcZtdhzcLAdbNddidkCdkDdkEdkFdkGdkGdkHdkFddidkIdkJdkKdlRdkKdkMdkIdkNdkOdkPdffdlVdkRdkSdkTdzSdffdkVdkWdkXdnFdoydnxdladladlbdladjSdnzdoRdoScKKcSwdnIdnJdpfdpgdfvdqtdfydlgdoFdlidljdlqdlldlmdfzdlndlodkhcJgdFEdlrdlsdmjdJEcJgcYKcXxdludlvdlwdlxdlydlzdlAdJMdbFdlDdlEdlzdlFdbydfIdlGdiSdiSdiRdiSdiSdlHdhicqCdbycqJabjaaaabjaaaabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbzaUpaRmaRmdYsdYtdfMaUpdcXaUpdcXdfNdlIdlJaUpdlKcZtcZtcIWdbMdlLcZtcZtcIWcIWcIWcZtcZtdbMdlMdbNddidlNdlOdlPdlPdlPdlOdlQdlPdlPdkIdlYdlSdlTdlUdlZdkIdmddlXdnidfidnkdmadmbdmcdnndffdfldmedjNdfndoTdnxdnydmgdmgdmgdjSdnzdoRdoScKKdmhdfvdfvdfvdfvdfvdqudmldmldmldmldmmdnMdmodmldmldmpdKVdmrdmsdmtdmudmudmudmtdmsdmvcVTdgYdfFdmwdmxdAgdfDdmzdmxdmAdmBdmCdfDdmDdmJdmEdmLdmGdmHdmIdiSdiSdomdmKdqUdaddfKbngcqJcqJcqJabjaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbzdbzdbzdmMddddYudmNdmOdmOdmOdmOdmOdmPdmQdcXdlKcZtdmVcYAdmSdeJcYAdmTdmUdmWdmXdoxdmYcZtdmZdnaddidnbdncdnddnednfdlPdngdnhdlPdkIdnrdlSdnjdlUdoIdkIdnldkOdnmdffdoJdnodnpdnqdoKdnsdntdnudnvdnwdoUdoVdoWdnAdipdoXdjSdpbdpcdnDcKKdnEdmidqidnGdYbdYcdYddnKdnLdnNdoadnOdnPdnQdnRdnSdlndlodkhdnTdnUdnVdnWdnXdnYdnTdgWdnZdobdofdocdoddoedogdoldohdoidojdokdptdqWdondfIdoodiSdiTdiSdiSdiRdopdfIdoqdadbngdiWdmFdotcqJabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaMWdoudYvdYuaRmaSPaUpdYtaRmdYuaSPdowdcXdafdbMdpTdYwdYxdYxdeIdeIdeJdeIdeIdjedozdbLcLAdoAddidlPdoBdlPdlPdERdlPdlPdoDdlPdkIdIgdvedoGdoHdoOdkIdIhdkOdnidfidpQdoLdoMdoNdqcdffdfldoPdIidfndqjdqkdqodILdqodrDdrEdrFdfodoYdoZdpadrGdrHdpddpedYidYjdphdpidpjdpkdpldpmdpndpodppdpqdprdpsdpzdpudpvdpwdpxdpydqvdpAdpBdpCdfFdpDdpEdpFdfDdpGdpHdpIdpJdpKdfDdiPdbydfJdpLdiSdiSdiRdiRdpMdpNdfJdoqdsmdevdpOdordosbngabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjdbzdpRdcXdcXdcXaRmdYydYydYydYzdcXdcXdnHaUpdbMdpWdYAdYodYBdpVdeJdhJdkAdYrdfRdrgcZtdpXdbNddiddiddiddiddiddiddiddiddiddidkIdpYdwedqadqbdqgdkIdqddlXdqedffdqfdfidrvdqhdqfdffdrIdrNdsudqldqldqmdqmdqndqmdsHdqmdqpdqpdftdfBdsIdmidmidqrdqsdYkdYldsUdqwdqxdqydqzdqAdqBdqCdqDdqEdqFdkhdqGdqHdqIdqJdqKdqHdqGcYKcXxdgYdfDdqLdqMdqNdfDdqOdqPdLPdqRdqSdfDdiPcSWdfJdqTdoodtBdqVdtEdqXdqYdfJctudbyaeBaeBaeBaeBaeCabjabjabjabiabjabiabiabiabjabiabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjaMWaOsdkrdqZdraaRmdrbdrcdrddrcdredrfdcXaOscZtdhJcAZdrldpUdrhdfVdfVdYCdrjdjhdsodjidrndrocYecFYcGacGacGacFYcGacYedrpdrqdkIdrrdCNdrtdrudrwdkIdrxdkOdrydffdsvdrzdrAdrBdrCdffdfldoPdkXdqldsJdsKdsLdsMdsLduedufdrJdrKdrLcKKdrMdceduhdrOdrPdrQdrRdrSdrTdrUdrVdrWdrXdrYdrZdsadsbdkgdscdmtdsddsedsfdsgdshdmtcYKcVTdsidfDdfDdfDdfDdfDdfDdfDdfDdfDdfDdfDdsjcSWdfIdfIdskdmKdfIdsldfIdfIdskdbxdbyaeBdtFdtGdRxaeCaeCaeCaaaabjaaaabjaaaabjaaaabjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjaMWaMWdbzaMYdbzaUpaSPaUpaRmaUpdbzaMWdbzaMWcZtdsndeJdrldpUdspdkAdYDdfVdhJdfRdYodbMdsqdIfdsrcHhcHhdsscHhdsrcHfcHgdstcNhdkIcLydsydswdsxdsAdkIdszdsCdsBdffdXkdsDdsEdsFdsGdffdfldkWdkXdqldujdvkdvldvldvldvmdvrdwodcecVAcKKdnEdrKdsNdsOdsPdsQdsRdsSdsTdsVdsZdsWdsXdsYdtfdtadtbdtcdtddGaduldtgdthdtidtjdtkcYKcXxdgYcJgdtldtmdtndMidtpcKYdtqdtrdtsdttdtudtvdtwdtxdtsdtsdttdtydtxdtwdtzdtAduNdtCduOdtDdGqdGrdGsdGXdbAacgacpacpacpacpacpacpaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabjabjabjdbzaUpdtJdtKdtLdlKdbzabjabjabjcZtdtMdhDdpSdfWdeJdfWdfWdrkdfWdYodtOcZtbYhbYhcJKcJKbYhcJKcJKbYhbYhcdvcirdtPdkIdrmdtRdtVdtTdtWdkIdtXdkOduYdffdvcdtYdtZduadubdffdfldoPducduddwqdwrdugdwsduidwsdxzdrJddJcVAcKKcSwdukdukdukdxGdukdumdundunduodundundundundundundupduqdukdmtdurdusdutduuduvdmtduwduxdgAdSdduzduzduAduBduCcKYdkoduDduEduFduGduHduIduIcqEduJduKdpOdpOduIduLduIduMaeBdGZdHZdIaaeCaeCaeCabjabjabjabjabjabjabjdbFabjabjabjabiabiabiabiabiaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjaMWaMWdbzaMYdbzaUpaSPaUpaRmaUpdbzaMWdbzaMWcZtdsndeJdrldpUdspdkAdYDdfVdhJdfRdYodbMdsqdIfdsrcHhcHhdsscHhdsrcHfcHgdstcNhdkIcLydsydswdsxdsAdkIdszdsCdsBdffdXkdsDdsEdsFdsGdffdfldkWdkXdqldujdvkdvldvldvldvmdvrdwodcecVAcKKdnEdrKdsNdsOdsPdsQdsRdsSdsTdsVdsZdsWdsXdsYdtfdtadtbdtcdtddGaduldtgdthdtidtjdtkcYKcXxdgYcJgdtldtmdtndMidtpcKYdtqdtrdtsdttdtudtvdtwdtxdtsdtsdttdtydtxdtwdtzdtAduNdtCduOdtDdGqdGrdGsdGXdKxacgacpacpacpacpacpacpaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabjabjabjdbzaUpdtJdtKdtLdlKdbzabjabjabjcZtdtMdhDdpSdfWdeJdfWdfWdrkdfWdYodtOcZtbYhbYhcJKcJKbYhcJKcJKbYhbYhcdvcirdtPdkIdrmdtRdtVdtTdtWdkIdtXdkOduYdffdvcdtYdtZduadubdffdfldoPducduddwqdwrdugdwsduidwsdxzdrJddJcVAcKKcSwdukdukdukdxGdukdumdundunduodundundundundundundupduqdukdmtdurdusdutduuduvdmtduwduxdgAdSdduzduzduAduBduCcKYdkoduDduEduFduGduHduIduIcqEduJduKdpOdpOduIduLduIduMaeBdGZdHZdIaaeCaeCaeCabjabjabjabjabjabjabjdPnabjabjabjabiabiabiabiabiaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFaaaacFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabiabjaaadbzdbzaMWdbzaMWdbzdbzaaaabjaaacZtduQduRdtQdYodhJdYGduSduUduVdYHduXcZtaaaabjaaaabjaaaabjaaaabjbYhcbCcgRcNhdkIduWdvZdvadvbdwcdkIdvddwddvfdffdffdffdffdvgdffdffdvhdvidvjdxBdxCdxDdvndvodvpdvqdXrdqpdqpdgCcKKcTWdukdvsdvtdvudvvdvwdvtdvxdvtdvxdvydvzdukdvAdvBdvCdvDdvEdmtdvFdvGdvHdvIdvJdmtcYKcXxdludvKdvLdvMdAqdvOdvPcKYdvQcWbaOxaOxaOxaOxaOxdvRdvRdvSdvSaOxbLnbLndvTbLnbLnaeBaeBaeCaeBaeCabjabjabjaaaabjaaaabjaaaaaaabGaaaaaaabjaaaabjaaaaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjaaaaaaaaaabjaaaabjaaaaaaaaaabjaaacZtcZtcZtcZtcZtcZtcZtcZtcZtcZtcZtcZtcZtabjdkIdkKdkKdkIdkKdkKdkIdkIdvVdvWdvXdkIdvYdwfdwadwbdwgdkIdwhdxkdxndxodxpdwidwjdwkdwldwmdihdoPdgvdwndyMdyNduidyOduidwsdyQdyTdqpcKJdwtdwudukdwvdwwdwxdwydvxdwwdvxdwzdvxdwAdwwdwBdwwdwCdwDdwEdwFdmtdwGdwHdwIdwJdwGdmtdwKcVTdgYcKYcKYcKYcKYcKYcKYcKYctudwLaOxdwMdwNdwOdwPdwQdwRdwSdwTdwUdwVdwWdwXdwYdwZdxabLnabjabjabjaaaabjaaaabWabWabWabWabWabjabGabjabWabWabWabWabWaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjaaaabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaabjabjabjabjacFacFacFacFabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjdkKdxbdxcdxddxedxfdxgdkIdxhdWndxjdkIdxidxqdvadxmdXudkIdyCdyDdyEdyEdyFdwidxsdxtdxudxvdxwdxxdxydqldzVdzWdzXdAadzXdzXdAbdBOdqpcKJcKKdxFdBSdxHdxIdxJdxKdxLdQddxLdxLdxLdxNdxOdAodxQdxRdxSdxTdxUdmtdUDdvGdxWdxXdxYdmtdgWdxZdgYcJgdtldtmdtndQudtpcKYdyacWbdvSdybdycdyddybdyedyfdygdybdyhbLndyidwXdyjdykdyldymabjabiaaaaaaabiabjaceacfacfacfacfacgabGaciacjacjacjacjacjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -10942,8 +10942,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFabjabjdyodyodBEdBFdAHdBGdCAdyodyoabjabjacFabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjacFabjacFabjabjabjabjabjabjacFabjacFabjabjabjabjabjabjacFabjacFdkIdkKdBAdkKdBBdkKdAUdkIdBAdWndxjdkIdkIdkIdWodkIdkIdkIdCKdCKdCLdCMdCMcKrcKrcKrcKrcKrcKudBhcKscKrdBIdBidBKdBCcKhdBMcKhdBNdBHcPxdBPdBQdBJdQsdBLdBUdBVdBWdBWdBUdBXdBYdBUdBZdCadCbdCcdCddCedBVdBVdCfdBYdBWdCadCgdbodChdCidCjdbodCkdClcmtdCmdClcmtdCndCoaOxdCpdybdycdybdCqdCrdygdzodCsbLndCtdCudCvdwZdCwdymabjabiaaaabiabjacfacfacfacfacfacgacpachacpaciacjacjacjacjacjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadyndCydCzdAHdAHdAHdAHdAHdDPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadCBdCCdCDdCEdCEdCEdCFdkIdCGdEydCHdCIcFRcgTdbNcdtdCJcEzdDQdDRdCLdDSdEacKrdCOcZtdCPdCQdCRdCSdCTcZtdCUdCVdCWcGodBRdCYdBTdVjdCXdDbdDcdDddDadDfdDgdDhdDidDjdDkdDkdDldDhdDkdDmdDndDodDpdDkdDqdDmdDhdDidDmdDhdDrdDsdDtdDudDvdDwdDtdDxdDydDxdDzdDAdDxdDxdDBdDCdDDdDEdDFdDGdDHdDIdDJdDKdDLbLndDMdDNdDNdyjdDObLnabjabiabjabiaaaacoacoacoacoacoabjabjacpabjabjacoacoacoacoacoaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFabjabjdyodyodEcdEvdAHdEwdEKdyodyoabjabjacFabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjacFabjacFabjabjabjabjabjabjacFabjacFdkIdDTdkIdkIdDTdkIdkIdkIdDUdDVdDWdDXdDXdDXdDYdDXdDZcEzdDQdDQdFndEadDScKrdEbdFTdEddEedEfdEgdEhcZtdEiciraosaosdDedEkaosaosdfudIMdPudXjdfudfudEodEpdEpdEodEqdEodEodEqdEodEodEqdEodEodEqdEodEodEqdEodEodEqdEodEpcKYdErdgXdEscKYbngcqJbngbngbngcqJbngbqCdDCdDCdEtdEtaOxaOxaOxdEtdEtdDCbLnbLndymdymdymdEubLnabjabiabjabiaaaaaaaaaaaaabjaaaaaaabjacpabjaaaaaaabjaaaaaaaaaaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjdyndyodFUdAHdFVdyodynabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaaaaabjaaadPndEAdEBdEEdEFdECdEDdWxdWydEGdEHcHhcHgcHfcHgcHgdEIdEJcEzdDQdDQdGOdDSdDScKrdELdEMdENdEOdEPdEQdXycZtdEScwDaosdETdEUdEVdEWaosdVwdEYdEZdFadFbdfuaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaaaaabjcKYdFcdFddFecKYaaaabjaaaaaaabjaaaabjaaaabjaaaaaaabjabjabjabjaaaaaaabjabjabjabjabjabjabjabjabjabjaaaabiabjaaaabWabWabWabWabWabjacpabjabWabWabWabWabWaaaabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjdyodyndFfdyndyoabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFacFacFacFaaaaaaaaaaaaaaaabjaaaacFbYhdFgdFgdFgdFhdFidFjdFhdFgdFgdFkdFgdFgdFgdFlcEGdEJcEzdFmdFmdFmdFmdFmcKrdGYcZtdFodFpdFqdFrdFscZtdCUdFtaosdFudFvdVxdFxaotdWIdFzcKKdFAdFBdFCabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjcTXdFDdTxdFFcTXaaaabjaaadFGdFGdFHdFGdFGdFGdFIdFJdFGdFGabjabjabjabjabjabiaaaabjabjabiabiabiaaaabjabjabjabjabjacfacfacfacfacfacgdbFaciacjacjacjacjacjaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjdyndyodFUdAHdFVdyodynabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaaaaabjaaadXXdEAdEBdEEdEFdECdEDdWxdWydEGdEHcHhcHgcHfcHgcHgdEIdEJcEzdDQdDQdGOdDSdDScKrdELdEMdENdEOdEPdEQdXycZtdEScwDaosdETdEUdEVdEWaosdVwdEYdEZdFadFbdfuaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaaaaabjcKYdFcdFddFecKYaaaabjaaaaaaabjaaaabjaaaabjaaaaaaabjabjabjabjaaaaaaabjabjabjabjabjabjabjabjabjabjaaaabiabjaaaabWabWabWabWabWabjacpabjabWabWabWabWabWaaaabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjdyodyndFfdyndyoabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFacFacFacFaaaaaaaaaaaaaaaabjaaaacFbYhdFgdFgdFgdFhdFidFjdFhdFgdFgdFkdFgdFgdFgdFlcEGdEJcEzdFmdFmdFmdFmdFmcKrdGYcZtdFodFpdFqdFrdFscZtdCUdFtaosdFudFvdVxdFxaotdWIdFzcKKdFAdFBdFCabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjcTXdFDdTxdFFcTXaaaabjaaadFGdFGdFHdFGdFGdFGdFIdFJdFGdFGabjabjabjabjabjabiaaaabjabjabiabiabiaaaabjabjabjabjabjacfacfacfacfacfacgdPnaciacjacjacjacjacjaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjdyndyodynabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaabjaaaabjabjdFgdFKdFLdFMdFNdFOdFMdFPdFNdFQdFRdFSdFgcdvcEGdbNdHBdIbdIydFWdFXdFYcZtdFZcZtdICdGbdGcdGddGecZtdGfdGgaosdGhdGidGjdGkdGldGmdFzdWKdGodGpdFCaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadFGdLadLbdLcdFGdFGdFHdFHdFGdGtdGudGvdGwdGxdGydGzdGAdGwdFGdFHdFGdFGabjabiaaaabiaaaaaaabjabjaaaabjaaaaaaabiaaaacoacoacoacoacoabjabGabjacoacoacoacoacoaaaabiaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjaaaabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjabjabjabjabjabjabiaaaaaaabjdFgdGBdGCdGDdFNdFOdGEdGEdGFdGGdGHdGIdFgcbCcEGdGJdGKdGLdGMcdwdXlcfmdbMdbMcZtcKsdJycKucZtcZtdbMcgUcwDaosdGPdGQdGRdGSaszdWLdGUcKKdGodFBdFCabjabjaaaaaadYedYedYedGWdYedYedGWdYedYedGWdYedYedGWdYedYedYeaaaaaadFGdLddLQdLUdHadHbdHcdHddHedHfdHgdHhdHidHjdIjdHldHmdHndHodHpdHqdFGaaaabiabjabiabjabjabiabiabiabjabiabjabiaaaaaaaaaabjaaaaaaaaaabGaaaaaaaaaabjaaaaaaaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaabiabjabiabjdFgdHrdHsdHsdFNdFOdHtdHsdGFdHudHvdHwdFgdHxdHydHzdHAdHAdKXdHCdHDdHAdHEdHFdHGdHHdHIdHJcFYdHKcYedHLdHMaosdHNdHOdHPdHQaosdWMdHSdHTdHUdHVdfuaaaabjaaadHWdYfdYfdYfdGWdYfdYfdGWdYfdYfdGWdYfdYfdGWdYfdYfdYfdHYaaadFGdLYdMadMvdFGdFGdIcdIcdFGdIddIedIkdJadJbdOidJcdJddIldImdIndIodFGaaaabjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaabiabiabjabiabjabiabiaaaabGaaaabiabiabiabjabiabiabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -6233,9 +6233,9 @@
"cpS" = (/obj/machinery/slot_machine{pixel_y = 2},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"cpT" = (/obj/structure/chair/stool,/obj/machinery/newscaster{pixel_x = -30},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"})
"cpU" = (/obj/structure/closet/secure_closet/medical2,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpV" = (/obj/item/surgicaldrill,/obj/item/stack/medical/bruise_pack/advanced,/obj/structure/table/glass,/obj/machinery/camera{c_tag = "Medbay Surgery 1 North"; network = list("SS13","Medbay")},/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpV" = (/obj/item/surgicaldrill,/obj/item/stack/medical/bruise_pack/advanced,/obj/machinery/camera{c_tag = "Medbay Surgery 1 North"; network = list("SS13","Medbay")},/obj/machinery/light{dir = 1; in_use = 1},/obj/structure/table/tray,/obj/item/scalpel,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpW" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpX" = (/obj/item/hemostat,/obj/item/scalpel,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpX" = (/obj/item/hemostat,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpY" = (/obj/item/bonegel,/obj/item/bonesetter,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery1)
"cpZ" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry)
"cqa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/public/glass{autoclose = 0; frequency = 1449; heat_proof = 1; icon_state = "door_locked"; id_tag = "gas_turbine_interior"; locked = 1; name = "Incinerator Interior Airlock"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/insulated{dir = 5},/turf/simulated/floor/engine/insulated,/area/maintenance/incinerator)
@@ -7315,7 +7315,7 @@
"cKI" = (/turf/simulated/wall,/area/space)
"cKJ" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"cKK" = (/obj/machinery/camera{active_power_usage = 0; c_tag = "Bomb Test Site"; desc = "A specially-reinforced camera with a long lasting battery, used to monitor the bomb testing site. An external light is attached to the top."; dir = 8; invuln = 1; light = null; luminosity = 3; name = "Hardened Bomb-Test Camera"; network = list("Toxins","Research","SS13"); use_power = 0},/obj/item/target/alien{anchored = 1},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"cKL" = (/obj/item/surgicaldrill,/obj/item/stack/medical/bruise_pack/advanced,/obj/machinery/camera{c_tag = "Medbay Surgery 1 South"; dir = 1; network = list("SS13")},/obj/machinery/light,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery2)
"cKL" = (/obj/item/surgicaldrill,/obj/item/stack/medical/bruise_pack/advanced,/obj/machinery/camera{c_tag = "Medbay Surgery 1 South"; dir = 1; network = list("SS13")},/obj/machinery/light,/obj/structure/table/tray,/obj/item/scalpel,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery2)
"cKM" = (/turf/simulated/wall,/area/medical/virology)
"cKN" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/toxins/server{name = "\improper Research Division Server Room"})
"cKO" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Test Subject Cell"; req_access_txt = "39"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/virology)
@@ -7442,7 +7442,7 @@
"cNf" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/r_n_d/circuit_imprinter,/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/assembly/robotics)
"cNg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel,/area/assembly/robotics)
"cNh" = (/obj/effect/landmark/start{name = "Roboticist"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/assembly/robotics)
"cNi" = (/obj/item/hemostat,/obj/item/scalpel,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery2)
"cNi" = (/obj/item/hemostat,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery2)
"cNj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"})
"cNk" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
"cNl" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"})
@@ -8453,6 +8453,7 @@
"dgC" = (/obj/structure/chair/stool,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"dgD" = (/obj/machinery/camera{c_tag = "Quartermaster's Office"; dir = 8},/obj/machinery/light{dir = 4},/turf/simulated/floor/engine,/area/hallway/secondary/entry{name = "Arrivals"})
"dgE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/starboard)
"dgF" = (/obj/structure/reagent_dispensers/oil,/turf/simulated/floor/plasteel,/area/assembly/robotics)
"dgG" = (/obj/structure/rack,/obj/item/stack/sheet/cardboard,/obj/item/radio/off,/obj/effect/spawner/lootdrop/maintenance,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"dgH" = (/obj/structure/closet/l3closet,/obj/effect/decal/warning_stripes/southeast,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
"dgI" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/starboard)
@@ -8502,7 +8503,7 @@
"dhF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{name = "storage room"; req_access = "12"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"dhG" = (/obj/item/seeds/watermelon,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"dhI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/mob/living/simple_animal/bot/cleanbot{name = "Mopfficer Sweepsky"; on = 0},/turf/simulated/floor/plating,/area/maintenance/fore)
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8676,7 +8677,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcvQcAfcAfcAfcAfcBecjccBgcCfcCfcCfcCfcCjabqarBaaaaaaaaaaaaaaabZUbZUcfccKCcPFcPxcEYcEYcEYcEYcEYcEYcEYcEYcPycPycPycMacPycPycPycPycPycPBcPAcPDcKZcKZcQbcLdcQfcLdcImdcLcMddeecIncIocQAcQCcQBcImcJgcnscgxcvmcwEcQKcJjcJlcJkcJncJmcMncMccJpcJqcCOczQdgSdgSdgSdgSdgSdgScJrcJscJtcKEcLlcKFcEKbZUcFGbZUcFHcJxcMrcLqcJAaRharAarAabqabqabqabqabqabqabqaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqcKJcJDcKJcIPcJEcIPcKKcJGcFNabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCtcCtcCtcCtcCtaaackraaacCtcCtcCtcCtcCtaaaaupaaaaaaaaaaaaaaaaaabZUbZUbZUbZUcJRcogcogcogcogcNTcogcogcQVcogcogcogcLzcNTcNTcRlcRocPycRpcNUcRLcREcwjcRMcwjcRMcSvcImcSBcMdcSCcIocSPcSMcTncMvcImcMScEXcgxcvmcKpcTwcLAcMmcMjcMjcMjcMtcMXcJpcgCcCOcMZdgScKxcfHcNdcgLdgTcYScKBcNqcMucMycEKcrUcKGceDcfYcFHcFHcFHcFHcFHcHfcKIarAabqaaaaaaaaaaaaaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqabqcALcALcLDcIPcIPcIPcLEcALcALabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaaaabqabqabqaaaaaacmHabqaaaaaaabqabqaaaaaaarBabqaaaaaaaaaaaaaaaaaaaaaaaabZUbZUbZUbZUbZUbZUbZUbZUbZUbZUbZUcoDcuVcTFchycoDcTZcjicUacUocUecUqcUpcUpcUrcUpcUFcUVcUUcVbcUWcVmcVlcVucVtcVEcVvcWkcVKcWGcWlcWHcIxcIxcNucLmcLpcLocLrcNgcMicJpcLscLtcLucBNcKxcfHchuchuchEcLxcLycIEcKEcNycEKcdNcLBceNcuVcLCbZUabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHUcALcLFcRFcPncALcHUabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaacmHaaaaaaaaaaaaabqaaaaaaaupaaacHZcHZcHZcFvcHZcHZcHZaaaabqaaaaaaaaaabqaaaabqabqabqaaabZUcWIchychychychycNZchydefcWUcwncXrcXlcXlcXwcXAcXycXYcImcYocYndfFcIncYIcYycYNcNEcImcMgcMhcgxcmmcIxcNQcOacMkcLocLocMlcObcNecJpcMocMpcMqdgScKxcfHchuckedgTcYTcKBcOrcOccPmcEKcjnchyceNchycMxbZUabqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcALcFNcRGcFNcALabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaacmHaaaaaaaaaaaaabqaaaaaaaupaaacHZcHZcHZcFvcHZcHZcHZaaaabqaaaaaaaaaabqaaaabqabqabqaaabZUcWIchychychychycNZchydefcWUcwncXrcXlcXlcXwcXAcXycXYcImcYocYndfFcIncYIcYycYNcNEcImcMgcMhcgxcmmcIxcNQcOacMkcLodgFcMlcObcNecJpcMocMpcMqdgScKxcfHchuckedgTcYTcKBcOrcOccPmcEKcjnchyceNchycMxbZUabqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcALcFNcRGcFNcALabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabearBarBarBaaaaaaaaacmHaaaaaaaaaarBarBarBauparBabqcHZcIRcIScIRcITcIRcHZcHZcFvcHZcFvcHZcHZaaaaaaabqaaaaaacHZcHZcHZcHZcHZbZUcKVbZUcDUcYOcDecRLdfOcRUcRUcRUcRUcRUcRUcImcImcImcImcYWcImcImcImcImbZUcNScgxcmmcIxcNfcOacLocLrcLocNhcPEcNYckzcNjcNkcNlcOkdgUdgUdgUdgUdgUcNocNncNpcQgcNrcEKchycuVchPchybZUbZUbZUabqabqaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFNcALcFNabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaarBabqcNtabqarBaaaaaaabqaaaaaaabqaaacHZcJHcJIcJJcJKcJHcGXcOGcJNcJOcJPcOHcHZaaacZmcIacIacIacLRdfRdfQcOIcHZcZvcZqcZwcDUcZIcZycZQcZOcOUdeidafdaddakcRUcNRcmVcmVcmWcQhcjecmYcmYcQicNVcNWcNXcCQcIxcOdcQkcQvcQvcQvcQwcQDcOVcOecOfcOgcOhcOicOjcPicOlcJLcOncOocOpclncQEcOscOtcmYcmYcOucOvcOwcOxbZUbZUbZUaWwaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaarBaaaabqaaaarBaaaaaaabqabqabqabqabqcHZcKMcHjcKOcHucKMcKMcPzcKRcKScKTcPKcHZaaadaodfTcMMcMNcMOdfUcMBdfVcMRdaydaxdaMdaLdaOdaNdaPcYCdaUdaQdbbdaVdbfcRUcOMbZUbZUbZUbZUbZUbZUbZUbZUczIcONcOOcOPcOQcORcOScOTcPRcOXcOWcLrcPoclCcOZcPacPbcPccPdcPecPfcPgcPhcQqcOpclNcPjbZUbZUbZUbZUbZUdenclGcQFclJcQrclJcPUabqabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8760,4 +8761,3 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -4482,7 +4482,7 @@
"bIj" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 1; layer = 2.9},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor,/obj/item/folder/white,/obj/item/reagent_containers/spray/cleaner,/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/reception)
"bIk" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/medical/research{name = "Research Division"})
"bIl" = (/obj/structure/chair/office/light{dir = 1},/obj/effect/landmark/start{name = "Roboticist"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/assembly/robotics)
"bIm" = (/obj/machinery/camera{c_tag = "Research Robotics Lab"; dir = 2; network = list("Research","SS13")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteredcorner"},/area/assembly/robotics)
"bIm" = (/obj/machinery/camera{c_tag = "Research Robotics Lab"; dir = 2; network = list("Research","SS13")},/obj/structure/reagent_dispensers/oil,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteredcorner"},/area/assembly/robotics)
"bIn" = (/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/assembly/robotics)
"bIo" = (/obj/machinery/computer/guestpass{pixel_y = 30},/obj/machinery/photocopier,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab)
"bIp" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab)
@@ -5114,7 +5114,7 @@
"bUr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; name = "Medbay Hall"; sortType = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2)
"bUs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; name = "Med Chemistry"; sortType = 11},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2)
"bUt" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
"bUu" = (/obj/structure/table/glass,/obj/item/bonegel{pixel_x = 6; pixel_y = 6},/obj/item/cautery,/obj/item/FixOVein{pixel_x = -6; pixel_y = 6},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/surgery1)
"bUu" = (/obj/item/bonegel{pixel_x = 6; pixel_y = 6},/obj/item/cautery,/obj/item/FixOVein{pixel_x = -6; pixel_y = 6},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1; in_use = 1},/obj/structure/table/tray,/obj/item/scalpel,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/surgery1)
"bUv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j1"; tag = "icon-pipe-j1 (EAST)"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/genetics_cloning)
"bUw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical/glass{id_tag = "CloningDoor"; name = "Genetics Cloning"; req_access_txt = "0"; req_one_access_txt = "5;9"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/genetics_cloning)
"bUx" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/genetics)
@@ -5694,17 +5694,17 @@
"cfz" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/public/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
"cfA" = (/obj/structure/closet/secure_closet/medical3,/obj/machinery/door_control{id = "surgeryobs1"; name = "Privacy Shutters Control"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/plasteel{tag = "icon-whitebluecorner (WEST)"; icon_state = "whitebluecorner"; dir = 8},/area/medical/surgery1)
"cfB" = (/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
"cfC" = (/obj/structure/table/glass,/obj/item/hemostat{pixel_x = 6},/obj/item/retractor{pixel_x = -6; pixel_y = 6},/obj/item/scalpel,/obj/item/stack/medical/bruise_pack/advanced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/surgery1)
"cfC" = (/obj/structure/table/glass,/obj/item/hemostat{pixel_x = 6},/obj/item/retractor{pixel_x = -6; pixel_y = 6},/obj/item/stack/medical/bruise_pack/advanced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/surgery1)
"cfD" = (/obj/structure/chair{dir = 8},/obj/machinery/camera{c_tag = "Medbay Surgery Observation"; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkblue"},/area/medical/ward)
"cfE" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "open"; id_tag = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery1)
"cfF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward)
"cfG" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward)
"cfH" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "open"; id_tag = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery2)
"cfI" = (/obj/structure/chair{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkblue"},/area/medical/ward)
"cfJ" = (/obj/structure/table/glass,/obj/item/hemostat{pixel_x = 6},/obj/item/retractor{pixel_x = -6; pixel_y = 6},/obj/item/scalpel,/obj/machinery/alarm{pixel_y = 25},/obj/item/stack/medical/bruise_pack/advanced,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/surgery2)
"cfJ" = (/obj/structure/table/glass,/obj/item/hemostat{pixel_x = 6},/obj/item/retractor{pixel_x = -6; pixel_y = 6},/obj/machinery/alarm{pixel_y = 25},/obj/item/stack/medical/bruise_pack/advanced,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/surgery2)
"cfK" = (/obj/structure/closet/secure_closet/medical3,/obj/machinery/door_control{id = "surgeryobs2"; name = "Privacy Shutters Control"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/surgery2)
"cfL" = (/obj/structure/table/glass,/obj/item/circular_saw,/obj/item/bonesetter{pixel_x = 5; pixel_y = 5},/obj/item/surgicaldrill,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/surgery2)
"cfM" = (/obj/structure/table/glass,/obj/item/bonegel{pixel_x = 6; pixel_y = 6},/obj/item/cautery,/obj/item/FixOVein{pixel_x = -6; pixel_y = 6},/obj/machinery/light{dir = 1; in_use = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/surgery2)
"cfM" = (/obj/item/bonegel{pixel_x = 6; pixel_y = 6},/obj/item/cautery,/obj/item/FixOVein{pixel_x = -6; pixel_y = 6},/obj/machinery/light{dir = 1; in_use = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/table/tray,/obj/item/scalpel,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/surgery2)
"cfN" = (/obj/structure/table,/obj/item/storage/box/gloves{pixel_x = 3; pixel_y = 3},/obj/item/storage/box/masks,/obj/item/reagent_containers/spray/cleaner{desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; name = "Surgery Cleaner"},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/medical/surgery2)
"cfO" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre Storage"; req_access_txt = "45"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/medical/surgery2)
"cfP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/medical/surgery2)
@@ -9150,3 +9150,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
File diff suppressed because it is too large Load Diff
+3
View File
@@ -1,3 +1,5 @@
#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
//shorthand
#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path)
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
@@ -13,6 +15,7 @@
// All signals. Format:
// When the signal is called: (signal arguments)
// All signals send the source datum of the signal as the first argument
// /datum signals
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component)
+8
View File
@@ -32,6 +32,14 @@
return
changeNext_click(1)
if(multicam_on)
var/turf/T = get_turf(A)
if(T)
for(var/obj/screen/movable/pic_in_pic/ai/P in T.vis_locs)
if(P.ai == src)
P.Click(params)
break
if(control_disabled || stat)
return
+2
View File
@@ -146,6 +146,8 @@
#define ui_ai_take_picture "SOUTH:6,WEST+12"
#define ui_ai_view_images "SOUTH:6,WEST+13"
#define ui_ai_sensor "SOUTH:6,WEST+14"
#define ui_ai_multicam "SOUTH+1:6,WEST+13"
#define ui_ai_add_multicam "SOUTH+1:6,WEST+14"
// Bots
#define ui_bot_radio "EAST-1:28,SOUTH:7"
+29
View File
@@ -140,6 +140,25 @@
var/mob/living/silicon/robot/borg = usr
borg.sensor_mode()
/obj/screen/ai/multicam
name = "Multicamera Mode"
icon_state = "multicam"
/obj/screen/ai/multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.toggle_multicam()
/obj/screen/ai/add_multicam
name = "New Camera"
icon_state = "new_cam"
/obj/screen/ai/add_multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.drop_new_multicam()
/mob/living/silicon/ai/create_mob_hud()
if(client && !hud_used)
@@ -228,3 +247,13 @@
using = new /obj/screen/ai/sensors()
using.screen_loc = ui_ai_sensor
static_inventory += using
//Multicamera mode
using = new /obj/screen/ai/multicam()
using.screen_loc = ui_ai_multicam
static_inventory += using
//Add multicamera camera
using = new /obj/screen/ai/add_multicam()
using.screen_loc = ui_ai_add_multicam
static_inventory += using
+144
View File
@@ -0,0 +1,144 @@
/obj/screen/movable/pic_in_pic
name = "Picture-in-picture"
screen_loc = "CENTER"
plane = GAME_PLANE
var/atom/center
var/width = 0
var/height = 0
var/list/shown_to = list()
var/list/viewing_turfs = list()
var/obj/screen/component_button/button_x
var/obj/screen/component_button/button_expand
var/obj/screen/component_button/button_shrink
var/mutable_appearance/standard_background
var/const/max_dimensions = 10
/obj/screen/movable/pic_in_pic/Initialize()
. = ..()
make_backgrounds()
/obj/screen/movable/pic_in_pic/Destroy()
for(var/C in shown_to)
unshow_to(C)
QDEL_NULL(button_x)
QDEL_NULL(button_shrink)
QDEL_NULL(button_expand)
return ..()
/obj/screen/movable/pic_in_pic/component_click(obj/screen/component_button/component, params)
if(component == button_x)
qdel(src)
else if(component == button_expand)
set_view_size(width+1, height+1)
else if(component == button_shrink)
set_view_size(width-1, height-1)
/obj/screen/movable/pic_in_pic/proc/make_backgrounds()
standard_background = new /mutable_appearance()
standard_background.icon = 'icons/misc/pic_in_pic.dmi'
standard_background.icon_state = "background"
standard_background.layer = SPACE_LAYER
/obj/screen/movable/pic_in_pic/proc/add_buttons()
var/static/mutable_appearance/move_tab
if(!move_tab)
move_tab = new /mutable_appearance()
//all these properties are always the same, and since adding something to the overlay
//list makes a copy, there is no reason to make a new one each call
move_tab.icon = 'icons/misc/pic_in_pic.dmi'
move_tab.icon_state = "move"
move_tab.plane = HUD_PLANE
var/matrix/M = matrix()
M.Translate(0, (height + 0.25) * world.icon_size)
move_tab.transform = M
overlays += move_tab
if(!button_x)
button_x = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "close"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "x"
MA.plane = HUD_PLANE
button_x.appearance = MA
M = matrix()
M.Translate((max(4, width) - 0.75) * world.icon_size, (height + 0.25) * world.icon_size)
button_x.transform = M
vis_contents += button_x
if(!button_expand)
button_expand = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "expand"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "expand"
MA.plane = HUD_PLANE
button_expand.appearance = MA
M = matrix()
M.Translate(world.icon_size, (height + 0.25) * world.icon_size)
button_expand.transform = M
vis_contents += button_expand
if(!button_shrink)
button_shrink = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "shrink"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "shrink"
MA.plane = HUD_PLANE
button_shrink.appearance = MA
M = matrix()
M.Translate(2 * world.icon_size, (height + 0.25) * world.icon_size)
button_shrink.transform = M
vis_contents += button_shrink
/obj/screen/movable/pic_in_pic/proc/add_background()
if((width > 0) && (height > 0))
var/matrix/M = matrix()
M.Scale(width + 0.5, height + 0.5)
M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size)
standard_background.transform = M
overlays += standard_background
/obj/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE)
width = Clamp(width, 0, max_dimensions)
height = Clamp(height, 0, max_dimensions)
src.width = width
src.height = height
y_off = -height * world.icon_size - 16
overlays.Cut()
add_background()
add_buttons()
if(do_refresh)
refresh_view()
/obj/screen/movable/pic_in_pic/proc/set_view_center(atom/target, do_refresh = TRUE)
center = target
if(do_refresh)
refresh_view()
/obj/screen/movable/pic_in_pic/proc/refresh_view()
vis_contents -= viewing_turfs
if(!width || !height)
return
var/turf/T = get_turf(center)
if(!T)
return
var/turf/lowerleft = locate(max(1, T.x - round(width/2)), max(1, T.y - round(height/2)), T.z)
var/turf/upperright = locate(min(world.maxx, lowerleft.x + width - 1), min(world.maxy, lowerleft.y + height - 1), lowerleft.z)
viewing_turfs = block(lowerleft, upperright)
vis_contents += viewing_turfs
/obj/screen/movable/pic_in_pic/proc/show_to(client/C)
if(C)
shown_to[C] = 1
C.screen += src
/obj/screen/movable/pic_in_pic/proc/unshow_to(client/C)
if(C)
shown_to -= C
C.screen -= src
+15
View File
@@ -23,6 +23,9 @@
master = null
return ..()
/obj/screen/proc/component_click(obj/screen/component_button/component, params)
return
/obj/screen/text
icon = null
icon_state = null
@@ -461,3 +464,15 @@
icon_state = "healthdoll_DEAD"
screen_loc = ui_healthdoll
var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays
/obj/screen/component_button
var/obj/screen/parent
/obj/screen/component_button/Initialize(mapload, obj/screen/new_parent)
. = ..()
parent = new_parent
/obj/screen/component_button/Click(params)
if(parent)
parent.component_click(src, params)
+1 -1
View File
@@ -14,7 +14,7 @@
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params)
return SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params)
/obj/attackby(obj/item/I, mob/living/user, params)
return ..() || (can_be_hit && I.attack_obj(src, user))
+2 -2
View File
@@ -261,13 +261,13 @@ SUBSYSTEM_DEF(garbage)
if(isnull(D.gc_destroyed))
if(D.SendSignal(COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted
if(SEND_SIGNAL(D, COMSIG_PARENT_QDELETED, force)) // Give the components a chance to prevent their parent from being deleted
return
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
var/start_tick = world.tick_usage
var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up.
D.SendSignal(COMSIG_PARENT_QDELETED, force, hint) // Let the (remaining) components know about the result of Destroy
SEND_SIGNAL(D, COMSIG_PARENT_QDELETED, force, hint) // Let the (remaining) components know about the result of Destroy
if(world.time != start_time)
I.slept_destroy++
else
+4 -4
View File
@@ -1,5 +1,5 @@
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN)||BUCKET_LEN)
#define BUCKET_POS(timer) (((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag)+1) % BUCKET_LEN)||BUCKET_LEN)
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
#define TIMER_ID_MAX (2**24) //max float with integer precision
@@ -122,7 +122,7 @@ SUBSYSTEM_DEF(timer)
if(!resumed)
timer = null
while(practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time)
while(practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time)
var/datum/timedevent/head = bucket_list[practical_offset]
if(!timer || !head || timer == head)
head = bucket_list[practical_offset]
@@ -170,7 +170,7 @@ SUBSYSTEM_DEF(timer)
qdel(timer)
continue
if(timer.timeToRun < head_offset + TICKS2DS(practical_offset))
if(timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
bucket_resolution = null //force bucket recreation
CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
if(timer.callBack && !timer.spent)
@@ -521,4 +521,4 @@ SUBSYSTEM_DEF(timer)
#undef BUCKET_LEN
#undef BUCKET_POS
#undef TIMER_MAX
#undef TIMER_ID_MAX
#undef TIMER_ID_MAX
+12 -7
View File
@@ -2,7 +2,7 @@
## Concept
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SendSignal()` call. Now every component that want's to can also know about this happening.
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SEND_SIGNAL` call. Now every component that want's to can also know about this happening.
### In the code
@@ -28,6 +28,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `COMPONENT_INCOMPATIBLE` Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. `parent` must not be modified if this is to be returned.
### Vars
1. `/datum/var/list/datum_components` (private)
@@ -61,6 +62,11 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Returns a reference to a component whose type MATCHES component_type if that component exists in the datum, null otherwise
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
1. `SEND_SIGNAL(target, sigtype, ...)` (public, final)
* Use to send signals to target datum
* Extra arguments are to be specified in the signal definition
* Returns a bitflag with signal specific information assembled from all activated components
* Arguments are packaged in a list and handed off to _SendSignal()
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
* Creates an instance of `component_type` in the datum and passes `...` to its `Initialize()` call
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
@@ -77,10 +83,9 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Properly transfers ownership of a component from one datum to another
* Signals `COMSIG_COMPONENT_REMOVING` on the parent
* Called on the datum you want to own the component with another datum's component
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
* Call to send a signal to the components of the target datum
* Extra arguments are to be specified in the signal definition
* Returns a bitflag with signal specific information assembled from all activated components
1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final)
* Handles most of the actual signaling procedure
* Will runtime if used on datums with an empty component list
1. `/datum/component/New(datum/parent, ...)` (private, final)
* Runs internal setup for the component
* Extra arguments are passed to `Initialize()`
@@ -108,13 +113,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Clears `parent` and removes the component from it's component list
1. `/datum/component/proc/_JoinParent` (private, final)
* Tries to add the component to it's `parent`s `datum_components` list
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
1. `/datum/component/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
* Makes a component listen for the specified `signal` on it's `parent` datum.
* When that signal is recieved `proc_ref` will be called on the component, along with associated arguments
* Example proc ref: `.proc/OnEvent`
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
* These callbacks run asyncronously
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `_SendSignal()` that initiated it
### See/Define signals and their arguments in __DEFINES\components.dm
+61 -27
View File
@@ -56,9 +56,10 @@
if(!force)
_RemoveFromParent()
if(!silent)
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
parent = null
LAZYCLEARLIST(signal_procs)
for(var/target in signal_procs)
UnregisterSignal(target, signal_procs[target])
return ..()
/datum/component/proc/_RemoveFromParent()
@@ -77,26 +78,67 @@
if(!dc.len)
P.datum_components = null
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src))
/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src) || QDELETED(target))
return
var/list/procs = signal_procs
if(!procs)
procs = list()
signal_procs = procs
signal_procs = procs = list()
if(!procs[target])
procs[target] = list()
var/list/lookup = target.comp_lookup
if(!lookup)
target.comp_lookup = lookup = list()
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
proc_or_callback = CALLBACK(src, proc_or_callback)
var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types)
for(var/sig_type in sig_types)
if(!override)
. = procs[sig_type]
if(.)
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
if(!override && procs[target][sig_type])
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
proc_or_callback = CALLBACK(src, proc_or_callback)
procs[sig_type] = proc_or_callback
procs[target][sig_type] = proc_or_callback
if(!lookup[sig_type]) // Nothing has registered here yet
lookup[sig_type] = src
else if(lookup[sig_type] == src) // We already registered here
continue
else if(!length(lookup[sig_type])) // One other thing registered here
lookup[sig_type] = list(lookup[sig_type]=TRUE)
lookup[sig_type][src] = TRUE
else // Many other things have registered here
lookup[sig_type][src] = TRUE
enabled = TRUE
/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
var/list/lookup = target.comp_lookup
if(!signal_procs || !signal_procs[target] || !lookup)
return
if(!islist(sig_type_or_types))
sig_type_or_types = list(sig_type_or_types)
for(var/sig in sig_type_or_types)
switch(length(lookup[sig]))
if(2)
lookup[sig] = (lookup[sig]-src)[1]
if(1)
stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup")
if(src in lookup[sig])
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
if(0)
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
else
lookup[sig] -= src
signal_procs[target] -= sig_type_or_types
if(length(signal_procs[target]))
signal_procs -= target
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
return
@@ -121,28 +163,20 @@
current_type = type2parent(current_type)
. += current_type
/datum/proc/SendSignal(sigtype, ...)
var/list/comps = datum_components
if(!comps)
return NONE
var/list/arguments = args.Copy(2)
var/target = comps[/datum/component]
/datum/proc/_SendSignal(sigtype, list/arguments)
var/target = comp_lookup[sigtype]
if(!length(target))
var/datum/component/C = target
if(!C.enabled)
return NONE
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
return NONE
var/datum/callback/CB = C.signal_procs[src][sigtype]
return CB.InvokeAsync(arglist(arguments))
. = NONE
for(var/I in target)
var/datum/component/C = I
if(!C.enabled)
continue
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
continue
var/datum/callback/CB = C.signal_procs[src][sigtype]
. |= CB.InvokeAsync(arglist(arguments))
/datum/proc/GetComponent(c_type)
@@ -224,7 +258,7 @@
new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal
if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
SendSignal(COMSIG_COMPONENT_ADDED, new_comp)
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp)
return new_comp
return old_comp
@@ -244,7 +278,7 @@
qdel(C)
return
C._RemoveFromParent()
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
SEND_SIGNAL(helicopter, COMSIG_COMPONENT_REMOVING, C)
C.parent = src
if(C == AddComponent(C))
C._JoinParent()
+4 -4
View File
@@ -30,8 +30,8 @@
precondition = _precondition
after_insert = _after_insert
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/OnExamine)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
var/list/possible_mats = list()
for(var/mat_type in subtypesof(/datum/material))
@@ -42,14 +42,14 @@
var/mat_path = possible_mats[id]
materials[id] = new mat_path()
/datum/component/material_container/proc/OnExamine(mob/user)
/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
for(var/I in materials)
var/datum/material/M = materials[I]
var/amt = amount(M.id)
if(amt)
to_chat(user, "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>")
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
if(user.a_intent != INTENT_HELP)
return
+14
View File
@@ -2,6 +2,7 @@
var/gc_destroyed //Time when this object was destroyed.
var/list/active_timers //for SStimer
var/list/datum_components //for /datum/components
var/list/comp_lookup
var/var_edited = FALSE //Warranty void if seal is broken
var/tmp/unique_datum_id = null
@@ -37,6 +38,19 @@
qdel(C, FALSE, TRUE)
dc.Cut()
var/list/lookup = comp_lookup
if(lookup)
for(var/sig in lookup)
var/list/comps = lookup[sig]
if(length(comps))
for(var/i in comps)
var/datum/component/comp = i
comp.UnregisterSignal(src, sig)
else
var/datum/component/comp = comps
comp.UnregisterSignal(src, sig)
comp_lookup = lookup = null
return QDEL_HINT_QUEUE
+1 -1
View File
@@ -97,7 +97,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
if(I)
if(ishuman(user))
var/mob/living/carbon/human/A = user
log_game("[key_name(user)] purchased [I.name]")
log_game("[key_name(user)] purchased [name]")
A.put_in_any_hand_if_possible(I)
if(istype(I,/obj/item/storage/box/) && I.contents.len>0)
+3 -3
View File
@@ -50,11 +50,11 @@
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
_preloader.load(src)
. = ..()
attempt_init(...)
attempt_init(arglist(args))
// This is distinct from /tg/ because of our space management system
// This is overriden in /atom/movable and the parent isn't called if the SMS wants to deal with it's init
/atom/proc/attempt_init(loc, ...)
/atom/proc/attempt_init(...)
var/do_initialize = SSatoms.initialized
if(do_initialize != INITIALIZATION_INSSATOMS)
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
@@ -295,7 +295,7 @@
else
to_chat(user, "<span class='danger'>It's empty.</span>")
SendSignal(COMSIG_PARENT_EXAMINE, user)
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user)
return distance == -1 || (get_dist(src, user) <= distance) || isobserver(user) //observers do not have a range limit
+3 -3
View File
@@ -10,19 +10,19 @@
/datum/game_mode/blob/declare_completion()
if(blobwincount <= blobs.len)
feedback_set_details("round_end_result","win - blob took over")
feedback_set_details("round_end_result","blob win - blob took over")
to_chat(world, "<FONT size = 3><B>The blob has taken over the station!</B></FONT>")
to_chat(world, "<B>The entire station was eaten by the Blob</B>")
log_game("Blob mode completed with a blob victory.")
else if(station_was_nuked)
feedback_set_details("round_end_result","halfwin - nuke")
feedback_set_details("round_end_result","blob halfwin - nuke")
to_chat(world, "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>")
to_chat(world, "<B>Directive 7-12 has been successfully carried out preventing the Blob from spreading.</B>")
log_game("Blob mode completed with a tie (station destroyed).")
else if(!blob_cores.len)
feedback_set_details("round_end_result","loss - blob eliminated")
feedback_set_details("round_end_result","blob loss - blob eliminated")
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
to_chat(world, "<B>The alien organism has been eradicated from the station</B>")
log_game("Blob mode completed with a crew victory.")
+2 -2
View File
@@ -273,11 +273,11 @@ var/global/list/all_cults = list()
bonus_check()
if(!check_cult_victory())
feedback_set_details("round_end_result","win - cult win")
feedback_set_details("round_end_result","cult win - cult win")
feedback_set("round_end_result",acolytes_survived)
to_chat(world, "<span class='danger'> <FONT size = 3> The cult wins! It has succeeded in serving its dark masters!</FONT></span>")
else
feedback_set_details("round_end_result","loss - staff stopped the cult")
feedback_set_details("round_end_result","cult loss - staff stopped the cult")
feedback_set("round_end_result",acolytes_survived)
to_chat(world, "<span class='warning'> <FONT size = 3>The staff managed to stop the cult!</FONT></span>")
+2 -2
View File
@@ -54,8 +54,8 @@
else
to_chat(world, "<span class='boldnotice'>Nobody survived the meteor storm!</span>")
feedback_set_details("round_end_result","end - evacuation")
feedback_set("round_end_result",survivors)
feedback_set_details("round_end_result","meteor end - evacuation")
feedback_set("round_end_result", "Meteor survivors: [survivors]")
..()
return 1
+18 -32
View File
@@ -168,10 +168,6 @@ proc/issyndicate(mob/living/M as mob)
/datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code)
var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
/*
spawn(1)
NukeNameAssign(nukelastname(synd_mind.current),syndicates) //allows time for the rest of the syndies to be chosen
*/
synd_mind.current.real_name = "[syndicate_name()] Team [leader_title]"
to_chat(synd_mind.current, "<B>You are the Syndicate leader for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>")
to_chat(synd_mind.current, "<B>If you feel you are not up to this task, give your ID to another operative.</B>")
@@ -309,51 +305,50 @@ proc/issyndicate(mob/living/M as mob)
//derp //Used for tracking if the syndies actually haul the nuke to the station //no
//herp //Used for tracking if the syndies got the shuttle off of the z-level //NO, DON'T FUCKING NAME VARS LIKE THIS
if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
feedback_set_details("round_end_result","win - syndicate nuke")
if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
feedback_set_details("round_end_result","nuclear win - syndicate nuke")
to_chat(world, "<FONT size = 3><B>Syndicate Major Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives have destroyed [station_name()]!</B>")
else if(!disk_rescued && station_was_nuked && syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
else if(!disk_rescued && station_was_nuked && syndies_didnt_escape)
feedback_set_details("round_end_result","nuclear halfwin - syndicate nuke - did not evacuate in time")
to_chat(world, "<FONT size = 3><B>Total Annihilation</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!")
else if(!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - blew wrong station")
else if(!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
feedback_set_details("round_end_result","nuclear halfwin - blew wrong station")
to_chat(world, "<FONT size = 3><B>Crew Minor Victory</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't lose the disk!")
else if(!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
else if(!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
feedback_set_details("round_end_result","nuclear halfwin - blew wrong station - did not evacuate in time")
to_chat(world, "<FONT size = 3><B>[syndicate_name()] operatives have earned Darwin Award!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't lose the disk!")
else if( disk_rescued && is_operatives_are_dead())
feedback_set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
else if(disk_rescued && is_operatives_are_dead())
feedback_set_details("round_end_result","nuclear loss - evacuation - disk secured - syndi team dead")
to_chat(world, "<FONT size = 3><B>Crew Major Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disc and killed the [syndicate_name()] Operatives</B>")
else if( disk_rescued )
feedback_set_details("round_end_result","loss - evacuation - disk secured")
else if(disk_rescued)
feedback_set_details("round_end_result","nuclear loss - evacuation - disk secured")
to_chat(world, "<FONT size = 3><B>Crew Major Victory</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disc and stopped the [syndicate_name()] Operatives!</B>")
else if(!disk_rescued && is_operatives_are_dead())
feedback_set_details("round_end_result","loss - evacuation - disk not secured")
else if(!disk_rescued && is_operatives_are_dead())
feedback_set_details("round_end_result","nuclear loss - evacuation - disk not secured")
to_chat(world, "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!</B>")
else if(!disk_rescued && crew_evacuated)
feedback_set_details("round_end_result","halfwin - detonation averted")
else if(!disk_rescued && crew_evacuated)
feedback_set_details("round_end_result","nuclear halfwin - detonation averted")
to_chat(world, "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives recovered the abandoned authentication disk but detonation of [station_name()] was averted.</B> Next time, don't lose the disk!")
else if(!disk_rescued && !crew_evacuated)
feedback_set_details("round_end_result","halfwin - interrupted")
else if(!disk_rescued && !crew_evacuated)
feedback_set_details("round_end_result","nuclear halfwin - interrupted")
to_chat(world, "<FONT size = 3><B>Neutral Victory</B></FONT>")
to_chat(world, "<B>Round was mysteriously interrupted!</B>")
..()
return
@@ -407,15 +402,6 @@ proc/issyndicate(mob/living/M as mob)
return newname
/proc/NukeNameAssign(var/lastname,var/list/syndicates)
for(var/datum/mind/synd_mind in syndicates)
switch(synd_mind.current.gender)
if(MALE)
synd_mind.name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
if(FEMALE)
synd_mind.name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]"
synd_mind.current.real_name = synd_mind.name
return
/datum/game_mode/nuclear/set_scoreboard_gvars()
var/foecount = 0
+12 -15
View File
@@ -51,9 +51,9 @@
lenin.restricted_roles = restricted_jobs
if(head_revolutionaries.len < required_enemies)
return 0
return FALSE
return 1
return TRUE
/datum/game_mode/revolution/post_setup()
@@ -72,10 +72,7 @@
for(var/datum/mind/head_mind in heads)
mark_for_death(rev_mind, head_mind)
spawn(rand(10,100))
// equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO
// Removing revolutionary uplinks. -Pete
equip_revolutionary(rev_mind.current)
addtimer(CALLBACK(src, .proc/equip_revolutionary, rev_mind.current), rand(10, 100))
for(var/datum/mind/rev_mind in head_revolutionaries)
greet_revolutionary(rev_mind)
@@ -92,7 +89,7 @@
check_heads()
ticker.mode.check_win()
check_counter = 0
return 0
return FALSE
/datum/game_mode/proc/forge_revolutionary_objectives(datum/mind/rev_mind)
@@ -223,7 +220,7 @@
command_announcement.Announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg')
return ..()
if(finished != 0)
return 1
return TRUE
else
return ..()
@@ -304,9 +301,9 @@
for(var/datum/mind/rev_mind in head_revolutionaries)
for(var/datum/objective/mutiny/objective in rev_mind.objectives)
if(!(objective.check_completion()))
return 0
return FALSE
return 1
return TRUE
/////////////////////////////
//Checks for a head victory//
@@ -316,21 +313,21 @@
var/turf/T = get_turf(rev_mind.current)
if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != DEAD) && rev_mind.current.client && T && is_station_level(T.z))
if(ishuman(rev_mind.current))
return 0
return 1
return FALSE
return TRUE
//////////////////////////////////////////////////////////////////////
//Announces the end of the game with all relavent information stated//
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
feedback_set_details("round_end_result","win - heads killed")
feedback_set_details("round_end_result","revolution win - heads killed")
to_chat(world, "<span class='redtext'>The heads of staff were killed or exiled! The revolutionaries win!</span>")
else if(finished == 2)
feedback_set_details("round_end_result","loss - rev heads killed")
feedback_set_details("round_end_result","revolution loss - rev heads killed")
to_chat(world, "<span class='redtext'>The heads of staff managed to stop the revolution!</span>")
..()
return 1
return TRUE
/datum/game_mode/proc/auto_declare_completion_revolution()
var/list/targets = list()
@@ -256,12 +256,16 @@ Made by Xhuis
/datum/game_mode/shadowling/declare_completion()
if(check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) //Doesn't end instantly - this is hacky and I don't know of a better way ~X
feedback_set_details("round_end_result","shadowling win - shadowling ascension")
to_chat(world, "<span class='greentext'><b>The shadowlings have ascended and taken over the station!</b></span>")
else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round
feedback_set_details("round_end_result","shadowling loss - shadowling killed")
to_chat(world, "<span class='redtext'><b>The shadowlings have been killed by the crew!</b></span>")
else if(!check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
feedback_set_details("round_end_result","shadowling loss - crew escaped")
to_chat(world, "<span class='redtext'><b>The crew escaped the station before the shadowlings could ascend!</b></span>")
else
feedback_set_details("round_end_result","shadowling loss - generic failure")
to_chat(world, "<span class='redtext'><b>The shadowlings have failed!</b></span>")
..()
return 1
+1 -1
View File
@@ -180,6 +180,6 @@
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
feedback_set_details("round_end_result","loss - wizard killed")
feedback_set_details("round_end_result","raging wizard loss - wizard killed")
to_chat(world, "<span class='warning'><FONT size = 3><B> The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT></span>")
..(1)
+1 -1
View File
@@ -192,7 +192,7 @@
/datum/game_mode/wizard/declare_completion(var/ragin = 0)
if(finished && !ragin)
feedback_set_details("round_end_result","loss - wizard killed")
feedback_set_details("round_end_result","wizard loss - wizard killed")
to_chat(world, "<span class='warning'><FONT size = 3><B> The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT></span>")
..()
return 1
+2 -2
View File
@@ -117,7 +117,7 @@
/datum/outfit/job/doctor/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
if(H.mind.role_alt_title)
if(H.mind && H.mind.role_alt_title)
switch(H.mind.role_alt_title)
if("Surgeon")
uniform = /obj/item/clothing/under/rank/medical/blue
@@ -269,7 +269,7 @@
/datum/outfit/job/psychiatrist/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
if(H.mind.role_alt_title)
if(H.mind && H.mind.role_alt_title)
switch(H.mind.role_alt_title)
if("Psychiatrist")
uniform = /obj/item/clothing/under/rank/psych
+1 -1
View File
@@ -138,7 +138,7 @@
/datum/outfit/job/detective/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
if(H.mind.role_alt_title)
if(H.mind && H.mind.role_alt_title)
switch(H.mind.role_alt_title)
if("Forensic Technician")
suit = /obj/item/clothing/suit/storage/det_suit/forensics/blue
+2
View File
@@ -30,8 +30,10 @@
var/busy = FALSE
var/emped = FALSE //Number of consecutive EMP's on this camera
var/in_use_lights = 0 // TO BE IMPLEMENTED
var/toggle_sound = 'sound/items/Wirecutter.ogg'
/obj/machinery/camera/New()
..()
wires = new(src)
@@ -138,7 +138,8 @@
return
T = get_turf(T)
loc = T
cameranet.visibility(src)
if(use_static)
cameranet.visibility(src, GetViewerClient())
if(visible_icon)
if(eye_user.client)
eye_user.client.images -= user_image
+58 -84
View File
@@ -27,7 +27,6 @@
/datum/autopsy_data
var/weapon = null
var/pretend_weapon = null
var/damage = 0
var/hits = 0
var/time_inflicted = 0
@@ -35,44 +34,35 @@
/datum/autopsy_data/proc/copy()
var/datum/autopsy_data/W = new()
W.weapon = weapon
W.pretend_weapon = pretend_weapon
W.damage = damage
W.hits = hits
W.time_inflicted = time_inflicted
return W
/obj/item/autopsy_scanner/proc/add_data(obj/item/organ/external/O)
if(!O.autopsy_data.len && !O.trace_chemicals.len)
return
/obj/item/autopsy_scanner/proc/add_data(obj/item/organ/O)
if(O.autopsy_data.len)
for(var/V in O.autopsy_data)
var/datum/autopsy_data/W = O.autopsy_data[V]
for(var/V in O.autopsy_data)
var/datum/autopsy_data/W = O.autopsy_data[V]
var/datum/autopsy_data_scanner/D = wdata[V]
if(!D)
D = new()
D.weapon = W.weapon
wdata[V] = D
if(!W.pretend_weapon)
if(1)
W.pretend_weapon = W.weapon
else
W.pretend_weapon = pick("mechanical toolbox", "wirecutters", "revolver", "crowbar", "fire extinguisher", "tomato soup", "oxygen tank", "emergency oxygen tank", "laser", "bullet")
if(!D.organs_scanned[O.name])
if(D.organ_names == "")
D.organ_names = O.name
else
D.organ_names += ", [O.name]"
qdel(D.organs_scanned[O.name])
D.organs_scanned[O.name] = W.copy()
var/datum/autopsy_data_scanner/D = wdata[V]
if(!D)
D = new()
D.weapon = W.weapon
wdata[V] = D
if(!D.organs_scanned[O.name])
if(D.organ_names == "")
D.organ_names = O.name
else
D.organ_names += ", [O.name]"
qdel(D.organs_scanned[O.name])
D.organs_scanned[O.name] = W.copy()
for(var/V in O.trace_chemicals)
if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V))
chemtraces += V
if(O.trace_chemicals.len)
for(var/V in O.trace_chemicals)
if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V))
chemtraces += V
/obj/item/autopsy_scanner/attackby(obj/item/P, mob/user)
if(istype(P, /obj/item/pen))
@@ -90,71 +80,55 @@
user.put_in_hands(R)
/obj/item/autopsy_scanner/attack_self(mob/user)
if(!wdata.len && !chemtraces.len)
return
var/scan_data = ""
if(timeofdeath)
scan_data += "<b>Time of death:</b> [station_time_timestamp("hh:mm:ss", timeofdeath)]<br><br>"
else
scan_data += "<b>Time of death:</b> Unknown / Still alive<br><br>"
var/n = 1
for(var/wdata_idx in wdata)
var/datum/autopsy_data_scanner/D = wdata[wdata_idx]
var/total_hits = 0
var/total_score = 0
var/list/weapon_chances = list() // maps weapon names to a score
var/age = 0
if(wdata.len)
var/n = 1
for(var/wdata_idx in wdata)
var/datum/autopsy_data_scanner/D = wdata[wdata_idx]
var/total_hits = 0
var/total_score = 0
var/age = 0
for(var/wound_idx in D.organs_scanned)
var/datum/autopsy_data/W = D.organs_scanned[wound_idx]
total_hits += W.hits
var/wname = W.pretend_weapon
if(wname in weapon_chances)
weapon_chances[wname] += W.damage
else
weapon_chances[wname] = max(W.damage, 1)
total_score+=W.damage
for(var/wound_idx in D.organs_scanned)
var/datum/autopsy_data/W = D.organs_scanned[wound_idx]
total_hits += W.hits
total_score+=W.damage
var/wound_age = W.time_inflicted
age = max(age, wound_age)
var/wound_age = W.time_inflicted
age = max(age, wound_age)
var/damage_desc
var/damage_desc
// total score happens to be the total damage
switch(total_score)
if(1 to 5)
damage_desc = "<font color='green'>negligible</font>"
if(5 to 15)
damage_desc = "<font color='green'>light</font>"
if(15 to 30)
damage_desc = "<font color='orange'>moderate</font>"
if(30 to 1000)
damage_desc = "<font color='red'>severe</font>"
else
damage_desc = "Unknown"
var/damaging_weapon = (total_score != 0)
var/damaging_weapon = (total_score != 0)
scan_data += "<b>Weapon #[n]</b><br>"
if(damaging_weapon)
scan_data += "Severity: [damage_desc]<br>"
scan_data += "Hits by weapon: [total_hits]<br>"
scan_data += "Approximate time of wound infliction: [station_time_timestamp("hh:mm", age)]<br>"
scan_data += "Affected limbs: [D.organ_names]<br>"
scan_data += "Weapon: [D.weapon]<br>"
scan_data += "<br>"
// total score happens to be the total damage
switch(total_score)
if(0)
damage_desc = "Unknown"
if(1 to 5)
damage_desc = "<font color='green'>negligible</font>"
if(5 to 15)
damage_desc = "<font color='green'>light</font>"
if(15 to 30)
damage_desc = "<font color='orange'>moderate</font>"
if(30 to 1000)
damage_desc = "<font color='red'>severe</font>"
if(!total_score)
total_score = D.organs_scanned.len
scan_data += "<b>Weapon #[n]</b><br>"
if(damaging_weapon)
scan_data += "Severity: [damage_desc]<br>"
scan_data += "Hits by weapon: [total_hits]<br>"
scan_data += "Approximate time of wound infliction: [station_time_timestamp("hh:mm", age)]<br>"
scan_data += "Affected limbs: [D.organ_names]<br>"
scan_data += "Possible weapons:<br>"
for(var/weapon_name in weapon_chances)
scan_data += "\t[100*weapon_chances[weapon_name]/total_score]% [weapon_name]<br>"
scan_data += "<br>"
n++
n++
if(chemtraces.len)
scan_data += "<b>Trace Chemicals: </b><br>"
@@ -242,6 +242,7 @@ var/global/list/datum/stack_recipe/abductor_recipes = list ( \
var/global/list/datum/stack_recipe/titanium_recipes = list (
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20),
new/datum/stack_recipe("surgical tray", /obj/structure/table/tray, 2, one_per_turf = 1, on_floor = 1),
)
/obj/item/stack/sheet/mineral/titanium/New(loc, amount=null)
+1
View File
@@ -407,6 +407,7 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/S = H.bodyparts_by_name[user.zone_sel.selecting]
if(!S)
return
@@ -44,6 +44,8 @@
new /obj/item/clothing/suit/storage/labcoat(src)
new /obj/item/radio/headset/headset_sci(src)
new /obj/item/radio/headset/headset_sci(src)
new /obj/item/reagent_containers/food/drinks/oilcan(src)
new /obj/item/reagent_containers/food/drinks/oilcan(src)
/obj/structure/closet/secure_closet/RD
name = "research director's locker"
+2 -2
View File
@@ -70,9 +70,9 @@ FLOOR SAFES
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
if(tum2 && (turns_total == 1 || prob(10))) // So multi turns dont super spam the chat
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
if(tumbler_1_pos == tumbler_1_open && turns_total == 1) // You cant hear tumblers if you spin fast!
if(tumbler_1_pos == tumbler_1_open && turns_total == 1 && tum1) // You cant hear tumblers if you spin fast!
to_chat(user, "<span class='italics'>You hear a [pick("tonk", "krunk", "plunk")] from [src].</span>")
if(tumbler_2_pos == tumbler_2_open && turns_total == 1 ) // You cant hear tumblers if you spin fast!
if(tumbler_2_pos == tumbler_2_open && turns_total == 1 && tum2) // You cant hear tumblers if you spin fast!
to_chat(user, "<span class='italics'>You hear a [pick("tink", "krink", "plink")] from [src].</span>")
if(unlocked)
if(user)
@@ -82,6 +82,10 @@
new /obj/structure/table/reinforced/brass(loc)
qdel(src)
/obj/structure/table/do_climb(mob/living/user)
. = ..()
item_placed(user)
/obj/structure/table/attack_hand(mob/living/user)
..()
if(climber)
@@ -91,6 +95,9 @@
/obj/structure/table/attack_tk() // no telehulk sorry
return
/obj/structure/table/proc/item_placed(item)
return
/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0)
if(height == 0)
return 1
@@ -181,6 +188,7 @@
return 0
G.affecting.forceMove(get_turf(src))
G.affecting.Weaken(2)
item_placed(G.affecting)
G.affecting.visible_message("<span class='danger'>[G.assailant] pushes [G.affecting] onto [src].</span>", \
"<span class='userdanger'>[G.assailant] pushes [G.affecting] onto [src].</span>")
add_attack_logs(G.assailant, G.affecting, "Pushed onto a table")
@@ -221,6 +229,7 @@
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
item_placed(I)
else
return ..()
@@ -545,6 +554,72 @@
/obj/structure/table/reinforced/brass/ratvar_act()
obj_integrity = max_integrity
/obj/structure/table/tray
name = "surgical tray"
desc = "A small metal tray with wheels."
anchored = FALSE
smooth = SMOOTH_FALSE
icon = 'icons/obj/stationobjs.dmi'
icon_state = "tray"
buildstack = /obj/item/stack/sheet/mineral/titanium
buildstackamount = 2
var/list/typecache_can_hold = list(/mob, /obj/item)
var/list/held_items = list()
/obj/structure/table/tray/Initialize()
. = ..()
verbs -= /obj/structure/table/verb/do_flip
typecache_can_hold = typecacheof(typecache_can_hold)
for(var/atom/movable/held in get_turf(src))
if(is_type_in_typecache(held, typecache_can_hold))
held_items += held.UID()
/obj/structure/table/tray/Move(NewLoc, direct)
var/atom/OldLoc = loc
. = ..()
if(!.) // ..() will return 0 if we didn't actually move anywhere.
return .
if(direct & (direct - 1)) // This represents a diagonal movement, which is split into multiple cardinal movements. We'll handle moving the items on the cardinals only.
return .
playsound(loc, pick('sound/items/cartwheel1.ogg', 'sound/items/cartwheel2.ogg'), 100, 1, ignore_walls = FALSE)
var/atom/movable/held
for(var/held_uid in held_items)
held = locateUID(held_uid)
if(!held)
held_items -= held_uid
continue
if(OldLoc != held.loc)
held_items -= held_uid
continue
held.forceMove(NewLoc)
/obj/structure/table/tray/item_placed(atom/movable/item)
. = ..()
if(is_type_in_typecache(item, typecache_can_hold))
held_items += item.UID()
/obj/structure/table/tray/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
if(can_deconstruct)
var/turf/T = get_turf(src)
new buildstack(T, buildstackamount)
qdel(src)
/obj/structure/table/tray/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>It is held together by some <b>screws</b> and <b>bolts</b>.</span>")
/obj/structure/table/tray/flip()
return 0
/obj/structure/table/tray/narsie_act()
return 0
/obj/structure/table/tray/ratvar_act()
return 0
/*
* Racks
*/
@@ -60,7 +60,7 @@
/datum/SDQL_parser/proc/parse_error(error_message)
error = 1
to_chat(usr, "<span class='danger'>SQDL2 Parsing Error: [error_message]</span>")
to_chat(usr, "<span class='danger'>SDQL2 Parsing Error: [error_message]</span>")
return query.len + 1
/datum/SDQL_parser/proc/parse()
+100 -154
View File
@@ -5,7 +5,7 @@
icon_state = ""
flags = CONDUCT
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=100)
materials = list(MAT_METAL = 100)
throwforce = 2
throw_speed = 3
throw_range = 10
@@ -18,7 +18,7 @@
var/secured = 1
var/list/attached_overlays = null
var/obj/item/assembly_holder/holder = null
var/cooldown = 0//To prevent spam
var/cooldown = 0 //To prevent spam
var/wires = WIRE_RECEIVE | WIRE_PULSE
var/datum/wires/connected = null // currently only used by timer/signaler
@@ -28,173 +28,119 @@
var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate()
var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message
proc/activate() //What the device does when turned on
return
/obj/item/assembly/proc/activate() //What the device does when turned on
return
proc/pulsed(var/radio = 0) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
return
/obj/item/assembly/proc/pulsed(radio = 0) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
return
proc/pulse(var/radio = 0) //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
return
/obj/item/assembly/proc/pulse(radio = 0) //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
return
proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here
return
/obj/item/assembly/proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here
return
proc/attach_assembly(var/obj/A, var/mob/user) //Called when an assembly is attacked by another
return
/obj/item/assembly/proc/attach_assembly(obj/A, mob/user) //Called when an assembly is attacked by another
return
proc/process_cooldown() //Called via spawn(10) to have it count down the cooldown var
return
/obj/item/assembly/proc/process_cooldown() //Called via spawn(10) to have it count down the cooldown var
return
proc/holder_movement() //Called when the holder is moved
return
/obj/item/assembly/proc/holder_movement() //Called when the holder is moved
return
proc/describe() // Called by grenades to describe the state of the trigger (time left, etc)
return "The trigger assembly looks broken!"
/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc)
return "The trigger assembly looks broken!"
/obj/item/assembly/interact(mob/user) //Called when attack_self is called
return
interact(mob/user as mob) //Called when attack_self is called
return
process_cooldown()
cooldown--
if(cooldown <= 0) return 0
spawn(10)
process_cooldown()
return 1
Destroy()
if(istype(src.loc, /obj/item/assembly_holder) || istype(holder))
var/obj/item/assembly_holder/A = src.loc
if(A.a_left == src)
A.a_left = null
else if(A.a_right == src)
A.a_right = null
src.holder = null
return ..()
pulsed(var/radio = 0)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
return 1
pulse(var/radio = 0)
if(holder && (wires & WIRE_PULSE))
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
holder.process_activation(src, 0, 1)
// if(connected && (wires & WIRE_PULSE))
// connected.Pulse(src)
// if(radio && (wires & WIRE_RADIO_PULSE))
//Not sure what goes here quite yet send signal?
if(istype(loc,/obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu
var/obj/item/grenade/G = loc
G.prime() // Adios, muchachos
return 1
activate()
if(!secured || (cooldown > 0)) return 0
cooldown = 2
spawn(10)
process_cooldown()
return 1
toggle_secure()
secured = !secured
update_icon()
return secured
attach_assembly(var/obj/item/assembly/A, var/mob/user)
holder = new/obj/item/assembly_holder(get_turf(src))
if(holder.attach(A,src,user))
to_chat(user, "<span class='notice'>You attach \the [A] to \the [src]!</span>")
return 1
/obj/item/assembly/process_cooldown()
cooldown--
if(cooldown <= 0)
return 0
spawn(10)
process_cooldown()
return 1
/obj/item/assembly/Destroy()
if(istype(loc, /obj/item/assembly_holder) || istype(holder))
var/obj/item/assembly_holder/A = loc
if(A.a_left == src)
A.a_left = null
else if(A.a_right == src)
A.a_right = null
holder = null
return ..()
attackby(obj/item/W as obj, mob/user as mob, params)
if(isassembly(W))
var/obj/item/assembly/A = W
if((!A.secured) && (!secured))
attach_assembly(A,user)
return
if(istype(W, /obj/item/screwdriver))
if(toggle_secure())
to_chat(user, "<span class='notice'>\The [src] is ready!</span>")
else
to_chat(user, "<span class='notice'>\The [src] can now be attached!</span>")
/obj/item/assembly/pulsed(radio = 0)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
return 1
/obj/item/assembly/pulse(radio = 0)
if(holder && (wires & WIRE_PULSE))
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
holder.process_activation(src, 0, 1)
if(istype(loc, /obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu
var/obj/item/grenade/G = loc
G.prime() // Adios, muchachos
return 1
/obj/item/assembly/activate()
if(!secured || (cooldown > 0))
return 0
cooldown = 2
spawn(10)
process_cooldown()
return 1
/obj/item/assembly/toggle_secure()
secured = !secured
update_icon()
return secured
/obj/item/assembly/attach_assembly(obj/item/assembly/A, mob/user)
holder = new /obj/item/assembly_holder(get_turf(src))
if(holder.attach(A, src, user))
to_chat(user, "<span class='notice'>You attach [A] to [src]!</span>")
return 1
return 0
/obj/item/assembly/attackby(obj/item/W, mob/user, params)
if(isassembly(W))
var/obj/item/assembly/A = W
if((!A.secured) && (!secured))
attach_assembly(A, user)
return
..()
if(isscrewdriver(W))
if(toggle_secure())
to_chat(user, "<span class='notice'>[src] is ready!</span>")
else
to_chat(user, "<span class='notice'>[src] can now be attached!</span>")
return
..()
/obj/item/assembly/process()
processing_objects.Remove(src)
process()
processing_objects.Remove(src)
/obj/item/assembly/examine(mob/user)
..()
if((in_range(src, user) || loc == user))
if(secured)
to_chat(user, "[src] is ready!")
else
to_chat(user, "[src] can be attached!")
/obj/item/assembly/attack_self(mob/user)
if(!user)
return
user.set_machine(src)
interact(user)
return 1
examine(mob/user)
..(user)
if((in_range(src, user) || loc == user))
if(secured)
to_chat(user, "\The [src] is ready!")
else
to_chat(user, "\The [src] can be attached!")
attack_self(mob/user as mob)
if(!user) return 0
user.set_machine(src)
interact(user)
return 1
interact(mob/user as mob)
return //HTML MENU FOR WIRES GOES HERE
/*
var/small_icon_state = null//If this obj will go inside the assembly use this for icons
var/list/small_icon_state_overlays = null//Same here
var/obj/holder = null
var/cooldown = 0//To prevent spam
proc
Activate()//Called when this assembly is pulsed by another one
Process_cooldown()//Call this via spawn(10) to have it count down the cooldown var
Attach_Holder(var/obj/H, var/mob/user)//Called when an assembly holder attempts to attach, sets src's loc in here
Activate()
if(cooldown > 0)
return 0
cooldown = 2
spawn(10)
Process_cooldown()
//Rest of code here
return 0
Process_cooldown()
cooldown--
if(cooldown <= 0) return 0
spawn(10)
Process_cooldown()
return 1
Attach_Holder(var/obj/H, var/mob/user)
if(!H) return 0
if(!H.IsAssemblyHolder()) return 0
//Remember to have it set its loc somewhere in here
*/
/obj/item/assembly/interact(mob/user)
return
+104 -124
View File
@@ -2,7 +2,7 @@
name = "proximity sensor"
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
materials = list(MAT_METAL=800, MAT_GLASS=200)
materials = list(MAT_METAL = 800, MAT_GLASS = 200)
origin_tech = "magnets=1;engineering=1"
secured = 0
@@ -13,142 +13,122 @@
var/timing = 0
var/time = 10
proc
toggle_scan()
sense()
describe()
if(timing)
return "<span class='notice'>The proximity sensor is arming.</span>"
return "The proximity sensor is [scanning?"armed":"disarmed"]."
activate()
if(!..()) return 0//Cooldown check
timing = !timing
update_icon()
return 0
toggle_secure()
secured = !secured
if(secured)
processing_objects.Add(src)
else
scanning = 0
timing = 0
processing_objects.Remove(src)
update_icon()
return secured
HasProximity(atom/movable/AM as mob|obj)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect)) return
if(AM.move_speed < 12) sense()
return
sense()
if((!secured)||(!scanning)||(cooldown > 0)) return 0
pulse(0)
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
return
process()
if(timing && (time >= 0))
time--
if(timing && time <= 0)
timing = 0
toggle_scan()
time = 10
return
dropped()
..()
spawn(0)
sense()
return
return
toggle_scan()
if(!secured) return 0
scanning = !scanning
update_icon()
return
/obj/item/assembly/prox_sensor/describe()
if(timing)
return "<span class='notice'>The proximity sensor is arming.</span>"
return "The proximity sensor is [scanning ? "armed" : "disarmed"]."
/obj/item/assembly/prox_sensor/activate()
if(!..())
return 0 //Cooldown check
timing = !timing
update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "prox_timing"
attached_overlays += "prox_timing"
if(scanning)
overlays += "prox_scanning"
attached_overlays += "prox_scanning"
if(holder)
holder.update_icon()
return 0
/obj/item/assembly/prox_sensor/toggle_secure()
secured = !secured
if(secured)
processing_objects.Add(src)
else
scanning = 0
timing = 0
processing_objects.Remove(src)
update_icon()
return secured
/obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect))
return
if(AM.move_speed < 12)
sense()
/obj/item/assembly/prox_sensor/proc/sense()
if((!secured)||(!scanning)||(cooldown > 0))
return 0
pulse(0)
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
Move()
..()
/obj/item/assembly/prox_sensor/process()
if(timing && (time >= 0))
time--
if(timing && time <= 0)
timing = 0
toggle_scan()
time = 10
/obj/item/assembly/prox_sensor/dropped()
..()
spawn(0)
sense()
return
holder_movement()
sense()
/obj/item/assembly/prox_sensor/proc/toggle_scan()
if(!secured)
return 0
scanning = !scanning
update_icon()
/obj/item/assembly/prox_sensor/update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "prox_timing"
attached_overlays += "prox_timing"
if(scanning)
overlays += "prox_scanning"
attached_overlays += "prox_scanning"
if(holder)
holder.update_icon()
interact(mob/user as mob)//TODO: Change this to the wires thingy
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return 0
var/second = time % 60
var/minute = (time - second) / 60
var/dat = text("<TT><B>Proximity Sensor</B>\n[] []:[]\n<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>\n</TT>", (timing ? "<A href='?src=[UID()];time=0'>Arming</A>" : "<A href='?src=[UID()];time=1'>Not Arming</A>"), minute, second)
dat += "<BR><A href='?src=[UID()];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
dat += "<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[UID()];close=1'>Close</A>"
var/datum/browser/popup = new(user, "prox", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "prox")
/obj/item/assembly/prox_sensor/Move()
..()
sense()
/obj/item/assembly/prox_sensor/holder_movement()
sense()
/obj/item/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return 0
var/second = time % 60
var/minute = (time - second) / 60
var/dat = text("<TT><B>Proximity Sensor</B>\n[] []:[]\n<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>\n</TT>", (timing ? "<A href='?src=[UID()];time=0'>Arming</A>" : "<A href='?src=[UID()];time=1'>Not Arming</A>"), minute, second)
dat += "<BR><A href='?src=[UID()];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
dat += "<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[UID()];close=1'>Close</A>"
var/datum/browser/popup = new(user, "prox", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "prox")
/obj/item/assembly/prox_sensor/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=prox")
onclose(usr, "prox")
return
if(href_list["scanning"])
toggle_scan()
Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=prox")
onclose(usr, "prox")
return
if(href_list["scanning"])
toggle_scan()
if(href_list["time"])
timing = text2num(href_list["time"])
update_icon()
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 600)
if(href_list["close"])
usr << browse(null, "window=prox")
return
if(usr)
attack_self(usr)
if(href_list["time"])
timing = text2num(href_list["time"])
update_icon()
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 600)
if(href_list["close"])
usr << browse(null, "window=prox")
return
if(usr)
attack_self(usr)
+1 -2
View File
@@ -10,10 +10,9 @@
permeability_coefficient = 0.50
actions_types = list(/datum/action/item_action/adjust)
burn_state = FIRE_PROOF
species_fit = list("Vox", "Vox Armalis", "Unathi", "Tajaran", "Vulpkanin", "Grey" )
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey" )
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
"Vox Armalis" = 'icons/mob/species/armalis/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
@@ -385,4 +385,11 @@
amount_per_transfer_from_this = 20
/obj/item/reagent_containers/food/drinks/waterbottle/large/empty
list_reagents = list()
list_reagents = list()
/obj/item/reagent_containers/food/drinks/oilcan
name = "Oil Injection Device"
desc = "A device with a spout on one end for use in replacing fluid in synthtics who have sprung leaks."
icon = 'icons/obj/surgery.dmi'
icon_state = "fixovein_old"
volume = 100
+1
View File
@@ -14,6 +14,7 @@
var/instant_application = 0 //if we want to bypass the forcedfeed delay
var/taste = TRUE//whether you can taste eating from this
burn_state = FLAMMABLE
container_type = INJECTABLE
/obj/item/reagent_containers/food/New()
..()
@@ -291,16 +291,17 @@
else
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
if(blood_volume < BLOOD_VOLUME_SAFE)
if(!isSynthetic() && blood_volume < BLOOD_VOLUME_SAFE)
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
if(bleedsuppress)
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
else if(bleed_rate)
var/bleed_message = !isSynthetic() ? "bleeding" : "leaking"
if(reagents.has_reagent("heparin"))
msg += "<B>[p_they(TRUE)] [p_are()] bleeding uncontrollably!</B>\n"
msg += "<B>[p_they(TRUE)] [p_are()] [bleed_message] uncontrollably!</B>\n"
else
msg += "<B>[p_they(TRUE)] [p_are()] bleeding!</B>\n"
msg += "<B>[p_they(TRUE)] [p_are()] [bleed_message]!</B>\n"
if(reagents.has_reagent("teslium"))
msg += "[p_they(TRUE)] [p_are()] emitting a gentle blue glow!\n"
+1 -1
View File
@@ -248,7 +248,7 @@
if(!L || L && (L.status & ORGAN_DEAD))
if(health >= config.health_threshold_crit)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else
else if(!(NOCRITDAMAGE in dna.species.species_traits))
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
failed_last_breath = TRUE
@@ -286,6 +286,11 @@
H.setOxyLoss(0)
H.SetLoseBreath(0)
var/takes_crit_damage = (!(NOCRITDAMAGE in species_traits))
if((H.health <= config.health_threshold_crit) && takes_crit_damage)
H.adjustBruteLoss(1)
return
/datum/species/proc/handle_dna(mob/living/carbon/human/H, remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here
return
@@ -15,20 +15,25 @@
skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources!
eyes = "blank_eyes"
brute_mod = 2.5 // 100% * 2.5 * 0.66 (robolimbs) = 165%
burn_mod = 2.5 // So they take 65% extra damage from brute/burn overall.
brute_mod = 2.28 // 100% * 2.28 * 0.66 (robolimbs) ~= 150%
burn_mod = 2.28 // So they take 50% extra damage from brute/burn overall
tox_mod = 0
clone_mod = 0
oxy_mod = 0
death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..."
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING)
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_INTORGANS, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS
dietflags = 0 //IPCs can't eat, so no diet
taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
blood_color = "#1F181F"
flesh_color = "#AAAAAA"
blood_color = "#3C3C3C"
exotic_blood = "oil"
blood_damage_type = STAMINA
//Default styles for created mobs.
default_hair = "Blue IPC Screen"
can_revive_by_healing = 1
+3 -4
View File
@@ -333,7 +333,7 @@
/mob/living/is_injectable(allowmobs = TRUE)
return (allowmobs && reagents && can_inject())
/mob/living/is_drawable(allowmobs = TRUE)
return (allowmobs && reagents && can_inject())
@@ -365,9 +365,8 @@
C.update_inv_legcuffed()
if(C.reagents)
for(var/datum/reagent/R in C.reagents.reagent_list)
C.reagents.clear_reagents()
C.reagents.addiction_list.Cut()
C.reagents.clear_reagents()
QDEL_LIST(C.reagents.addiction_list)
// rejuvenate: Called by `revive` to get the mob into a revivable state
// the admin "rejuvenate" command calls `revive`, not this proc.
+19 -1
View File
@@ -104,6 +104,13 @@ var/list/ai_verbs_default = list(
var/arrivalmsg = "$name, $rank, has arrived on the station."
var/multicam_allowed = FALSE
var/multicam_on = FALSE
var/obj/screen/movable/pic_in_pic/ai/master_multicam
var/list/multicam_screens = list()
var/list/all_eyes = list()
var/max_multicams = 6
/mob/living/silicon/ai/proc/add_ai_verbs()
verbs |= ai_verbs_default
verbs |= silicon_subsystems
@@ -691,10 +698,13 @@ var/list/ai_verbs_default = list(
light_cameras()
if(istype(A, /obj/machinery/camera))
current = A
if(A != GLOB.ai_camera_room_landmark)
end_multicam()
. = ..()
if(.)
if(!A && isturf(loc) && eyeobj)
end_multicam()
client.eye = eyeobj
client.perspective = MOB_PERSPECTIVE
eyeobj.get_remote_view_fullscreens(src)
@@ -1249,6 +1259,14 @@ var/list/ai_verbs_default = list(
else
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
/mob/living/silicon/ai/proc/camera_visibility(mob/camera/aiEye/moved_eye)
cameranet.visibility(moved_eye, client, all_eyes)
/mob/living/silicon/ai/forceMove(atom/destination)
. = ..()
if(.)
end_multicam()
/mob/living/silicon/ai/handle_fire()
return
@@ -1259,4 +1277,4 @@ var/list/ai_verbs_default = list(
return FALSE
/mob/living/silicon/ai/ExtinguishMob()
return
return
@@ -38,29 +38,64 @@ var/datum/cameranet/cameranet = new()
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
/datum/cameranet/proc/visibility(mob/camera/aiEye/ai)
// 0xf = 15
var/x1 = max(0, ai.x - 16) & ~(CHUNK_SIZE - 1)
var/y1 = max(0, ai.y - 16) & ~(CHUNK_SIZE - 1)
var/x2 = min(world.maxx, ai.x + 16) & ~(CHUNK_SIZE - 1)
var/y2 = min(world.maxy, ai.y + 16) & ~(CHUNK_SIZE - 1)
/datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes)
if(!islist(moved_eyes))
moved_eyes = moved_eyes ? list(moved_eyes) : list()
if(islist(other_eyes))
other_eyes = (other_eyes - moved_eyes)
else
other_eyes = list()
var/list/visibleChunks = list()
var/list/chunks_pre_seen = list()
var/list/chunks_post_seen = list()
for(var/x = x1; x <= x2; x += 16)
for(var/y = y1; y <= y2; y += 16)
visibleChunks += getCameraChunk(x, y, ai.z)
for(var/V in moved_eyes)
var/mob/camera/aiEye/eye = V
if(C)
chunks_pre_seen |= eye.visibleCameraChunks
// 0xf = 15
var/static_range = eye.static_visibility_range
var/x1 = max(0, eye.x - static_range) & ~(CHUNK_SIZE - 1)
var/y1 = max(0, eye.y - static_range) & ~(CHUNK_SIZE - 1)
var/x2 = min(world.maxx, eye.x + static_range) & ~(CHUNK_SIZE - 1)
var/y2 = min(world.maxy, eye.y + static_range) & ~(CHUNK_SIZE - 1)
var/list/remove = ai.visibleCameraChunks - visibleChunks
var/list/add = visibleChunks - ai.visibleCameraChunks
var/list/visibleChunks = list()
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
c.remove(ai)
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
visibleChunks |= getCameraChunk(x, y, eye.z)
var/list/remove = eye.visibleCameraChunks - visibleChunks
var/list/add = visibleChunks - eye.visibleCameraChunks
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
c.remove(eye, FALSE)
for(var/chunk in add)
var/datum/camerachunk/c = chunk
c.add(eye, FALSE)
if(C)
chunks_post_seen |= eye.visibleCameraChunks
if(C)
for(var/V in other_eyes)
var/mob/camera/aiEye/eye = V
chunks_post_seen |= eye.visibleCameraChunks
var/list/remove = chunks_pre_seen - chunks_post_seen
var/list/add = chunks_post_seen - chunks_pre_seen
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
C.images -= c.obscured
for(var/chunk in add)
var/datum/camerachunk/c = chunk
C.images += c.obscured
for(var/chunk in add)
var/datum/camerachunk/c = chunk
c.add(ai)
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
@@ -21,10 +21,11 @@
// Add an AI eye to the chunk, then update if changed.
/datum/camerachunk/proc/add(mob/camera/aiEye/eye)
var/client/client = eye.GetViewerClient()
if(client)
client.images += obscured
/datum/camerachunk/proc/add(mob/camera/aiEye/eye, add_images = TRUE)
if(add_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images += obscured
eye.visibleCameraChunks += src
visible++
seenby += eye
@@ -33,10 +34,11 @@
// Remove an AI eye from the chunk, then update if changed.
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye)
var/client/client = eye.GetViewerClient()
if(client)
client.images -= obscured
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_images = TRUE)
if(remove_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images -= obscured
eye.visibleCameraChunks -= src
seenby -= eye
if(visible > 0)
@@ -14,6 +14,8 @@
var/list/visibleCameraChunks = list()
var/mob/living/silicon/ai/ai = null
var/relay_speech = FALSE
var/use_static = TRUE
var/static_visibility_range = 16
// Use this when setting the aiEye's location.
@@ -25,10 +27,13 @@
return
T = get_turf(T)
loc = T
cameranet.visibility(src)
if(ai.client)
if(use_static)
ai.camera_visibility(src)
if(ai.client && !ai.multicam_on)
ai.client.eye = src
//Holopad
if(ai.master_multicam)
ai.master_multicam.refresh_view()
if(istype(ai.current, /obj/machinery/hologram/holopad))
var/obj/machinery/hologram/holopad/H = ai.current
H.move_hologram(ai, T)
@@ -41,18 +46,16 @@
return ai.client
return null
/mob/camera/aiEye/proc/RemoveImages()
var/client/C = GetViewerClient()
if(C)
if(C && use_static)
for(var/V in visibleCameraChunks)
var/datum/camerachunk/chunk = V
C.images -= chunk.obscured
/mob/camera/aiEye/Destroy()
if(ai)
//ai.all_eyes -= src
ai.all_eyes -= src
ai = null
for(var/V in visibleCameraChunks)
var/datum/camerachunk/chunk = V
@@ -62,9 +65,9 @@
/atom/proc/move_camera_by_click()
if(istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = usr
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)) && (AI.eyeobj.z == z))
AI.cameraFollow = null
if(isturf(src.loc) || isturf(src))
if(isturf(loc) || isturf(src))
AI.eyeobj.setLoc(src)
// AI MOVEMENT
@@ -124,6 +127,7 @@
if(eyeobj)
return
eyeobj = new /mob/camera/aiEye()
all_eyes += eyeobj
eyeobj.ai = src
eyeobj.setLoc(loc)
eyeobj.name = "[name] (AI Eye)"
@@ -59,6 +59,7 @@
spawn(20)
to_chat(src, "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection.")
end_multicam()
sleep(50)
my_area = get_area(src)
T = get_turf(src)
@@ -10,4 +10,6 @@
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 1
O.emotion = "Neutral"
if(multicam_on)
end_multicam()
view_core()
@@ -0,0 +1,260 @@
//Picture in picture
/obj/screen/movable/pic_in_pic/ai
var/mob/living/silicon/ai/ai
var/mutable_appearance/highlighted_background
var/highlighted = FALSE
var/mob/camera/aiEye/pic_in_pic/aiEye
/obj/screen/movable/pic_in_pic/ai/Initialize()
. = ..()
aiEye = new /mob/camera/aiEye/pic_in_pic()
aiEye.screen = src
/obj/screen/movable/pic_in_pic/ai/Destroy()
set_ai(null)
QDEL_NULL(aiEye)
return ..()
/obj/screen/movable/pic_in_pic/ai/Click()
..()
if(ai)
ai.select_main_multicam_window(src)
/obj/screen/movable/pic_in_pic/ai/make_backgrounds()
..()
highlighted_background = new /mutable_appearance()
highlighted_background.icon = 'icons/misc/pic_in_pic.dmi'
highlighted_background.icon_state = "background_highlight"
highlighted_background.layer = SPACE_LAYER
/obj/screen/movable/pic_in_pic/ai/add_background()
if((width > 0) && (height > 0))
var/matrix/M = matrix()
M.Scale(width + 0.5, height + 0.5)
M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size)
highlighted_background.transform = M
standard_background.transform = M
overlays += highlighted ? highlighted_background : standard_background
/obj/screen/movable/pic_in_pic/ai/set_view_size(width, height, do_refresh = TRUE)
aiEye.static_visibility_range = (round(max(width, height) / 2) + 1)
if(ai)
ai.camera_visibility(aiEye)
..()
/obj/screen/movable/pic_in_pic/ai/set_view_center(atom/target, do_refresh = TRUE)
..()
aiEye.setLoc(get_turf(target))
/obj/screen/movable/pic_in_pic/ai/refresh_view()
..()
aiEye.setLoc(get_turf(center))
/obj/screen/movable/pic_in_pic/ai/proc/highlight()
if(highlighted)
return
highlighted = TRUE
overlays -= standard_background
overlays += highlighted_background
/obj/screen/movable/pic_in_pic/ai/proc/unhighlight()
if(!highlighted)
return
highlighted = FALSE
overlays -= highlighted_background
overlays += standard_background
/obj/screen/movable/pic_in_pic/ai/proc/set_ai(mob/living/silicon/ai/new_ai)
if(ai)
ai.multicam_screens -= src
ai.all_eyes -= aiEye
if(ai.master_multicam == src)
ai.master_multicam = null
if(ai.multicam_on)
unshow_to(ai.client)
ai = new_ai
if(new_ai)
new_ai.multicam_screens += src
ai.all_eyes += aiEye
if(new_ai.multicam_on)
show_to(new_ai.client)
//Turf, area, and landmark for the viewing room
/turf/unsimulated/ai_visible
name = ""
icon = 'icons/misc/pic_in_pic.dmi'
icon_state = "room_background"
flags = NOJAUNT
/turf/unsimulated/ai_visible/Initialize()
. = ..()
obscured = image(null, src, null)
/area/ai_multicam_room
name = "ai_multicam_room"
icon_state = "ai_camera_room"
dynamic_lighting = FALSE
valid_territory = FALSE
ambientsounds = list()
GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
/obj/effect/landmark/ai_multicam_room
name = "ai camera room"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
/obj/effect/landmark/ai_multicam_room/Initialize()
. = ..()
qdel(GLOB.ai_camera_room_landmark)
GLOB.ai_camera_room_landmark = src
/obj/effect/landmark/ai_multicam_room/Destroy()
if(GLOB.ai_camera_room_landmark == src)
GLOB.ai_camera_room_landmark = null
return ..()
//Dummy camera eyes
/mob/camera/aiEye/pic_in_pic
name = "Secondary AI Eye"
var/obj/screen/movable/pic_in_pic/ai/screen
var/list/cameras_telegraphed = list()
var/telegraph_cameras = TRUE
var/telegraph_range = 7
/mob/camera/aiEye/pic_in_pic/GetViewerClient()
if(screen && screen.ai)
return screen.ai.client
/mob/camera/aiEye/pic_in_pic/setLoc(turf/T)
T = get_turf(T)
forceMove(T)
if(screen && screen.ai)
screen.ai.camera_visibility(src)
else
cameranet.visibility(src)
update_camera_telegraphing()
/mob/camera/aiEye/pic_in_pic/proc/update_camera_telegraphing()
if(!telegraph_cameras)
return
var/list/obj/machinery/camera/add = list()
var/list/obj/machinery/camera/remove = list()
var/list/obj/machinery/camera/visible = list()
for(var/VV in visibleCameraChunks)
var/datum/camerachunk/CC = VV
for(var/V in CC.cameras)
var/obj/machinery/camera/C = V
if (!C.can_use() || (get_dist(C, src) > telegraph_range))
continue
visible |= C
add = visible - cameras_telegraphed
remove = cameras_telegraphed - visible
for(var/V in remove)
var/obj/machinery/camera/C = V
if(QDELETED(C))
continue
cameras_telegraphed -= C
C.in_use_lights--
C.update_icon()
for(var/V in add)
var/obj/machinery/camera/C = V
if(QDELETED(C))
continue
cameras_telegraphed |= C
C.in_use_lights++
C.update_icon()
/mob/camera/aiEye/pic_in_pic/proc/disable_camera_telegraphing()
telegraph_cameras = FALSE
for(var/V in cameras_telegraphed)
var/obj/machinery/camera/C = V
if(QDELETED(C))
continue
C.in_use_lights--
C.update_icon()
cameras_telegraphed.Cut()
/mob/camera/aiEye/pic_in_pic/Destroy()
disable_camera_telegraphing()
return ..()
//AI procs
/mob/living/silicon/ai/proc/drop_new_multicam(silent = FALSE)
if(!multicam_allowed)
if(!silent)
to_chat(src, "<span class='warning'>This action is currently disabled. Contact an administrator to enable this feature.</span>")
return
if(!eyeobj)
return
if(multicam_screens.len >= max_multicams)
if(!silent)
to_chat(src, "<span class='warning'>Cannot place more than [max_multicams] multicamera windows.</span>")
return
var/obj/screen/movable/pic_in_pic/ai/C = new /obj/screen/movable/pic_in_pic/ai()
C.set_view_size(3, 3, FALSE)
C.set_view_center(get_turf(eyeobj))
C.set_ai(src)
if(!silent)
to_chat(src, "<span class='notice'>Added new multicamera window.</span>")
return C
/mob/living/silicon/ai/proc/toggle_multicam()
if(!multicam_allowed)
to_chat(src, "<span class='warning'>This action is currently disabled. Contact an administrator to enable this feature.</span>")
return
if(multicam_on)
end_multicam()
else
start_multicam()
/mob/living/silicon/ai/proc/start_multicam()
if(multicam_on || aiRestorePowerRoutine || !isturf(loc))
return
if(!GLOB.ai_camera_room_landmark)
to_chat(src, "<span class='warning'>This function is not available at this time.</span>")
return
multicam_on = TRUE
refresh_multicam()
to_chat(src, "<span class='notice'>Multiple-camera viewing mode activated.</span>")
/mob/living/silicon/ai/proc/refresh_multicam()
reset_perspective(GLOB.ai_camera_room_landmark)
if(client)
for(var/V in multicam_screens)
var/obj/screen/movable/pic_in_pic/P = V
P.show_to(client)
/mob/living/silicon/ai/proc/end_multicam()
if(!multicam_on)
return
multicam_on = FALSE
select_main_multicam_window(null)
if(client)
for(var/V in multicam_screens)
var/obj/screen/movable/pic_in_pic/P = V
P.unshow_to(client)
reset_perspective()
to_chat(src, "<span class='notice'>Multiple-camera viewing mode deactivated.</span>")
/mob/living/silicon/ai/proc/select_main_multicam_window(obj/screen/movable/pic_in_pic/ai/P)
if(master_multicam == P)
return
if(master_multicam)
master_multicam.set_view_center(get_turf(eyeobj), FALSE)
master_multicam.unhighlight()
master_multicam = null
if(P)
P.highlight()
eyeobj.setLoc(get_turf(P.center))
P.set_view_center(eyeobj)
master_multicam = P
@@ -307,4 +307,9 @@
if(!organ_found)
to_chat(user, "<span class='warning'>No prosthetics located.</span>")
if(H.isSynthetic())
to_chat(user, "<span class='notice'>Internal Fluid Level:[H.blood_volume]/[H.max_blood]</span>")
if(H.bleed_rate)
to_chat(user, "<span class='warning'>Warning:External component leak detected!</span>")
src.add_fingerprint(user)
@@ -117,6 +117,9 @@
parts -= picked
if(updating_health)
updatehealth("heal overall damage")
/mob/living/silicon/robot/take_overall_damage(brute = 0, burn = 0, updating_health = TRUE, used_weapon = null, sharp = 0)
if(status_flags & GODMODE) return //godmode
var/list/datum/robot_component/parts = get_damageable_components()
+1 -1
View File
@@ -572,7 +572,7 @@
CureIfHasDisability(TWITCHBLOCK)
/mob/living/proc/CureIfHasDisability(block)
if(dna.GetSEState(block))
if(dna && dna.GetSEState(block))
dna.SetSEState(block, 0, 1) //Fix the gene
genemutcheck(src, block,null, MUTCHK_FORCED)
dna.UpdateSE()
@@ -253,6 +253,7 @@ obj/machinery/lapvend/attackby(obj/item/I, mob/user)
fabricated_laptop.forceMove(loc)
fabricated_laptop = null
else if((devtype == 2) && fabricated_tablet)
fabricated_tablet.update_icon()
fabricated_tablet.forceMove(loc)
fabricated_tablet = null
atom_say("Enjoy your new product!")
@@ -764,5 +764,7 @@ var/const/INGEST = 2
processing_objects -= src
QDEL_LIST(reagent_list)
reagent_list = null
QDEL_LIST(addiction_list)
addiction_list = null
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
@@ -194,6 +194,11 @@
reagent_state = LIQUID
color = "#3C3C3C"
taste_message = "motor oil"
process_flags = ORGANIC | SYNTHETIC
/datum/reagent/oil/reaction_turf(turf/T, volume)
if(volume >= 3 && !isspaceturf(T) && !locate(/obj/effect/decal/cleanable/blood/oil) in T)
new /obj/effect/decal/cleanable/blood/oil(T)
/datum/reagent/iodine
name = "Iodine"
@@ -97,9 +97,9 @@
/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("sorium", created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 1, 5, 6)
goonchem_vortex(T, 1, min(10, created_volume), min(11, created_volume + 1))
holder.remove_reagent("sorium", created_volume)
/datum/chemical_reaction/sorium_vortex
name = "sorium_vortex"
@@ -110,7 +110,7 @@
/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 1, 5, 6)
goonchem_vortex(T, 1, min(10, created_volume), min(11, created_volume + 1))
/datum/chemical_reaction/liquid_dark_matter
name = "Liquid Dark Matter"
@@ -122,9 +122,9 @@
/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("liquid_dark_matter", created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 0, 5, 6)
goonchem_vortex(T, 0, min(10, created_volume), min(11, created_volume + 1))
holder.remove_reagent("liquid_dark_matter", created_volume)
/datum/chemical_reaction/ldm_vortex
name = "LDM Vortex"
@@ -135,7 +135,7 @@
/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 0, 5, 6)
goonchem_vortex(T, 0, min(10, created_volume), min(11, created_volume + 1))
/datum/chemical_reaction/blackpowder
name = "Black Powder"
@@ -411,7 +411,7 @@ datum/chemical_reaction/flash_powder
/datum/chemical_reaction/shock_explosion/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
for(var/mob/living/carbon/C in view(6, T))
for(var/mob/living/carbon/C in view(min(8, round(created_volume * 2)), T))
C.Beam(T,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) //What? Why are we beaming from the mob to the turf? Turf to mob generates really odd results.
C.electrocute_act(3.5, "electrical blast")
holder.del_reagent("teslium") //Clear all remaining Teslium and Uranium, but leave all other reagents untouched.
+8 -1
View File
@@ -13,9 +13,9 @@
var/lastrigger = "" // The last person to rig this fuel tank - Stored with the object. Only the last person matter for investigation
/obj/structure/reagent_dispensers/attackby(obj/item/I, mob/user, params)
. = ..()
if(I.is_refillable())
return FALSE //so we can refill them via their afterattack.
. = ..()
/obj/structure/reagent_dispensers/New()
create_reagents(tank_volume)
@@ -56,6 +56,13 @@
tank_volume = 100000
/obj/structure/reagent_dispensers/oil
name = "oil tank"
desc = "A tank of oil, commonly used to by robotics to fix leaking IPCs or just to loosen up those rusted underused parts."
icon_state = "oil"
reagent_id = "oil"
tank_volume = 3000
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank full of industrial welding fuel. Do not consume."
@@ -80,3 +80,13 @@
materials = list(MAT_METAL=500, MAT_GLASS=50)
build_path = /obj/item/clothing/mask/muzzle/safety/shock
category = list("Miscellaneous")
/datum/design/data_disk
name = "Genetics Data Disk"
desc = "Disk that allows you to store genetic data."
id = "datadisk"
req_tech = list("programming" = 3, "biotech" = 2)
build_type = PROTOLATHE
materials = list(MAT_METAL=300, MAT_GLASS=100)
build_path = /obj/item/disk/data
category = list("Miscellaneous")
@@ -64,7 +64,6 @@
actions += monkey_recycle_action
/obj/machinery/computer/camera_advanced/xenobio/attack_hand(mob/user)
if(!ishuman(user)) //AIs using it might be weird
return
+1 -1
View File
@@ -64,7 +64,7 @@
var/obj/item/organ/external/BP = X
var/brutedamage = BP.brute_dam
if(BP.is_robotic())
if(BP.is_robotic() && !isSynthetic())
continue
//We want an accurate reading of .len
+1 -1
View File
@@ -89,7 +89,7 @@
if(!breath || (breath.total_moles() == 0))
if(H.health >= config.health_threshold_crit)
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
else
else if(!(NOCRITDAMAGE in H.dna.species.species_traits))
H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
H.failed_last_breath = TRUE
+1 -1
View File
@@ -203,7 +203,7 @@
// Let's not drag this on, medbay has only so much antibiotics
//Adds autopsy data for used_weapon.
/obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
/obj/item/organ/proc/add_autopsy_data(var/used_weapon = "Unknown", var/damage)
var/datum/autopsy_data/W = autopsy_data[used_weapon]
if(!W)
W = new()
@@ -175,6 +175,8 @@
owner.handle_splints()
if(used_weapon)
add_autopsy_data("[used_weapon]", brute + burn)
else
add_autopsy_data(null, brute + burn)
// Make sure we don't exceed the maximum damage a limb can take before dismembering
if((brute_dam + burn_dam + brute + burn) < max_damage)
@@ -3,7 +3,7 @@
#define KIDAN_LANTERN_HUNGERCOST 0.5
#define KIDAN_LANTERN_MINHUNGER 150
#define KIDAN_LANTERN_LIGHT 4
#define KIDAN_LANTERN_LIGHT 5
/obj/item/organ/internal/lantern
name = "Bioluminescent Lantern"
+23 -3
View File
@@ -3,10 +3,30 @@
/obj/item/organ/internal/stack
name = "vox cortical stack"
icon_state = "brain-prosthetic"
name = "cortical stack"
icon_state = "cortical-stack"
parent_organ = "head"
organ_tag = "stack"
slot = "vox_stack"
status = ORGAN_ROBOT
vital = TRUE
vital = TRUE
var/stackdamaged = FALSE
/obj/item/organ/internal/stack/on_life()
if(damage < 1 && stackdamaged)
owner.mutations.Remove(SCRAMBLED)
owner.dna.SetSEState(SCRAMBLEBLOCK,0)
genemutcheck(owner,SCRAMBLEBLOCK,null,MUTCHK_FORCED)
stackdamaged = FALSE
..()
/obj/item/organ/internal/stack/emp_act(severity)
if(owner)
owner.mutations.Add(SCRAMBLED)
owner.dna.SetSEState(SCRAMBLEBLOCK,1,1)
genemutcheck(owner,SCRAMBLEBLOCK,null,MUTCHK_FORCED)
owner.AdjustConfused(4)
if(!stackdamaged)
stackdamaged = TRUE
..()
+77
View File
@@ -56,6 +56,83 @@
-->
<div class="commit sansserif">
<h2 class="date">24 October 2018</h2>
<h3 class="author">Alonefromhell updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Mind check in pre_quip added, to prevent runtime.</li>
</ul>
<h3 class="author">Birdtalon updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Backend cleanup of assembly.dm and proximity.dm</li>
</ul>
<h3 class="author">Certhic updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Runtime error in CureIfHasDisability</li>
<li class="bugfix">Borg health is now updated after being repaired</li>
</ul>
<h3 class="author">Farie82 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Tablets now spawn correctly. No more buying (seemingly) broken tablets</li>
</ul>
<h3 class="author">Fethas updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Ipcs bleed oil. Bleeding can be patched by welders and organ mainp surgery(if you have to heal an ipc via surgery we may as well take that out too).</li>
<li class="tweak">Kidan biolum slightly brighter. tweak:Vox now become confused and unintellible(..more) on cort stack damage.</li>
</ul>
<h3 class="author">Warior4356 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Safe tumbler 2 no longer makes I am open noise when turning tumbler 1.</li>
</ul>
<h3 class="author">dovydas12345 updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Added data disk to misc designs.</li>
</ul>
<h3 class="author">variableundefined updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Using reagent dispenser like fuel and water tank no longer give you an attack cooldown / animation.</li>
<li class="rscadd">Tracking for shadowling win rate. Improved parsability for other win/loss round type's win rate.</li>
</ul>
<h2 class="date">23 October 2018</h2>
<h3 class="author">Alonefromhell updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">You should now be able to put all your favorite chems in food again.</li>
</ul>
<h3 class="author">Fox McCloud updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Reagents now GC slightly better</li>
</ul>
<h2 class="date">22 October 2018</h2>
<h3 class="author">Dave-TH updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Fancy tables now properly smooth.</li>
</ul>
<h3 class="author">MrStonedOne updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Fixes a cause of lag in the Timer subsystem</li>
</ul>
<h3 class="author">Purpose updated:</h3>
<ul class="changes bgimages16">
<li class="rscdel">Removes unused code in Nuclear gamemode.</li>
<li class="rscdel">Removes some empty icon files.</li>
<li class="spellcheck">Fixes a typo in an SDQL parse warning.</li>
<li class="tweak">Code improvement with timers in Revolution gamemode.</li>
</ul>
<h3 class="author">name here updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">The autopsy scanner now works even when it does not know the weapon and/or the time of death.</li>
<li class="rscdel">Unused weapon chance code</li>
</ul>
<h3 class="author">uc_guy updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Removed logging ambiguity for uplink purchases.</li>
</ul>
<h3 class="author">variableundefined updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Component refactor from tg made by ninjanomnom has been ported over. Report unexpected issue (with autolathe / ORM)</li>
</ul>
<h2 class="date">21 October 2018</h2>
<h3 class="author">Alonefromhell updated:</h3>
<ul class="changes bgimages16">
+48
View File
@@ -7640,3 +7640,51 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: Minor refactor of revenant code.
- bugfix: Some relative path & commented out code has been cleared up in code. Report
unexpected issues.
2018-10-22:
Dave-TH:
- bugfix: Fancy tables now properly smooth.
MrStonedOne:
- bugfix: Fixes a cause of lag in the Timer subsystem
Purpose:
- rscdel: Removes unused code in Nuclear gamemode.
- rscdel: Removes some empty icon files.
- spellcheck: Fixes a typo in an SDQL parse warning.
- tweak: Code improvement with timers in Revolution gamemode.
name here:
- bugfix: The autopsy scanner now works even when it does not know the weapon and/or
the time of death.
- rscdel: Unused weapon chance code
uc_guy:
- tweak: Removed logging ambiguity for uplink purchases.
variableundefined:
- tweak: Component refactor from tg made by ninjanomnom has been ported over. Report
unexpected issue (with autolathe / ORM)
2018-10-23:
Alonefromhell:
- bugfix: You should now be able to put all your favorite chems in food again.
Fox McCloud:
- tweak: Reagents now GC slightly better
2018-10-24:
Alonefromhell:
- bugfix: Mind check in pre_quip added, to prevent runtime.
Birdtalon:
- tweak: Backend cleanup of assembly.dm and proximity.dm
Certhic:
- bugfix: Runtime error in CureIfHasDisability
- bugfix: Borg health is now updated after being repaired
Farie82:
- bugfix: Tablets now spawn correctly. No more buying (seemingly) broken tablets
Fethas:
- tweak: Ipcs bleed oil. Bleeding can be patched by welders and organ mainp surgery(if
you have to heal an ipc via surgery we may as well take that out too).
- tweak: Kidan biolum slightly brighter. tweak:Vox now become confused and unintellible(..more)
on cort stack damage.
Warior4356:
- bugfix: Safe tumbler 2 no longer makes I am open noise when turning tumbler 1.
dovydas12345:
- rscadd: Added data disk to misc designs.
variableundefined:
- bugfix: Using reagent dispenser like fuel and water tank no longer give you an
attack cooldown / animation.
- rscadd: Tracking for shadowling win rate. Improved parsability for other win/loss
round type's win rate.
@@ -0,0 +1,6 @@
author: "tigercat2000"
delete-after: True
changes:
- rscadd: "PiP Hud Elements"
- experiment: "AI PiP Multicam - Enabled by admins"
- bugfix: "Calling /New( with excess arguments is now properly directed to /Initialize("
@@ -0,0 +1,4 @@
author: "Dave-TH"
delete-after: True
changes:
- rscadd: "Adds surgical trays! You can drag these cool tables around and the items placed on them come along for the ride! Nifty!"
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+2
View File
@@ -135,6 +135,7 @@
#include "code\_onclick\hud\monkey.dm"
#include "code\_onclick\hud\movable_screen_objects.dm"
#include "code\_onclick\hud\other_mobs.dm"
#include "code\_onclick\hud\picture_in_picture.dm"
#include "code\_onclick\hud\radial.dm"
#include "code\_onclick\hud\robot.dm"
#include "code\_onclick\hud\screen_objects.dm"
@@ -1737,6 +1738,7 @@
#include "code\modules\mob\living\silicon\ai\life.dm"
#include "code\modules\mob\living\silicon\ai\login.dm"
#include "code\modules\mob\living\silicon\ai\logout.dm"
#include "code\modules\mob\living\silicon\ai\multicam.dm"
#include "code\modules\mob\living\silicon\ai\say.dm"
#include "code\modules\mob\living\silicon\ai\update_status.dm"
#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm"
Binary file not shown.
Binary file not shown.