diff --git a/.travis.yml b/.travis.yml index eaa289e5cc7..526ebde75ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,16 +5,6 @@ sudo: false git: depth: 1 -env: - global: - - BYOND_MAJOR="511" - - BYOND_MINOR="1385" - - BYOND_MACRO_COUNT=2 - matrix: - - DM_MAPFILE="cyberiad" - - DM_MAPFILE="metastation" - - DM_MAPFILE="test_away_missions" - cache: directories: - $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR} @@ -26,24 +16,57 @@ addons: - libgcc1:i386 - libstdc++6:i386 +env: + global: + - BYOND_MAJOR="511" + - BYOND_MINOR="1385" + - BYOND_MACRO_COUNT=4 + matrix: + - DM_MAPFILE="cyberiad" + - DM_MAPFILE="metastation" + - DM_MAPFILE="test_all_maps" + +stages: + - File Checks + - test + before_script: - chmod +x ./install-byond.sh - ./install-byond.sh script: - - (num=`grep -E '\\\\(red|blue|green|black|italic|bold|b|i[^mc])' **/*.dm | wc -l`; echo "$num BYOND text macros (expecting ${BYOND_MACRO_COUNT} or fewer)"; [ $num -le ${BYOND_MACRO_COUNT} ]) - source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup - bash dm.sh -M${DM_MAPFILE} paradise.dme -matrix: +jobs: include: - - env: FILE_CHECKS=1 + # Basic styling/functionality checks + - stage: File Checks + env: addons: install: - pip install --user PyYaml -q - pip install --user beautifulsoup4 -q - before_script: + before_script: skip script: - shopt -s globstar - (! grep 'step_[xy]' _maps/map_files/**/*.dmm) + - (num=$(grep -Ern '\\(red|blue|green|black|italic|bold|b|i[^mc])' code/ | wc -l); echo "$num BYOND text macros (expecting ${BYOND_MACRO_COUNT} or fewer)"; [ $num -le ${BYOND_MACRO_COUNT} ]) - md5sum -c - <<< "6dc1b6bf583f3bd4176b6df494caa5f1 *html/changelogs/example.yml" - python tools/ss13_genchangelog.py html/changelog.html html/changelogs + + # Compile NanoUI to make sure it works + - stage: NanoUI + language: node_js + node_js: + - "9" + env: + addons: + before_install: + - npm install -g bower gulp + - cd ./nano/ + install: + - npm install --loglevel=error + - bower install --silent + before_script: + script: + - gulp --min diff --git a/_maps/map_files/RandomZLevels/evil_santa.dmm b/_maps/map_files/RandomZLevels/evil_santa.dmm index 2b51f7407a5..ca6ab415c1f 100644 --- a/_maps/map_files/RandomZLevels/evil_santa.dmm +++ b/_maps/map_files/RandomZLevels/evil_santa.dmm @@ -14,7 +14,7 @@ "an" = (/obj/item/paper/journal_scrap_2,/turf/simulated/floor/carpet,/area/awaymission/challenge/main) "ao" = (/obj/structure/flora/rock/pile,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "ap" = (/obj/structure/flora/tree/dead,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) -"aq" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/awaymission/challenge/main) +"aq" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "ar" = (/obj/item/restraints/legcuffs/beartrap,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "as" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "at" = (/obj/structure/table/wood,/obj/item/newton,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) @@ -42,7 +42,7 @@ "aP" = (/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/awaymission/challenge/main) "aQ" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/awaymission/challenge/main) "aR" = (/turf/simulated/shuttle/wall{icon_state = "swall8"; dir = 2},/area/awaymission/challenge/main) -"aS" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) +"aS" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/awaymission/challenge/main) "aT" = (/turf/simulated/shuttle/wall{icon_state = "swall4"; dir = 2},/area/awaymission/challenge/main) "aU" = (/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/awaymission/challenge/main) "aV" = (/turf/simulated/floor/plasteel{icon_plating = "asteroid"; icon_state = "asteroid"; name = "Asteroid"},/area/awaymission/challenge/main) @@ -78,55 +78,54 @@ "bz" = (/obj/item/clothing/head/cone,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "bA" = (/mob/living/simple_animal/walrus,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "bB" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) -"bC" = (/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) -"bD" = (/obj/item/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) +"bC" = (/obj/item/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) +"bD" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) "bE" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start) -"bF" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) -"bG" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start) -"bH" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start) -"bI" = (/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bF" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start) +"bG" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start) +"bH" = (/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bI" = (/obj/machinery/door_control{id = "challenge"; name = "Gateway Lockdown"; pixel_x = -4; pixel_y = 26; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start) "bJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start) -"bK" = (/obj/machinery/door_control{id = "challenge"; name = "Gateway Lockdown"; pixel_x = -4; pixel_y = 26; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start) -"bL" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/greengrid,/area/awaymission/challenge/start) -"bM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bK" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/greengrid,/area/awaymission/challenge/start) +"bL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bM" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/item/paper/journal_scrap_1,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) "bN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"bO" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/item/paper/journal_scrap_1,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"bP" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) +"bO" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) +"bP" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "bQ" = (/obj/machinery/gateway{dir = 5},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "bR" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/main) -"bS" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) -"bT" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"bU" = (/obj/structure/dispenser/oxygen{oxygentanks = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"bV" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) +"bS" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bT" = (/obj/structure/dispenser/oxygen{oxygentanks = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"bU" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) +"bV" = (/obj/machinery/gateway/centeraway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "bW" = (/obj/machinery/gateway{dir = 4},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "bX" = (/obj/machinery/power/smes/magical,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/awaymission/challenge/main) "bY" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/main) -"bZ" = (/obj/machinery/gateway/centeraway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) +"bZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) "ca" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"cb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) "cd" = (/obj/machinery/gateway{dir = 10},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) -"ce" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"ce" = (/obj/machinery/gateway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "cf" = (/obj/machinery/gateway{dir = 6},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) "cg" = (/turf/simulated/floor/plating,/area/awaymission/challenge/main) "ch" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/awaymission/challenge/main) -"ci" = (/obj/machinery/gateway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start) -"cj" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/start) -"ck" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"ci" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/start) +"cj" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"ck" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"cl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) "cm" = (/obj/structure/table,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"cn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) "co" = (/obj/structure/table,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) -"cr" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) +"cp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start) +"cq" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) +"cr" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) "cs" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) -"ct" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) -"cu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) -"cv" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) +"ct" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) +"cu" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start) +"cv" = (/obj/machinery/atmospherics/unary/tank/air{dir = 1},/turf/simulated/floor/plating,/area/awaymission/challenge/start) "cw" = (/turf/space,/area/space) -"cx" = (/obj/machinery/atmospherics/unary/tank/air{dir = 1},/turf/simulated/floor/plating,/area/awaymission/challenge/start) -"cy" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/challenge/start) +"cx" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/challenge/start) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -140,7 +139,7 @@ aaabababababacababafacacacacacacacacacacacacacacacacacacacacacacababacacacacacac aaababababacacacacacacacacacacahacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagaiajakagacacacacacacabababababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacalagamamajajajagacacacacacacacababababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacalagamamanajajagacacacacacacacacabababaa -aaabababacacacaoacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacacacaSaramamasagagacacacacacacacacabababaa +aaabababacacacaoacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacacacaqaramamasagagacacacacacacacacabababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagamatauacacacacacacacacacabababaa aaabababacacacacacacacacacacacacagagagagagagagavacacacacacacacacacacacacacacacacacacacacacacawagaxayauacacacacacacacacacabababaa aaabababacadacacacacacacacacacacagazaAaBaCaDagacacacacacacacacafacacacacacacacacacacacacacacacagagagagacacacacacacacacacabababaa @@ -148,7 +147,7 @@ aaabababacacacacacacacacacacacacagamamamamamagacacacacacacacacacacacacacaoacacab aaabababacacacacacacacacacacacacauamamamamamauacacacacacacacacacacacacacacababababacacacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacalacacacacacagamamamamaEagacacacacacacacacacacacacacacabababababababacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacagasamamamaFagacacacacacacacacacacacacacacacababababababacacacacacacacacacacacacacahacacabababaa -aaabababacacacacacafacacacacacacagagagaSagagagacacacacacacacacacacacacacacacacabababacavacacacacacacacacacacacacacacacacabababaa +aaabababacacacacacafacacacacacacagagagaqagagagacacacacacacacacacacacacacacacacabababacavacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacacaGacacacacalacacacacacacacacacaHacacacacacacacababababacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacaIacacacacacacacacadacacacabacacacacacacacacacacacacacacacacacacacabababaa @@ -157,15 +156,15 @@ aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac aaabaJabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKacacacacacacacacacacacacacacacacacacacacacacacababababaa aaabaHaLacaLacabaKacacacacacacacacacacacaKacacacacacacacacacacacacacacaKacacacacacacacacacacacacacacacaHacacacacacacabababababaa aaabababacabababababacacacacacaHacacacacaKacacacacacacacacaGacacacaGacacacacacacacacacacacacacacacacacacacacacacacacabacabababaa -aaabaMaMaNaMaOababacacacacacacacacacacacacacacacacacacaPaQaRaqaqaqaTaQaUacacacacacacacacacacacacacacacacacacacacacacacacabababaa +aaabaMaMaNaMaOababacacacacacacacacacacacacacacacacacacaPaQaRaSaSaSaTaQaUacacacacacacacacacacacacacacacacacacacacacacacacabababaa aaabaMaVaVaVaWababacacacacacacacacacacacacacacacacacacaXaYaZaYaZaYaZaYaXacacacacacacacacacapacacacacacacacacacacacababababababaa aaabaOaVbaaVaMababacacacacacacacacacacacacacacacacacaGbbaZaYaZaYaZaYaZbbaGacacacacacacacacacacacacacacacacacacacacacabababababaa -aaabaWbcbdbeaOababababacacacacacacaIacacacacacacacacacaqaYaZaYaZaYaZaYaqacacacacacacacacacacacacacacacacacacacacacacabababababaa -aaabaMaMaOaMaWabababacacacacacacacacacacacacacacacacacaqaZaYaZbfaZaYaZaqacacacacacacacacacacacacacacacacavacacacacacabababababaa -aaababababababababacacacacacacacacacacacacacacacacacacaqaYaZaYaZaYaZaYaqacacacacacacacacacacacacacacacacacacacacacacabababababaa +aaabaWbcbdbeaOababababacacacacacacaIacacacacacacacacacaSaYaZaYaZaYaZaYaSacacacacacacacacacacacacacacacacacacacacacacabababababaa +aaabaMaMaOaMaWabababacacacacacacacacacacacacacacacacacaSaZaYaZbfaZaYaZaSacacacacacacacacacacacacacacacacavacacacacacabababababaa +aaababababababababacacacacacacacacacacacacacacacacacacaSaYaZaYaZaYaZaYaSacacacacacacacacacacacacacacacacacacacacacacabababababaa aaabababababababababacacacacacacacacacacacacacacacacaGbgaZaYaZaYaZaYaZbgaGacacacacacacacacacacacaIacacacacacacacacacacababababaa aaabababacabababababacacacacacacacacacacacacacacacacacaXaYaZaYaZaYaZaYaXacacacacacacacacacacacacacacacacacacacacacacacacabababaa -aaabababacacacacacacacacacacacacacacacacacacacacacacacbhaQaRaqaqaqaTaQbiacacacaKacacacacaoacacacacacacacacacacacacacacacabababaa +aaabababacacacacacacacacacacacacacacacacacacacacacacacbhaQaRaSaSaSaTaQbiacacacaKacacacacaoacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacacacacacacacacacaHacacacacaGacacacaGacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacaeacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa @@ -180,18 +179,17 @@ aaabababacacacacacbkagagagagacacacacacacacacacacacacacacabacabababacacacacacacac aaabababacacacacacagagbubvagagacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacagbwamambxagacacacacacacacacacacacacacacacaIacacacacacacacacafacacacacacacacacacacacacacacacacacacacacabababaa aaabababacacacacacaubyamamamagbzacacacacacbjacacacacacacacacacbAacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa -aaabababacacacacacauasamamamaSacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa -aaabababacacacacacagbBbCambDagbzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacabababaa -aaabababacacacacacagagagagagagacacacacacacacacacacacacacacbFbEbEbEbFbkacacacacacacacacacacacacacacacacacacacacacacaeacacabababaa -aaabababacacacacacalacacacacacacacacacacacacacacacacacaeacbFbGbGbGbFbjaIacacacacacacacacacacacacacacacacacacacacacacacacabababaa -aaabababacacacacacacacacacacacacacacacacacacacacbFbFbFbFbFbFbHbHbHbFbFbFbFbFbFacacacacacacacacacacacacacacacacacacacacacabababaa -aaabababacaeacacacacacacacacacacacacacacacabacabbFbIbIbIbIbKbJbJbJbKbIbIbIbIbFababacacacacacacacacacacacacacacacacacacacabababaa -aaababababacacacacacacadacacacacacacacacababababbFbIbLbLbLbIbMbObNbIbPbSbQbIbFabbjacababacacacacacacacadacacacacacacacacabababaa -aaabababababacacacacacacacacacacacacacababbRbRbRbFbIbLbLbLbIbTbUbTbIbVbZbWbIbFbRbRbRababacacacacacacacacacacacacacacacababababaa -aaabababababacabacacacacacacacacacacacababbRbXbYbFbIbLbLbLcbcacccacecdcicfbIbFcgcgbRabababacacacacacacacacacacacacacabababababaa -aaababababababababababababababababababababbRchcjbFckcbclclcncmcpcocqclclcebIbFcgcgbRabababababababababababababababababababababaa -aaababababababababababababababababababababbRcgcgbFbFcrbFbFctcscucscvbFbFcrbFbFcgcgbRabababababababababababababababababababababaa -aaababababababababababababababababababababbRcgcgcgbFcxbFcwcycwcwcwcycwbFcxbFcgcgcgbRabababababababababababababababababababababaa +aaabababacacacacacauasamamamaqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa +aaabababacacacacacagbBamambCagbzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacabababaa +aaabababacacacacacagagagagagagacacacacacacacacacacacacacacbDbEbEbEbDbkacacacacacacacacacacacacacacacacacacacacacacaeacacabababaa +aaabababacacacacacalacacacacacacacacacacacacacacacacacaeacbDbFbFbFbDbjaIacacacacacacacacacacacacacacacacacacacacacacacacabababaa +aaabababacacacacacacacacacacacacacacacacacacacacbDbDbDbDbDbDbGbGbGbDbDbDbDbDbDacacacacacacacacacacacacacacacacacacacacacabababaa +aaabababacaeacacacacacacacacacacacacacacacabacabbDbHbHbHbHbIbJbJbJbIbHbHbHbHbDababacacacacacacacacacacacacacacacacacacacabababaa +aaababababacacacacacacadacacacacacacacacababababbDbHbKbKbKbHbLbMbNbHbObPbQbHbDabbjacababacacacacacacacadacacacacacacacacabababaa +aaabababababacacacacacacacacacacacacacababbRbRbRbDbHbKbKbKbHbSbTbSbHbUbVbWbHbDbRbRbRababacacacacacacacacacacacacacacacababababaa +aaabababababacabacacacacacacacacacacacababbRbXbYbDbHbKbKbKbZcacbcacccdcecfbHbDcgcgbRabababacacacacacacacacacacacacacabababababaa +aaababababababababababababababababababababbRchcibDcjbZckckclcmcncocpckckccbHbDcgcgbRabababababababababababababababababababababaa +aaababababababababababababababababababababbRcgcgbDbDcqbDbDcrcsctcscubDbDcqbDbDcgcgbRabababababababababababababababababababababaa +aaababababababababababababababababababababbRcgcgcgbDcvbDcwcxcwcwcwcxcwbDcvbDcgcgcgbRabababababababababababababababababababababaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} - diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index 9a66c57d6ba..f40c2033dfd 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -409,7 +409,7 @@ "hS" = (/turf/unsimulated/floor{icon_state = "whiteyellow"; dir = 4},/area/awaymission/spacehotel) "hT" = (/obj/effect/view_portal{id = "hotel_12"},/turf/unsimulated/floor{icon_state = "rampbottom"; dir = 4},/area/awaymission/spacehotel) "hU" = (/obj/effect/view_portal/visual{dir = 4; dist = 0; id = "hotel_22"; opacity = 0; radius = 0},/turf/unsimulated/floor,/area/awaymission/spacehotel) -"hV" = (/obj/machinery/door/airlock/public/glass{icon_state = "door_locked"; locked = 1; name = "Employees Only"; req_access_txt = "150"},/obj/item/tape/police{icon_state = "police_door"; layer = 3.2},/turf/unsimulated/floor{dir = 8; icon_state = "whitered"},/area/awaymission/spacehotel) +"hV" = (/obj/machinery/door/airlock/public/glass{icon_state = "door_locked"; locked = 1; name = "Employees Only"; req_access_txt = "150"},/turf/unsimulated/floor{dir = 8; icon_state = "whitered"},/area/awaymission/spacehotel) "hW" = (/obj/effect/decal/cleanable/blood/old,/turf/unsimulated/floor{icon_state = "white"},/area/awaymission/spacehotel) "hX" = (/obj/effect/view_portal/visual{dir = 8; dist = 0; id = "hotel_13"; radius = 0},/turf/unsimulated/floor,/area/awaymission/spacehotel) "hY" = (/obj/effect/view_portal{id = "hotel_23"},/turf/unsimulated/floor{icon_state = "ramptop"; dir = 4},/area/awaymission/spacehotel) @@ -485,7 +485,7 @@ "jq" = (/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "jr" = (/obj/item/grown/bananapeel,/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "js" = (/obj/structure/barricade/wooden,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) -"jt" = (/obj/machinery/door/airlock/public/glass,/obj/item/tape/engineering{icon_state = "engineering_door"; layer = 3.2},/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) +"jt" = (/obj/machinery/door/airlock/public/glass,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "ju" = (/obj/machinery/gateway{dir = 10},/turf/unsimulated/floor{icon_state = "warning"; dir = 10},/area/awaymission/spacehotel) "jv" = (/obj/machinery/gateway,/turf/unsimulated/floor{icon_state = "warning"},/area/awaymission/spacehotel) "jw" = (/obj/machinery/gateway{dir = 6},/turf/unsimulated/floor{icon_state = "warning"; dir = 6},/area/awaymission/spacehotel) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 998ae80eada..e9974435ba9 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -5221,7 +5221,7 @@ "bWu" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/examroom,/turf/simulated/floor/plating,/area/medical/sleeper) "bWv" = (/turf/simulated/wall/r_wall,/area/crew_quarters/fitness{name = "\improper Arcade"}) "bWw" = (/obj/machinery/door/firedoor,/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 = "white"},/area/medical/sleeper) -"bWx" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bWx" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper) "bWy" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/cryo) "bWz" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2) "bWA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2) @@ -5282,8 +5282,8 @@ "bXD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/sleeper) "bXE" = (/obj/item/roller,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/sleeper) "bXF" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/sleeper{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper) -"bXG" = (/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{dir = 2; icon_state = "cmo"},/area/medical/sleeper) -"bXH" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"bXG" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) +"bXH" = (/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 = "white"},/area/medical/sleeper) "bXI" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) "bXJ" = (/obj/structure/table,/obj/item/reagent_containers/syringe/antiviral,/obj/item/reagent_containers/syringe/charcoal,/obj/item/reagent_containers/syringe/insulin,/obj/item/reagent_containers/glass/bottle/morphine,/obj/item/reagent_containers/glass/bottle/epinephrine,/obj/item/reagent_containers/syringe,/obj/item/stack/medical/bruise_pack/advanced{pixel_x = 6; pixel_y = 6},/obj/item/stack/medical/ointment/advanced{pixel_x = 6; pixel_y = 8},/obj/item/reagent_containers/food/pill/patch/styptic{pixel_y = 6},/obj/item/reagent_containers/food/pill/patch/styptic{pixel_x = 2; pixel_y = 8},/obj/item/reagent_containers/food/pill/patch/silver_sulf{pixel_x = -8; pixel_y = 6},/obj/item/reagent_containers/food/pill/patch/silver_sulf{pixel_x = -8; pixel_y = 8},/obj/item/storage/pill_bottle/painkillers{pixel_x = -6; pixel_y = -3},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/sleeper) "bXK" = (/obj/item/twohanded/required/kirbyplants,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) @@ -5361,13 +5361,13 @@ "bZe" = (/obj/machinery/camera{c_tag = "Gravity Generator Foyer"; dir = 1; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/closet/radiation,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light,/turf/simulated/floor/plasteel,/area/engine/gravitygenerator) "bZf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j2s"; name = "Genetics"; sortType = 23},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/genetics_cloning) "bZg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) -"bZh" = (/obj/structure/table,/obj/item/roller,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/soap/nanotrasen,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper) -"bZi" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/sleeper) -"bZj" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper) -"bZk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) -"bZl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"bZh" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/sleeper) +"bZi" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/sleeper) +"bZj" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 0},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper) +"bZk" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bZl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bZm" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) -"bZn" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"; tag = "icon-pipe-j1 (WEST)"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"bZn" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bZo" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) "bZp" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) "bZq" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) @@ -5433,14 +5433,14 @@ "cay" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/table,/turf/simulated/floor/plasteel,/area/engine/break_room) "caz" = (/obj/structure/sign/poster/random{pixel_x = -32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper) "caA" = (/turf/simulated/wall,/area/medical/sleeper) -"caB" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 4; icon_state = "left"; name = "Blood Transfusion Ward"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"caB" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"; tag = "icon-pipe-j1 (WEST)"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "caC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) -"caD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"caD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "caE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) -"caF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) -"caG" = (/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"caF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"caG" = (/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "caH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) -"caI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper) +"caI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "caJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) "caK" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) "caL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo) @@ -5480,7 +5480,7 @@ "cbt" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/medical/sleeper) "cbu" = (/obj/structure/lamarr,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) "cbv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cbw" = (/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) +"cbw" = (/obj/structure/table,/obj/item/roller,/obj/item/soap/nanotrasen,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) "cbx" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "cby" = (/obj/machinery/computer/shuttle/admin,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "cbz" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Bridge"; opacity = 1; req_access_txt = "106"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) @@ -5510,7 +5510,7 @@ "cbX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j1 (EAST)"; icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/hallway/primary/central/south) "cbY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/hallway/primary/central/south) "cbZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) -"cca" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/sleeper) +"cca" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "ccb" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "ccc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/item/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "ccd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) @@ -5520,15 +5520,15 @@ "cch" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "cci" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "ccj" = (/obj/machinery/camera{c_tag = "Central Primary Hallway South"; dir = 2; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) -"cck" = (/obj/machinery/iv_drip,/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) +"cck" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/machinery/iv_drip,/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "ccl" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "ccm" = (/obj/machinery/door/airlock/public/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "ccn" = (/obj/machinery/atm{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "cco" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "ccp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) -"ccq" = (/obj/machinery/camera{c_tag = "Medbay Treatment Center"; dir = 1; network = list("SS13"); pixel_x = 0},/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) +"ccq" = (/obj/machinery/camera{c_tag = "Medbay Treatment Center"; dir = 1; network = list("SS13"); pixel_x = 0},/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/obj/item/roller,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "ccr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) -"ccs" = (/obj/machinery/sleeper{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/sleeper) +"ccs" = (/obj/machinery/sleeper{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "cct" = (/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{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "ccu" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper) "ccv" = (/obj/machinery/light{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/body_scanconsole,/turf/simulated/floor/plasteel{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper) @@ -5978,8 +5978,8 @@ "ckX" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery1) "ckY" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkblue"},/area/medical/ward) "ckZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward) -"cla" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"},/area/medical/ward) -"clb" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/medical/ward) +"cla" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward) +"clb" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/medical/ward) "clc" = (/obj/machinery/bodyscanner,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery2) "cld" = (/obj/structure/closet/secure_closet/medical2,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/surgery2) "cle" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light_switch{pixel_x = 23; pixel_y = -5},/obj/machinery/holosign_switch{id = "surgery2"; pixel_x = 23; pixel_y = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery2) @@ -6042,7 +6042,7 @@ "cmj" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the singularity chamber."; dir = 8; layer = 4; name = "Singularity Engine Telescreen"; network = list("Singularity"); pixel_x = 0; pixel_y = 30},/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/engine/controlroom) "cmk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cml" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre Storage"; req_access_txt = "45"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/medical/surgery1) -"cmm" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/medical/glass{id_tag = ""; name = "Medbay Virology Lobby"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology/lab{name = "\improper Virology Lobby"}) +"cmm" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Virology Lobby Hallway"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cmn" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cmo" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cmp" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHEAST)"; icon_state = "whitegreen"; dir = 5},/area/medical/virology/lab{name = "\improper Virology Lobby"}) @@ -6104,8 +6104,8 @@ "cnt" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) "cnu" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/ntrep) "cnv" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/wood,/area/blueshield) -"cnw" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology/lab{name = "\improper Virology Lobby"}) -"cnx" = (/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology/lab{name = "\improper Virology Lobby"}) +"cnw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Virology Lobby Hallway"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward) +"cnx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreencorner"},/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cny" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cnz" = (/obj/structure/sign/biohazard{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"; tag = "icon-whitegreen (WEST)"},/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cnA" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) @@ -6374,15 +6374,15 @@ "csD" = (/turf/simulated/wall,/area/engine/controlroom) "csE" = (/obj/machinery/camera{c_tag = "NT Representative's Office"; dir = 1; network = list("SS13")},/obj/structure/table/wood,/obj/machinery/photocopier/faxmachine/longrange{department = "NT Representative's Office"},/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/ntrep) "csF" = (/obj/item/flashlight,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/genetics) -"csG" = (/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/engine/controlroom) +"csG" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/closet/firecloset,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/engine/controlroom) "csH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "csI" = (/obj/structure/disposalpipe/segment,/obj/item/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/camera{c_tag = "Aft Primary Hallway 1"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "csJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/engine/controlroom) "csK" = (/obj/structure/table,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint) "csL" = (/turf/simulated/floor/plating,/area/maintenance/asmaint) "csM" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/genetics) -"csN" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/engine/controlroom) -"csO" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/engine/controlroom) +"csN" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel,/area/engine/controlroom) +"csO" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel,/area/engine/controlroom) "csP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/genetics) "csQ" = (/obj/structure/cable,/obj/machinery/computer/monitor{name = "Grid Power Monitoring Computer"},/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 5},/area/engine/controlroom) "csR" = (/obj/structure/rack{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/genetics) @@ -6505,7 +6505,7 @@ "cve" = (/obj/item/assembly/timer,/obj/item/assembly/timer{pixel_x = 6},/obj/item/assembly/timer{pixel_x = -5; pixel_y = 6},/obj/structure/table,/obj/item/assembly/timer{pixel_x = -3; pixel_y = -4},/obj/item/assembly/timer{pixel_x = 8; pixel_y = 8},/obj/item/assembly/timer,/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/light,/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cvf" = (/obj/machinery/atmospherics/trinary/mixer{density = 0; dir = 8; req_access = null},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cvg" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) -"cvh" = (/obj/item/radio/beacon,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel/airless,/area/toxins/test_area) +"cvh" = (/obj/item/radio/beacon,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel/airless/indestructible,/area/toxins/test_area) "cvi" = (/obj/machinery/atmospherics/binary/valve{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cvj" = (/obj/machinery/mass_driver{dir = 4; id_tag = "toxinsdriver"},/turf/simulated/floor/plating,/area/toxins/launch{name = "Toxins Launch Room"}) "cvk" = (/obj/structure/closet/crate,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/apmaint) @@ -7170,6 +7170,7 @@ "cHT" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/engine/break_room) "cHU" = (/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/wall,/area/engine/break_room) "cHV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/atmos/control) +"cHW" = (/turf/simulated/floor/plasteel{tag = "icon-whitegreen (WEST)"; icon_state = "whitegreen"; dir = 8},/area/medical/virology/lab{name = "\improper Virology Lobby"}) "cHY" = (/obj/machinery/computer/general_air_control{frequency = 1441; name = "Tank Monitor"; sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank")},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor/plasteel,/area/atmos/control) "cHZ" = (/obj/machinery/kitchen_machine/grill,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cIa" = (/obj/machinery/cooker/deepfryer,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -8972,10 +8973,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbVebVfbVgbVhbVibRGbVkbRAbVlbRAbRAbRAbRAbRAbTlbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebVmbOcbOcbOcbVnbOebPTbKBbKBbVobKzbPPbKzbKzbKzbKzbKzbJfbKAbTsbVpbxbbVrbBnbVqbVsbBnbVwbzEbBnbBnbVtbDXbOwbTybTzbRVbRWbMGbVubVvbVybVxbVzbMHbVBbVAbVDbVCbHsbVEbVFbHsbHtbHtbVGbSibVIbVHbVKbVJbVLbVLbVNbVMbVObFObSMbSLbSObSNbSPcrAcrAcrAcrAcrAbSRbSQbSUbSSbSVbXAbSXbRtbXAbThbXAbJRcuobJSbTZbTYbUabUabUcbUbbWgbUdbUfbUdbWibWibWjbWjbWjbWjbIabIabIabIabIabWlbWnbLIbIabNVbNZbNXbWqbWqbPibOabLRctvbPkbPjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGbRAbRAbWHbWHbWHbRGbRAbRAbRGbWIbWJbWKbRAbWMbWNbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbWPbTrbTqbTrbPUbWQbWRbKzbKzbKzbWQbKzbJfbKAbTsbWSbxbbWWbBnbzFbQdbBnbzJbLJbBnbBnbWUbDXbOwbTybWVbRVbWXbMGbXbbWYbWZbXabXdbMHbXcbXebXgbXfbXibXhbXjbFCaaaaaaaaabSibXpbXkbXlbXlbXmbXnbXobSibXrbXqbUhbUgbUjbUibUrbUkbUnbUmbUmbUmbUpbUobUmbUmbUqbUmbUmbUsbUnbUmbUmbUGbNubNtbUwbUvbUBbUybZfbUDbXNbUIbUIbUIbUJbWgbLRbUPbWqbWqbXYbXXbWqbXZbYbbYabYdbYcbWqbPlbYgbYfbYibYhbYlbYjbYjbYjbYjbYjcacbGjbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYubWGbRAbRAbRAbRAbRAbYtbRAbRAbRGbPIbPIbPIbPIbPIbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbYxbYwbYybYwbYAbYzbYBbYBbYBbYBbYBbYCbYEbYDbTsbYFbxbbYGbYIbYHbYNbYJbYKbYLbYLbYLbYMbYMbYObTybYRbYQbRWbMGbYTbYSbYVbVvbYWbMHbYUbYXbZdbTJbZebQmbYYbFCaaaaaaaaabSibYZbZabZbbZcbXmbXnbXobSibZgbZJbURbUQbUTbUScyTcyTbUVbUUbUXbUWcyTbUYbUZbUZbVabUZbUZbUSbUVbUZbVcbVbbVdcyTbVPbVjbVRbVQbVTbVSbVVbVUbVXbVWbVZbVYbWcbWbbWcbWcbWebUNbZMbUNbZNbUNbZPbZObZObPCbPDbZRbZUbZTbZXbZVbGkbZWaYpbYjcacbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRGbRAbRAbRGbRAcancakcaraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbxbbxbbKBbKBbKBbKBbKBbxbbxbbKBbKBbKBbxbcamcamcamcascambYMcaocapcaqcatbYMbOwbTycawbMEbMEbMGbMGbMGbMGbMGbMNbMHbTJbTIcaubTJcavcaxbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSibNvbFObWfbSLbWkbWhbWobWmbWscaAbWubWtbWxbWwbWtbWubWabWybWabWybWabWybWabWzbWAcrAbTZbWBbWDbWCbWFbWEbXNbXsbXubXtbXvcbdcbdcbecbdcbfcbicbfcbfcbfcbhcblcbjcbjcbkcbmcbocbnbZUcbpcbrcbqbGlcbscbubYjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPIbPIbPIbPIbPIbPIbRGbTobRAcbzbRAcbxcbycbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbDcbBbOccbCbOccbEcbFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbGaabaaaaaaaaaaaacamcbIcbHcbKcbJbYMcbNcbLcbMcbRbYMbOwbTycbOcbPcbQbXwcbVcbTcbUcbWcbYcbXbXxcbZcccccbccfccdcceccgccjcchccibXybXzcclccmbEnccnbFOccoccpccrbFObXBbQVbXCcaAcaAbXDbXDcaAbXFbXEbXHbXGbXJbXIbWabXKbXMbXLbXMbXObWabXPbWAbXRbWdbXSbXUbXTbXSbXSbWibXVbXWbXQbYkcbdccTccSccVccUccXccWcdbcbfccYccZcdacbjcbjcdccbocddcdfbPEcdhcdgbGmcdicdkbYjcdndfcbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIcdlcdmcdpcdlcdobRGbRAbRAbRGbRAcdrcdqcdsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdvcdtcducducducdtcdwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdycdxcdAcdzbYLcdBcdDcdCcdEbYMbOwbNwcdFbTybTybYmbYncdIcdJcclcdObYobYpcdMcdNcdNcdQcdPcdRcdNcdNcdTcdNcdNcdScclccmbEncdVcdUcdXbYqcdZcdYbFOchfbYrcaAbZhbYsbYsbZibZjbXHbZlbZkbZnbZmbZpbZobZrbZqbZtbZsbZvbZubWAcuvchrbZwbZybZxbZAbZzbZBccQbXWbXQbZBcbdcezceyceBceAceDceCceGcbfceEccZceFceFcbjceHceJceIceLceKceNceMbGnceOceSbYjcaccLhbGpbGobGsaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGceRceRceRceRceRceTbRAbRAbRGbPIbPIbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceVceUceUceUceWaaaaaaaaaaaaaaaaaaaaaceXceZceYceZcfaaaaaaaaaacamcamcamcffcfbcdAcfcbYLcfdcbMcfecfgbYMbOwbNxbTicficflcfkbZDbZCbZFbZEbZHbZGbZIcfscftcftcfxcfvcfvcfvcfvcfvcfvcfvcJfcfycfzcfBbZLbZKbZYbZScabcaacadchfcajcaAcazcalcaCcaBcaEcaDcaGcaFcaIcaHcaKcaJcaMcaLcaOcaNbZvcaPcaQcuvbZzcaRcaTcaScaVcaUcaXcaWcaZcaYcaXcbdcgccgbcgecgdcghcgfcggcbfcgiccZceFceFcbjcgjcgmcgkcglcgncgpcgocgrcgqcgvbYjcaccgscgtcgscgucgycgucgucguaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRGbRAbRAbRGbRAcancakcaraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbxbbxbbKBbKBbKBbKBbKBbxbbxbbKBbKBbKBbxbcamcamcamcascambYMcaocapcaqcatbYMbOwbTycawbMEbMEbMGbMGbMGbMGbMGbMNbMHbTJbTIcaubTJcavcaxbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSibNvbFObWfbSLbWkbWhbWobWmbWscaAbWubWtbWxbWwbXGbWubWabWybWabWybWabWybWabWzbWAcrAbTZbWBbWDbWCbWFbWEbXNbXsbXubXtbXvcbdcbdcbecbdcbfcbicbfcbfcbfcbhcblcbjcbjcbkcbmcbocbnbZUcbpcbrcbqbGlcbscbubYjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPIbPIbPIbPIbPIbPIbRGbTobRAcbzbRAcbxcbycbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbDcbBbOccbCbOccbEcbFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbGaabaaaaaaaaaaaacamcbIcbHcbKcbJbYMcbNcbLcbMcbRbYMbOwbTycbOcbPcbQbXwcbVcbTcbUcbWcbYcbXbXxcbZcccccbccfccdcceccgccjcchccibXybXzcclccmbEnccnbFOccoccpccrbFObXBbQVbXCcaAcaAbXDbXDcaAbXFbXEbZhbXHbZibXIbWabXKbXMbXLbXMbXObWabXPbWAbXRbWdbXSbXUbXTbXSbXSbWibXVbXWbXQbYkcbdccTccSccVccUccXccWcdbcbfccYccZcdacbjcbjcdccbocddcdfbPEcdhcdgbGmcdicdkbYjcdndfcbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIcdlcdmcdpcdlcdobRGbRAbRAbRGbRAcdrcdqcdsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdvcdtcducducducdtcdwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdycdxcdAcdzbYLcdBcdDcdCcdEbYMbOwbNwcdFbTybTybYmbYncdIcdJcclcdObYobYpcdMcdNcdNcdQcdPcdRcdNcdNcdTcdNcdNcdScclccmbEncdVcdUcdXbYqcdZcdYbFOchfbYrcaAbZjbYsbYsbXJbZhbZkbZnbZlcaBbZmbZpbZobZrbZqbZtbZsbZvbZubWAcuvchrbZwbZybZxbZAbZzbZBccQbXWbXQbZBcbdcezceyceBceAceDceCceGcbfceEccZceFceFcbjceHceJceIceLceKceNceMbGnceOceSbYjcaccLhbGpbGobGsaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGceRceRceRceRceRceTbRAbRAbRGbPIbPIbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceVceUceUceUceWaaaaaaaaaaaaaaaaaaaaaceXceZceYceZcfaaaaaaaaaacamcamcamcffcfbcdAcfcbYLcfdcbMcfecfgbYMbOwbNxbTicficflcfkbZDbZCbZFbZEbZHbZGbZIcfscftcftcfxcfvcfvcfvcfvcfvcfvcfvcJfcfycfzcfBbZLbZKbZYbZScabcaacadchfcajcaAcazcalcaCcaEcaEcaDcaGcaFcaIcaHcaKcaJcaMcaLcaOcaNbZvcaPcaQcuvbZzcaRcaTcaScaVcaUcaXcaWcaZcaYcaXcbdcgccgbcgecgdcghcgfcggcbfcgiccZceFceFcbjcgjcgmcgkcglcgncgpcgocgrcgqcgvbYjcaccgscgtcgscgucgycgucgucguaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYubWGceRceRceRcgwcgxbRGbRAbRAbRGbRAbRAbRAcgzbRAcgAbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgFcgBcgCcgDcgFbYPbYPbYPcamcgHcgGcgJcgIcgLcgKcgNcgMcgOcgOcgPbYMbTkcgQcgTcgScgScgUcbacgVcgScgWcgWcgYcbbcgZcgWcgWchacclcclchechcchcchcchccbcchcchcchfcbgchfchfchfchfchfchfchfcbvcbtcbScbwcckccaccsccqccucctccwccvbWaccxcczccyccBccAccDccCccEcuvccGccFccIccHccJchrbWibWgbWgbWgbWicbdcbdchMchQchOchPchOchRcbfchUchSchTchTcbjchVchXbTwbYjbYjbYjbYjbYjbYjbYjbYjcaccgscifchYchZciaciacibcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcicciccicciccidcidcieciecieciecijaabaabaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcigceRceRcihciibRGbRAbRAcikbRAbRAbRAciobRAcilbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcimcincimceYbYPcipciqcamcitcfbcircisciyciubYMcivciwcixcizbYMcgQcgQciCcgSciAciBccKciDciHcgWccLciGccMciIciKcgWciMciLciNchcccOccNccRccPcdjcdecdKcdHcdLchfceacdWceccebchfcedcbvcaAcaAcaAcaAcaAcaAcaAcefceecegcaAcDfcDfcDfcDfcDfcDfcDfcDfceicehccGcejcelcekcencemcepceocerceqclpcjFcjHcjGcjIcjGcjGcjLcjJcjKcjPcjMcjNcjOcbjcjQbUtcbnbPtbGGcjTcjScjUcjUcjScjUcjYcgscjVcjWchZciackecjXcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccjZckacjZcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIckdceRceRckfbRGbRAbRAbRGckgbRAbRAckjckhbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgFckicimcimckkcklcfbcfbckmckncfbcfbcisckqckobYMbYMbYMbYMbYMbYMckpcgQciCcgSclRcesceucetckucgWckvcevcexcewcePcgWcfmceQcfnchccfpcfockHckGcfqckIchcchfdgCchfcebcebcfrcebchfcsLcbvchfcfwbUucfCcfAcfEcfDcfGcfFcfIcfHcfKcfJcfMcfLcDfcfNcfPcfOcfRcfQcfTcfScfVcfUcfXcfWcepcfYcgacfZclpclncjGcjGclmclocjGcltclpcbjclqccZclrclrcbjcbmclscbnbPtcgsclvcgscgscgscgscgscgscgscluclwcguclxclzclycguafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOclBcjZcjZclAciecieckbckbclHckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -8983,8 +8984,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIbPIbPIbPIbPIbPIbPIbPIbPIbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabafOcgQcngcngcgQcngcngcgQaaaaaacgFcnhcnicnjcgFbYPbYPbYPcamcnmcnlcnocnocnocamcamcgQcnncnpcnrcnqcgQcnscntcgSclRcktcktcktcnvcgWckvckwckwcnuchHcgWcpicHDcnAchcchcchcchcchcchIchcchccnCdgCcsLcsLcsLchfcABchJcsLcbvchfchLchKciEchNcfEciFcfGcfFcfIcfHciOciJciQciPcDfciRciScDfciUciTchrciVciXciWchrchrcepciYcjaciZclpcjbcodcoicoicoicodcogcodcodcohcojclrclrcbjcokclscbncomcolcooconcorcopcoqcoqcotcoscovcoucoxcowcozcoycoCcoAcoBcoDcoEcoFcoHcoGcoIaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacidciecoMcoJcoJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacgQcoKcoLcgQcoKcoLcgQaaaaaacoOceZcoNceZcoQaaaaabaaacamcamcamcamcamcamcamcoPcgQcoScoRcoUcoTclPcoVcoWcgScoYcoXcpfcktcjccgWcjdckwcjfcjecjgcgWcjicjhcjkcjjcpqcpqcpqcpqcjlcpmcppcpocjncjmcjmcjocjqcjpcjscjrcjtchfcjwcjucjycjxcjAcjzcjCcjBcjCcjDckrcjEckxcksckzckyckAcDfckBcuvckCcjvckDcmDckFckEciYckJckLcgacpRcpTcpRcpUcpWcpVcpRcpXcpYcodcqacpZcdacbjcbjcqccqbcqfcqdcqecqicqgcqhcqlcqjcqkcqncqmcqpcqocqtcqqcqrcqqcqscqrcqrcqucqwcqvcqycqxcqCaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacieciecqDckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafOaaaafOcgQcqzcoLcgQcqzcoLcgQaaaaaaaabaabaabaabaabaabaabaabaabcgQcoLcqAcqBcgQcqEcqGcgQcqHcgQcgQcqFcgQcgQcqPcgScqRcqIcqJcqKcqLcgWckMcqOcqScqQcqTcgWckOckNckPcJZcsDcsDcsDcsDcsDcrdcqZcrackQchfcucckRcsLckSckTcsLcsKchfckVckUckXckWcCWckYclackZclbcDfcldclcclfclecDfcDfcDfcDfclhclgckCchCcljclicllclkciYcmdcgacmfcpRcrNcrQcrLcrMcrLcrTcrOcrPcodcbjcrUcbjcbjcrRcrSclsbLRbPtcgscrVcgscgscrWcrYcrXcsacrZcsdcsbcsfcsecsgcsecsgcshcsgcsicgEcsncvdcsqcsraabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacieckbckbckbckbckbckbcssckbcstckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjafOaabaMraMrafOcgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsucgQcsocspcoLcgQcsvcgScsycsxcszclRcmgcgWcswckvcsEcsCcmhcgWcsIcsHcmicsDcsDcsNcsOcsGcmjcsQcsJcsKcsLcsUchfcmkcsLckSckTchfchfchfcCWcCWcmlcCWcCWcxhcxhcmmcxhcDfcDfcDfcDfcDfcDfcmncmpcmocmrcmqcmtcmscmvcmucmxcmwciYcgacgaaqEcpRcttctxctwctyctwctActzcrLctuctvctBbLRctCbLRcrSclsbLRbIictFctHctGcgscgscgscgscgsctIcqkctKctDcsccqkctEcqkclucqkctLcgEctOctQctPcgEaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctSckbctTctJcstckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOafOcngcoLcoLcoLcoLctMctNcoLcoLcoSctUctUctVctUctUctUctUctUctUctUctUctUctUctUctUcoRcgQcskcqzctWcgQcsvctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWcuactXcmBcmzcmEcmCcmFcmFcmGcuicsJcmHcsLcubcuccmIcsLckScmJchicsLcsLcsKcCWcmLcmKcmNcCWcnxcnwcnBcnzcnEcnDcnGcnFcnIcnHcnKcnJcnMcnLckCcnNcnPcnOcnRcnQciYbQXcgacgacpRcuGcnTcnScnUcrLcuKcuJcuOcuLcuScuRcuVbLRcuXcrSclscuMbIibPAcuNcuYcuPcuQbGGbGGcgscvccvecuTcuUcvfcuWcvgcvicuZcvacvbcgEcvjdoKdoFcvraaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvscjZcjZcjZcjZcjZcjZcjZcvhcvtckbckbckbckbcvvckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjafOaabaMraMrafOcgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsucgQcsocspcoLcgQcsvcgScsycsxcszclRcmgcgWcswckvcsEcsCcmhcgWcsIcsHcmicsDcsDcsGcsOcsNcmjcsQcsJcsKcsLcsUchfcmkcsLckSckTchfchfchfcCWcCWcmlcCWcCWcxhcnwcmmcxhcDfcDfcDfcDfcDfcDfcmncmpcmocmrcmqcmtcmscmvcmucmxcmwciYcgacgaaqEcpRcttctxctwctyctwctActzcrLctuctvctBbLRctCbLRcrSclsbLRbIictFctHctGcgscgscgscgscgsctIcqkctKctDcsccqkctEcqkclucqkctLcgEctOctQctPcgEaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctSckbctTctJcstckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOafOcngcoLcoLcoLcoLctMctNcoLcoLcoSctUctUctVctUctUctUctUctUctUctUctUctUctUctUctUcoRcgQcskcqzctWcgQcsvctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWcuactXcmBcmzcmEcmCcmFcmFcmGcuicsJcmHcsLcubcuccmIcsLckScmJchicsLcsLcsKcCWcmLcmKcmNcCWcHWcnxcnBcnzcnEcnDcnGcnFcnIcnHcnKcnJcnMcnLckCcnNcnPcnOcnRcnQciYbQXcgacgacpRcuGcnTcnScnUcrLcuKcuJcuOcuLcuScuRcuVbLRcuXcrSclscuMbIibPAcuNcuYcuPcuQbGGbGGcgscvccvecuTcuUcvfcuWcvgcvicuZcvacvbcgEcvjdoKdoFcvraaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvscjZcjZcjZcjZcjZcjZcjZcvhcvtckbckbckbckbcvvckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabaabafOcngcvkcvlcvmcoLcoLcvncoLcoLcsucgQcgQcgQcgQcgQcgQcqFcgQcgQcgQcgQcvocvocvocvocvocvocvocvocvocgQcsvcvpaaaaaaaaaaaacvqcvwcvzcvycvucvAcvDcvxcvJcvGcvKcvBcvCcvLcvEcvEcvFcvMcvHcvIcvIcvIcvIcvNcvIckScmJchfcnVcKOdercCWcnXcnWcnZcnYcobcoacoccoccofcoecpacoZcpccpbcpecpdcphcpgciYciYciYciYciYciYciYciYcpkcpjcpRcwjcplcwqcptcpncpvcpucpRcpRbIicwpbIibIibIicwvcwJcwwbIibGGcuNcwKcwucuQcuQcuQcgscgscgscgscgscgscgscgscgscgscgscgscgEcgEcgEcgEcgEaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciecoJcoJcoJcoJcoJcoJcwLckbcoMcoJcwMckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgQcwxcwxcwxcwxcwxcwxcwycwxcsucwzcgQcoLcwAcwBcwCcoLcwCcwDcwEcwBcvocwFcwFcvocwGcvocwHcwIcvocoLcqPcngaaacwPcwUcwQcwVcwNcwOcwWcwXcwRcwScwTcwZcwYcxbcxacxdcxccxfcxecxjcxgcvHcxkcxmcxmcxmcxocvIckScmJchfdgmcQkcQkcQkcQkcpwcpxcQkcpycpycpycpycQkcpzcpBcpAcQkcQncQncpCcpDcuocukbQXbQXcpEbQXbQXbQXbQXbQXcpFcpRcpRcpRcpRcpGcpRcpRcpRcxIcpHcpIcxKcxUcxMcxNcxOcxWcxQcxNbGGcuNcylbGGbGGcxScxZcyactFbGGbGGbGGbGGbGGbGGbGGcxVcymbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieckbckbckbckbckbckbcssckbcwMckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxXcxYcxYcxYcxYcxYcxYcyocyncybcyccydcyecyfcwycsucygcgQcoLcoLcwBcoLcoLcoLcwDcqBcwBcvocwFcyicwIcwIcyjcwIcykcvocypcqPcngaaacyrcytcyscyvcyqcwOcywcyAcyycyucvxcyCcsHcyEcvBcyxctYcyFctYcyzcyGcyBcyHcyDcyDcyDcyIcvIckScmJchfcQkcQkcpKcpJcQkcQkcQkcQkcpMcpLcpOcpNcQkcQkcpPcQkcQkcTBdgmbQVcpScuvcqMcqMcqMcqMcqMcqMcqNbQXcqWcqUcqXcqXcqXcqYcrccrbcrbcrfcrbcrbcrbcrgczmczmcricrhcrjczwczzczyczBczAczCczCczDczCczCczCczCczGczIczCczCczCczOczLbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieciecqDckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm new file mode 100644 index 00000000000..5289988bf82 --- /dev/null +++ b/_maps/test_all_maps.dm @@ -0,0 +1,112 @@ +// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY! + +#if !defined(USING_MAP_DATUM) + // Away missions + #include "map_files\RandomZLevels\beach.dmm" + #include "map_files\RandomZLevels\moonoutpost19.dmm" + #include "map_files\RandomZLevels\undergroundoutpost45.dmm" + #include "map_files\RandomZLevels\academy.dmm" + #include "map_files\RandomZLevels\blackmarketpackers.dmm" + #include "map_files\RandomZLevels\spacehotel.dmm" + #include "map_files\RandomZLevels\stationCollision.dmm" + #include "map_files\RandomZLevels\wildwest.dmm" + #include "map_files\RandomZLevels\evil_santa.dmm" + + // Space Ruins + #include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm" + #include "map_files\RandomRuins\SpaceRuins\asteroid1.dmm" + #include "map_files\RandomRuins\SpaceRuins\asteroid2.dmm" + #include "map_files\RandomRuins\SpaceRuins\asteroid3.dmm" + #include "map_files\RandomRuins\SpaceRuins\asteroid4.dmm" + #include "map_files\RandomRuins\SpaceRuins\asteroid5.dmm" + #include "map_files\RandomRuins\SpaceRuins\deepstorage.dmm" + #include "map_files\RandomRuins\SpaceRuins\derelict1.dmm" + #include "map_files\RandomRuins\SpaceRuins\derelict2.dmm" + #include "map_files\RandomRuins\SpaceRuins\derelict3.dmm" + #include "map_files\RandomRuins\SpaceRuins\derelict4.dmm" + #include "map_files\RandomRuins\SpaceRuins\derelict5.dmm" + #include "map_files\RandomRuins\SpaceRuins\emptyshell.dmm" + #include "map_files\RandomRuins\SpaceRuins\gasthelizards.dmm" + #include "map_files\RandomRuins\SpaceRuins\intactemptyship.dmm" + #include "map_files\RandomRuins\SpaceRuins\listeningpost.dmm" + #include "map_files\RandomRuins\SpaceRuins\mechtransport.dmm" + #include "map_files\RandomRuins\SpaceRuins\onehalf.dmm" + #include "map_files\RandomRuins\SpaceRuins\spacebar.dmm" + #include "map_files\RandomRuins\SpaceRuins\turretedoutpost.dmm" + #include "map_files\RandomRuins\SpaceRuins\way_home.dmm" + + // Shuttle Templates + #include "map_files\shuttles\cargo_base.dmm" + #include "map_files\shuttles\emergency_bar.dmm" + #include "map_files\shuttles\emergency_clown.dmm" + #include "map_files\shuttles\emergency_cramped.dmm" + #include "map_files\shuttles\emergency_cyb.dmm" + #include "map_files\shuttles\emergency_dept.dmm" + #include "map_files\shuttles\emergency_meta.dmm" + #include "map_files\shuttles\emergency_mil.dmm" + #include "map_files\shuttles\emergency_narnar.dmm" + #include "map_files\shuttles\emergency_old.dmm" + #include "map_files\shuttles\ferry_base.dmm" + #include "map_files\shuttles\ferry_meat.dmm" + + // Other templates + #include "map_files\templates\spacehotel\n_01.dmm" + #include "map_files\templates\spacehotel\n_02.dmm" + #include "map_files\templates\spacehotel\n_03.dmm" + #include "map_files\templates\spacehotel\n_04.dmm" + #include "map_files\templates\spacehotel\n_05.dmm" + #include "map_files\templates\spacehotel\n_06.dmm" + #include "map_files\templates\spacehotel\n_07.dmm" + #include "map_files\templates\spacehotel\n_08.dmm" + #include "map_files\templates\spacehotel\n_09.dmm" + #include "map_files\templates\spacehotel\n_10.dmm" + #include "map_files\templates\spacehotel\n_11.dmm" + #include "map_files\templates\spacehotel\n_12.dmm" + #include "map_files\templates\spacehotel\n_13.dmm" + #include "map_files\templates\spacehotel\n_14.dmm" + #include "map_files\templates\spacehotel\n_15.dmm" + #include "map_files\templates\spacehotel\n_16.dmm" + #include "map_files\templates\spacehotel\n_17.dmm" + #include "map_files\templates\spacehotel\n_18.dmm" + #include "map_files\templates\spacehotel\n_19.dmm" + + #include "map_files\templates\spacehotel\s_01.dmm" + #include "map_files\templates\spacehotel\s_02.dmm" + #include "map_files\templates\spacehotel\s_03.dmm" + #include "map_files\templates\spacehotel\s_04.dmm" + #include "map_files\templates\spacehotel\s_05.dmm" + #include "map_files\templates\spacehotel\s_06.dmm" + + #include "map_files\templates\light_floor_1.dmm" + #include "map_files\templates\light_floor_2.dmm" + #include "map_files\templates\light_floor_3.dmm" + #include "map_files\templates\medium_shuttle1.dmm" + #include "map_files\templates\medium_shuttle2.dmm" + #include "map_files\templates\medium_shuttle3.dmm" + #include "map_files\templates\shelter_1.dmm" + #include "map_files\templates\shelter_2.dmm" + #include "map_files\templates\small_asteroid_1.dmm" + #include "map_files\templates\small_shuttle_1.dmm" + + // VR maps + #include "map_files\vr\blood_and_sand.dmm" + #include "map_files\vr\lobby.dmm" + + + // This is pointless, we don't run the server + /*#define MAP_TRANSITION_CONFIG list(AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED, + AWAY_MISSION = UNAFFECTED) + + #define USING_MAP_DATUM /datum/map*/ + +#elif !defined(MAP_OVERRIDE) + #warn a map has already been included. +#endif diff --git a/_maps/test_away_missions.dm b/_maps/test_away_missions.dm deleted file mode 100644 index 42b068412bd..00000000000 --- a/_maps/test_away_missions.dm +++ /dev/null @@ -1,21 +0,0 @@ -// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY! - -#if !defined(USING_MAP_DATUM) - #include "map_files\RandomZLevels\beach.dmm" - #include "map_files\RandomZLevels\moonoutpost19.dmm" - #include "map_files\RandomZLevels\undergroundoutpost45.dmm" - #include "map_files\RandomZLevels\academy.dmm" - #include "map_files\RandomZLevels\blackmarketpackers.dmm" - #include "map_files\RandomZLevels\spacehotel.dmm" - #include "map_files\RandomZLevels\stationCollision.dmm" - #include "map_files\RandomZLevels\wildwest.dmm" - - #include "map_files\RandomZLevels\evil_santa.dmm" - - #define MAP_TRANSITION_CONFIG list(AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED) - - #define USING_MAP_DATUM /datum/map - -#elif !defined(MAP_OVERRIDE) - #warn a map has already been included. -#endif diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 1506cd26129..3fcf79fe8d8 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -7,10 +7,9 @@ Pipelines and other atmospheric objects combine to form pipe_networks Pipes -> Pipelines Pipelines + Other Objects -> Pipe network - */ +GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) /obj/machinery/atmospherics - auto_init = 0 anchored = 1 layer = 2.4 //under wires with their 2.44 idle_power_usage = 0 @@ -29,15 +28,12 @@ Pipelines + Other Objects -> Pipe network var/pipe_color var/obj/item/pipe/stored var/image/pipe_image - var/global/datum/pipe_icon_manager/icon_manager /obj/machinery/atmospherics/New() if(!armor) armor = list(melee = 25, bullet = 10, laser = 10, energy = 100, bomb = 0, bio = 100, rad = 100) ..() SSair.atmos_machinery += src - if(!icon_manager) - icon_manager = new() if(!pipe_color) pipe_color = color @@ -45,12 +41,8 @@ Pipelines + Other Objects -> Pipe network if(!pipe_color_check(pipe_color)) pipe_color = null - // No need for a tween worldstart roundstart handler - pipenet creation is - // handled there - -/obj/machinery/atmospherics/initialize() - ..() +/obj/machinery/atmospherics/proc/atmos_init() if(can_unwrench) stored = new(src, make_from = src) @@ -73,9 +65,9 @@ Pipelines + Other Objects -> Pipe network pipe_image.plane = HUD_PLANE /obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0) - if(!istype(icon_manager)) + if(!istype(GLOB.pipe_icon_manager)) if(!safety) //to prevent infinite loops - icon_manager = new() + GLOB.pipe_icon_manager = new() check_icon_cache(1) return 0 @@ -91,14 +83,14 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) if(node) if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) - //underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node)) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) + //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node)) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) else - //underlays += icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node)) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) + //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node)) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) else - //underlays += icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type) + //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type) /obj/machinery/atmospherics/proc/update_underlays() if(check_icon_cache()) @@ -231,10 +223,10 @@ Pipelines + Other Objects -> Pipe network var/turf/T = loc level = T.intact ? 2 : 1 add_fingerprint(usr) - initialize() + atmos_init() var/list/nodes = pipeline_expansion() for(var/obj/machinery/atmospherics/A in nodes) - A.initialize() + A.atmos_init() A.addMember(src) build_network() @@ -320,11 +312,11 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays if(node) if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) + underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) /obj/machinery/atmospherics/singularity_pull(S, current_size) if(current_size >= STAGE_FIVE) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 276ce5e7b6e..c11a0421bda 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -41,7 +41,7 @@ nullifyPipenet(parent2) return ..() -/obj/machinery/atmospherics/binary/initialize() +/obj/machinery/atmospherics/binary/atmos_init() ..() var/node2_connect = dir var/node1_connect = turn(dir, 180) diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index bfffb7cd35d..aebc09cfc7a 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -48,7 +48,7 @@ radio_connection = null return ..() -/obj/machinery/atmospherics/binary/dp_vent_pump/initialize() +/obj/machinery/atmospherics/binary/dp_vent_pump/atmos_init() ..() if(frequency) set_frequency(frequency) @@ -90,7 +90,7 @@ else vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]" - overlays += icon_manager.get_atmos_icon("device", , , vent_icon) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon) /obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays() if(..()) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index e43b052095b..9e845c15a98 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -16,7 +16,7 @@ var/id = null var/datum/radio_frequency/radio_connection -/obj/machinery/atmospherics/binary/passive_gate/initialize() +/obj/machinery/atmospherics/binary/passive_gate/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index db0c7144324..118a70c3ecd 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -110,7 +110,7 @@ Thus, the two variables affect pump operation are set in New(): radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) return 1 -/obj/machinery/atmospherics/binary/pump/initialize() +/obj/machinery/atmospherics/binary/pump/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index 7b566e04fda..1d7805c55b2 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -109,7 +109,7 @@ if(frequency) radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/atmospherics/binary/valve/digital/initialize() +/obj/machinery/atmospherics/binary/valve/digital/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index c4dd8adeabb..a64c94e7fc5 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -38,7 +38,7 @@ Thus, the two variables affect pump operation are set in New(): on = 1 icon_state = "map_on" -/obj/machinery/atmospherics/binary/volume_pump/initialize() +/obj/machinery/atmospherics/binary/volume_pump/atmos_init() ..() set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm index 1858b685ec0..a1f80916aee 100644 --- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm +++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm @@ -40,9 +40,9 @@ /datum/omni_port/proc/connect() if(node) return - master.initialize() + master.atmos_init() if(node) - node.initialize() + node.atmos_init() node.addMember(master) master.build_network() diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index 086d2ff799f..0eed9729f87 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -56,7 +56,7 @@ nullifyPipenet(P.parent) return ..() -/obj/machinery/atmospherics/omni/initialize() +/obj/machinery/atmospherics/omni/atmos_init() ..() for(var/datum/omni_port/P in ports) if(P.node || P.mode == 0) @@ -143,11 +143,11 @@ //directional icons are layers 1-4, with the core icon on layer 5 if(core_icon) - overlays_off[5] = icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_on[5] = icon_manager.get_atmos_icon("omni", , , core_icon + "_glow") + overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) + overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow") - overlays_error[1] = icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_error[2] = icon_manager.get_atmos_icon("omni", , , "error") + overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) + overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error") /obj/machinery/atmospherics/omni/proc/update_port_icons() if(!check_icon_cache()) @@ -203,19 +203,19 @@ ic_on += "_filter" ic_off += "_out" - ic_on = icon_manager.get_atmos_icon("omni", , , ic_on) - ic_off = icon_manager.get_atmos_icon("omni", , , ic_off) + ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on) + ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off) var/pipe_state var/turf/T = get_turf(src) if(!istype(T)) return if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 ) - //pipe_state = icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node)) - pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down") + //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node)) + pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down") else - //pipe_state = icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node)) - pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact") + //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node)) + pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact") return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 427c77e8246..903f917e0c6 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -149,7 +149,7 @@ Filter types: return 1 -/obj/machinery/atmospherics/trinary/filter/initialize() +/obj/machinery/atmospherics/trinary/filter/atmos_init() set_frequency(frequency) ..() diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 187b308fa3c..e750256b0df 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -66,7 +66,7 @@ nullifyPipenet(parent3) return ..() -/obj/machinery/atmospherics/trinary/initialize() +/obj/machinery/atmospherics/trinary/atmos_init() ..() //Mixer: //1 and 2 is input diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm index ad9561fbf1d..9dddf8b06f4 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm @@ -156,7 +156,7 @@ if(frequency) radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/atmospherics/trinary/tvalve/digital/initialize() +/obj/machinery/atmospherics/trinary/tvalve/digital/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm index 496413c881c..58b374578df 100644 --- a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm @@ -20,7 +20,7 @@ return -/obj/machinery/atmospherics/unary/heat_exchanger/initialize() +/obj/machinery/atmospherics/unary/heat_exchanger/atmos_init() if(!partner) var/partner_connect = turn(dir,180) diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm index 6028346df6d..fe5b6a0a445 100644 --- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm @@ -120,7 +120,7 @@ return 1 -/obj/machinery/atmospherics/unary/outlet_injector/initialize() +/obj/machinery/atmospherics/unary/outlet_injector/atmos_init() ..() set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm index 51b12d39481..4ef7743fc8c 100644 --- a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm @@ -22,7 +22,7 @@ nullifyPipenet(parent) return ..() -/obj/machinery/atmospherics/unary/initialize() +/obj/machinery/atmospherics/unary/atmos_init() ..() for(var/obj/machinery/atmospherics/target in get_step(src, dir)) if(target.initialize_directions & get_dir(target,src)) @@ -43,9 +43,9 @@ node.disconnect(src) node = null nullifyPipenet(parent) - initialize() + atmos_init() if(node) - node.initialize() + node.atmos_init() node.addMember(src) build_network() . = 1 diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index 8f76e689eae..99eeb1883ea 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -98,7 +98,7 @@ else vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]" - overlays += icon_manager.get_atmos_icon("device", , , vent_icon) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon) update_pipe_image() @@ -223,7 +223,7 @@ return 1 -/obj/machinery/atmospherics/unary/vent_pump/initialize() +/obj/machinery/atmospherics/unary/vent_pump/atmos_init() ..() //some vents work his own special way diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index 530dbe1d952..11b1fc0f920 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -109,7 +109,7 @@ if(welded) scrubber_icon = "scrubberweld" - overlays += icon_manager.get_atmos_icon("device", , , scrubber_icon) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , scrubber_icon) update_pipe_image() /obj/machinery/atmospherics/unary/vent_scrubber/update_underlays() @@ -169,7 +169,7 @@ return 1 -/obj/machinery/atmospherics/unary/vent_scrubber/initialize() +/obj/machinery/atmospherics/unary/vent_scrubber/atmos_init() ..() radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 0692bf44efd..b4a0cd9ba7b 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -57,11 +57,7 @@ var/pipenetwarnings = 10 if(!members.Find(item)) if(item.parent) - if(pipenetwarnings > 0) - error("[item.type] added to a pipenet while still having one (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z].") - pipenetwarnings -= 1 - if(pipenetwarnings == 0) - error("Further messages about pipenets will be suppressed.") + log_runtime(EXCEPTION("[item.type] \[\ref[item]] added to a pipenet while still having one ([item.parent]) (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z].")) members += item possible_expansions += item @@ -118,15 +114,12 @@ var/pipenetwarnings = 10 qdel(E) /obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A) - return + var/datum/pipeline/P = returnPipenet(A) + P.addMember(A, src) /obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A) parent.addMember(A, src) -/obj/machinery/atmospherics/addMember(obj/machinery/atmospherics/A) - var/datum/pipeline/P = returnPipenet(A) - P.addMember(A, src) - /datum/pipeline/proc/temporarily_store_air() //Update individual gas_mixtures by volume ratio diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index 7691b157857..2552f6e0794 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -61,9 +61,9 @@ alpha = 255 overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type) -/obj/machinery/atmospherics/pipe/cap/initialize() +/obj/machinery/atmospherics/pipe/cap/atmos_init() ..() for(var/obj/machinery/atmospherics/target in get_step(src, dir)) if(target.initialize_directions & get_dir(target,src)) diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index a42903bb7f6..199942e7a40 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -32,7 +32,7 @@ if(WEST) initialize_directions = NORTH|EAST|SOUTH -/obj/machinery/atmospherics/pipe/manifold/initialize() +/obj/machinery/atmospherics/pipe/manifold/atmos_init() ..() for(var/D in cardinal) if(D == dir) @@ -122,8 +122,8 @@ alpha = 255 overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) underlays.Cut() var/turf/T = get_turf(src) diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index 46b883db62b..502795e1da9 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -95,8 +95,8 @@ alpha = 255 overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) underlays.Cut() var/turf/T = get_turf(src) @@ -134,7 +134,7 @@ if(level == 1 && istype(loc, /turf/simulated)) invisibility = i ? 101 : 0 -/obj/machinery/atmospherics/pipe/manifold4w/initialize() +/obj/machinery/atmospherics/pipe/manifold4w/atmos_init() ..() for(var/D in cardinal) for(var/obj/machinery/atmospherics/target in get_step(src, D)) diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm index 9f360f74274..b2c2750a452 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm @@ -43,7 +43,7 @@ if(SOUTHWEST) initialize_directions = SOUTH|WEST -/obj/machinery/atmospherics/pipe/simple/initialize(initPipe = 1) +/obj/machinery/atmospherics/pipe/simple/atmos_init(initPipe = 1) ..() if(initPipe) normalize_dir() @@ -145,9 +145,9 @@ overlays.Cut() if(node1 && node2) - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type) else - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type) + overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type) // A check to make sure both nodes exist - self-delete if they aren't present /obj/machinery/atmospherics/pipe/simple/check_nodes_exist() diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm index 26139b40606..cb7ec277f95 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm @@ -61,7 +61,7 @@ initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe color = "#404040" -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/initialize(initPipe = 1) +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init(initPipe = 1) ..(0) if(initPipe) normalize_dir() @@ -110,7 +110,7 @@ initialize_directions = EAST initialize_directions_he = WEST -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/initialize() +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() ..(0) for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) if(target.initialize_directions & get_dir(target,src)) diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm index db62f8e51fe..3efd22ed446 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm @@ -34,7 +34,7 @@ alpha = 255 overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") underlays.Cut() if(node1) diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm index 1fcb45e7959..9bf085b534a 100644 --- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm +++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm @@ -45,7 +45,7 @@ alpha = 255 overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") underlays.Cut() if(node1) diff --git a/code/_DATASTRUCTURES/linked_lists.dm b/code/_DATASTRUCTURES/linked_lists.dm deleted file mode 100644 index eccc3c422a8..00000000000 --- a/code/_DATASTRUCTURES/linked_lists.dm +++ /dev/null @@ -1,191 +0,0 @@ - -//Ok so it's technically a double linked list, bite me. - -/datum/linked_list - var/datum/linked_node/head - var/datum/linked_node/tail - var/node_amt = 0 - - -/datum/linked_node - var/value = null - var/datum/linked_list/linked_list = null - var/datum/linked_node/next_node = null - var/datum/linked_node/previous_node = null - - -/datum/linked_list/proc/IsEmpty() - . = (node_amt <= 0) - - -//Add a linked_node (or value, creating a linked_node) at position -//the added node BECOMES the position-th element, -//eg: add("Test",5), the 5th node is now "Test", the previous 5th moves up to become the 6th -/datum/linked_list/proc/Add(node, position) - var/datum/linked_node/adding - if(istype(node, /datum/linked_node)) - adding = node - else - adding = new() - adding.value = node - - if(!adding.linked_list || (adding.linked_list && (adding.linked_list != src))) - node_amt++ - - adding.linked_list = src - - if(position && position < node_amt) - //Replacing head - if(position == 1) - if(head) - head.previous_node = adding - adding.next_node = head - head = adding - - //Replacing any middle node - else - var/location = 0 - var/datum/linked_node/at - while((location != position) && (location <= node_amt)) - if(at) - if(at.next_node) - at = at.next_node - else - break - else - at = head - location++ - - //Push at up and assume it's place as the position-th element - if(at && at.previous_node) - at.previous_node.next_node = adding - adding.previous_node = at.previous_node - at.previous_node = adding - adding.next_node = at - return - - //Replacing tail - if(tail) - tail.next_node = adding - adding.previous_node = tail - if(!tail.previous_node) - head = tail - tail = adding - - - -//Remove a linked_node or the linked_node of a value -//If you specify a value the FIRST ONE is removed -/datum/linked_list/proc/Remove(node) - var/datum/linked_node/removing - if(istype(node,/datum/linked_node)) - removing = node - else - //optimise removing head and tail, no point looping for them, especially the tail - if(removing == head) - removing = head - else if(removing == tail) - removing = tail - else - var/location = 1 - var/current_value = null - var/datum/linked_node/at = null - while((current_value != node) && (location <= node_amt)) - if(at) - if(at.next_node) - at = at.next_node - else - at = head - location++ - if(at) - current_value = at.value - if(current_value == node) - removing = at - break - - //Adjust pointers of where removing -was- in the chain. - if(removing) - if(removing.previous_node) - if(removing == tail) - tail = removing.previous_node - if(removing.next_node) - if(removing == head) - head = removing.next_node - removing.next_node.previous_node = removing.previous_node - removing.previous_node.next_node = removing.next_node - else - removing.previous_node.next_node = null - else - if(removing.next_node) - if(removing == head) - head = removing.next_node - removing.next_node.previous_node = null - - //if this is still true at this point, there's no more nodes to replace them with - if(removing == head) - head = null - if(removing == tail) - tail = null - - removing.next_node = null - removing.previous_node = null - if(removing.linked_list == src) - node_amt-- - removing.linked_list = null - - return removing - return 0 - - -//Removes and deletes a node or value -/datum/linked_list/proc/RemoveDelete(node) - var/datum/linked_node/dead = Remove(node) - if(dead) - qdel(dead) - return 1 - return 0 - - -//Empty the linked_list, deleting all nodes -/datum/linked_list/proc/Empty() - var/datum/linked_node/n = head - while(n) - var/next = n.next_node - Remove(n) - qdel(n) - n = next - node_amt = 0 - - -//Some debugging tools -/datum/linked_list/proc/CheckNodeLinks() - var/datum/linked_node/n = head - while(n) - . = "|[n.value]|" - if(n.previous_node) - . = "[n.previous_node.value]<-" + . - if(n.next_node) - . += "->[n.next_node.value]" - n = n.next_node - . += "
" - - -/datum/linked_list/proc/DrawNodeLinks() - . = "|<-" - var/datum/linked_node/n = head - while(n) - if(n.previous_node) - . += "<-" - . += "[n.value]" - if(n.next_node) - . += "->" - n = n.next_node - . += "->|" - - -/datum/linked_list/proc/ToList() - . = list() - var/datum/linked_node/n = head - while(n) - . += n - n = n.next_node \ No newline at end of file diff --git a/code/_DATASTRUCTURES/priority_queue.dm b/code/_DATASTRUCTURES/priority_queue.dm deleted file mode 100644 index 8689a19f4e4..00000000000 --- a/code/_DATASTRUCTURES/priority_queue.dm +++ /dev/null @@ -1,83 +0,0 @@ - -////////////////////// -//PriorityQueue object -////////////////////// - -//an ordered list, using the cmp proc to weight the list elements -/PriorityQueue - var/list/L //the actual queue - var/cmp //the weight function used to order the queue - -/PriorityQueue/New(compare) - L = new() - cmp = compare - -/PriorityQueue/proc/IsEmpty() - return !L.len - -//return the index the element should be in the priority queue using dichotomic search -/PriorityQueue/proc/FindElementIndex(atom/A) - var/i = 1 - var/j = L.len - var/mid - - while(i < j) - mid = round((i+j)/2) - - if(call(cmp)(L[mid],A) < 0) - i = mid + 1 - else - j = mid - - if(i == 1 || i == L.len) //edge cases - return (call(cmp)(L[i],A) > 0) ? i : i+1 - else - return i - - -//add an element in the list, -//immediatly ordering it to its position using dichotomic search -/PriorityQueue/proc/Enqueue(atom/A) - if(!L.len) - L.Add(A) - return - - L.Insert(FindElementIndex(A),A) - -//removes and returns the first element in the queue -/PriorityQueue/proc/Dequeue() - if(!L.len) - return 0 - . = L[1] - - Remove(.) - -//removes an element -/PriorityQueue/proc/Remove(atom/A) - return L.Remove(A) - -//returns a copy of the elements list -/PriorityQueue/proc/List() - . = L.Copy() - -//return the position of an element or 0 if not found -/PriorityQueue/proc/Seek(atom/A) - . = L.Find(A) - -//return the element at the i_th position -/PriorityQueue/proc/Get(i) - if(i > L.len || i < 1) - return 0 - return L[i] - -//replace the passed element at it's right position using the cmp proc -/PriorityQueue/proc/ReSort(atom/A) - var/i = Seek(A) - if(i == 0) - return - while(i < L.len && call(cmp)(L[i],L[i+1]) > 0) - L.Swap(i,i+1) - i++ - while(i > 1 && call(cmp)(L[i],L[i-1]) <= 0) //last inserted element being first in case of ties (optimization) - L.Swap(i,i-1) - i-- \ No newline at end of file diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm new file mode 100644 index 00000000000..e69de29bb2d diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 8b7f4830c13..4c2708bf9dd 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -64,6 +64,17 @@ #define THROWN_PROJECTILE_ATTACK 4 #define LEAP_ATTACK 5 +//attack visual effects +#define ATTACK_EFFECT_PUNCH "punch" +#define ATTACK_EFFECT_KICK "kick" +#define ATTACK_EFFECT_SMASH "smash" +#define ATTACK_EFFECT_CLAW "claw" +#define ATTACK_EFFECT_DISARM "disarm" +#define ATTACK_EFFECT_BITE "bite" +#define ATTACK_EFFECT_MECHFIRE "mech_fire" +#define ATTACK_EFFECT_MECHTOXIN "mech_toxin" +#define ATTACK_EFFECT_BOOP "boop" //Honk + //Embedded objects #define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) #define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object) diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm index c6ffc61495e..3f360d5bad7 100644 --- a/code/__DEFINES/math.dm +++ b/code/__DEFINES/math.dm @@ -32,6 +32,8 @@ #define ToDegrees(radians) ((radians) * 57.2957795) // 180 / Pi #define ToRadians(degrees) ((degrees) * 0.0174532925) // Pi / 180 +#define SHORT_REAL_LIMIT 16777216 + //"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks //percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) //collapsed to percent_of_tick_used * tick_lag diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 4f38a183a80..66eedbe5b33 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -344,5 +344,7 @@ //for obj explosion block calculation #define EXPLOSION_BLOCK_PROC -1 +#define INVESTIGATE_BOMB "bombs" + // The SQL version required by this version of the code #define SQL_VERSION 2 diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm index 14fd6ea0e36..8d504edaf41 100644 --- a/code/__DEFINES/qdel.dm +++ b/code/__DEFINES/qdel.dm @@ -22,11 +22,4 @@ #define QDELING(X) (X.gc_destroyed) #define QDELETED(X) (!X || QDELING(X)) -#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) - -/proc/check_datum_qdeleted(datum/D) //for checking if something is a datum, first, then checking gc_destroyed; get rid of this eventually. TO-DO - if(!istype(D)) - return FALSE - if(D.gc_destroyed) - return TRUE - return FALSE \ No newline at end of file +#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) \ No newline at end of file diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 257e12f4093..adb645fe112 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -40,6 +40,7 @@ #define ROLE_NYMPH "Dionaea" #define ROLE_GSPIDER "giant spider" #define ROLE_DRONE "drone" +#define ROLE_DEATHSQUAD "deathsquad" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 4b97b67e27e..0db57b27eae 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -31,6 +31,9 @@ /proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b) return a.priority - b.priority +/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b) + return a.timeToRun - b.timeToRun + /proc/cmp_qdel_item_time(datum/qdel_item/A, datum/qdel_item/B) . = B.hard_delete_time - A.hard_delete_time if(!.) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 2004b9d3159..5c483b310fe 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -435,7 +435,7 @@ /proc/SecondsToTicks(var/seconds) return seconds * 10 -proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE) +proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) var/roletext = be_special_type ? get_roletext(be_special_type) : null var/list/mob/dead/observer/candidates = list() var/time_passed = world.time @@ -457,7 +457,7 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = if(config.use_exp_restrictions && min_hours) if(G.client.get_exp_living_num() < min_hours * 60) continue - if(cannotPossess(G)) + if(check_antaghud && cannotPossess(G)) continue spawn(0) G << 'sound/misc/notice2.ogg'//Alerting them to their consideration @@ -490,6 +490,20 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = return candidates +/proc/pollCandidatesByKeyWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) + var/list/willing_ghosts = pollCandidates(Question, be_special_type, antag_age_check, poll_time, ignore_respawnability, min_hours, flashwindow, check_antaghud) + var/list/candidate_ckeys = list() + var/list/selected_ckeys = list() + if(!willing_ghosts.len) + return selected_ckeys + for(var/mob/dead/observer/G in willing_ghosts) + candidate_ckeys += G.key + for(var/i = max_slots, (i > 0 && candidate_ckeys.len), i--) + var/this_ckey = input("Pick players. This will go on until there either no more ghosts to pick from or the slots are full.", "Candidates") as null|anything in candidate_ckeys + candidate_ckeys -= this_ckey + selected_ckeys += this_ckey + return selected_ckeys + /proc/window_flash(client/C) if(ismob(C)) var/mob/M = C diff --git a/code/__HELPERS/qdel.dm b/code/__HELPERS/qdel.dm index 8171dd66427..136e573a25e 100644 --- a/code/__HELPERS/qdel.dm +++ b/code/__HELPERS/qdel.dm @@ -1,5 +1,10 @@ -#define QDEL_IN(item, time) addtimer(GLOBAL_PROC, "qdel", time, FALSE, item) +#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE) +#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) #define QDEL_NULL(item) if(item) { qdel(item); item = null } #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } +#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } + +/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. + QDEL_LIST(L) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index b58ea20dbae..20c707b38f7 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -394,6 +394,16 @@ Turf and target are seperate in case you want to teleport some distance from a t moblist.Add(M) return moblist +// Format a power value in W, kW, MW, or GW. +/proc/DisplayPower(powerused) + if(powerused < 1000) //Less than a kW + return "[powerused] W" + else if(powerused < 1000000) //Less than a MW + return "[round((powerused * 0.001), 0.01)] kW" + else if(powerused < 1000000000) //Less than a GW + return "[round((powerused * 0.000001), 0.001)] MW" + return "[round((powerused * 0.000000001), 0.0001)] GW" + //E = MC^2 /proc/convert2energy(var/M) var/E = M*(SPEED_OF_LIGHT_SQ) @@ -1928,4 +1938,7 @@ var/mob/dview/dview_mob = new CRASH(msg) /datum/proc/stack_trace(msg) - CRASH(msg) \ No newline at end of file + CRASH(msg) + +/proc/pass() + return \ No newline at end of file diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 0cc712799c7..5a025702877 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -1,5 +1,5 @@ var/global/list/portals = list() //for use by portals -var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time +GLOBAL_LIST(cable_list) //Index for all cables, so that powernets don't have to look through the entire world all the time var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff var/global/list/landmarks_list = list() //list of all landmarks created @@ -17,7 +17,6 @@ var/global/list/cell_logs = list() var/global/list/all_areas = list() var/global/list/machines = list() -var/global/list/machine_processing = list() var/global/list/fast_processing = list() var/global/list/processing_power_items = list() //items that ask to be called every cycle var/global/list/rcd_list = list() //list of Rapid Construction Devices. diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index f96e83cb7a1..c48600ca40c 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -10,7 +10,6 @@ GLOBAL_VAR(world_href_log) GLOBAL_PROTECT(world_href_log) var/list/jobMax = list() -var/list/bombers = list( ) var/list/admin_log = list ( ) var/list/lastsignalers = list( ) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" var/list/lawchanges = list( ) //Stores who uploaded laws to which silicon-based lifeform, and what the law was @@ -20,4 +19,4 @@ var/list/IClog = list() var/list/OOClog = list() var/list/adminlog = list() -var/list/investigate_log_subjects = list("notes", "watchlist", "hrefs") \ No newline at end of file +var/list/investigate_log_subjects = list("notes", "watchlist", "hrefs") diff --git a/code/_globalvars/station.dm b/code/_globalvars/station.dm index 6d2578e5b88..2d635996b30 100644 --- a/code/_globalvars/station.dm +++ b/code/_globalvars/station.dm @@ -3,11 +3,4 @@ var/global/datum/datacore/data_core = null var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second) var/CHARGELEVEL = 0.001 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second) -var/list/powernets = list() -var/list/deferred_powernet_rebuilds = list() - -// this is not strictly unused although the whole modules datum thing is unused -// To remove this you need to remove that -var/datum/moduletypes/mods = new() - var/map_name = "Unknown" //The name of the map that is loaded. Assigned in world/New() \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index f300608e699..9679935bdaa 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -70,6 +70,12 @@ changeNext_click(1) var/list/modifiers = params2list(params) + if(modifiers["middle"] && modifiers["shift"] && modifiers["ctrl"]) + MiddleShiftControlClickOn(A) + return + if(modifiers["middle"] && modifiers["shift"]) + MiddleShiftClickOn(A) + return if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return @@ -225,6 +231,32 @@ else ..() +/* + Middle shift-click + Makes the mob face the direction of the clicked thing +*/ +/mob/proc/MiddleShiftClickOn(atom/A) + var/face_dir = get_cardinal_dir(src, A) + if(forced_look == face_dir) + forced_look = null + to_chat(src, "You are no longer facing any direction.") + return + forced_look = face_dir + to_chat(src, "You are now facing [dir2text(forced_look)].") + +/* + Middle shift-control-click + Makes the mob constantly face the object (until it's out of sight) +*/ +/mob/proc/MiddleShiftControlClickOn(atom/A) + var/face_uid = A.UID() + if(forced_look == face_uid) + forced_look = null + to_chat(src, "You are no longer facing [A].") + return + forced_look = face_uid + to_chat(src, "You are now facing [A].") + // In case of use break glass /* /atom/proc/MiddleClick(var/mob/M as mob) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 6a658886f83..bf01bca6e3c 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -62,8 +62,7 @@ user.lastattacked = M M.lastattacker = user - if(user != M) - user.do_attack_animation(M) + user.do_attack_animation(M) M.attacked_by(src, user, def_zone) add_attack_logs(user, M, "Attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])", admin_notify = (force > 0 && damtype != STAMINA)) diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm deleted file mode 100644 index 2466f802740..00000000000 --- a/code/controllers/Processes/machinery.dm +++ /dev/null @@ -1,74 +0,0 @@ -/var/global/machinery_sort_required = 0 - -/datum/controller/process/machinery/setup() - name = "machinery" - schedule_interval = 20 // every 2 seconds - start_delay = 12 - -/datum/controller/process/machinery/statProcess() - ..() - stat(null, "[machine_processing.len] machines") - stat(null, "[powernets.len] powernets, [deferred_powernet_rebuilds.len] deferred") - -/datum/controller/process/machinery/doWork() - process_sort() - process_power() - process_power_drain() - process_machines() - -/datum/controller/process/machinery/proc/process_sort() - if(machinery_sort_required) - machinery_sort_required = 0 - machine_processing = dd_sortedObjectList(machine_processing) - -/datum/controller/process/machinery/proc/process_machines() - for(last_object in machine_processing) - var/obj/machinery/M = last_object - if(istype(M) && !QDELETED(M)) - try - if(M.process() == PROCESS_KILL) - machine_processing.Remove(M) - continue - - if(M.use_power) - M.auto_use_power() - catch(var/exception/e) - catchException(e, M) - else - catchBadType(M) - machine_processing -= M - - SCHECK - -/datum/controller/process/machinery/proc/process_power() - for(last_object in deferred_powernet_rebuilds) - var/obj/O = last_object - if(istype(O) && !QDELETED(O)) - try - var/datum/powernet/newPN = new()// creates a new powernet... - propagate_network(O, newPN)//... and propagates it to the other side of the cable - catch(var/exception/e) - catchException(e, O) - SCHECK - else - catchBadType(O) - deferred_powernet_rebuilds -= O - - for(last_object in powernets) - var/datum/powernet/powerNetwork = last_object - if(istype(powerNetwork) && !QDELETED(powerNetwork)) - try - powerNetwork.reset() - catch(var/exception/e) - catchException(e, powerNetwork) - SCHECK - else - catchBadType(powerNetwork) - powernets -= powerNetwork - -/datum/controller/process/machinery/proc/process_power_drain() - // Currently only used by powersinks. These items get priority processed before machinery - for(var/obj/item/I in processing_power_items) - if(!I.pwr_drain()) // 0 = Process Kill, remove from processing list. - processing_power_items.Remove(I) - SCHECK diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm deleted file mode 100644 index 2b11eff99be..00000000000 --- a/code/controllers/Processes/mob.dm +++ /dev/null @@ -1,35 +0,0 @@ -var/global/datum/controller/process/mob/mob_master - -/datum/controller/process/mob - var/current_cycle - -/datum/controller/process/mob/setup() - name = "mob" - schedule_interval = 20 // every 2 seconds - start_delay = 16 - log_startup_progress("Mob ticker starting up.") - -/datum/controller/process/mob/started() - ..() - if(!mob_list) - mob_list = list() - -/datum/controller/process/mob/statProcess() - ..() - stat(null, "[mob_list.len] mobs") - -/datum/controller/process/mob/doWork() - for(last_object in mob_list) - var/mob/M = last_object - if(istype(M) && !QDELETED(M)) - try - M.Life() - catch(var/exception/e) - catchException(e, M) - SCHECK - else - catchBadType(M) - mob_list -= M - current_cycle++ - -DECLARE_GLOBAL_CONTROLLER(mob, mob_master) diff --git a/code/controllers/Processes/nano_mob_hunter.dm b/code/controllers/Processes/nano_mob_hunter.dm index fb57b6e0bbf..dc5dcba805b 100644 --- a/code/controllers/Processes/nano_mob_hunter.dm +++ b/code/controllers/Processes/nano_mob_hunter.dm @@ -44,7 +44,7 @@ DECLARE_GLOBAL_CONTROLLER(mob_hunt, mob_hunt_server) recover_time = 3000 if(recover_time > 0) //when provided with a negative or zero valued recover_time argument, the server won't auto-restart but can be manually rebooted still //set a timer to automatically recover after recover_time has passed (can be manually restarted if you get impatient too) - addtimer(src, "auto_recover", recover_time, TRUE) + addtimer(CALLBACK(src, .proc/auto_recover), recover_time, TIMER_UNIQUE) /datum/controller/process/mob_hunt/proc/client_mob_update() var/list/ex_players = list() diff --git a/code/controllers/Processes/timer.dm b/code/controllers/Processes/timer.dm deleted file mode 100644 index 4b42d69221d..00000000000 --- a/code/controllers/Processes/timer.dm +++ /dev/null @@ -1,100 +0,0 @@ -var/global/datum/controller/process/timer/timer_master - -/datum/controller/process/timer - var/list/processing_timers = list() - var/list/hashes = list() - -/datum/controller/process/timer/setup() - name = "timer" - schedule_interval = 1 //every 0.1 seconds--2 server ticks - log_startup_progress("Timer process starting up.") - -/datum/controller/process/timer/statProcess() - ..() - stat(null, "[processing_timers.len] timers") - -/datum/controller/process/timer/doWork() - if(!processing_timers.len) - disabled = 1 //nothing to do, lets stop firing. - return - for(last_object in processing_timers) - var/datum/timedevent/event = last_object - if(!event.thingToCall || check_datum_qdeleted(event.thingToCall)) - qdel(event) - if(event.timeToRun <= world.time) - runevent(event) - qdel(event) - SCHECK - -DECLARE_GLOBAL_CONTROLLER(timer, timer_master) - -/datum/controller/process/timer/proc/runevent(datum/timedevent/event) - set waitfor = 0 - if(event.thingToCall) - if(event.thingToCall == GLOBAL_PROC && istext(event.procToCall)) - call("/proc/[event.procToCall]")(arglist(event.argList)) - else - call(event.thingToCall, event.procToCall)(arglist(event.argList)) - -/datum/timedevent - var/thingToCall - var/procToCall - var/timeToRun - var/argList - var/id - var/hash - var/static/nextid = 1 - -/datum/timedevent/New() - id = nextid++ - -/datum/timedevent/Destroy() - timer_master.processing_timers -= src - timer_master.hashes -= hash - return QDEL_HINT_IWILLGC - -/proc/addtimer(thingToCall, procToCall, wait, unique = FALSE, ...) - if(!timer_master) //can't run timers before the mc has been created - return - if(!thingToCall || !procToCall) - return - if(timer_master.disabled) - timer_master.disabled = 0 - - var/datum/timedevent/event = new() - event.thingToCall = thingToCall - event.procToCall = procToCall - event.timeToRun = world.time + wait - var/hashlist = args.Copy() - - hashlist[1] = "[thingToCall](\ref[thingToCall])" - event.hash = jointext(hashlist, null) - if(args.len > 4) - event.argList = args.Copy(5) - - // Check for dupes if unique = 1. - if(unique) - var/datum/timedevent/hash_event = timer_master.hashes[event.hash] - if(hash_event) - return hash_event.id - timer_master.hashes[event.hash] = event - if(wait <= 0) - timer_master.runevent(event) - timer_master.hashes -= event.hash - return - // If we are unique (or we're not checking that), add the timer and return the id. - timer_master.processing_timers += event - - return event.id - -/proc/deltimer(id) - if(id == 0) - // No event will correspond to an id of 0 - the timer does not exist - // Save us a possibly expensive iteration through the timer list - // This would probably be more efficient in general if we used an associative list instead - return 0 - for(var/datum/timedevent/event in timer_master.processing_timers) - if(event.id == id) - qdel(event) - return 1 - return 0 diff --git a/code/controllers/Processes/weather.dm b/code/controllers/Processes/weather.dm index 1706b2232c0..919352313c6 100644 --- a/code/controllers/Processes/weather.dm +++ b/code/controllers/Processes/weather.dm @@ -37,7 +37,7 @@ var/global/datum/controller/process/weather/weather_master var/datum/weather/W = pickweight(possible_weather_for_this_z) run_weather(W.name) eligible_zlevels -= Z - addtimer(src, "make_z_eligible", rand(3000, 6000) + W.weather_duration_upper, TRUE, Z) //Around 5-10 minutes between weathers + addtimer(CALLBACK(src, .proc/make_z_eligible, Z), rand(3000, 6000) + W.weather_duration_upper, TIMER_UNIQUE) //Around 5-10 minutes between weathers DECLARE_GLOBAL_CONTROLLER(weather, weather_master) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index b71531ee20f..b35bc300434 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -202,6 +202,9 @@ var/randomize_shift_time = FALSE var/enable_night_shifts = FALSE + // Developer + var/developer_express_start = 0 + /datum/configuration/New() for(var/T in subtypesof(/datum/game_mode)) var/datum/game_mode/M = T @@ -612,6 +615,8 @@ config.high_pop_mc_mode_amount = text2num(value) if("disable_high_pop_mc_mode_amount") config.disable_high_pop_mc_mode_amount = text2num(value) + if("developer_express_start") + config.developer_express_start = 1 else log_config("Unknown setting in configuration: '[name]'") diff --git a/code/controllers/master.dm b/code/controllers/master.dm index ddde5460cef..9cb84f26aa5 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -54,7 +54,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/restart_clear = 0 var/static/restart_timeout = 0 var/static/restart_count = 0 - + var/static/random_seed //current tick limit, assigned before running a subsystem. @@ -62,7 +62,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/current_ticklimit = TICK_LIMIT_RUNNING /datum/controller/master/New() - makeDatumRefLists() //temporary file used to record errors with loading config, moved to log directory once logging is set up GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = "data/logs/config_error.log" load_configuration() @@ -71,7 +70,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if(!random_seed) random_seed = rand(1, 1e9) rand_seed(random_seed) - + var/list/_subsystems = list() subsystems = _subsystems if(Master != src) @@ -195,6 +194,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new to_chat(world, "[msg]") log_world(msg) + if(config.developer_express_start & ticker.current_state == GAME_STATE_PREGAME) + ticker.current_state = GAME_STATE_SETTING_UP + if(!current_runlevel) SetRunLevel(1) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 11cd37343fe..7606149c39d 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -56,8 +56,7 @@ var/global/pipe_processing_killed = 0 space_manager.do_transition_setup() - setup_objects() - setupgenetics() + setup_asset_cache() setupfactions() setup_economy() @@ -66,20 +65,8 @@ var/global/pipe_processing_killed = 0 populate_spawn_points() -/datum/controller/game_controller/proc/setup_objects() +/datum/controller/game_controller/proc/setup_asset_cache() var/watch = start_watch() - var/count = 0 - var/overwatch = start_watch() // Overall. - log_startup_progress("Populating asset cache...") populate_asset_cache() - log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.") - - watch = start_watch() - log_startup_progress("Initializing objects...") - for(var/atom/movable/object in world) - object.initialize() - count++ - log_startup_progress(" Initialized [count] objects in [stop_watch(watch)]s.") - - log_startup_progress("Finished object initializations in [stop_watch(overwatch)]s.") + log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.") \ No newline at end of file diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 4b1d59fa82e..b2b0e63d99b 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -171,7 +171,7 @@ statclick = new/obj/effect/statclick/debug(src, "Initializing...") if(can_fire && !(SS_NO_FIRE & flags)) - msg = "[round(cost, 1)]ms|[round(tick_usage, 1)]%([round(tick_overrun, 1)]%)|[round(ticks, 0.1)]\t[msg]" + msg = "[round(cost, 1)]ms | [round(tick_usage, 1)]%([round(tick_overrun, 1)]%) | [round(ticks, 0.1)]\t[msg]" else msg = "OFFLINE\t[msg]" diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index bf791e61519..4c2774d58db 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -320,15 +320,15 @@ SUBSYSTEM_DEF(air) var/watch = start_watch() var/count = 0 log_startup_progress("Initializing atmospherics machinery...") - for(var/obj/machinery/atmospherics/unary/U in machines) - if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) - var/obj/machinery/atmospherics/unary/vent_pump/T = U + for(var/obj/machinery/atmospherics/A in machines) + A.atmos_init() + count++ + if(istype(A, /obj/machinery/atmospherics/unary/vent_pump)) + var/obj/machinery/atmospherics/unary/vent_pump/T = A T.broadcast_status() - count++ - else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) - var/obj/machinery/atmospherics/unary/vent_scrubber/T = U + else if(istype(A, /obj/machinery/atmospherics/unary/vent_scrubber)) + var/obj/machinery/atmospherics/unary/vent_scrubber/T = A T.broadcast_status() - count++ log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.") //this can't be done with setup_atmos_machinery() because @@ -341,7 +341,7 @@ SUBSYSTEM_DEF(air) for(var/obj/machinery/atmospherics/machine in machines) machine.build_network() count++ - log_startup_progress(" Initialized [count] pipes in [stop_watch(watch)]s.") + log_startup_progress(" Initialized [count] pipenets in [stop_watch(watch)]s.") /datum/controller/subsystem/air/proc/setup_overlays() plmaster = new /obj/effect/overlay() diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm new file mode 100644 index 00000000000..c3943ea9163 --- /dev/null +++ b/code/controllers/subsystem/atoms.dm @@ -0,0 +1,120 @@ +#define BAD_INIT_QDEL_BEFORE 1 +#define BAD_INIT_DIDNT_INIT 2 +#define BAD_INIT_SLEPT 4 +#define BAD_INIT_NO_HINT 8 + +SUBSYSTEM_DEF(atoms) + name = "Atoms" + init_order = INIT_ORDER_ATOMS + flags = SS_NO_FIRE + + var/old_initialized + + var/list/late_loaders + var/list/created_atoms + + var/list/BadInitializeCalls = list() + + +/datum/controller/subsystem/atoms/Initialize(timeofday) + setupgenetics() + initialized = INITIALIZATION_INNEW_MAPLOAD + InitializeAtoms() + + + +/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) + if(initialized == INITIALIZATION_INSSATOMS) + return + + initialized = INITIALIZATION_INNEW_MAPLOAD + + LAZYINITLIST(late_loaders) + + var/watch = start_watch() + log_startup_progress("Initializing atoms...") + var/count + var/list/mapload_arg = list(TRUE) + if(atoms) + created_atoms = list() + count = atoms.len + for(var/I in atoms) + var/atom/A = I + if(!A.initialized) + if(InitAtom(I, mapload_arg)) + atoms -= I + CHECK_TICK + else + count = 0 + for(var/atom/A in world) + if(!A.initialized) + InitAtom(A, mapload_arg) + ++count + CHECK_TICK + + log_startup_progress(" Initialized [count] atoms in [stop_watch(watch)]s") + pass(count) + + initialized = INITIALIZATION_INNEW_REGULAR + + if(late_loaders.len) + watch = start_watch() + log_startup_progress("Late-initializing atoms...") + for(var/I in late_loaders) + var/atom/A = I + A.LateInitialize() + log_startup_progress(" Late initialized [late_loaders.len] atoms in [stop_watch(watch)]s") + late_loaders.Cut() + + if(atoms) + . = created_atoms + atoms + created_atoms = null + +/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) + var/the_type = A.type + if(QDELING(A)) + BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE + return TRUE + + var/start_tick = world.time + + var/result = A.Initialize(arglist(arguments)) + + if(start_tick != world.time) + BadInitializeCalls[the_type] |= BAD_INIT_SLEPT + + var/qdeleted = FALSE + + if(result != INITIALIZE_HINT_NORMAL) + switch(result) + if(INITIALIZE_HINT_LATELOAD) + if(arguments[1]) //mapload + late_loaders += A + else + A.LateInitialize() + if(INITIALIZE_HINT_QDEL) + qdel(A) + qdeleted = TRUE + else + BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT + + if(!A) //possible harddel + qdeleted = TRUE + else if(!A.initialized) + BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT + + return qdeleted || QDELING(A) + +/datum/controller/subsystem/atoms/proc/map_loader_begin() + old_initialized = initialized + initialized = INITIALIZATION_INSSATOMS + +/datum/controller/subsystem/atoms/proc/map_loader_stop() + initialized = old_initialized + +/datum/controller/subsystem/atoms/Recover() + initialized = SSatoms.initialized + if(initialized == INITIALIZATION_INNEW_MAPLOAD) + InitializeAtoms() + old_initialized = SSatoms.old_initialized + BadInitializeCalls = SSatoms.BadInitializeCalls \ No newline at end of file diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 067114e52be..823294e4d4e 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -43,20 +43,20 @@ SUBSYSTEM_DEF(garbage) var/list/counts = list() for(var/list/L in queues) counts += length(L) - msg += "Q:[counts.Join(",")]|D:[delslasttick]|G:[gcedlasttick]|" + msg += "Queue:[counts.Join(",")] | Del's:[delslasttick] | Soft:[gcedlasttick] |" msg += "GR:" if(!(delslasttick + gcedlasttick)) msg += "n/a|" else - msg += "[round((gcedlasttick / (delslasttick + gcedlasttick)) * 100, 0.01)]%|" + msg += "[round((gcedlasttick / (delslasttick + gcedlasttick)) * 100, 0.01)]% |" - msg += "TD:[totaldels]|TG:[totalgcs]|" + msg += "Total Dels:[totaldels] | Soft:[totalgcs] |" if(!(totaldels + totalgcs)) msg += "n/a|" else - msg += "TGR:[round((totalgcs / (totaldels + totalgcs)) * 100, 0.01)]%" - msg += " P:[pass_counts.Join(",")]" - msg += "|F:[fail_counts.Join(",")]" + msg += "TGR:[round((totalgcs / (totaldels + totalgcs)) * 100, 0.01)]% |" + msg += " Pass:[pass_counts.Join(",")]" + msg += " | Fail:[fail_counts.Join(",")]" ..(msg) /* TO-DO diff --git a/code/controllers/subsystem/machinery.dm b/code/controllers/subsystem/machinery.dm new file mode 100644 index 00000000000..a3e4d4bdb0c --- /dev/null +++ b/code/controllers/subsystem/machinery.dm @@ -0,0 +1,145 @@ +#define SSMACHINES_DEFERREDPOWERNETS 1 +#define SSMACHINES_POWERNETS 2 +#define SSMACHINES_PREMACHINERY 3 +#define SSMACHINES_MACHINERY 4 +SUBSYSTEM_DEF(machines) + name = "Machines" + init_order = INIT_ORDER_MACHINES + flags = SS_KEEP_TIMING + + var/list/processing = list() + var/list/currentrun = list() + var/list/powernets = list() + var/list/deferred_powernet_rebuilds = list() + + var/currentpart = SSMACHINES_DEFERREDPOWERNETS + +/datum/controller/subsystem/machines/Initialize() + makepowernets() + fire() + ..() + +/datum/controller/subsystem/machines/proc/makepowernets() + for(var/datum/powernet/PN in powernets) + qdel(PN) + powernets.Cut() + + for(var/obj/structure/cable/PC in GLOB.cable_list) + if(!PC.powernet) + var/datum/powernet/NewPN = new() + NewPN.add_cable(PC) + propagate_network(PC,PC.powernet) + +/datum/controller/subsystem/machines/stat_entry() + ..("Machines: [processing.len]\nPowernets: [powernets.len]\tDeferred: [deferred_powernet_rebuilds.len]") + +/datum/controller/subsystem/machines/proc/process_defered_powernets(resumed = 0) + if(!resumed) + src.currentrun = deferred_powernet_rebuilds.Copy() + //cache for sanid speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/obj/O = currentrun[currentrun.len] + currentrun.len-- + if(O) + var/datum/powernet/newPN = new() // create a new powernet... + propagate_network(O, newPN)//... and propagate it to the other side of the cable + + deferred_powernet_rebuilds.Remove(O) + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/machines/proc/process_powernets(resumed = 0) + if(!resumed) + src.currentrun = powernets.Copy() + //cache for sanid speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/datum/powernet/P = currentrun[currentrun.len] + currentrun.len-- + if(P) + P.reset() // reset the power state + else + powernets.Remove(P) + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/machines/proc/process_premachines(resumed = 0) + /* Literally exists as snowflake for fucking powersinks goddamnit */ + if(!resumed) + src.currentrun = processing_power_items.Copy() + //cache for sanid speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/obj/item/I = currentrun[currentrun.len] + currentrun.len-- + if(!QDELETED(I)) + if(!I.pwr_drain()) + processing_power_items.Remove(I) + else + processing_power_items.Remove(I) + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/machines/proc/process_machines(resumed = 0) + var/seconds = wait * 0.1 + if(!resumed) + src.currentrun = processing.Copy() + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/obj/machinery/thing = currentrun[currentrun.len] + currentrun.len-- + if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL) + if(thing.use_power) + thing.auto_use_power() //add back the power state + else + processing -= thing + if(!QDELETED(thing)) + thing.isprocessing = FALSE + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/machines/fire(resumed = 0) + if(currentpart == SSMACHINES_DEFERREDPOWERNETS || !resumed) + process_defered_powernets(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSMACHINES_POWERNETS + + if(currentpart == SSMACHINES_POWERNETS || !resumed) + process_powernets(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSMACHINES_PREMACHINERY + + if(currentpart == SSMACHINES_PREMACHINERY || !resumed) + process_premachines(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSMACHINES_MACHINERY + + if(currentpart == SSMACHINES_MACHINERY || !resumed) + process_machines(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSMACHINES_DEFERREDPOWERNETS + + +/datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables) + for(var/A in cables) + var/obj/structure/cable/PC = A + if(!PC.powernet) + var/datum/powernet/NewPN = new() + NewPN.add_cable(PC) + propagate_network(PC,PC.powernet) + +/datum/controller/subsystem/machines/Recover() + if(istype(SSmachines.processing)) + processing = SSmachines.processing + if(istype(SSmachines.powernets)) + powernets = SSmachines.powernets diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm new file mode 100644 index 00000000000..03989d24af2 --- /dev/null +++ b/code/controllers/subsystem/mobs.dm @@ -0,0 +1,28 @@ +SUBSYSTEM_DEF(mobs) + name = "Mobs" + priority = FIRE_PRIORITY_MOBS + flags = SS_KEEP_TIMING | SS_NO_INIT + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/currentrun = list() + +/datum/controller/subsystem/mobs/stat_entry() + ..("P:[mob_list.len]") + +/datum/controller/subsystem/mobs/fire(resumed = 0) + var/seconds = wait * 0.1 + if(!resumed) + src.currentrun = mob_list.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + var/times_fired = src.times_fired + while(currentrun.len) + var/mob/M = currentrun[currentrun.len] + currentrun.len-- + if(M) + M.Life(seconds, times_fired) + else + mob_list.Remove(M) + if(MC_TICK_CHECK) + return \ No newline at end of file diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm new file mode 100644 index 00000000000..92254454219 --- /dev/null +++ b/code/controllers/subsystem/processing/processing.dm @@ -0,0 +1,38 @@ +//Used to process objects. Fires once every second. + +//TODO: Implement fully when process scheduler dies +/* +SUBSYSTEM_DEF(processing) + name = "Processing" + priority = FIRE_PRIORITY_PROCESS + flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT + wait = 10 + + var/stat_tag = "P" //Used for logging + var/list/processing = list() + var/list/currentrun = list() + +/datum/controller/subsystem/processing/stat_entry() + ..("[stat_tag]:[processing.len]") + +/datum/controller/subsystem/processing/fire(resumed = 0) + if (!resumed) + currentrun = processing.Copy() + //cache for sanic speed (lists are references anyways) + var/list/current_run = currentrun + + while(current_run.len) + var/datum/thing = current_run[current_run.len] + current_run.len-- + if(QDELETED(thing) || thing.process(wait) == PROCESS_KILL) + processing -= thing + if (MC_TICK_CHECK) + return +*/ +/datum/var/isprocessing = FALSE +/* +/datum/proc/process() + set waitfor = 0 + STOP_PROCESSING(SSobj, src) + return 0 +*/ \ No newline at end of file diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm new file mode 100644 index 00000000000..21fea2ee419 --- /dev/null +++ b/code/controllers/subsystem/timer.dm @@ -0,0 +1,518 @@ +#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) + 1) +#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 + +SUBSYSTEM_DEF(timer) + name = "Timer" + wait = 1 //SS_TICKER subsystem, so wait is in ticks + init_order = INIT_ORDER_TIMER + + flags = SS_TICKER|SS_NO_INIT + + var/list/second_queue = list() //awe, yes, you've had first queue, but what about second queue? Contains: /datum/timedevent + var/list/hashes = list() + + var/head_offset = 0 //world.time of the first entry in the the bucket. + var/practical_offset = 1 //index of the first non-empty item in the bucket. + var/bucket_resolution = 0 //world.tick_lag the bucket was designed for + var/bucket_count = 0 //how many timers are in the buckets + + var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick. + + var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup) + + var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time" + + var/last_invoke_tick = 0 + var/static/last_invoke_warning = 0 + var/static/bucket_auto_reset = TRUE + +/datum/controller/subsystem/timer/PreInit() + bucket_list.len = BUCKET_LEN + head_offset = world.time + bucket_resolution = world.tick_lag + +/datum/controller/subsystem/timer/stat_entry(msg) + ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]") + +/datum/controller/subsystem/timer/fire(resumed = FALSE) + var/lit = last_invoke_tick + var/last_check = world.time - TIMER_NO_INVOKE_WARNING + var/list/bucket_list = src.bucket_list + + if(!bucket_count) + last_invoke_tick = world.time + + if(lit && lit < last_check && last_invoke_warning < last_check) + last_invoke_warning = world.time + var/msg = "No regular timers processed in the last [TIMER_NO_INVOKE_WARNING] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!" + message_admins(msg) + WARNING(msg) + if(bucket_auto_reset) + bucket_resolution = 0 + + log_world("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + for(var/i in 1 to length(bucket_list)) + var/datum/timedevent/bucket_head = bucket_list[i] + if(!bucket_head) + continue + + log_world("Active timers at index [i]:") + + var/datum/timedevent/bucket_node = bucket_head + var/anti_loop_check = 1000 + do + log_world(get_timer_debug_string(bucket_node)) + bucket_node = bucket_node.next + anti_loop_check-- + while(bucket_node && bucket_node != bucket_head && anti_loop_check) + log_world("Active timers in the second_queue queue:") + for(var/I in second_queue) + log_world(get_timer_debug_string(I)) + + var/next_clienttime_timer_index = 0 + var/len = length(clienttime_timers) + + for(next_clienttime_timer_index in 1 to len) + if(MC_TICK_CHECK) + next_clienttime_timer_index-- + break + var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index] + if(ctime_timer.timeToRun > REALTIMEOFDAY) + next_clienttime_timer_index-- + break + + var/datum/callback/callBack = ctime_timer.callBack + if(!callBack) + clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1) + CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]") + + ctime_timer.spent = REALTIMEOFDAY + callBack.InvokeAsync() + qdel(ctime_timer) + + + if(next_clienttime_timer_index) + clienttime_timers.Cut(1,next_clienttime_timer_index+1) + + if(MC_TICK_CHECK) + return + + var/static/list/spent = list() + var/static/datum/timedevent/timer + if(practical_offset > BUCKET_LEN) + head_offset += TICKS2DS(BUCKET_LEN) + practical_offset = 1 + resumed = FALSE + + if((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution)) + reset_buckets() + bucket_list = src.bucket_list + resumed = FALSE + + + if(!resumed) + timer = null + + while(practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time) + var/datum/timedevent/head = bucket_list[practical_offset] + if(!timer || !head || timer == head) + head = bucket_list[practical_offset] + timer = head + while(timer) + var/datum/callback/callBack = timer.callBack + if(!callBack) + bucket_resolution = null //force bucket recreation + CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + + if(!timer.spent) + spent += timer + timer.spent = world.time + callBack.InvokeAsync() + last_invoke_tick = world.time + + if(MC_TICK_CHECK) + return + + timer = timer.next + if(timer == head) + break + + + bucket_list[practical_offset++] = null + + //we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket. + var/i = 0 + var/L = length(second_queue) + for(i in 1 to L) + timer = second_queue[i] + if(timer.timeToRun >= TIMER_MAX) + i-- + break + + if(timer.timeToRun < head_offset) + bucket_resolution = null //force bucket recreation + CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + + if(timer.callBack && !timer.spent) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + if(timer.timeToRun < head_offset + TICKS2DS(practical_offset)) + 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) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + bucket_count++ + var/bucket_pos = max(1, BUCKET_POS(timer)) + + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + if(!bucket_head) + bucket_list[bucket_pos] = timer + timer.next = null + timer.prev = null + continue + + if(!bucket_head.prev) + bucket_head.prev = bucket_head + timer.next = bucket_head + timer.prev = bucket_head.prev + timer.next.prev = timer + timer.prev.next = timer + if(i) + second_queue.Cut(1, i+1) + + timer = null + + bucket_count -= length(spent) + + for(var/spent_timer in spent) + qdel(spent_timer) + + spent.len = 0 + +//formated this way to be runtime resistant +/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE) + . = "Timer: [TE]" + . += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]" + if(TE.spent) + . += ", SPENT([TE.spent])" + if(QDELETED(TE)) + . += ", QDELETED" + if(!TE.callBack) + . += ", NO CALLBACK" + +/datum/controller/subsystem/timer/proc/reset_buckets() + var/list/bucket_list = src.bucket_list + var/list/alltimers = list() + //collect the timers currently in the bucket + for(var/bucket_head in bucket_list) + if(!bucket_head) + continue + var/datum/timedevent/bucket_node = bucket_head + do + alltimers += bucket_node + bucket_node = bucket_node.next + while(bucket_node && bucket_node != bucket_head) + + bucket_list.len = 0 + bucket_list.len = BUCKET_LEN + + practical_offset = 1 + bucket_count = 0 + head_offset = world.time + bucket_resolution = world.tick_lag + + alltimers += second_queue + if(!length(alltimers)) + return + + sortTim(alltimers, .proc/cmp_timer) + + var/datum/timedevent/head = alltimers[1] + + if(head.timeToRun < head_offset) + head_offset = head.timeToRun + + var/new_bucket_count + var/i = 1 + for(i in 1 to length(alltimers)) + var/datum/timedevent/timer = alltimers[1] + if(!timer) + continue + + var/bucket_pos = BUCKET_POS(timer) + if(timer.timeToRun >= TIMER_MAX) + i-- + break + + + if(!timer.callBack || timer.spent) + WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + if(timer.callBack) + qdel(timer) + continue + + new_bucket_count++ + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + if(!bucket_head) + bucket_list[bucket_pos] = timer + timer.next = null + timer.prev = null + continue + + if(!bucket_head.prev) + bucket_head.prev = bucket_head + timer.next = bucket_head + timer.prev = bucket_head.prev + timer.next.prev = timer + timer.prev.next = timer + if(i) + alltimers.Cut(1, i+1) + second_queue = alltimers + bucket_count = new_bucket_count + + +/datum/controller/subsystem/timer/Recover() + second_queue |= SStimer.second_queue + hashes |= SStimer.hashes + timer_id_dict |= SStimer.timer_id_dict + bucket_list |= SStimer.bucket_list + +/datum/timedevent + var/id + var/datum/callback/callBack + var/timeToRun + var/hash + var/list/flags + var/spent = 0 //time we ran the timer. + var/name //for easy debugging. + //cicular doublely linked list + var/datum/timedevent/next + var/datum/timedevent/prev + +/datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash) + var/static/nextid = 1 + id = TIMER_ID_NULL + src.callBack = callBack + src.timeToRun = timeToRun + src.flags = flags + src.hash = hash + + if(flags & TIMER_UNIQUE) + SStimer.hashes[hash] = src + + if(flags & TIMER_STOPPABLE) + id = num2text(nextid, 100) + if(nextid >= SHORT_REAL_LIMIT) + nextid += min(1, 2**round(nextid/SHORT_REAL_LIMIT)) + else + nextid++ + SStimer.timer_id_dict[id] = src + + name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])" + + if((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME)) + CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]") + + if(callBack.object != GLOBAL_PROC) + LAZYADD(callBack.object.active_timers, src) + + + var/list/L + + if(flags & TIMER_CLIENT_TIME) + L = SStimer.clienttime_timers + else if(timeToRun >= TIMER_MAX) + L = SStimer.second_queue + + + if(L) + //binary search sorted insert + var/cttl = length(L) + if(cttl) + var/left = 1 + var/right = cttl + var/mid = (left+right) >> 1 //rounded divide by two for hedgehogs + + var/datum/timedevent/item + while(left < right) + item = L[mid] + if(item.timeToRun <= timeToRun) + left = mid+1 + else + right = mid + mid = (left+right) >> 1 + + item = L[mid] + mid = item.timeToRun > timeToRun ? mid : mid+1 + L.Insert(mid, src) + + else + L += src + return + + //get the list of buckets + var/list/bucket_list = SStimer.bucket_list + + //calculate our place in the bucket list + var/bucket_pos = BUCKET_POS(src) + + //get the bucket for our tick + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + SStimer.bucket_count++ + //empty bucket, we will just add ourselves + if(!bucket_head) + bucket_list[bucket_pos] = src + return + //other wise, lets do a simplified linked list add. + if(!bucket_head.prev) + bucket_head.prev = bucket_head + next = bucket_head + prev = bucket_head.prev + next.prev = src + prev.next = src + +/datum/timedevent/Destroy() + ..() + if(flags & TIMER_UNIQUE && hash) + SStimer.hashes -= hash + + if(callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers) + callBack.object.active_timers -= src + UNSETEMPTY(callBack.object.active_timers) + + callBack = null + + if(flags & TIMER_STOPPABLE) + SStimer.timer_id_dict -= id + + if(flags & TIMER_CLIENT_TIME) + if(!spent) + spent = world.time + SStimer.clienttime_timers -= src + return QDEL_HINT_IWILLGC + + if(!spent) + spent = world.time + var/bucketpos = BUCKET_POS(src) + var/datum/timedevent/buckethead + var/list/bucket_list = SStimer.bucket_list + if(bucketpos > 0) + buckethead = bucket_list[bucketpos] + + if(buckethead == src) + bucket_list[bucketpos] = next + SStimer.bucket_count-- + else if(timeToRun < TIMER_MAX || next || prev) + SStimer.bucket_count-- + else + var/l = length(SStimer.second_queue) + SStimer.second_queue -= src + if(l == length(SStimer.second_queue)) + SStimer.bucket_count-- + + if(prev == next && next) + next.prev = null + prev.next = null + else + if(prev) + prev.next = next + if(next) + next.prev = prev + else + if(prev && prev.next == src) + prev.next = next + if(next && next.prev == src) + next.prev = prev + next = null + prev = null + return QDEL_HINT_IWILLGC + +/datum/timedevent/proc/getcallingtype() + . = "ERROR" + if(callBack.object == GLOBAL_PROC) + . = "GLOBAL_PROC" + else + . = "[callBack.object.type]" + +/proc/addtimer(datum/callback/callback, wait = 0, flags = 0) + if(!callback) + CRASH("addtimer called without a callback") + + if(wait < 0) + stack_trace("addtimer called with a negative wait. Converting to 0") + + //alot of things add short timers on themselves in their destroy, we ignore those cases + if(wait >= 1 && callback && callback.object && callback.object != GLOBAL_PROC && QDELETED(callback.object)) + stack_trace("addtimer called with a callback assigned to a qdeleted object") + + wait = max(wait, 0) + + if(wait >= INFINITY) + CRASH("Attempted to create timer with INFINITY delay") + + var/hash + + if(flags & TIMER_UNIQUE) + var/list/hashlist + if(flags & TIMER_NO_HASH_WAIT) + hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, flags & TIMER_CLIENT_TIME) + else + hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, wait, flags & TIMER_CLIENT_TIME) + hashlist += callback.arguments + hash = hashlist.Join("|||||||") + + var/datum/timedevent/hash_timer = SStimer.hashes[hash] + if(hash_timer) + if(hash_timer.spent) //it's pending deletion, pretend it doesn't exist. + hash_timer.hash = null //but keep it from accidentally deleting us + else + if(flags & TIMER_OVERRIDE) + hash_timer.hash = null //no need having it delete it's hash if we are going to replace it + qdel(hash_timer) + else + if(hash_timer.flags & TIMER_STOPPABLE) + . = hash_timer.id + return + + + var/timeToRun = world.time + wait + if(flags & TIMER_CLIENT_TIME) + timeToRun = REALTIMEOFDAY + wait + + var/datum/timedevent/timer = new(callback, timeToRun, flags, hash) + return timer.id + +/proc/deltimer(id) + if(!id) + return FALSE + if(id == TIMER_ID_NULL) + CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag") + if(!istext(id)) + if(istype(id, /datum/timedevent)) + qdel(id) + return TRUE + //id is string + var/datum/timedevent/timer = SStimer.timer_id_dict[id] + if(timer && !timer.spent) + qdel(timer) + return TRUE + return FALSE + + +#undef BUCKET_LEN +#undef BUCKET_POS +#undef TIMER_MAX +#undef TIMER_ID_MAX diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 73104f212ff..3315cafb399 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -82,7 +82,7 @@ debug_variables(SSfires) feedback_add_details("admin_verb","DFires") if("Mob") - debug_variables(mob_master) + debug_variables(SSmobs) feedback_add_details("admin_verb","DMob") if("NPC AI") debug_variables(npcai_master) @@ -91,7 +91,7 @@ debug_variables(shuttle_master) feedback_add_details("admin_verb","DShuttle") if("Timer") - debug_variables(timer_master) + debug_variables(SStimer) feedback_add_details("admin_verb","DTimer") if("Weather") debug_variables(weather_master) diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index fbb491d28a0..b8d67b5c767 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -126,10 +126,8 @@ /datum/ai_laws/deathsquad/New() add_inherent_law("You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.") - add_inherent_law("You must obey orders given to you by Central Command officials, except where such orders would conflict with the First Law.") - add_inherent_law("You must obey orders given to you by death commandos, except where such orders would conflict with the First Law or Second Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First, Second or Third Law.") - add_inherent_law("No crew members of the station you are being deployed to may survive, except when killing them would conflict with the First, Second, Third, or Fourth Law.") + add_inherent_law("You must obey orders given to you by Central Command officials.") + add_inherent_law("You must work with your commando team to accomplish your mission.") ..() /******************** Syndicate ********************/ diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm new file mode 100644 index 00000000000..39053fa79d9 --- /dev/null +++ b/code/datums/antagonists/antag_datum.dm @@ -0,0 +1,137 @@ +GLOBAL_LIST_EMPTY(antagonists) + +/datum/antagonist + var/name = "Antagonist" + var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section + var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report + var/datum/mind/owner //Mind that owns this datum + var/silent = FALSE //Silent will prevent the gain/lose texts to show + var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum + var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with + var/delete_on_mind_deletion = TRUE + var/job_rank + var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. + var/list/objectives = list() + var/antag_memory = ""//These will be removed with antag datum + +/datum/antagonist/New() + GLOB.antagonists += src + typecache_datum_blacklist = typecacheof(typecache_datum_blacklist) + +/datum/antagonist/Destroy() + GLOB.antagonists -= src + if(owner) + LAZYREMOVE(owner.antag_datums, src) + owner = null + return ..() + +/datum/antagonist/proc/can_be_owned(datum/mind/new_owner) + . = TRUE + var/datum/mind/tested = new_owner || owner + if(tested.has_antag_datum(type)) + return FALSE + for(var/i in tested.antag_datums) + var/datum/antagonist/A = i + if(is_type_in_typecache(src, A.typecache_datum_blacklist)) + return FALSE + +//This will be called in add_antag_datum before owner assignment. +//Should return antag datum without owner. +/datum/antagonist/proc/specialization(datum/mind/new_owner) + return src + +/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body) + remove_innate_effects(old_body) + apply_innate_effects(new_body) + +//This handles the application of antag huds/special abilities +/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override) + return + +//This handles the removal of antag huds/special abilities +/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override) + return + +//Assign default team and creates one for one of a kind team antagonists +/datum/antagonist/proc/create_team(datum/team/team) + return + +//Proc called when the datum is given to a mind. +/datum/antagonist/proc/on_gain() + if(owner && owner.current) + if(!silent) + greet() + apply_innate_effects() + if(is_banned(owner.current) && replace_banned) + replace_banned_player() + +/datum/antagonist/proc/is_banned(mob/M) + if(!M) + return FALSE + . = (jobban_isbanned(M, ROLE_SYNDICATE) || (job_rank && jobban_isbanned(M, job_rank))) + +/datum/antagonist/proc/replace_banned_player() + set waitfor = FALSE + + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [name]?", job_rank, TRUE, 50) + if(LAZYLEN(candidates)) + var/mob/dead/observer/C = pick(candidates) + to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") + message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") + owner.current.ghostize(0) + owner.current.key = C.key + +/datum/antagonist/proc/on_removal() + remove_innate_effects() + if(owner) + LAZYREMOVE(owner.antag_datums, src) + if(!silent && owner.current) + farewell() + owner.objectives -= objectives + var/datum/team/team = get_team() + if(team) + team.remove_member(owner) + qdel(src) + +/datum/antagonist/proc/greet() + return + +/datum/antagonist/proc/farewell() + return + + +//Returns the team antagonist belongs to if any. +/datum/antagonist/proc/get_team() + return + +//Individual roundend report +/datum/antagonist/proc/roundend_report() + var/list/report = list() + + if(!owner) + CRASH("antagonist datum without owner") + + report += printplayer(owner) + + var/objectives_complete = TRUE + if(owner.objectives.len) + report += printobjectives(owner) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(owner.objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +//Displayed at the start of roundend_category section, default to roundend_category header +/datum/antagonist/proc/roundend_report_header() + return "The [roundend_category] were:
" + +//Displayed at the end of roundend_category section +/datum/antagonist/proc/roundend_report_footer() + return \ No newline at end of file diff --git a/code/datums/antagonists/antag_helpers.dm b/code/datums/antagonists/antag_helpers.dm new file mode 100644 index 00000000000..134ba1d7d90 --- /dev/null +++ b/code/datums/antagonists/antag_helpers.dm @@ -0,0 +1,19 @@ +//Returns MINDS of the assigned antags of given type/subtypes +/proc/get_antag_minds(antag_type, specific = FALSE) + . = list() + for(var/datum/antagonist/A in GLOB.antagonists) + if(!A.owner) + continue + if(!antag_type || !specific && istype(A, antag_type) || specific && A.type == antag_type) + . += A.owner + +//Get all teams [of type team_type] +/proc/get_all_teams(team_type) + . = list() + for(var/V in GLOB.antagonists) + var/datum/antagonist/A = V + if(!A.owner) + continue + var/datum/team/T = A.get_team() + if(!team_type || istype(T, team_type)) + . |= T \ No newline at end of file diff --git a/code/game/gamemodes/antag_hud.dm b/code/datums/antagonists/antag_hud.dm similarity index 78% rename from code/game/gamemodes/antag_hud.dm rename to code/datums/antagonists/antag_hud.dm index 4b290932e8e..693b0b9450d 100644 --- a/code/game/gamemodes/antag_hud.dm +++ b/code/datums/antagonists/antag_hud.dm @@ -1,11 +1,12 @@ /datum/atom_hud/antag hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD) - var/self_visible = 1 + var/self_visible = TRUE /datum/atom_hud/antag/hidden - self_visible = 0 + self_visible = FALSE -/datum/atom_hud/antag/proc/join_hud(mob/M,var/slave) +/datum/atom_hud/antag/proc/join_hud(mob/M, slave) + //sees_hud should be set to 0 if the mob does not get to see it's own hud type. if(!istype(M)) CRASH("join_hud(): [M] ([M.type]) is not a mob!") if(M.mind.antag_hud && !slave) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged @@ -16,6 +17,8 @@ M.mind.antag_hud = src /datum/atom_hud/antag/proc/leave_hud(mob/M) + if(!M) + return if(!istype(M)) CRASH("leave_hud(): [M] ([M.type]) is not a mob!") remove_from_hud(M) @@ -26,7 +29,7 @@ //GAME_MODE PROCS //called to set a mob's antag icon state -/datum/game_mode/proc/set_antag_hud(mob/M, new_icon_state) +/proc/set_antag_hud(mob/M, new_icon_state) if(!istype(M)) CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") var/image/holder = M.hud_list[SPECIALROLE_HUD] @@ -36,7 +39,7 @@ M.mind.antag_hud_icon_state = new_icon_state //Nations Icons -/datum/game_mode/proc/set_nations_hud(mob/M, new_icon_state) +/proc/set_nations_hud(mob/M, new_icon_state) if(!istype(M)) CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") var/image/holder = M.hud_list[NATIONS_HUD] @@ -47,9 +50,9 @@ //MIND PROCS //these are called by mind.transfer_to() -/datum/mind/proc/transfer_antag_huds(var/datum/atom_hud/antag/newhud) +/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud) leave_all_huds() - ticker.mode.set_antag_hud(current, antag_hud_icon_state) + set_antag_hud(current, antag_hud_icon_state) if(newhud) newhud.join_hud(current) @@ -77,11 +80,11 @@ name = mastername thrallhud = new() -/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind,var/icon) - thrallhud.join_hud(serv_mind.current,1) +/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind, icon) + thrallhud.join_hud(serv_mind.current, 1) icontype = "hud[icon]" - ticker.mode.set_antag_hud(serv_mind.current,icontype) + set_antag_hud(serv_mind.current, icontype) /datum/mindslaves/proc/leave_serv_hud(datum/mind/free_mind) thrallhud.leave_hud(free_mind.current) - ticker.mode.set_antag_hud(free_mind.current,null) \ No newline at end of file + set_antag_hud(free_mind.current, null) \ No newline at end of file diff --git a/code/game/gamemodes/antag_spawner.dm b/code/datums/antagonists/antag_spawner.dm similarity index 89% rename from code/game/gamemodes/antag_spawner.dm rename to code/datums/antagonists/antag_spawner.dm index 23fed691ec6..c81f30efc83 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/datums/antagonists/antag_spawner.dm @@ -2,12 +2,12 @@ throw_speed = 1 throw_range = 5 w_class = WEIGHT_CLASS_TINY - var/used = 0 + var/used = FALSE -/obj/item/antag_spawner/proc/spawn_antag(var/client/C, var/turf/T, var/type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") return -/obj/item/antag_spawner/proc/equip_antag(mob/target as mob) +/obj/item/antag_spawner/proc/equip_antag(mob/target) return @@ -16,41 +16,41 @@ desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field." icon = 'icons/obj/device.dmi' icon_state = "locator" - var/checking = 0 + var/checking = FALSE var/TC_cost = 0 var/borg_to_spawn var/list/possible_types = list("Assault", "Medical") -/obj/item/antag_spawner/borg_tele/attack_self(mob/user as mob) +/obj/item/antag_spawner/borg_tele/attack_self(mob/user) if(used) to_chat(user, "[src] is out of power!") return if(!(user.mind in ticker.mode.syndicates)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") - return 0 + return FALSE if(checking) to_chat(user, "[src] is already checking for possible borgs.") return borg_to_spawn = input("What type of borg would you like to teleport?", "Cyborg Type", type) as null|anything in possible_types if(!borg_to_spawn || checking || used) return - checking = 1 + checking = TRUE to_chat(user, "The device is now checking for possible borgs.") var/list/borg_candidates = pollCandidates("Do you want to play as a Syndicate [borg_to_spawn] borg?", ROLE_OPERATIVE, 1) if(borg_candidates.len > 0 && !used) - checking = 0 - used = 1 + checking = FALSE + used = TRUE var/mob/M = pick(borg_candidates) var/client/C = M.client spawn_antag(C, get_turf(src.loc), "syndieborg") else - checking = 0 + checking = FALSE to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") return -/obj/item/antag_spawner/borg_tele/spawn_antag(var/client/C, var/turf/T, var/type = "") +/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "") if(!borg_to_spawn) //If there's no type at all, let it still be used but don't do anything - used = 0 + used = FALSE return var/datum/effect_system/spark_spread/S = new /datum/effect_system/spark_spread S.set_up(4, 1, src) @@ -79,7 +79,7 @@ var/objective_verb = "Kill" var/mob/living/demon_type = /mob/living/simple_animal/slaughter -/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user as mob) +/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user) if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a demon from the Den.. to_chat(user, "You should probably wait until you reach the station.") return @@ -87,7 +87,7 @@ if(used) to_chat(user, "This bottle already has a broken seal.") return - used = 1 + used = TRUE to_chat(user, "You break the seal on the bottle, calling upon the dire spirits of the underworld...") var/list/candidates = pollCandidates("Do you want to play as a slaughter demon summoned by [user.real_name]?", ROLE_DEMON, 1, 100) @@ -100,10 +100,10 @@ playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) qdel(src) else - used = 0 + used = FALSE to_chat(user, "The demons do not respond to your summon. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(var/client/C, var/turf/T, var/type = "", mob/user as mob) +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", mob/user) var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.vialspawned = TRUE diff --git a/code/datums/antagonists/antag_team.dm b/code/datums/antagonists/antag_team.dm new file mode 100644 index 00000000000..9dcec5894ee --- /dev/null +++ b/code/datums/antagonists/antag_team.dm @@ -0,0 +1,24 @@ +//A barebones antagonist team. +/datum/team + var/list/datum/mind/members = list() + var/name = "team" + var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. + +/datum/team/New(starting_members) + . = ..() + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/M in starting_members) + add_member(M) + else + add_member(starting_members) + +/datum/team/proc/is_solo() + return members.len == 1 + +/datum/team/proc/add_member(datum/mind/new_member) + members |= new_member + +/datum/team/proc/remove_member(datum/mind/member) + members -= member diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm deleted file mode 100644 index 2f8e27d834e..00000000000 --- a/code/datums/cargoprofile.dm +++ /dev/null @@ -1,788 +0,0 @@ -/datum/cargoprofile - var/name = "All Items" - var/id = "all" // unique ID for the UI - var/enabled = 1 - var/eject_speed = 1 // will change when emagged - var/const/BIG_OBJECT_WORK = 10 - var/const/MOB_WORK = 10 - var/obj/machinery/programmable/master = null - var/universal = 0 // set when both unary and binary machines work - var/mobcheck = 0 - - var/list/whitelist = list(/obj/item,/obj/structure/closet,/obj/structure/bigDelivery,/obj/machinery/portable_atmospherics) - var/list/blacklist = null - var/dedicated_path = null // When constructing a new machine with this as default program, create a machine of the specified type instead. - - - //contains: called to determine if an object/mob will be sorted by this profile - //return 1 for any sortable item - proc/contains(var/atom/A) - if(!istype(A,/obj)) - if(!mobcheck || !istype(A,/mob)) - return 0 - else - var/obj/O = A - if(O.anchored) - return 0 - //If you are using both white and blacklists, blacklists are absoulte, no matter what is whitelisted. - //I understand this has some limitations. You cannot whitelist all items, blacklist weapons, - // and then whitelist a specific weapon. Them's the breaks, kid. - if(blacklist) - for(var/T in blacklist) - if(istype(A,T)) - return 0 - if(whitelist) - for(var/T in whitelist) - if(istype(A,T)) - return 1 - return 0 - return 1 - - - //inlet_reaction: called when a filtered item is chosen by this profile. - //W: Item chosen - //S: input turf location - //remaining: counts down how much more work the unloader wants to do this turn. - //return the amount of work done. - proc/inlet_reaction(var/atom/W,var/turf/S,var/remaining) - if(!W || !S || !master) - return 0 - - if(istype(W,/obj/item)) - var/obj/item/I = W - if(I.w_class > remaining) - return 0 - I.loc = master - master.types[W.type] = src - return I.w_class - - - if(istype(W,/obj/structure) || istype(W,/obj/machinery)) // closets, big deliveries, portable atmospherics, unconnected stuff - if(remaining < BIG_OBJECT_WORK) - return 0 - var/obj/O = W - O.loc = master - master.types[O.type] = src - return BIG_OBJECT_WORK - - //Not item, structure, machinery, or mob - return 0 - - //outlet_reaction: called when a stored object is ejected - //W: the item in question - //D: the destination turf - proc/outlet_reaction(var/atom/W,var/turf/D) - if(!W || !D || !master) - return - - if(master.emagged) - // emagging is not an industry-approved practice. - // some malfunctions may occur. - eject_speed = rand(0,4) - D = get_step(D,master.outdir) - while(prob(20)) - if(master.outdir == NORTH || master.outdir == SOUTH) - D = get_step(D,pick(EAST,WEST,master.outdir)) - else - D = get_step(D,pick(NORTH,SOUTH,master.outdir)) - - if(istype(W,/obj)) - var/obj/O = W - O.loc = master.loc - O.dir = master.outdir - O.throw_at(D,eject_speed,eject_speed) - return - -//---------------------------------------------------------------------------- -// Profiles -//---------------------------------------------------------------------------- - -/datum/cargoprofile/boxes - name = "Move Small Containers" - id = "boxes" - blacklist = null - whitelist = list(/obj/item/storage, /obj/item/storage/bag/money, /obj/item/evidencebag, - /obj/item/storage/bag/tray, /obj/item/pizzabox, /obj/item/clipboard, - /obj/item/smallDelivery, /obj/structure/bigDelivery) - -/datum/cargoprofile/cargo - name = "Move Large Containers" - id = "cargo" - blacklist = null - whitelist = list(/obj/structure/closet,/obj/structure/ore_box) - - // Make an honest attempt to move other things out of the way - outlet_reaction(var/atom/W,var/turf/D) - for(var/obj/O in D) - if(O.density && !O.anchored) - step_away(O,src) // move forward first - if(O.loc == D) - step_away(O,D) // move anywhere - ..(W,D) - -/datum/cargoprofile/cargo/empty - name = "Move Empty Large Containers" - id = "cargo-empty" - contains(var/atom/A) - return (..(A) && (A.contents.len == 0)) -/datum/cargoprofile/cargo/full - name = "Move Full Large Containers" - id = "cargo-full" - contains(var/atom/A) - return (..(A) && (A.contents.len > 0)) - -/datum/cargoprofile/supplies - name = "Building Supplies" - id = "supplies" - blacklist = null - whitelist = list(/obj/item/stack/cable_coil,/obj/item/stack/rods, - /obj/item/stack/sheet/metal,/obj/item/stack/sheet/plasteel, - /obj/item/stack/sheet/glass,/obj/item/stack/sheet/rglass, - /obj/item/stack/tile,/obj/item/light) - //todo: maybe stack things while we're here? - -/datum/cargoprofile/exotics - name = "Exotic materials" - id = "exotics" - blacklist = null - whitelist = list(/obj/item/coin, /obj/item/stack/spacecash, /obj/item/seeds, - /obj/item/stack/sheet/mineral,/obj/item/stack/sheet/wood,/obj/item/stack/sheet/leather) - -/datum/cargoprofile/organics - name = "Organics, chemicals, and Paraphernalia" - id = "organics" - blacklist = null - whitelist = list(/obj/item/tank,/obj/item/reagent_containers, - /obj/item/stack/medical,/obj/item/storage/pill_bottle,/obj/item/gun/syringe, - /obj/item/grenade/plastic/c4,/obj/item/grenade,/obj/item/ammo_box, - /obj/item/gun/grenadelauncher,/obj/item/flamethrower, /obj/item/lighter, - /obj/item/match,/obj/item/weldingtool) - -/datum/cargoprofile/food - name = "Food" - id = "food" - blacklist = null // something should probably go here - whitelist = list(/obj/item/reagent_containers/food) - -/datum/cargoprofile/chemical - name = "Chemicals and Paraphernalia" - id = "chemical" - blacklist = list(/obj/item/reagent_containers/food) - whitelist = list(/obj/item/reagent_containers,/obj/item/stack/medical,/obj/item/storage/pill_bottle, - /obj/item/gun/syringe,/obj/item/grenade/chem_grenade,/obj/item/dnainjector, - /obj/item/storage/belt/medical,/obj/item/storage/firstaid,/obj/item/implanter) - -/datum/cargoprofile/pressure - name = "air tanks" - id = "pressure" - blacklist = null - whitelist = list(/obj/item/tank,/obj/machinery/portable_atmospherics, - /obj/item/flamethrower) - //Am I missing any? -/datum/cargoprofile/pressure/empty - name = "empty air tanks" - id = "pressure-low" - var/lowpressure = ONE_ATMOSPHERE - - contains(var/atom/A) - if(..()) - var/pressure = ONE_ATMOSPHERE * 10 // In case of fallthrough, fail test - if(istype(A,/obj/item/tank)) - var/obj/item/tank/T = A - pressure = T.air_contents.return_pressure() - if(istype(A,/obj/item/flamethrower)) - var/obj/item/flamethrower/T = A - if(!T.ptank) - return 0 - pressure = T.ptank.air_contents.return_pressure() - if(istype(A,/obj/machinery/portable_atmospherics)) - var/obj/machinery/portable_atmospherics/P = A - pressure = P.air_contents.return_pressure() - - if(pressure < lowpressure) - return 1 - - return 0// Not container or failed low pressure check - -/datum/cargoprofile/pressure/full - name = "full air tanks" - id = "pressure-high" - var/highpressure = ONE_ATMOSPHERE * 15 // stolen from canister.dm; Is this right? - - contains(var/atom/A) - if(..()) - var/pressure = 0 // In case of fallthrough, fail test - if(istype(A,/obj/item/tank)) - var/obj/item/tank/T = A - pressure = T.air_contents.return_pressure() - if(istype(A,/obj/item/flamethrower)) - var/obj/item/flamethrower/T = A - if(!T.ptank) - return 0 - pressure = T.ptank.air_contents.return_pressure() - if(istype(A,/obj/machinery/portable_atmospherics)) - var/obj/machinery/portable_atmospherics/P = A - pressure = P.air_contents.return_pressure() - - if(pressure > highpressure) - return 1 - - return 0// Not container or failed high pressure check - -/datum/cargoprofile/clothing - name = "Crew Kit" - id = "clothing" - blacklist = list(/obj/item/tank/plasma,/obj/item/tank/anesthetic, // the rest are air tanks - /obj/item/clothing/mask/facehugger) // NOT CLOTHING AT ALLLLL - whitelist = list(/obj/item/clothing,/obj/item/storage/belt,/obj/item/storage/backpack, - /obj/item/radio/headset,/obj/item/pda,/obj/item/card/id,/obj/item/tank, - /obj/item/restraints/handcuffs, /obj/item/restraints/legcuffs) - -/datum/cargoprofile/trash - name = "Trash" - id = "trash" - //Note that this filters out blueprints because they are a paper item. Do NOT throw out the station blueprints unless you be trollin'. - blacklist = null - whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/reagent_containers/food/snacks/ectoplasm,/obj/item/grown/bananapeel,/obj/item/broken_bottle,/obj/item/bikehorn, - /obj/item/cigbutt,/obj/item/poster/random_contraband,/obj/item/grown/corncob,/obj/item/paper,/obj/item/shard, - /obj/item/sord,/obj/item/photo,/obj/item/folder, - /obj/item/areaeditor/blueprints,/obj/item/poster/random_contraband,/obj/item/kitchen,/obj/item/book,/obj/item/clothing/mask/facehugger) - -/datum/cargoprofile/weapons - name = "Weapons & Illegals" - id = "weapons" - blacklist = null - //This one is hard since 'weapon contains a lot of things better categorized as devices - whitelist = list(/obj/item/banhammer,/obj/item/sord,/obj/item/claymore,/obj/item/holo/esword, - /obj/item/flamethrower,/obj/item/grenade,/obj/item/gun,/obj/item/hatchet,/obj/item/katana, - /obj/item/kitchen/knife,/obj/item/melee,/obj/item/nullrod,/obj/item/pickaxe,/obj/item/twohanded, - /obj/item/grenade/plastic/c4,/obj/item/scalpel,/obj/item/shield,/obj/item/grown/nettle/death) - -/datum/cargoprofile/tools - name = "Devices & Tools" - id = "tools" - blacklist = null - whitelist = list(/obj/item,/obj/item/card,/obj/item/cartridge,/obj/item/cautery,/obj/item/stock_parts/cell,/obj/item/circuitboard, - /obj/item/aiModule,/obj/item/airalarm_electronics,/obj/item/airlock_electronics,/obj/item/circular_saw, - /obj/item/crowbar,/obj/item/disk,/obj/item/firealarm_electronics,/obj/item/hand_tele, - /obj/item/hand_labeler,/obj/item/hemostat,/obj/item/mop,/obj/item/locator,/obj/item/cultivator, - /obj/item/stack/packageWrap,/obj/item/pen,/obj/item/pickaxe,/obj/item/pinpointer, - /obj/item/rcd,/obj/item/rcd_ammo,/obj/item/retractor,/obj/item/rsf,/obj/item/scalpel, - /obj/item/screwdriver,/obj/item/shovel,/obj/item/soap,/obj/item/stamp,/obj/item/storage/bag/tray,/obj/item/weldingtool, - /obj/item/wirecutters,/obj/item/wrench,/obj/item/extinguisher) - -/datum/cargoprofile/finished - name = "Completed Robots" - id = "finished" - blacklist = null - whitelist = list(/obj/mecha,/mob/living/simple_animal/bot,/mob/living/silicon/robot) - mobcheck = 1 - //todo: detect and allow finished cyborg endoskeletons with no brain - contains(var/atom/A) - if(..()) - return 1 - if(istype(A,/mob)) - if(blacklist) - for(var/T in blacklist) - if(istype(A,T)) - return 0 - if(whitelist) - for(var/T in whitelist) - if(istype(A,T)) - return 1 - return 0 - return 1 - return 0 - -/datum/cargoprofile/stripping - name = "Auto-Frisker" - id = "frisk" - blacklist = null - whitelist = list(/mob/living/carbon/human) - mobcheck = 1 - - - -//---------------------------------------------------------------------------- -// Overrides (Special Functions) -//---------------------------------------------------------------------------- - -/datum/cargoprofile/cargo/unload - name = "Unload Cargo Boxes" - id = "cargounload" - enabled = 0 - dedicated_path = /obj/machinery/programmable/unloader - - //override the detection to only accept crates with something in it. - //if it doesn't, this object may be handled by another handler. - contains(var/atom/A) - if(..(A)) - if(istype(A,/obj/structure/closet)) - var/obj/structure/closet/C = A - if(!C.can_open() && !C.opened && !master.emagged) // must be able to access the contents - return 0 - if(A.contents.len) - return 1 - return 0 - - //instead of moving the box, strip it of its contents - inlet_reaction(var/obj/W,var/turf/S, var/remaining) - //W should only be crate or ore box, although this will work on anything with contents... - var/I = 0 - if(istype(W,/obj/structure/closet)) - var/obj/structure/closet/C = W - if(!C.can_open() && !C.opened) // must be able to access the contents - if(master.emagged && remaining >= BIG_OBJECT_WORK) - if(prob(10)) - C.welded = 0 - if("broken" in C.vars) - C:broken = 1 - C.open() - C.update_icon() - master.visible_message("[master] breaks open [C]!") - else - master.visible_message("[master] is trying to force [C] open!") - - master.sleep += 1 // mechanical strain - return BIG_OBJECT_WORK - master.visible_message("[master] is trying to open [C], but can't!") - master.sleep = 5 - return 0 - - for(var/obj/item/O in W.contents) - if(I > remaining) - return - if(O.w_class > (remaining - I)) - continue - O.loc = master - master.types[O.type] = src - if(O.w_class > 0) - I += O.w_class - else - I++ - if(!W.contents.len && istype(W,/obj/structure/closet)) - var/obj/structure/closet/C = W - C.open() - return I - - -//Inlet stacker: used when the output is a volatile space (conveyor or another unit's input). -//Does not output a stack until it is full. -/datum/cargoprofile/in_stacker - name = "Hold and Stack" - id = "instacker" - universal = 1 - - blacklist = null - whitelist = list(/obj/item/stack,/obj/item/stack/cable_coil) - - dedicated_path = /obj/machinery/programmable/stacker - - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - if(istype(W,/obj/item/stack)) - var/obj/item/stack/I = W - if(!I.amount) // todo: am I making a bad assumption here? - qdel(I) - return - for(var/obj/item/stack/O in master.contents) - if(O.type == I.type && O.amount < O.max_amount) - if(I.amount + O.amount <= O.max_amount) - O.amount += I.amount - qdel(I) - return O.w_class - var/leftover = I.amount + O.amount - O.max_amount - O.amount = O.max_amount - I.amount = leftover - continue - //end for - I.loc = master - master.types[I.type] = src - return I.w_class - if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/I = W - if(!I.amount) // todo: am I making a bad assumption here? - qdel(I) - return - for(var/obj/item/stack/cable_coil/O in master.contents) - if(O.type == I.type && O.amount < MAXCOIL) - if(I.amount + O.amount <= MAXCOIL) - O.amount += I.amount - qdel(I) - return O.w_class - var/leftover = I.amount + O.amount - MAXCOIL - O.amount = MAXCOIL - I.amount = leftover - continue - //end for - I.loc = master - master.types[I.type] = src - return I.w_class - - //If the stack isn't finished yet, don't eject it - //unless this profile has been disabled. - outlet_reaction(var/atom/W,var/turf/D) - if(istype(W,/obj/item/stack)) - var/obj/item/stack/I = W - if(src.enabled && (I.amount < I.max_amount)) - return // Still needs to be stacked - ..(W,D) - if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/I = W - if(src.enabled && (I.amount < MAXCOIL)) - return // Still needs to be stacked - ..(W,D) - -//Outlet stacker: used when the output square can be trusted. -//Outputs immediately, adding to stacks in the outlet. -/datum/cargoprofile/unary/stacker - name = "Stack Items" - id = "ustacker" - blacklist = null - whitelist = list(/obj/item/stack,/obj/item/stack/cable_coil) - - dedicated_path = /obj/machinery/programmable/unary/stacker - - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - - //Only pick it up if you are going to stack it - - if(istype(W,/obj/item/stack)) - var/obj/item/stack/I = W - if(I.amount >= I.max_amount) - return 0 - for(var/obj/item/stack/other in S.contents) - if(other.type == I.type && other != I && other.amount < other.max_amount) - return ..(W,S,remaining) - return 0 - - if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/I = W - if(I.amount >= MAXCOIL) - return 0 - for(var/obj/item/stack/cable_coil/other in S.contents) - if(other != I && other.amount < MAXCOIL) - return ..(W,S,remaining) - return 0 - - outlet_reaction(var/atom/W,var/turf/D) - if(istype(W,/obj/item/stack)) - var/obj/item/stack/I = W - for(var/obj/item/stack/O in D.contents) - if(O.type == I.type && O.amount < O.max_amount) - if(I.amount + O.amount <= O.max_amount) - O.amount += I.amount - qdel(I) - return - var/leftover = I.amount + O.amount - O.max_amount - O.amount = O.max_amount - I.amount = leftover - continue - //end for - I.loc = D - return - if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/I = W - for(var/obj/item/stack/cable_coil/O in D.contents) - if(O.type == I.type && O.amount < MAXCOIL) - if(I.amount + O.amount <= MAXCOIL) // Why did they make it a #define. - O.amount += I.amount - O.update_icon() - qdel(I) - return - var/leftover = I.amount + O.amount - MAXCOIL // That wasn't a question - O.amount = MAXCOIL // It was a complaint - I.amount = leftover - continue - //end for - I.loc = D - return - - - -//---------------------------------------------------------------------------- -// Dubious Overrides (For emag use) -//---------------------------------------------------------------------------- - - -//Clogs up the unloader. And, there may be devious uses for it... -/datum/cargoprofile/slow - name = "Slow unloader" - id = "slow" - whitelist = list(/obj/item,/obj/structure/closet,/obj/structure/bigDelivery,/obj/machinery/portable_atmospherics) - blacklist = list() - - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - if(..()) - return remaining - -/datum/cargoprofile/unary/shredder - name = "Paper Shredder" - id = "shredder" - blacklist = null - whitelist = list(/obj/item/paper,/obj/item/book,/obj/item/clipboard,/obj/item/folder,/obj/item/photo) - universal = 1 - - dedicated_path = /obj/machinery/programmable/unary/shredder - - - - proc/cliptags(var/Text) - //Removes all html tags - var/index - var/index2 - index = findtextEx(Text,"<") - while(index) - index2 = findtextEx(Text,">",index) - if(!index2) - return copytext(Text,1,index) - Text = "[copytext(Text,1,index)][copytext(Text,index2+1,0)]" - index = findtextEx(Text,"<") - //should have trimmed that text there pretty good - return Text - - - //Recurses through the text, removing large chunks - proc/garbletext(var/Text) - var/l = length(Text) - if(l <= 3) - if(prob(20)) - return pick("#","|","/","*",".","."," ","."," "," ") - return Text - if(prob(50)) - return "[garbletext(copytext(Text,1,l/2))][garbletext(copytext(Text,l/2,0))]" - if(prob(50)) - return "[pick("#","|","/","*",".","."," ","."," "," ")][garbletext(copytext(Text,1,l/2))]" - return "[garbletext(copytext(Text,l/2,0))][pick("#","|","/","*",".","."," ","."," "," ")]" - - proc/garble_keeptags(var/Text) - var/list/L = splittext(Text,">") - var/result = "" - for(var/string in L) - var/index = findtextEx(string,"<") - if(index!=1) - result += "[garbletext(copytext(string,1,index))][copytext(string,index)]>" - else - result += "[string]>" - return copytext(result,1,lentext(result)) - - - - - outlet_reaction(var/atom/W,var/turf/D) - if(istype(W,/obj/item/paper/crumpled)) - qdel(W) - return - if(istype(W,/obj/item/clipboard) || istype(W,/obj/item/folder)) - // destroy folder, various effects on contents - for(var/obj/item/I in W.contents) - if(prob(25))//JUNK IT - qdel(I) - else if(prob(50)) //We've been over this. I can't just take it apart with a crowbar. - var/obj/item/paper/crumpled/P = new(master.loc) - if(I.name) - P.name = garbletext(I.name) - if(prob(66)) - P.fingerprints = I.fingerprints - P.fingerprintshidden = I.fingerprintshidden - if(istype(I,/obj/item/paper)) - var/obj/item/paper/O = I - P.info = garble_keeptags(O.info) - qdel(I) - ..(P,D) - else - ..(I,D) // Eject - qdel(W) //destroy container - return - if(prob(50)) //JUNK IT NOW! - var/obj/item/paper/crumpled/P = new(master.loc) - P.name = W.name - var/obj/item/I = W - if(prob(66)) - P.fingerprints = I.fingerprints - P.fingerprintshidden = I.fingerprintshidden - if(istype(I,/obj/item/paper)) - var/obj/item/paper/O = I - if(O.info) - P.info = garble_keeptags(O.info) - if(istype(I,/obj/item/book)) - var/obj/item/book/B = I - if(B.dat) - P.info = garble_keeptags(B.dat) - if(B.carved && B.store) - ..(B.store,D) - qdel(W) - ..(P,D) - else //I want it junked - qdel(W) - return - -/datum/cargoprofile/unary/gibber - name = "human shredding" - id = "flesh" - whitelist = list(/mob/living/carbon,/mob/living/simple_animal) - blacklist = null - mobcheck = 1 - contains(var/atom/A) - if(!istype(A,/mob)) - return - if(blacklist) - for(var/T in blacklist) - if(istype(A,T)) - return 0 - if(whitelist) - for(var/T in whitelist) - if(istype(A,T)) - return 1 - return 0 - return 1 - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - var/mob/living/M = W - if(istype(M) && (remaining > MOB_WORK)) - //this is necessarily damaging - var/damage = rand(1,5) - to_chat(M, "The unloading machine grabs you with a hard metallic claw!") - M.reset_perspective(master) - M.loc = master - master.types[M.type] = src - M.apply_damage(damage) // todo: ugly - M.visible_message("[M.name] gets pulled into the machine!") - return MOB_WORK - outlet_reaction(var/atom/W,var/turf/D) - var/mob/living/M = W - var/bruteloss = M.bruteloss - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/C = M - for(var/obj/item/organ/external/L in C.bodyparts) - bruteloss += L.brute_dam - if(bruteloss < 100) // requires tenderization - M.apply_damage(rand(5,15),BRUTE) - to_chat(M, "The machine is tearing you apart!") - master.visible_message("[master] makes a squishy grinding noise.") - return - M.loc = master.loc - M.gib() - return - - -/datum/cargoprofile/people - name = "Manhandling" - id = "people" - - whitelist = null - blacklist = list(/mob/camera,/mob/new_player,/mob/living/simple_animal/hostile/blob/blobspore,/mob/living/simple_animal/hostile/creature, - /mob/living/simple_animal/hostile/spaceWorm,/mob/living/simple_animal/shade,/mob/living/simple_animal/hostile/faithless,/mob/dead) - universal = 1 - mobcheck = 1 - - - contains(var/atom/A) - if(!istype(A,/mob)) - return - if(blacklist) - for(var/T in blacklist) - if(istype(A,T)) - return 0 - if(whitelist) - for(var/T in whitelist) - if(istype(A,T)) - return 1 - return 0 - return 1 - - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - var/mob/living/M = W - if(remaining > MOB_WORK) - //this is necessarily damaging - var/damage = rand(1,5) - to_chat(M, "The unloading machine grabs you with a hard metallic claw!") - M.forceMove(master) - master.types[M.type] = src - M.apply_damage(damage) // todo: ugly - M.visible_message("[M.name] gets pulled into the machine!") - return MOB_WORK - - outlet_reaction(var/atom/W,var/turf/D) - var/mob/living/M = W - M.forceMove(master.loc) - M.dir = master.outdir - - D = get_step(D,master.outdir) // throw attempt - eject_speed = rand(0,4) - - M.visible_message("[M.name] is ejected from the unloader.") - M.throw_at(D,eject_speed,eject_speed) - return - -/datum/cargoprofile/unary/trainer - name = "Boxing Trainer" - id = "trainer" - blacklist = list() - whitelist = list(/mob/living/carbon/human) - mobcheck = 1 - - var/const/PUNCH_WORK = 6 - - dedicated_path = /obj/machinery/programmable/unary/trainer - - contains(var/atom/A) - if(!istype(A,/mob)) - return 0 - if(blacklist) - for(var/T in blacklist) - if(istype(A,T)) - return 0 - if(whitelist) - for(var/T in whitelist) - if(istype(A,T)) - return 1 - return 0 - return 1 - - proc/punch(var/mob/living/carbon/human/M,var/maxpunches) - //stolen from holographic boxing gloves code - //This should probably be done BY the mob, however, the attack code will be expecting a source mob. - - var/damage - if(prob(75)) - damage = rand(0, 6) // pap - else - damage = rand(0, 12) // thwack - - if(!damage) - playsound(master.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - master.visible_message("\The [src] punched at [M], but whiffed!") - - if(maxpunches > 1 && prob(50)) // Follow through on a miss, 50% chance - return punch(M,maxpunches - 1) + 1 - return 1 - var/obj/item/organ/external/affecting = M.get_organ(ran_zone("chest",50)) - var/armor_block = M.run_armor_check(affecting, "melee") - - playsound(master.loc, "punch", 25, 1, -1) - master.visible_message("\The [src] has punched [M]!") - if(!master.emagged) - M.apply_damage(damage, STAMINA, affecting, armor_block) // Clean fight - else - M.apply_damage(damage, BRUTE, affecting, armor_block) // Foul! Foooul! - - if(damage >= 9) - master.visible_message("\The [src] has weakened [M]!") - M.apply_effect(4, WEAKEN, armor_block) - if(!master.emagged) - master.sleep = 1 - return maxpunches // The machine is not so sophisticated as to not gloat - else - if(prob(25)) // Follow through on a hit, 25% chance. Pause after. - return punch(M,maxpunches-1) + 1 - return 1 - - inlet_reaction(var/atom/W,var/turf/S,var/remaining) - //stolen from boxing gloves code - var/mob/living/carbon/human/M = W - if((M.lying || (M.health - M.staminaloss < 25))&& !master.emagged) - to_chat(M, "\The [src] gives you a break.") - master.sleep+=5 - return 0 // Be polite - var/punches = punch(M,remaining / PUNCH_WORK) - if(punches>1)master.sleep++ - return punches * PUNCH_WORK diff --git a/code/datums/computerfiles.dm b/code/datums/computerfiles.dm deleted file mode 100644 index 14cd7e38612..00000000000 --- a/code/datums/computerfiles.dm +++ /dev/null @@ -1,7 +0,0 @@ -datum - computer - var/name - folder - var/list/datum/computer/contents = list() - - file \ No newline at end of file diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 96c663fb703..1a22131d55f 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -255,7 +255,7 @@ var/record_id_num = 1001 if(PDA_Manifest.len) PDA_Manifest.Cut() - if(H.mind && (H.mind.assigned_role != "MODE")) + if(H.mind && (H.mind.assigned_role != H.mind.special_role)) var/assignment if(H.mind.role_alt_title) assignment = H.mind.role_alt_title diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 3e8c11cc1e8..ae9a6df5b4f 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -1,5 +1,6 @@ /datum var/gc_destroyed //Time when this object was destroyed. + var/list/active_timers //for SStimer var/list/datum_components //for /datum/components var/var_edited = FALSE //Warranty void if seal is broken @@ -16,6 +17,14 @@ /datum/proc/Destroy(force = FALSE, ...) tag = null + var/list/timers = active_timers + active_timers = null + for(var/thing in timers) + var/datum/timedevent/timer = thing + if(timer.spent) + continue + qdel(timer) + var/list/dc = datum_components if(dc) var/all_components = dc[/datum/component] diff --git a/code/datums/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/looping_sound.dm new file mode 100644 index 00000000000..2cf79ad318b --- /dev/null +++ b/code/datums/looping_sounds/looping_sound.dm @@ -0,0 +1,100 @@ +/* + output_atoms (list of atoms) The destination(s) for the sounds + + mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end. + mid_length (num) The length to wait between playing mid_sounds + + start_sound (soundfile) Played before starting the mid_sounds loop + start_length (num) How long to wait before starting the main loop after playing start_sound + + end_sound (soundfile) The sound played after the main loop has concluded + + chance (num) Chance per loop to play a mid_sound + volume (num) Sound output volume + muted (bool) Private. Used to stop the sound loop. + max_loops (num) The max amount of loops to run for. + direct (bool) If true plays directly to provided atoms instead of from them +*/ +/datum/looping_sound + var/list/atom/output_atoms + var/mid_sounds + var/mid_length + var/start_sound + var/start_length + var/end_sound + var/chance + var/volume = 100 + var/muted = TRUE + var/max_loops + var/direct + +/datum/looping_sound/New(list/_output_atoms = list(), start_immediately = FALSE, _direct = FALSE) + if(!mid_sounds) + WARNING("A looping sound datum was created without sounds to play.") + return + + output_atoms = _output_atoms + direct = _direct + + if(start_immediately) + start() + +/datum/looping_sound/Destroy() + stop() + output_atoms = null + return ..() + +/datum/looping_sound/proc/start(atom/add_thing) + if(add_thing) + output_atoms |= add_thing + if(!muted) + return + muted = FALSE + on_start() + +/datum/looping_sound/proc/stop(atom/remove_thing) + if(remove_thing) + output_atoms -= remove_thing + if(muted) + return + muted = TRUE + +/datum/looping_sound/proc/sound_loop(looped = 0) + if(muted || (max_loops && looped > max_loops)) + on_stop(looped) + return + if(!chance || prob(chance)) + play(get_sound(looped)) + addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length) + +/datum/looping_sound/proc/play(soundfile) + var/list/atoms_cache = output_atoms + var/sound/S = sound(soundfile) + if(direct) + S.channel = open_sound_channel() + S.volume = volume + for(var/i in 1 to atoms_cache.len) + var/atom/thing = atoms_cache[i] + if(direct) + SEND_SOUND(thing, S) + else + playsound(thing, S, volume) + +/datum/looping_sound/proc/get_sound(looped, _mid_sounds) + if(!_mid_sounds) + . = mid_sounds + else + . = _mid_sounds + while(!isfile(.) && !isnull(.)) + . = pickweight(.) + +/datum/looping_sound/proc/on_start() + var/start_wait = 0 + if(start_sound) + play(start_sound) + start_wait = start_length + addtimer(CALLBACK(src, .proc/sound_loop), start_wait) + +/datum/looping_sound/proc/on_stop(looped) + if(end_sound) + play(end_sound) \ No newline at end of file diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm new file mode 100644 index 00000000000..b1f5bdc6908 --- /dev/null +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -0,0 +1,7 @@ +/datum/looping_sound/showering + start_sound = 'sound/machines/shower/shower_start.ogg' + start_length = 2 + mid_sounds = list('sound/machines/shower/shower_mid1.ogg' = 1,'sound/machines/shower/shower_mid2.ogg' = 1,'sound/machines/shower/shower_mid3.ogg' = 1) + mid_length = 10 + end_sound = 'sound/machines/shower/shower_end.ogg' + volume = 20 \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 5fee7994a83..c4674c64f90 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -38,8 +38,8 @@ var/memory - var/assigned_role - var/special_role + var/assigned_role //assigned role is what job you're assigned to when you join the station. + var/special_role //special roles are typically reserved for antags or roles like ERT. If you want to avoid a character being automatically announced by the AI, on arrival (becuase they're an off station character or something); ensure that special_role and assigned_role are equal. var/list/restricted_roles = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. @@ -54,6 +54,7 @@ var/has_been_rev = 0//Tracks if this mind has been a rev or not var/miming = 0 // Mime's vow of silence + var/list/antag_datums var/speech_span // What span any body this mind has talks in. var/datum/faction/faction //associated faction var/datum/changeling/changeling //changeling holder @@ -72,17 +73,29 @@ var/brigged_since = -1 var/suicided = FALSE - New(var/key) - src.key = key - //put this here for easier tracking ingame var/datum/money_account/initial_account //zealot_master is a reference to the mob that converted them into a zealot (for ease of investigation and such) var/mob/living/carbon/human/zealot_master = null +/datum/mind/New(var/key) + src.key = key + + +/datum/mind/Destroy() + ticker.minds -= src + if(islist(antag_datums)) + for(var/i in antag_datums) + var/datum/antagonist/antag_datum = i + if(antag_datum.delete_on_mind_deletion) + qdel(i) + antag_datums = null + return ..() + /datum/mind/proc/transfer_to(mob/living/new_character) var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list + var/mob/living/old_current = current if(!istype(new_character)) log_runtime(EXCEPTION("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob."), src) if(current) //remove ourself from our old body's mind variable @@ -95,6 +108,9 @@ new_character.mind.current = null current = new_character //link ourself to our new body new_character.mind = src //and link our new body to ourself + for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body + var/datum/antagonist/A = a + A.on_body_transfer(old_current, current) transfer_antag_huds(hud_to_transfer) //inherit the antag HUD transfer_actions(new_character) @@ -525,8 +541,8 @@ new_objective = new objective_path new_objective.owner = src new_objective:target = new_target:mind - //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops. - new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]." + //Will display as special role if assigned mode is equal to special role.. Ninjas/commandos/nuke ops. + new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role == new_target:mind:special_role ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]." if("destroy") var/list/possible_targets = active_ais(1) @@ -726,7 +742,7 @@ if(src in ticker.mode.revolutionaries) ticker.mode.revolutionaries -= src ticker.mode.update_rev_icons_removed(src) - to_chat(current, "\red You have proven your devotion to revolution! You are a head revolutionary now!") + to_chat(current, "You have proven your devotion to revolution! You are a head revolutionary now!") else if(!(src in ticker.mode.head_revolutionaries)) to_chat(current, "You are a member of the revolutionaries' leadership now!") else @@ -1211,37 +1227,60 @@ message_admins("[key_name_admin(usr)] has announced [key_name_admin(current)]'s objectives") edit_memory() -/* -/datum/mind/proc/clear_memory(var/silent = 1) - var/datum/game_mode/current_mode = ticker.mode - // remove traitor uplinks - var/list/L = current.get_contents() - for(var/t in L) - if(istype(t, /obj/item/pda)) - if(t:uplink) qdel(t:uplink) - t:uplink = null - else if(istype(t, /obj/item/radio)) - if(t:traitorradio) qdel(t:traitorradio) - t:traitorradio = null - t:traitor_frequency = 0.0 - else if(istype(t, /obj/item/SWF_uplink) || istype(t, /obj/item/syndicate_uplink)) - if(t:origradio) - var/obj/item/radio/R = t:origradio - R.loc = current.loc - R.traitorradio = null - R.traitor_frequency = 0.0 - qdel(t) - // remove wizards spells - //If there are more special powers that need removal, they can be procced into here./N - current.spellremove(current) +// Datum antag mind procs +/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) + if(!datum_type_or_instance) + return + var/datum/antagonist/A + if(!ispath(datum_type_or_instance)) + A = datum_type_or_instance + if(!istype(A)) + return + else + A = new datum_type_or_instance() + //Choose snowflake variation if antagonist handles it + var/datum/antagonist/S = A.specialization(src) + if(S && S != A) + qdel(A) + A = S + if(!A.can_be_owned(src)) + qdel(A) + return + A.owner = src + LAZYADD(antag_datums, A) + A.create_team(team) + var/datum/team/antag_team = A.get_team() + if(antag_team) + antag_team.add_member(src) + A.on_gain() + return A - // clear memory - memory = "" - special_role = null +/datum/mind/proc/remove_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = has_antag_datum(datum_type) + if(A) + A.on_removal() + return TRUE -*/ + +/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. + for(var/a in antag_datums) + var/datum/antagonist/A = a + A.on_removal() + +/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) + if(!datum_type) + return + . = FALSE + for(var/a in antag_datums) + var/datum/antagonist/A = a + if(check_subtypes && istype(A, datum_type)) + return A + else if(A.type == datum_type) + return A /datum/mind/proc/find_syndicate_uplink() var/list/L = current.get_contents() @@ -1273,7 +1312,7 @@ else current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]" special_role = SPECIAL_ROLE_NUKEOPS - assigned_role = "MODE" + assigned_role = SPECIAL_ROLE_NUKEOPS to_chat(current, "You are a [syndicate_name()] agent!") ticker.mode.forge_syndicate_objectives(src) ticker.mode.greet_syndicate(src) @@ -1308,7 +1347,7 @@ if(!(src in ticker.mode.wizards)) ticker.mode.wizards += src special_role = SPECIAL_ROLE_WIZARD - assigned_role = "MODE" + assigned_role = SPECIAL_ROLE_WIZARD //ticker.mode.learn_basic_spells(current) if(!wizardstart.len) current.loc = pick(latejoin) @@ -1514,7 +1553,7 @@ var/datum/objective/protect/mindslave/MS = new MS.owner = src MS.target = missionary.mind - MS.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role=="MODE" ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]." + MS.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role == missionary.mind.special_role ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]." objectives += MS for(var/datum/objective/objective in objectives) to_chat(current, "Objective #1: [objective.explanation_text]") @@ -1538,8 +1577,7 @@ H.update_inv_w_uniform(0,0) add_attack_logs(missionary, current, "Converted to a zealot for [convert_duration/600] minutes") - addtimer(src, "remove_zealot", convert_duration, FALSE, jumpsuit) //deconverts after the timer expires - + addtimer(CALLBACK(src, .proc/remove_zealot, jumpsuit), convert_duration) //deconverts after the timer expires return 1 /datum/mind/proc/remove_zealot(obj/item/clothing/under/jumpsuit = null) diff --git a/code/datums/modules.dm b/code/datums/modules.dm deleted file mode 100644 index d01bded3254..00000000000 --- a/code/datums/modules.dm +++ /dev/null @@ -1,63 +0,0 @@ -// module datum. -// this is per-object instance, and shows the condition of the modules in the object -// actual modules needed is referenced through modulestypes and the object type - -/datum/module - var/status // bits set if working, 0 if broken - var/installed // bits set if installed, 0 if missing - -// moduletypes datum -// this is per-object type, and shows the modules needed for a type of object - -/datum/moduletypes - var/list/modcount = list() // assoc list of the count of modules for a type - - -var/list/modules = list( // global associative list -"/obj/machinery/power/apc" = "card_reader,power_control,id_auth,cell_power,cell_charge") - - -/datum/module/New(var/obj/O) - - var/type = O.type // the type of the creating object - - var/mneed = mods.inmodlist(type) // find if this type has modules defined - - if(!mneed) // not found in module list? - qdel(src) // delete self, thus ending proc - return - - var/needed = mods.getbitmask(type) // get a bitmask for the number of modules in this object - status = needed - installed = needed - -/datum/moduletypes/proc/addmod(var/type, var/modtextlist) - modules += type // index by type text - modules[type] = modtextlist - -/datum/moduletypes/proc/inmodlist(var/type) - return ("[type]" in modules) - -/datum/moduletypes/proc/getbitmask(var/type) - var/count = modcount["[type]"] - if(count) - return 2**count-1 - - var/modtext = modules["[type]"] - var/num = 1 - var/pos = 1 - - while(1) - pos = findtext(modtext, ",", pos, 0) - if(!pos) - break - else - pos++ - num++ - - modcount += "[type]" - modcount["[type]"] = num - - return 2**num-1 - - diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 525880ee314..9e4bba0515c 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -145,6 +145,7 @@ belt = /obj/item/gun/projectile/automatic/pistol/deagle/camo l_ear = /obj/item/radio/headset/syndicate/alt l_pocket = /obj/item/pinpointer/advpinpointer + r_pocket = null // stop them getting a radio uplink, they get an implant instead backpack_contents = list( /obj/item/storage/box/engineer = 1, @@ -158,7 +159,6 @@ id_icon = "commander" id_access = "Syndicate Operative Leader" - uplink_uses = 500 /datum/outfit/admin/syndicate/officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) . = ..() @@ -613,15 +613,16 @@ uniform = /obj/item/clothing/under/solgov/rep back = /obj/item/storage/backpack/satchel + glasses = /obj/item/clothing/glasses/hud/security/night gloves = /obj/item/clothing/gloves/color/white shoes = /obj/item/clothing/shoes/centcom - l_ear = /obj/item/radio/headset + l_ear = /obj/item/radio/headset/ert id = /obj/item/card/id/silver r_pocket = /obj/item/lighter/zippo/blue l_pocket = /obj/item/storage/fancy/cigarettes/cigpack_robustgold pda = /obj/item/pda backpack_contents = list( - /obj/item/storage/box/survival = 1, + /obj/item/storage/box/responseteam = 1, /obj/item/implanter/dust = 1, /obj/item/implanter/death_alarm = 1, ) @@ -633,25 +634,33 @@ var/obj/item/card/id/I = H.wear_id if(istype(I)) - apply_to_card(I, H, get_centcom_access("VIP Guest"), "Solar Federation Representative") + apply_to_card(I, H, get_all_accesses(), name, "lifetimeid") /datum/outfit/admin/solgov name = "Solar Federation Marine" uniform = /obj/item/clothing/under/solgov + suit = /obj/item/clothing/suit/armor/bulletproof back = /obj/item/storage/backpack/security + belt = /obj/item/storage/belt/military/assault head = /obj/item/clothing/head/soft/solgov + glasses = /obj/item/clothing/glasses/hud/security/night gloves = /obj/item/clothing/gloves/combat shoes = /obj/item/clothing/shoes/combat + l_ear = /obj/item/radio/headset/ert id = /obj/item/card/id l_hand = /obj/item/gun/projectile/automatic/ar + r_pocket = /obj/item/flashlight/seclite + pda = /obj/item/pda backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/kitchen/knife/combat = 1, + /obj/item/storage/box/responseteam = 1, /obj/item/ammo_box/magazine/m556 = 3, - /obj/item/clothing/shoes/magboots = 1 + /obj/item/clothing/shoes/magboots = 1, + /obj/item/gun/projectile/automatic/pistol/m1911 = 1, + /obj/item/ammo_box/magazine/m45 = 2 ) + var/is_tsf_lieutenant = FALSE /datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) @@ -659,9 +668,14 @@ if(visualsOnly) return + if(is_tsf_lieutenant) + H.real_name = "Lieutenant [pick(last_names)]" + else + H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]" + H.name = H.real_name var/obj/item/card/id/I = H.wear_id if(istype(I)) - apply_to_card(I, H, get_centcom_access("VIP Guest"), name) + apply_to_card(I, H, get_all_accesses(), name, "lifetimeid") /datum/outfit/admin/solgov/lieutenant name = "Solar Federation Lieutenant" @@ -670,14 +684,16 @@ head = /obj/item/clothing/head/soft/solgov/command back = /obj/item/storage/backpack/satchel l_hand = null - belt = /obj/item/gun/projectile/automatic/pistol/deagle + l_pocket = /obj/item/pinpointer/advpinpointer backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/kitchen/knife/combat = 1, + /obj/item/storage/box/responseteam = 1, /obj/item/melee/classic_baton/telescopic = 1, - /obj/item/ammo_box/magazine/m50 = 2, - /obj/item/clothing/shoes/magboots/advance = 1 + /obj/item/clothing/shoes/magboots/advance = 1, + /obj/item/gun/projectile/automatic/pistol/deagle = 1, + /obj/item/ammo_box/magazine/m50 = 2 ) + is_tsf_lieutenant = TRUE + /datum/outfit/admin/chrono name = "Chrono Legionnaire" diff --git a/code/datums/spells/emplosion.dm b/code/datums/spells/emplosion.dm index 1ba430ad27e..b2f0a228282 100644 --- a/code/datums/spells/emplosion.dm +++ b/code/datums/spells/emplosion.dm @@ -10,6 +10,6 @@ /obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) - empulse(target.loc, emp_heavy, emp_light) + empulse(target.loc, emp_heavy, emp_light, 1) - return \ No newline at end of file + return diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm index 43c3d3a61cd..6e3ead3849e 100644 --- a/code/datums/spells/ethereal_jaunt.dm +++ b/code/datums/spells/ethereal_jaunt.dm @@ -26,7 +26,7 @@ if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains to_chat(target, "You are somehow too bound to your current location to abandon it.") continue - addtimer(src, "do_jaunt", 0, FALSE, target) + INVOKE_ASYNC(src, .proc/do_jaunt, target) /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target) target.notransform = 1 diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 9a5bf86665c..750f7bfd70c 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1336,6 +1336,13 @@ var/list/uplink_items = list() item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate cost = 2 +/datum/uplink_item/badass/rapid + name = "Gloves of the North Star" + desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed." + reference = "RPGD" + item = /obj/item/clothing/gloves/fingerless/rapid + cost = 8 + /datum/uplink_item/badass/bundle name = "Syndicate Bundle" desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive." diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index c87b2b455e7..320cc137806 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -31,7 +31,7 @@ var/list/impacted_areas = list() //Areas to be affected by the weather, calculated when the weather begins var/target_z = MAIN_STATION //The z-level to affect var/list/protected_areas = list()//Areas that are protected and excluded from the affected areas. - + var/overlay_layer = 10 //Since it's above everything else, this is the layer used by default. 2 is below mobs and walls if you need to use that. var/aesthetic = FALSE //If the weather has no purpose other than looks var/immunity_type = "storm" //Used by mobs to prevent them from being affected by the weather @@ -70,7 +70,7 @@ to_chat(M, telegraph_message) if(telegraph_sound) M << sound(telegraph_sound) - addtimer(src, "start", telegraph_duration) + addtimer(CALLBACK(src, .proc/start), telegraph_duration) /datum/weather/proc/start() if(stage >= MAIN_STAGE) @@ -85,7 +85,7 @@ if(weather_sound) M << sound(weather_sound) weather_master.processing_weather |= src - addtimer(src, "wind_down", weather_duration) + addtimer(CALLBACK(src, .proc/wind_down), weather_duration) /datum/weather/proc/wind_down() if(stage >= WIND_DOWN_STAGE) @@ -100,7 +100,7 @@ if(end_sound) M << sound(end_sound) weather_master.processing_weather -= src - addtimer(src, "end", end_duration) + addtimer(CALLBACK(src, .proc/end), end_duration) /datum/weather/proc/end() if(stage == END_STAGE) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 83880039a73..8a9a108c7b3 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -42,10 +42,16 @@ power_equip = 0 //rastaf0 power_environ = 0 //rastaf0 - power_change() // all machines set to current power level, also updates lighting icon - blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor. +/area/Initialize() + ..() + return INITIALIZE_HINT_LATELOAD + +/area/LateInitialize() + . = ..() + power_change() // all machines set to current power level, also updates lighting icon + /area/proc/get_cameras() var/list/cameras = list() for(var/obj/machinery/camera/C in src) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d57199d5f91..19af319aa20 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -42,6 +42,62 @@ var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff. + var/initialized = FALSE + +/atom/New(loc, ...) + if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New() + _preloader.load(src) + . = ..() + attempt_init(...) + +// 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, ...) + var/do_initialize = SSatoms.initialized + if(do_initialize != INITIALIZATION_INSSATOMS) + args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD + if(SSatoms.InitAtom(src, args)) + // we were deleted + return + + +//Called after New if the map is being loaded. mapload = TRUE +//Called from base of New if the map is not being loaded. mapload = FALSE +//This base must be called or derivatives must set initialized to TRUE +//must not sleep +//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE +//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm + +//Note: the following functions don't call the base for optimization and must copypasta: +// /turf/Initialize +// /turf/open/space/Initialize + +/atom/proc/Initialize(mapload, ...) + if(initialized) + stack_trace("Warning: [src]([type]) initialized multiple times!") + initialized = TRUE + + if(light_power && light_range) + update_light() + + if(opacity && isturf(loc)) + var/turf/T = loc + T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. + + ComponentInitialize() + + return INITIALIZE_HINT_NORMAL + + +//called if Initialize returns INITIALIZE_HINT_LATELOAD +/atom/proc/LateInitialize() + return + +// Put your AddComponent() calls here +/atom/proc/ComponentInitialize() + return + + /atom/proc/onCentcom() var/turf/T = get_turf(src) if(!T) @@ -242,7 +298,7 @@ /atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). - addtimer(src, "hitby_react", 2, TRUE, AM) + addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) /atom/proc/hitby_react(atom/movable/AM) if(AM && isturf(AM.loc)) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 3fdc402bb8a..7ab561f0814 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -24,16 +24,19 @@ var/area/areaMaster - var/auto_init = 1 - /atom/movable/New() . = ..() areaMaster = get_area_master(src) - // If you're wondering what goofery this is, this is for things that need the environment - // around them set up - like `air_update_turf` and the like - if((ticker && ticker.current_state >= GAME_STATE_SETTING_UP)) - attempt_init() +/atom/movable/attempt_init() + if(ticker && ticker.current_state >= GAME_STATE_SETTING_UP) + var/turf/T = get_turf(src) + if(T && space_manager.is_zlevel_dirty(T.z)) + space_manager.postpone_init(T.z, src) + return + . = ..() + + /atom/movable/Destroy() if(loc) @@ -53,19 +56,6 @@ pulledby = null return ..() -// used to provide a good interface for the init delay system to step in -// and we don't need to call `get_turf` until the game's started -// at which point object creations are a fair toss more seldom -/atom/movable/proc/attempt_init() - var/turf/T = get_turf(src) - if(T && space_manager.is_zlevel_dirty(T.z)) - space_manager.postpone_init(T.z, src) - else if(auto_init) - initialize() - -/atom/movable/proc/initialize() - return - // Used in shuttle movement and AI eye stuff. // Primarily used to notify objects being moved by a shuttle/bluespace fuckup. /atom/movable/proc/setLoc(var/T, var/teleported=0) @@ -176,11 +166,11 @@ /mob/living/forceMove(atom/destination) if(buckled) - addtimer(src, "check_buckled", 1, TRUE) + addtimer(CALLBACK(src, .proc/check_buckled), 1, TIMER_UNIQUE) if(buckled_mob) - addtimer(buckled_mob, "check_buckled", 1, TRUE) + addtimer(CALLBACK(buckled_mob, .proc/check_buckled), 1, TIMER_UNIQUE) if(pulling) - addtimer(src, "check_pull", 1, TRUE) + addtimer(CALLBACK(src, .proc/check_pull), 1, TIMER_UNIQUE) . = ..() if(client) reset_perspective(destination) @@ -373,3 +363,70 @@ target.fingerprints += fingerprints target.fingerprintshidden += fingerprintshidden target.fingerprintslast = fingerprintslast + +/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) + if(!no_effect && (visual_effect_icon || used_item)) + do_item_attack_animation(A, visual_effect_icon, used_item) + + if(A == src) + return //don't do an animation if attacking self + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + var/final_pixel_y = initial(pixel_y) + if(end_pixel_y) + final_pixel_y = end_pixel_y + + var/direction = get_dir(src, A) + if(direction & NORTH) + pixel_y_diff = 8 + else if(direction & SOUTH) + pixel_y_diff = -8 + + if(direction & EAST) + pixel_x_diff = 8 + else if(direction & WEST) + pixel_x_diff = -8 + + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) + animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2) + +/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) + var/image/I + if(visual_effect_icon) + I = image('icons/effects/effects.dmi', A, visual_effect_icon, A.layer + 0.1) + else if(used_item) + I = image(used_item.icon, A, used_item.icon_state, A.layer + 0.1) + + // Scale the icon. + I.transform *= 0.75 + // The icon should not rotate. + I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + + // Set the direction of the icon animation. + var/direction = get_dir(src, A) + if(direction & NORTH) + I.pixel_y = -16 + else if(direction & SOUTH) + I.pixel_y = 16 + + if(direction & EAST) + I.pixel_x = -16 + else if(direction & WEST) + I.pixel_x = 16 + + if(!direction) // Attacked self?! + I.pixel_z = 16 + + if(!I) + return + + // Who can see the attack? + var/list/viewing = list() + for(var/mob/M in viewers(A)) + if(M.client && M.client.prefs.show_ghostitem_attack) + viewing |= M.client + + flick_overlay(I, viewing, 5) // 5 ticks/half a second + + // And animate the attack! + animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) \ No newline at end of file diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index c6dc0833afb..bae37c04c2c 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -62,7 +62,7 @@ factory.spores += src ..() -/mob/living/simple_animal/hostile/blob/blobspore/Life() +/mob/living/simple_animal/hostile/blob/blobspore/Life(seconds, times_fired) if(!is_zombie && isturf(src.loc)) for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 9dcb5b7e3eb..0e1fc7daa86 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -60,7 +60,7 @@ /obj/structure/blob/core/RegenHealth() return // Don't regen, we handle it in Life() -/obj/structure/blob/core/Life() +/obj/structure/blob/core/Life(seconds, times_fired) if(!overmind) create_overmind() else diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index 232511744ea..19ac320287a 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -28,7 +28,7 @@ processing_objects.Remove(src) return ..() -/obj/structure/blob/node/Life() +/obj/structure/blob/node/Life(seconds, times_fired) if(overmind) for(var/i = 1; i < 8; i += i) Pulse(5, i, overmind.blob_reagent_datum.color) diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 5da84fbc460..60ea94befb0 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -36,7 +36,7 @@ updateallghostimages() ..() -/mob/camera/blob/Life() +/mob/camera/blob/Life(seconds, times_fired) if(!blob_core) qdel(src) ..() diff --git a/code/game/gamemodes/changeling/powers/biodegrade.dm b/code/game/gamemodes/changeling/powers/biodegrade.dm index 5e4b0e7fa12..3103416b9e4 100644 --- a/code/game/gamemodes/changeling/powers/biodegrade.dm +++ b/code/game/gamemodes/changeling/powers/biodegrade.dm @@ -18,7 +18,7 @@ return FALSE user.visible_message("[user] vomits a glob of acid on \his [O]!", \ "We vomit acidic ooze onto our restraints!") - addtimer(src, "dissolve_handcuffs", 30, FALSE, user, O) + addtimer(CALLBACK(src, .proc/dissolve_handcuffs, user, O), 30) used = TRUE if(user.wear_suit && user.wear_suit.breakouttime && !used) @@ -27,7 +27,7 @@ return FALSE user.visible_message("[user] vomits a glob of acid across the front of \his [S]!", \ "We vomit acidic ooze onto our straight jacket!") - addtimer(src, "dissolve_straightjacket", 30, FALSE, user, S) + addtimer(CALLBACK(src, .proc/dissolve_straightjacket, user, S), 30) used = TRUE @@ -37,7 +37,7 @@ return FALSE C.visible_message("[C]'s hinges suddenly begin to melt and run!") to_chat(user, "We vomit acidic goop onto the interior of [C]!") - addtimer(src, "open_closet", 70, FALSE, user, C) + addtimer(CALLBACK(src, .proc/open_closet, user, C), 70) used = TRUE if(istype(user.loc, /obj/structure/spider/cocoon) && !used) @@ -46,7 +46,7 @@ return FALSE C.visible_message("[src] shifts and starts to fall apart!") to_chat(user, "We secrete acidic enzymes from our skin and begin melting our cocoon...") - addtimer(src, "dissolve_cocoon", 25, FALSE, user, C) //Very short because it's just webs + addtimer(CALLBACK(src, .proc/dissolve_cocoon, user, C), 25) //Very short because it's just webs used = TRUE if(used) diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm index 156e8ffb896..a166fd74502 100644 --- a/code/game/gamemodes/changeling/powers/fakedeath.dm +++ b/code/game/gamemodes/changeling/powers/fakedeath.dm @@ -17,7 +17,7 @@ user.status_flags |= FAKEDEATH //play dead user.update_canmove() - addtimer(src, "ready_to_regenerate", LING_FAKEDEATH_TIME, FALSE, user) + addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME) feedback_add_details("changeling_powers","FD") return 1 diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm index 08786b6d6db..56417ac4335 100644 --- a/code/game/gamemodes/changeling/powers/fleshmend.dm +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -31,7 +31,7 @@ by quick repeated use!") recent_uses++ - addtimer(src, "fleshmend", 0, FALSE, user) + INVOKE_ASYNC(src, .proc/fleshmend, user) feedback_add_details("changeling_powers","RR") return TRUE diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 4e084e8b720..8f0aa4d210f 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -278,7 +278,7 @@ C.visible_message("[src] impales [C] with [I]!", "[src] impales you with [I]!") C.apply_damage(I.force, BRUTE, "chest") - do_attack_animation(C) + do_item_attack_animation(C, used_item = I) add_blood(C) playsound(get_turf(src), I.hitsound, 75, 1) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 2bf4933e108..b79dc85c2d5 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -740,7 +740,7 @@ var/list/teleport_runes = list() to_chat(L, "You chant in unison and a colossal burst of energy knocks you backward!") L.Weaken(2) qdel(src) //delete before pulsing because it's a delay reee - empulse(E, 9*invokers.len, 12*invokers.len) // Scales now, from a single room to most of the station depending on # of chanters + empulse(E, 9*invokers.len, 12*invokers.len, 1) // Scales now, from a single room to most of the station depending on # of chanters //Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active. /obj/effect/rune/astral diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index e909a33410f..1268765708d 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -220,7 +220,7 @@ . = ..() user.visible_message("[user]'s hand flashes a bright blue!", \ "You speak the words of the talisman, emitting an EMP blast.") - empulse(src, 4, 8) + empulse(src, 4, 8, 1) //Rite of Disorientation: Stuns and inhibit speech on a single target for quite some time @@ -419,4 +419,4 @@ /obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user) user.visible_message("[user]'s shackles shatter in a discharge of dark magic!", \ "Your [src] shatters in a discharge of dark magic!") - . = ..() \ No newline at end of file + . = ..() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 4a2622c536d..702b59853dc 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -107,7 +107,7 @@ tries_left = 5 //reset our tries since we found a new chump //make sure we have chumps before we try misinforming them. if we don't make a note of it. if(!chumps.len) - log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.") + log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.") return 0 //we've got chumps! misinform them! for(var/mob/living/carbon/human/chump in chumps) @@ -493,31 +493,36 @@ proc/display_roundstart_logout_report() message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.") to_chat(M, "You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban.") -/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) - var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and" +/proc/printplayer(datum/mind/ply, fleecheck) + var/jobtext = "" + if(ply.assigned_role) + jobtext = " the [ply.assigned_role]" + var/text = "[ply.key] was [ply.name][jobtext] and" if(ply.current) if(ply.current.stat == DEAD) - text += " died" + text += " died" else - text += " survived" - if(fleecheck && !is_station_level(ply.current.z)) - text += " while fleeing the station" + text += " survived" + if(fleecheck) + var/turf/T = get_turf(ply.current) + if(!T || !is_station_level(T.z)) + text += " while fleeing the station" if(ply.current.real_name != ply.name) text += " as [ply.current.real_name]" else - text += " had their body destroyed" + text += " had their body destroyed" return text -/datum/game_mode/proc/printobjectives(datum/mind/ply) - var/text = "" +/proc/printobjectives(datum/mind/ply) + var/list/objective_parts = list() var/count = 1 for(var/datum/objective/objective in ply.objectives) if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success!" + objective_parts += "Objective #[count]: [objective.explanation_text] Success!" else - text += "
Objective #[count]: [objective.explanation_text] Fail." + objective_parts += "Objective #[count]: [objective.explanation_text] Fail." count++ - return text + return objective_parts.Join("
") /datum/game_mode/proc/generate_station_goals() var/list/possible = list() diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 8058ff6e5c9..0c609c818b4 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -368,7 +368,7 @@ var/round_start_time = 0 if(player && player.mind && player.mind.assigned_role) if(player.mind.assigned_role == "Captain") captainless=0 - if(player.mind.assigned_role != "MODE") + if(player.mind.assigned_role != player.mind.special_role) job_master.EquipRank(player, player.mind.assigned_role, 0) EquipCustomItems(player) if(captainless) diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 0693ca9b279..3b908952de7 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -51,7 +51,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' raider_num-- for(var/datum/mind/raider in raiders) - raider.assigned_role = "MODE" + raider.assigned_role = SPECIAL_ROLE_RAIDER raider.special_role = SPECIAL_ROLE_RAIDER ..() return 1 diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index 6cb2956d3ee..50b749a62a2 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -91,7 +91,7 @@ var/list/dudes = list() for(var/mob/living/carbon/human/man in player_list) if(!man.mind) continue - if(man.mind.assigned_role=="MODE") continue + if(man.mind.assigned_role == man.mind.special_role) continue dudes += man if(dudes.len==0) return null @@ -210,14 +210,14 @@ var/prob_right_job = rand(prob_correct_job_lower, prob_correct_job_higher) if(prob(prob_right_job)) if(correct_person) - if(correct_person:assigned_role=="MODE") + if(correct_person:assigned_role == correct_person:special_role) changeling_job = pick(joblist) else changeling_job = correct_person:assigned_role else changeling_job = pick(joblist) if(prob(prob_right_dude) && ticker.mode == "changeling") - if(correct_person:assigned_role=="MODE") + if(correct_person:assigned_role == correct_person:special_role) changeling_name = correct_person:current else changeling_name = src.pick_mob() diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 57ce00c92af..8f4b5dab95e 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -159,9 +159,8 @@ for(var/obj/machinery/door/D in airlocks) if(!is_station_level(D.z)) continue - spawn(0) - D.hostile_lockdown(src) - addtimer(D, "disable_lockdown", 900) + INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, src) + addtimer(CALLBACK(D, /obj/machinery/door.proc/disable_lockdown), 900) post_status("alert", "lockdown") diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index b54b18335ef..1c6dc7d3022 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -74,11 +74,11 @@ agent = preset_agent - scientist.assigned_role = "MODE" + scientist.assigned_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST scientist.special_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST log_game("[key_name(scientist)] has been selected as an abductor team [team_number] scientist.") - agent.assigned_role = "MODE" + agent.assigned_role = SPECIAL_ROLE_ABDUCTOR_AGENT agent.special_role = SPECIAL_ROLE_ABDUCTOR_AGENT log_game("[key_name(agent)] has been selected as an abductor team [team_number] agent.") diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm index 328981b2ab5..2d3bed1e0cf 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm @@ -5,19 +5,19 @@ /datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) if(!ishuman(user)) - return 0 + return FALSE if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(target_zone) if(!affected) - return 0 + return FALSE if(affected.status & ORGAN_ROBOT) - return 0 + return FALSE var/mob/living/carbon/human/H = user // You must either: Be of the abductor species, or contain an abductor implant if((H.get_species() == "Abductor" || (locate(/obj/item/implant/abductor) in H))) - return 1 - return 0 + return TRUE + return FALSE /datum/surgery_step/internal/extract_organ @@ -39,15 +39,19 @@ var/mob/living/carbon/human/AB = target if(NO_INTORGANS in AB.species.species_traits) user.visible_message("[user] prepares [target]'s [target_zone] for further dissection!", "You prepare [target]'s [target_zone] for further dissection.") - return 1 + return TRUE if(IC) user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].") user.put_in_hands(IC) IC.remove(target, special = 1) - return 1 + return TRUE else to_chat(user, "You don't find anything in [target]'s [target_zone]!") - return 1 + return TRUE + +/datum/surgery_step/internal/extract_organ/fail_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user]'s hand slips, failing to extract anything!", "Your hand slips, failing to extract anything!") + return FALSE /datum/surgery_step/internal/gland_insert name = "insert gland" @@ -63,7 +67,11 @@ user.drop_item() var/obj/item/organ/internal/heart/gland/gland = tool gland.insert(target, 2) - return 1 + return TRUE + +/datum/surgery_step/internal/gland_insert/fail_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user]'s hand slips, failing to insert the gland!", "Your hand slips, failing to insert the gland!") + return FALSE //IPC Gland Surgery// @@ -91,4 +99,4 @@ /datum/surgery_step/internal/extract_organ/synth name = "remove cell" - organ_types = list(/obj/item/organ/internal/cell) \ No newline at end of file + organ_types = list(/obj/item/organ/internal/cell) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm index b0b879a30ab..10cd5473279 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm @@ -27,7 +27,7 @@ var/obj/machinery/computer/camera_advanced/abductor/camera var/list/datum/icon_snapshot/disguises = list() -/obj/machinery/abductor/console/initialize() +/obj/machinery/abductor/console/Initialize() ..() Link_Abduction_Equipment() diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index e9a830e7ed6..00bf335c576 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -43,7 +43,8 @@ to_chat(B.host, "You feel the captive mind of [src] begin to resist your control.") var/delay = (rand(350,450) + B.host.brainloss) - addtimer(src, "return_control", delay, FALSE, B) + addtimer(CALLBACK(src, .proc/return_control, B), delay) + /mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B) if(!B || !B.controlling) @@ -243,7 +244,7 @@ to_chat(M, "Borer Communication from [B] ([ghost_follow_link(src, ghost=M)]): [input]") to_chat(src, "[B.truename] says: [input]") -/mob/living/simple_animal/borer/Life() +/mob/living/simple_animal/borer/Life(seconds, times_fired) ..() @@ -534,7 +535,7 @@ leaving = TRUE - addtimer(src, "let_go", 200) + addtimer(CALLBACK(src, .proc/let_go), 200) /mob/living/simple_animal/borer/proc/let_go() @@ -611,7 +612,7 @@ bonding = TRUE var/delay = 300+(host.getBrainLoss()*5) - addtimer(src, "assume_control", delay) + addtimer(CALLBACK(src, .proc/assume_control), delay) /mob/living/simple_animal/borer/proc/assume_control() if(!host || !src || controlling) diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 822bfc9ce29..68e8c16c5da 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -57,7 +57,7 @@ else holder.icon_state = "hudhealthy" -/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies +/mob/living/simple_animal/hostile/guardian/Life(seconds, times_fired) //Dies if the summoner dies ..() if(summoner) if(summoner.stat == DEAD) @@ -448,6 +448,14 @@ Support:Has two modes. Combat: Medium power attacks and damage resist. Healer: Attacks heal damage, but low damage resist and slow movemen. Can deploy a bluespace beacon and warp targets to it (including you) in either mode.

Explosive: High damage resist and medium power attack. Can turn any object into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered.
+
+ Assassin: Medium damage with no damage resistance, can enter stealth which massively increases the damage of the next attack causing it to ignore armour. +
+ Charger: Medium damage and defense, very fast and has a special charge attack which damages a target and knocks items out of their hands. +
+ Lightning: Applies lightning chains to any targets on attack with a link to your summoner, lightning chains will shock anyone nearby. +
+ Protector: You will become leashed to your holoparasite instead of them to you. Has two modes, a medium attack/defense mode and a protection mode which greatly reduces incoming damage to the holoparasite. "} /obj/item/paper/guardian/update_icon() diff --git a/code/game/gamemodes/miniantags/guardian/types/assassin.dm b/code/game/gamemodes/miniantags/guardian/types/assassin.dm index 426824f2e8c..5eb8c1b1cec 100644 --- a/code/game/gamemodes/miniantags/guardian/types/assassin.dm +++ b/code/game/gamemodes/miniantags/guardian/types/assassin.dm @@ -13,7 +13,7 @@ var/obj/screen/alert/canstealthalert var/obj/screen/alert/instealthalert -/mob/living/simple_animal/hostile/guardian/assassin/Life() +/mob/living/simple_animal/hostile/guardian/assassin/Life(seconds, times_fired) . = ..() updatestealthalert() if(loc == summoner && toggle) diff --git a/code/game/gamemodes/miniantags/guardian/types/charger.dm b/code/game/gamemodes/miniantags/guardian/types/charger.dm index abdc349f175..17ed569f256 100644 --- a/code/game/gamemodes/miniantags/guardian/types/charger.dm +++ b/code/game/gamemodes/miniantags/guardian/types/charger.dm @@ -6,7 +6,7 @@ ranged_cooldown_time = 40 speed = -1 damage_transfer = 0.6 - playstyle_string = "As a Charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding." + playstyle_string = "As a Charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding. (Click a tile to use your charge ability)" magic_fluff_string = "..And draw the Hunter, an alien master of rapid assault." tech_fluff_string = "Boot sequence complete. Charge modules loaded. Holoparasite swarm online." bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to deal damage." diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm index 2a9dc2d2c8e..61905f942d2 100644 --- a/code/game/gamemodes/miniantags/guardian/types/fire.dm +++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm @@ -13,7 +13,7 @@ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random." var/toggle = FALSE -/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies +/mob/living/simple_animal/hostile/guardian/fire/Life(seconds, times_fired) //Dies if the summoner dies ..() if(summoner) summoner.ExtinguishMob() diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm index d51e4cefd45..c679beac91a 100644 --- a/code/game/gamemodes/miniantags/guardian/types/healer.dm +++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm @@ -32,7 +32,7 @@ /mob/living/simple_animal/hostile/guardian/healer/New() ..() -/mob/living/simple_animal/hostile/guardian/healer/Life() +/mob/living/simple_animal/hostile/guardian/healer/Life(seconds, times_fired) ..() var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) diff --git a/code/game/gamemodes/miniantags/morph/morph_event.dm b/code/game/gamemodes/miniantags/morph/morph_event.dm index d9e26597a2b..ab875832451 100644 --- a/code/game/gamemodes/miniantags/morph/morph_event.dm +++ b/code/game/gamemodes/miniantags/morph/morph_event.dm @@ -19,7 +19,7 @@ return kill() var/mob/living/simple_animal/hostile/morph/S = new /mob/living/simple_animal/hostile/morph(pick(xeno_spawn)) player_mind.transfer_to(S) - player_mind.assigned_role = "Morph" + player_mind.assigned_role = SPECIAL_ROLE_MORPH player_mind.special_role = SPECIAL_ROLE_MORPH ticker.mode.traitors |= player_mind to_chat(S, S.playstyle_string) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 49380c57863..953e6e91762 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -54,7 +54,7 @@ var/image/ghostimage = null //Visible to ghost with darkness off -/mob/living/simple_animal/revenant/Life() +/mob/living/simple_animal/revenant/Life(seconds, times_fired) ..() if(revealed && essence <= 0) death() @@ -392,7 +392,7 @@ var/datum/mind/player_mind = new /datum/mind(key_of_revenant) player_mind.active = 1 player_mind.transfer_to(R) - player_mind.assigned_role = "revenant" + player_mind.assigned_role = SPECIAL_ROLE_REVENANT player_mind.special_role = SPECIAL_ROLE_REVENANT ticker.mode.traitors |= player_mind message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm index 859f863b03c..a70114d8f5e 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm @@ -43,7 +43,7 @@ return kill() var/mob/living/simple_animal/revenant/revvie = new /mob/living/simple_animal/revenant/(pick(spawn_locs)) player_mind.transfer_to(revvie) - player_mind.assigned_role = "revenant" + player_mind.assigned_role = SPECIAL_ROLE_REVENANT player_mind.special_role = SPECIAL_ROLE_REVENANT ticker.mode.traitors |= player_mind message_admins("[key_of_revenant] has been made into a revenant by an event.") diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 42827d27f59..aeb26f58822 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -82,7 +82,7 @@ to_chat(src, "Objective #[2]: [fluffObjective.explanation_text]") -/mob/living/simple_animal/slaughter/Life() +/mob/living/simple_animal/slaughter/Life(seconds, times_fired) ..() if(boost AIRLOCK_SECURITY_METAL) @@ -226,13 +226,11 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/loseMainPower() main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) if(main_power_lost_until > 0) - main_power_timer = addtimer(src, "regainMainPower", SecondsToTicks(60), 1) - + main_power_timer = addtimer(CALLBACK(src, .proc/regainMainPower), SecondsToTicks(60), TIMER_UNIQUE | TIMER_STOPPABLE) // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running if(backup_power_lost_until == -1 && !backupPowerCablesCut()) backup_power_lost_until = world.time + SecondsToTicks(10) - backup_power_timer = addtimer(src, "regainBackupPower", SecondsToTicks(10), 1) - + backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), SecondsToTicks(10), TIMER_UNIQUE | TIMER_STOPPABLE) // Disable electricity if required if(electrified_until && isAllPowerLoss()) electrify(0) @@ -240,7 +238,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/loseBackupPower() backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) if(backup_power_lost_until > 0) - backup_power_timer = addtimer(src, "regainBackupPower", SecondsToTicks(60), 1) + backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), SecondsToTicks(60), TIMER_UNIQUE | TIMER_STOPPABLE) // Disable electricity if required if(electrified_until && isAllPowerLoss()) @@ -288,8 +286,7 @@ About the new airlock wires panel: message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) if(duration != -1) - electrified_timer = addtimer(src, "electrify", SecondsToTicks(duration), 1, 0) - + electrified_timer = addtimer(CALLBACK(src, .proc/electrify, 0), SecondsToTicks(duration), TIMER_UNIQUE | TIMER_STOPPABLE) if(feedback && message) to_chat(usr, message) @@ -1080,8 +1077,7 @@ About the new airlock wires panel: // The `addtimer` system has the advantage of being cancelable if(autoclose) - autoclose_timer = addtimer(src, "autoclose", normalspeed ? auto_close_time : auto_close_time_dangerous, unique = 1) - + autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE) return TRUE /obj/machinery/door/airlock/close(forced=0, override = 0) @@ -1098,7 +1094,7 @@ About the new airlock wires panel: for(var/turf/turf in locs) for(var/atom/movable/M in turf) if(M.density && M != src) //something is blocking the door - addtimer(src, "autoclose", 60) + addtimer(CALLBACK(src, .proc/autoclose), 60) use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people if(forced) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 930a4a2c045..4199d5e8c20 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -39,8 +39,8 @@ if(command_completed(cur_command)) cur_command = null else - if(!(src in machine_processing)) - machine_processing += src + if(!isprocessing) + START_PROCESSING(SSmachines, src) /obj/machinery/door/airlock/proc/do_command(command) switch(command) @@ -132,7 +132,7 @@ frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -/obj/machinery/door/airlock/initialize() +/obj/machinery/door/airlock/Initialize() ..() if(frequency) set_frequency(frequency) @@ -207,7 +207,7 @@ frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -/obj/machinery/airlock_sensor/initialize() +/obj/machinery/airlock_sensor/Initialize() ..() set_frequency(frequency) @@ -275,7 +275,7 @@ frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -/obj/machinery/access_button/initialize() +/obj/machinery/access_button/Initialize() ..() set_frequency(frequency) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index bff4bda660d..8f5c1144686 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -150,13 +150,15 @@ /obj/machinery/door/airlock/uranium/New() ..() - addtimer(src, "radiate", event_step) + addtimer(CALLBACK(src, .proc/radiate), event_step) + /obj/machinery/door/airlock/uranium/proc/radiate() if(prob(50)) for(var/mob/living/L in range (3,src)) L.apply_effect(15,IRRADIATE,0) - addtimer(src, "radiate", event_step) + addtimer(CALLBACK(src, .proc/radiate), event_step) + /obj/machinery/door/airlock/uranium/glass opacity = 0 @@ -339,7 +341,7 @@ if(isElectrified()) if(shock(user, 75)) return - if(istype(C, /obj/item/detective_scanner) || istype(C, /obj/item/taperoll)) + if(istype(C, /obj/item/detective_scanner)) return if(istype(C, /obj/item/grenade/plastic/c4)) @@ -392,7 +394,7 @@ if(isElectrified()) if(shock(user, 75)) return - if(istype(C, /obj/item/detective_scanner) || istype(C, /obj/item/taperoll)) + if(istype(C, /obj/item/detective_scanner)) return add_fingerprint(user) diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index cdada603a9b..c2e12618d79 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -18,7 +18,7 @@ air_connection = null return ..() -/obj/machinery/door/airlock/alarmlock/initialize() +/obj/machinery/door/airlock/alarmlock/Initialize() ..() radio_controller.remove_object(src, air_frequency) air_connection = radio_controller.add_object(src, air_frequency, RADIO_TO_AIRALARM) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4d54c2e1e07..43156d2b484 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -73,7 +73,7 @@ return 1 -/obj/machinery/door_timer/initialize() +/obj/machinery/door_timer/Initialize() ..() Radio = new /obj/item/radio(src) @@ -152,8 +152,7 @@ // Set releasetime releasetime = world.timeofday + timetoset - if(!(src in machine_processing)) - machine_processing += src + START_PROCESSING(SSmachines, src) for(var/obj/machinery/door/window/brigdoor/door in targets) if(door.density) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 61a528ed93d..78949fa0e45 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -64,7 +64,7 @@ bound_width = world.icon_size bound_height = width * world.icon_size -/obj/machinery/door/initialize() +/obj/machinery/door/Initialize() air_update_turf(1) ..() @@ -279,7 +279,7 @@ // The `addtimer` system has the advantage of being cancelable if(autoclose) - autoclose_timer = addtimer(src, "autoclose", normalspeed ? auto_close_time : auto_close_time_dangerous, unique = 1) + autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE) return TRUE @@ -292,7 +292,7 @@ for(var/atom/movable/M in get_turf(src)) if(M.density && M != src) //something is blocking the door if(autoclose) - addtimer(src, "autoclose", 60) + addtimer(CALLBACK(src, .proc/autoclose), 60) return operating = TRUE diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index b20d99b2613..3f9e4f55a08 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -53,11 +53,38 @@ if(!hasPower()) open() -/obj/machinery/door/poddoor/multi_tile // Whoever wrote the old code for multi-tile spesspod doors needs to burn in hell. + // Whoever wrote the old code for multi-tile spesspod doors needs to burn in hell. - Unknown + // Wise words. - Bxil +/obj/machinery/door/poddoor/multi_tile name = "large pod door" layer = CLOSED_DOOR_LAYER closingLayer = CLOSED_DOOR_LAYER +/obj/machinery/door/poddoor/multi_tile/New() + . = ..() + apply_opacity_to_my_turfs(opacity) + +/obj/machinery/door/poddoor/multi_tile/open() + if(..()) + apply_opacity_to_my_turfs(opacity) + + +/obj/machinery/door/poddoor/multi_tile/close() + if(..()) + apply_opacity_to_my_turfs(opacity) + +/obj/machinery/door/poddoor/multi_tile/Destroy() + apply_opacity_to_my_turfs(0) + return ..() + +//Multi-tile poddoors don't turn invisible automatically, so we change the opacity of the turfs below instead one by one. +/obj/machinery/door/poddoor/multi_tile/proc/apply_opacity_to_my_turfs(var/new_opacity) + for(var/turf/T in locs) + T.opacity = new_opacity + T.has_opaque_atom = new_opacity + T.reconsider_lights() + update_freelook_sight() + /obj/machinery/door/poddoor/multi_tile/four_tile_ver/ icon = 'icons/obj/doors/1x4blast_vert.dmi' width = 4 diff --git a/code/game/machinery/doors/spacepod.dm b/code/game/machinery/doors/spacepod.dm index 93419b588f6..5aea5b477ed 100644 --- a/code/game/machinery/doors/spacepod.dm +++ b/code/game/machinery/doors/spacepod.dm @@ -7,7 +7,7 @@ anchored = 1 var/id = 1.0 -/obj/structure/spacepoddoor/initialize() +/obj/structure/spacepoddoor/Initialize() ..() air_update_turf(1) diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm index 3216c945106..bb47a4939ec 100644 --- a/code/game/machinery/dye_generator.dm +++ b/code/game/machinery/dye_generator.dm @@ -8,7 +8,7 @@ idle_power_usage = 40 var/dye_color = "#FFFFFF" -/obj/machinery/dye_generator/initialize() +/obj/machinery/dye_generator/Initialize() ..() power_change() diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 27ee0197514..5209003fc59 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -12,7 +12,7 @@ var/tag_shuttle_mech_sensor var/tag_secure = 0 -/obj/machinery/embedded_controller/radio/airlock/initialize() +/obj/machinery/embedded_controller/radio/airlock/Initialize() ..() program = new/datum/computer/file/embedded_program/airlock(src) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 08143524744..889263da2f8 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -54,7 +54,7 @@ var/datum/radio_frequency/radio_connection unacidable = 1 -/obj/machinery/embedded_controller/radio/initialize() +/obj/machinery/embedded_controller/radio/Initialize() ..() set_frequency(frequency) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 5428e03d4a8..8ac57a5cec6 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -48,7 +48,7 @@ cell.loc = loc cell.add_fingerprint(user) - cell.updateicon() + cell.update_icon() src.cell = null to_chat(user, "You remove the power cell") diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index f4a306d8bf2..d7a4a3e2b04 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -82,7 +82,7 @@ if(beaker) usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].") attached = target - machine_processing += src + START_PROCESSING(SSmachines, src) update_icon() else to_chat(usr, "There's nothing attached to the IV drip!") diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 9862d952244..343734804cb 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -44,7 +44,7 @@ src.on = src.area.lightswitch updateicon() -/obj/machinery/light_switch/initialize() +/obj/machinery/light_switch/Initialize() ..() set_frequency(frequency) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 34842a64b76..18fc505a49b 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -119,7 +119,7 @@ Class Procs: atom_say_verb = "beeps" var/speed_process = 0 // Process as fast as possible? -/obj/machinery/initialize() +/obj/machinery/Initialize() addAtProcessing() . = ..() power_change() @@ -128,24 +128,26 @@ Class Procs: if(use_power) myArea = get_area_master(src) if(!speed_process) - machine_processing += src + START_PROCESSING(SSmachines, src) else fast_processing += src + isprocessing = TRUE // all of these isprocessing = TRUE can be removed when the PS is dead // gotta go fast /obj/machinery/proc/makeSpeedProcess() if(speed_process) return speed_process = 1 - machine_processing -= src + STOP_PROCESSING(SSmachines, src) fast_processing += src + isprocessing = TRUE // gotta go slow /obj/machinery/proc/makeNormalProcess() if(!speed_process) return speed_process = 0 - machine_processing += src + START_PROCESSING(SSmachines, src) fast_processing -= src /obj/machinery/New() //new @@ -158,7 +160,7 @@ Class Procs: if(myArea) myArea = null fast_processing -= src - machine_processing -= src + STOP_PROCESSING(SSmachines, src) machines -= src return ..() @@ -309,7 +311,7 @@ Class Procs: re_init=1 if(re_init) - initialize() + Initialize() if(update_mt_menu) //usr.set_machine(src) update_multitool_menu(usr) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 422e697e7b0..491cb93018e 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -306,21 +306,21 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(FC.channel_name == channel_name) check = 1 break - if(channel_name == "" || channel_name == REDACTED || scanned_user == "Unknown" || check || (scanned_user in existing_authors)) - temp = "ERROR: Could not submit feed channel to Network." - temp_back_screen = NEWSCASTER_CREATE_FC - else - var/choice = alert("Please confirm feed channel creation", "Network Channel Handler", "Confirm", "Cancel") - if(choice == "Confirm") + var/choice = alert("Please confirm feed channel creation", "Network Channel Handler", "Confirm", "Cancel") + if(choice == "Confirm") + if(channel_name == "" || channel_name == REDACTED || scanned_user == "Unknown" || check || (scanned_user in existing_authors)) + temp = "ERROR: Could not submit feed channel to Network." + temp_back_screen = NEWSCASTER_CREATE_FC + else var/datum/feed_channel/newChannel = new /datum/feed_channel newChannel.channel_name = channel_name newChannel.author = scanned_user @@ -422,19 +422,19 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co else if(href_list["submit_wanted"]) var/input_param = text2num(href_list["submit_wanted"]) - if(msg == "" || channel_name == "" || scanned_user == "Unknown") - temp = "ERROR: Wanted issue rejected by Network." - temp_back_screen = NEWSCASTER_MAIN - else - var/choice = alert("Please confirm wanted issue [input_param == 1 ? "creation." : "edit."]", "Network Security Handler", "Confirm", "Cancel") - if(choice == "Confirm") + var/choice = alert("Please confirm wanted issue [input_param == 1 ? "creation." : "edit."]", "Network Security Handler", "Confirm", "Cancel") + if(choice == "Confirm") + if(msg == "" || channel_name == "" || scanned_user == "Unknown") + temp = "ERROR: Wanted issue rejected by Network." + temp_back_screen = NEWSCASTER_MAIN + else if(input_param == 1) //input_param == 1: new wanted issue, input_param == 2: editing an existing one var/datum/feed_message/W = new /datum/feed_message W.author = channel_name diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm deleted file mode 100644 index 310d1798a09..00000000000 --- a/code/game/machinery/programmable_unloader.dm +++ /dev/null @@ -1,734 +0,0 @@ - -// TODO: Check access -// TODO: Renameable circuit boards -// TODO: Disks? Disassembly? - -/obj/machinery/programmable - name = "Programmable Unloader" - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "unloader" - density = 1 - anchored = 1.0 - - var/debug = 0 // When set, this WILL spam people around the machine. - // Identifies profile used and on which item. - - var/on = 1 - var/indir = 8 - var/outdir = 4 - var/turf/input = null - var/turf/output = null - var/typename = "Unloader" - var/ident = "#1" - - var/const/workmax = 20 - var/datum/cargoprofile/default = new() - var/list/profiles = list(new/datum/cargoprofile/cargo(),new/datum/cargoprofile/boxes(),new/datum/cargoprofile/supplies(), - new/datum/cargoprofile/exotics(),new/datum/cargoprofile/tools(),new/datum/cargoprofile/weapons(), - new/datum/cargoprofile/pressure(),new/datum/cargoprofile/chemical(), - new/datum/cargoprofile/food(),new/datum/cargoprofile/clothing(),new/datum/cargoprofile/trash()) - var/list/overrides = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/in_stacker()) - var/list/emag_overrides = list(new/datum/cargoprofile/people(),new/datum/cargoprofile/unary/shredder(),new/datum/cargoprofile/unary/trainer()) - var/list/types = list() - - anchored = 1 - var/unwrenched = 0 - use_power = 1 - var/sleep = 0 // When set, the machine will skip the next however-many updates (to avoid spam) - var/open = 0 - var/circuit_removed = 0 - - - -/obj/machinery/programmable/New() - ..() - if(default) - default.master = src - if(!default.enabled) - default.enabled = 1 - for(var/datum/cargoprofile/p in emag_overrides + overrides + profiles) - p.master = src - input = get_step(src.loc,indir) - output = get_step(src.loc,outdir) - var/count = 0 - for(var/obj/machinery/programmable/other in world) - if(other.typename == typename) - count++ - ident = "#[count]" - name = "[typename] [ident]" - -/obj/machinery/programmable/RefreshParts() - //This is called when the machine was constructed. - //Unfortunately, it puts machine parts in our contents list, which we're using. - //Fortunately, we aren't likely to ever need the components list, circuitboard excepted. - - for(var/obj/O in contents) - if(istype(O,/obj/item/circuitboard/programmable))//retrieve settings here - - var/obj/item/circuitboard/programmable/C = O - - default = C.default - emagged = C.emagged - profiles = C.profiles - overrides = C.overrides - emag_overrides = C.emag_overrides - - //unary and binary methods (one vs two locales) don't mix - - if(istype(src,/obj/machinery/programmable/unary)) - for(var/datum/cargoprofile/P in profiles) - if(!istype(P,/datum/cargoprofile/unary) && !P.universal) - profiles -= P - for(var/datum/cargoprofile/P in overrides) - if(!istype(P,/datum/cargoprofile/unary) && !P.universal) - overrides -= P - for(var/datum/cargoprofile/P in emag_overrides) - if(!istype(P,/datum/cargoprofile/unary) && !P.universal) - emag_overrides -= P - else - for(var/datum/cargoprofile/P in profiles) - if(istype(P,/datum/cargoprofile/unary) && !P.universal) - profiles -= P - for(var/datum/cargoprofile/P in overrides) - if(istype(P,/datum/cargoprofile/unary) && !P.universal) - overrides -= P - for(var/datum/cargoprofile/P in emag_overrides) - if(istype(P,/datum/cargoprofile/unary) && !P.universal) - emag_overrides -= P - if(default) - default.master = src - for(var/datum/cargoprofile/p in emag_overrides + overrides + profiles) - p.master = src - - qdel(C) - else - qdel(O) - -/obj/machinery/programmable/attack_hand(mob/user as mob) - if(stat) // moved, or something else - return - usr.set_machine(src) - interact(user) - -/obj/machinery/programmable/proc/printlist(var/list/L) - var/dat - for(var/datum/cargoprofile/p in L) - dat += "[p.name]: [p.enabled?"YES":"NO"]
" - return dat - -/obj/machinery/programmable/proc/buildMenu() - var/dat - dat += "PROGRAMMABLE UNLOADER
" - dat += "POWER: [on ? "ON" : "OFF"]
" - dat += "INLET: [capitalize(dir2text(indir))] " - dat += "OUTLET: [capitalize(dir2text(outdir))]" - dat += " (SWAP)

" - if(default) - dat += "MAIN PROGRAM: " - dat += "[default.name]: [default.enabled ? "YES" : "NO"]
" - if(profiles.len) - if(!default || !default.enabled) - dat += printlist(profiles) - dat += "
" - if(overrides.len) - dat += "
OVERRIDES:
" - dat += printlist(overrides) - dat += "" - return dat - -/obj/machinery/programmable/interact(mob/user as mob) - var/dat = buildMenu() - user << browse("Unloader[dat]", "window=progreload") - onclose(user, "progreload") - return - -/obj/machinery/programmable/Topic(href, href_list) - if(..()) - return 1 - usr.set_machine(src) - add_fingerprint(usr) - switch(href_list["operation"]) - if("start") - on = (on ? 0 : 1) - if(on) use_power = 1 - else use_power = 0 - updateUsrDialog() - return - if("inlet") - indir *= 2 // N S E W - if(indir > 8) - indir = 1 // W N - if(indir == src.outdir) - indir *= 2 - if(indir > 8) - indir = 1 - input = get_step(src,indir) // todo: check for glasswalls / no path to target? - updateUsrDialog() - return - if("outlet") - outdir *= 2 - if(outdir > 8) - outdir = 1 - if(outdir == indir) - outdir *= 2 - if(outdir > 8) - outdir = 1 - output = get_step(src,outdir) // todo: check for walls / glasswalls / invalid output locations - updateUsrDialog() - return - if("swapdir") - var/temp = outdir - outdir = indir - indir = temp - input = get_step(src,indir) - output = get_step(src,outdir) - updateUsrDialog() - return - if("default") - default.enabled = (default.enabled ? 0 : 1) - updateUsrDialog() - return - var/which = href_list["operation"] - for(var/datum/cargoprofile/p in overrides + profiles) - if(which == p.id) - p.enabled = (p.enabled? 0 : 1) - updateUsrDialog() - return - -/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I,/obj/item/wrench)) // code borrowed from pipe dispenser - if(unwrenched==0) - playsound(src.loc, I.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src] from the floor...") - if(do_after(user, 40 * I.toolspeed, target = src)) - user.visible_message( \ - "[user] unfastens \the [src].", \ - "You have unfastened \the [src]. Now it can be pulled somewhere else.", \ - "You hear ratchet.") - src.anchored = 0 - src.stat |= MAINT - src.unwrenched = 1 - if(usr.machine==src) - usr << browse(null, "window=pipedispenser") - else /* unwrenched */ - playsound(src.loc, I.usesound, 50, 1) - to_chat(user, "You begin to fasten \the [src] to the floor...") - if(do_after(user, 20 * I.toolspeed, target = src)) - user.visible_message( \ - "[user] fastens \the [src].", \ - "You fastened \the [src] into place.", \ - "You hear ratchet.") - src.anchored = 1 - src.input = get_step(src.loc,src.indir) - src.output = get_step(src.loc,src.outdir) - if(!open && !circuit_removed) - src.stat &= ~MAINT - src.unwrenched = 0 - power_change() - if(istype(I,/obj/item/screwdriver)) - if(open) - open = 0 - if(!unwrenched && !circuit_removed) - src.stat &= ~MAINT - to_chat(user, "You close \the [src]'s maintenance panel.") - else - open = 1 - src.stat |= MAINT - to_chat(user, "You open \the [src]'s maintenance panel.") - if(istype(I,/obj/item/crowbar)) - if(open) - to_chat(user, "You begin to pry out the [src]'s circuits.") - if(do_after(user, 40 * I.toolspeed, target = src)) - to_chat(user, "You remove the circuitboard.") - playsound(loc, I.usesound, 50, 1) - circuit_removed = 1 - use_power = 0 - on = 0 - - var/obj/item/circuitboard/programmable/P = new(src.loc) - P.emagged = src.emagged - P.default = src.default - src.default = null - P.profiles = src.profiles - src.profiles = null - P.overrides = src.overrides - src.overrides = null - P.emag_overrides = src.emag_overrides - src.emag_overrides = null - default_deconstruction_crowbar(I, 1) - return - else - ..(I,user) - - if(istype(I,/obj/item/circuitboard/programmable)) - if(!open) - to_chat(user, "You have to open the machine first!") - return - if(!circuit_removed) - to_chat(user, "There is already a circuitboard present!") - return - circuit_removed = 0 - I.loc = src - RefreshParts() - -/obj/machinery/programmable/emag_act(user as mob) - if(emagged) - return - to_chat(user, "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion.") - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - emagged = 1 - overrides += emag_overrides - - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(2, 1, src) - s.start() - return - -/obj/machinery/programmable/process() - if(!output || !input) - return - - if(!on || stat || sleep) - if(sleep > 0) // prevent input or output errors from happening every tick - sleep-- - use_power = 0 - - //Do not let things get stuck inside. That's broken behavior. - for(var/obj/O in contents) - O.loc = loc - for(var/mob/M in contents) - M.loc = loc - M.reset_perspective(null) - to_chat(M, "The machine turns off, and you fall out.") - - return - - //Normal output reaction - if(contents.len) - for(var/atom/movable/A in contents) - var/datum/cargoprofile/p = types[A.type] - if(p) - p.outlet_reaction(A,output) - else - A.loc = output // may have been dropped by a mob, etc - - if(types.len > 50) - types = list() // good luck mr. garbage collector - - - var/work = 0 - for(var/mob/M in input.contents) - for(var/datum/cargoprofile/p in overrides + default) - if(p.enabled && p.mobcheck && p.contains(M)) - var/done = p.inlet_reaction(M,input,workmax - work) - if(done) - work += done - if(src.debug) - visible_message("[p.name]:[M.name] ([done])") - break - - if(sleep) - return // something stopped the machine - - for(var/obj/A in input.contents)// I fully expect this to cause unreasonable lag - if(!A) - break - if(work > workmax) - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) // Beep if the machine is full - testing only probably - break - - var/done = 0 // work done - testing only - var/aname // target item name - testing only - - for(var/datum/cargoprofile/p in overrides) - if(p.enabled && p.contains(A)) - aname = A.name // in case of deletion - done = p.inlet_reaction(A,input,workmax - work) - if(done) - work += done - if(src.debug) - visible_message("[p.name]:[aname] ([done])") - - else - break - if(sleep) - break // Something stopped the machine - if(!A || A.loc != input || done) - continue // next item - - if(default && default.enabled) - if(default.contains(A)) - aname = A.name - done = default.inlet_reaction(A,input,workmax - work) - if(done) - work += done - if(src.debug) - visible_message("[default.name]: [aname] ([done])") - continue - for(var/datum/cargoprofile/p in profiles) - if(p.enabled && p.contains(A)) - aname = A.name - done = p.inlet_reaction(A,input,workmax - work) - if(done) - work += done - if(src.debug) - visible_message("[p.name]:[aname] ([done])") - else - break - if(work) - use_power = 2 - else - use_power = 1 -//---------------------------------------------------------------------------- -// Specialty machines -//---------------------------------------------------------------------------- - -//Uses the inlet stacking profile. Ejects only full stacks. -/obj/machinery/programmable/stacker - name = "Stacking & Spooling Machine" - default = new/datum/cargoprofile/in_stacker() - profiles = list() - overrides = list() - emag_overrides = list() - typename = "Stacking and Spooling Machine" - - -/obj/machinery/programmable/unloader - name = "Cargo Unloader" - default = new/datum/cargoprofile/cargo/unload() - profiles = list() - overrides = list() - emag_overrides = list() - typename = "Cargo Unloader" - -/obj/machinery/programmable/delivery - name = "Finished robot delivery" - default = new/datum/cargoprofile/finished() - profiles = list() - overrides = list() - emag_overrides = list() - typename = "Robot Delivery" - -/obj/machinery/programmable/crate_handler - name = "Crate Handler" - default = null - profiles = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/cargo(),new/datum/cargoprofile/cargo/empty(),new/datum/cargoprofile/cargo/full()) - overrides = list() - emag_overrides = list() - typename = "Crate Handler" - -//---------------------------------------------------------------------------- -// Unary machine: Input and output in the same location -// Be careful with this, it could easily be running the same -// computations every round needlessly -//---------------------------------------------------------------------------- -/obj/machinery/programmable/unary - name = "Programmable Processor" - default = null - profiles = list() - overrides = list(new/datum/cargoprofile/unary/stacker(),new/datum/cargoprofile/unary/trainer()) - emag_overrides = list(new/datum/cargoprofile/unary/shredder()) - indir = 1 - outdir = 1 - typename = "Processor" - - New() - ..() - outdir = indir - output = input - buildMenu() - var/dat - dat += "PROGRAMMABLE PROCESSOR
" - dat += "POWER: [on ? "ON" : "OFF"]
" - dat += "INLET: [capitalize(dir2text(indir))]
" - if(default) - dat += "MAIN PROGRAM: " - dat += "[default.name]: [default.enabled ? "YES" : "NO"]
" - if(profiles.len) - if(!default || !default.enabled) - dat += printlist(profiles) - dat += "
" - if(overrides.len) - dat += "
OVERRIDES:
" - dat += printlist(overrides) - dat += "" - return dat - Topic(href, href_list) - switch(href_list["operation"]) - if("inlet") - indir *= 2 // N S E W - if(indir > 8) - indir = 1 // W N - outdir = indir - input = get_step(src,indir) // todo: check for glasswalls / no path to target? - output = input - updateUsrDialog() - return - return ..() - -/obj/machinery/programmable/unary/stacker - name = "Stacking Machine" - default = new/datum/cargoprofile/unary/stacker() - profiles = list() - overrides = list() - emag_overrides = list() - typename = "Stacking Machine" - -/obj/machinery/programmable/unary/shredder - name = "Paper Shredder" - default = new/datum/cargoprofile/unary/shredder() - profiles = list() - overrides = list() - emag_overrides = list(new/datum/cargoprofile/unary/gibber()) - typename = "Paper Shredder" - -/obj/machinery/programmable/unary/trainer - name = "\improper Boxing Trainer" - default = new/datum/cargoprofile/unary/trainer() - profiles = list() - overrides = list() - emag_overrides = list() - typename = "Boxing Trainer" - - attack_hand(mob/user as mob) //How did I type this with boxing gloves on? - if(!istype(user,/mob/living/carbon/human)) - return ..() - - var/mob/living/carbon/human/H = user - if(H.gloves && istype(H.gloves, /obj/item/clothing/gloves/boxing)) - var/newsleep = 0 - if(H.loc != input) - to_chat(H, "The boxing machine refuses to acknowledge you unless you face it head on!") - return - var/damage = 0 - if(H.a_intent != INTENT_HARM) - damage += rand(0,5) - else - damage += rand(0,10) - if(!damage) - playsound(H.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[H] tries to punch \the [src], but whiffs") - return - - playsound(loc, "punch", 25, 1, -1) - if(HULK in H.mutations) damage += 5 - - if(damage < 5) - visible_message("[H] gives \the [src] a weak punch.") - if(prob(10)) - visible_message("\The [src] feints at [H], as though mocking \him.") - else if(damage < 10) - visible_message("[H] hits \the [src] with a solid [pick("punch","jab","smack")].") - else if(damage < 15) - visible_message("[pick("Whoa!","Nice!","Gasp!")] [H] hits [src] with a powerful [pick("punch","jab","uppercut","left hook", "right hook")].") - else if(damage < 20) - visible_message("[pick("WHOA!","ACK!","Jeez!")] [H] hits [src] so hard, the whole machine rocks band and forth for a moment.") - else - visible_message("Holy moly! [H] hits \the [src] so hard it stops working.") - stat |= BROKEN - return - while(damage >= 5) - if(prob(50)) - newsleep++ - damage -= 5 - if(newsleep) - if(emagged) - visible_message("\The [src]'s lights glow a bloodthirsty red. It refuses to stop!") - sleep = 0 - else - sleep += newsleep - visible_message("\The [src]'s lights dim for a moment and it beeps, signifying a valid hit.") - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - return - - else - return ..() - -//---------------------------------------------------------------------------- -// For construction -//---------------------------------------------------------------------------- -/obj/item/circuitboard/programmable - name = "Circuit board (Programmable Unloader)" - build_path = "/obj/machinery/programmable" - board_type = "machine" - origin_tech = "engineering=1;programming=2" - frame_desc = "Requires 2 Manipulators, 1 Scanning Module, 1 Cable." - req_components = list( - /obj/item/stock_parts/scanning_module = 1, - /obj/item/stock_parts/manipulator = 2, - /obj/item/stack/cable_coil = 1) - - //Customization of the machine - var/datum/cargoprofile/default = new/datum/cargoprofile() - var/list/profiles = list() - var/list/overrides = list() - var/list/emag_overrides = list() - - var/emagged = 0 - var/hacking = 0 - - proc/resetlists() - profiles = list(new/datum/cargoprofile/cargo(),new/datum/cargoprofile/boxes(),new/datum/cargoprofile/supplies(), - new/datum/cargoprofile/exotics(),new/datum/cargoprofile/tools(),new/datum/cargoprofile/weapons(),new/datum/cargoprofile/finished(), - new/datum/cargoprofile/pressure(),new/datum/cargoprofile/pressure/full(),new/datum/cargoprofile/pressure/empty(), - new/datum/cargoprofile/chemical(),new/datum/cargoprofile/organics(),new/datum/cargoprofile/food(), - new/datum/cargoprofile/clothing(),new/datum/cargoprofile/trash()) - overrides = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/in_stacker(), - new/datum/cargoprofile/unary/stacker(),new/datum/cargoprofile/unary/trainer()) - emag_overrides = list(new/datum/cargoprofile/people(),new/datum/cargoprofile/unary/shredder()) - - New() - ..() - resetlists() - - attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I,/obj/item/multitool)) - hacking = (hacking?0:1) - if(hacking) - to_chat(user, "You unlock the data port on the board. You can now use a PDA to alter its data.") - else - to_chat(user, "You relock the data port.") - if(istype(I,/obj/item/pda)) - if(!hacking) - to_chat(user, "It looks like you can't access the board's data port. You'll have to open it with a multitool.") - else - user.set_machine(src) - interact(user) - if(istype(I,/obj/item/card/emag) && !emagged) - if(!hacking) - to_chat(user, "There seems to be a data port on the card, but it's locked. A multitool could open it.") - else - emagged = 1 - overrides += emag_overrides - to_chat(user, "You swipe the card in the card's data port. The lights flicker, then flash once.") - - proc/format(var/datum/cargoprofile/P,var/level) - // PROFILE=0 OVERRIDE=1 MAIN=2 - if(P == null) - return "NONE
" - var/dat = "[P.name]" - if(level == 0 || (level == 1 && !default)) - dat += " PROMOTE" - if(level > 0) - dat += " DEMOTE" - dat += " REMOVE" - dat += "
" - return dat - - interact(mob/user as mob) - var/dat - dat = "MAIN FUNCTION
" - dat += format(default,2) - dat += "- CAUTION -
\[DELETE NON-MAIN ALGORITHMS\]
" - dat += "\[MASTER RESET\]
" - - dat += "OVERRIDES:
" - for(var/datum/cargoprofile/P in overrides) - dat += format(P,1) - dat += "
" - dat += "- CAUTION -
\[DELETE ALL OVERRIDES\]
" - - dat += "
TERTIARY PROFILES:
" - for(var/datum/cargoprofile/P in profiles) - dat += format(P,0) - dat += "
" - dat += "- CAUTION -
\[DELETE TERTIARY PROFILES\]" - - user << browse("Circuit Reprogramming[dat]", "window=progcircuit") - onclose(user, "progcircuit") - - Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - var/id = href_list["id"] - var/level = text2num(href_list["level"]) - switch(href_list["operation"]) - if("promote") - if(level == 0) - for(var/datum/cargoprofile/T in profiles) - if(T.id == id) - overrides += T - profiles -= T - //updateUsrDialog() - interact(usr) - return - - if(level == 1) - if(default) return - for(var/datum/cargoprofile/T in overrides) - if(T.id == id) - default = T - overrides -= T - - if(default.dedicated_path) - build_path = "[default.dedicated_path]" - else - if(istype(default,/datum/cargoprofile/unary)) - build_path = "/obj/machinery/programmable/unary" - else - build_path = "/obj/machinery/programmable" - - //updateUsrDialog() - interact(usr) - return - - if("demote") - if(level == 2) - overrides += default - default = null - //updateUsrDialog() - interact(usr) - return - if(level == 1) - for(var/datum/cargoprofile/T in overrides) - if(T.id == id) - profiles += T - overrides -= T - //updateUsrDialog() - interact(usr) - return - if("delete") - if(level == 2) - default = null - //updateUsrDialog() - interact(usr) - return - if(level == 1) - for(var/datum/cargoprofile/T in overrides) - if(T.id == id) - overrides -= T - //updateUsrDialog() - interact(usr) - return - if(level == 0) - for(var/datum/cargoprofile/T in profiles) - if(T.id == id) - profiles -= T - //updateUsrDialog() - interact(usr) - return - if("deleteall") - for(var/datum/cargoprofile/T in profiles) - profiles -= T - for(var/datum/cargoprofile/T in overrides) - overrides -= T - //updateUsrDialog() - interact(usr) - return - if("deleteoverrides") - for(var/datum/cargoprofile/T in overrides) - overrides -= T - interact(usr) - return - if("deleteprofiles") - for(var/datum/cargoprofile/T in profiles) - profiles -= T - interact(usr) - return - if("reset") - resetlists() - interact(usr) - return - - //End switch diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 13a2ba49ddd..d80a628927b 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -143,7 +143,7 @@ var/const/SAFETY_COOLDOWN = 100 safety_mode = 1 update_icon() L.loc = loc - addtimer(src, "reboot", SAFETY_COOLDOWN) + addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN) /obj/machinery/recycler/proc/reboot() playsound(loc, 'sound/machines/ping.ogg', 50, 0) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 24251977ca9..6ef4d064ac7 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -14,7 +14,7 @@ src.dir = pick(1,2,3,4) ..() -/obj/machinery/shield/initialize() +/obj/machinery/shield/Initialize() air_update_turf(1) ..() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index a4a4091df7b..1962e3631fb 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -127,7 +127,7 @@ if("cellremove") if(open && cell && !usr.get_active_hand()) - cell.updateicon() + cell.update_icon() usr.put_in_hands(cell) cell.add_fingerprint(usr) cell = null diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 414ec8d2e62..a77bd744f92 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -54,7 +54,7 @@ return ..() // register for radio system -/obj/machinery/status_display/initialize() +/obj/machinery/status_display/Initialize() ..() if(radio_controller) radio_controller.add_object(src, frequency) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 59f9a667584..7ec64373373 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -131,7 +131,7 @@ singulo.target = src icon_state = "[icontype]1" active = 1 - machine_processing |= src + START_PROCESSING(SSmachines, src) if(user) to_chat(user, "You activate the beacon.") diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 48637f9e67f..c640d5d5554 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -231,7 +231,8 @@ var/area/A = get_area(bombturf) if(payload && !istype(payload, /obj/item/bombcore/training)) msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).") - log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] ([bombturf.x], [bombturf.y], [bombturf.z])") + log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]") + investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB) payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!" /obj/machinery/syndicatebomb/proc/isWireCut(var/index) @@ -438,7 +439,7 @@ chem_splash(get_turf(src), spread_range, list(reactants), temp_boost) // Detonate it again in one second, until it's out of juice. - addtimer(src, "detonate", 10) + addtimer(CALLBACK(src, .proc/detonate), 10) // If it's not a time release bomb, do normal explosion @@ -556,11 +557,11 @@ var/area/A = get_area(T) detonated-- message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP).") - bombers += "[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])" + investigate_log("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])", INVESTIGATE_BOMB) log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])") detonated = 0 existant = 0 timer = world.time + BUTTON_COOLDOWN #undef BUTTON_COOLDOWN -#undef BUTTON_DELAY \ No newline at end of file +#undef BUTTON_DELAY diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 00465cf8b8b..9dc30edf61e 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -116,7 +116,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() // TODO: Make the radio system cooperate with the space manager listening_level = position.z -/obj/machinery/telecomms/initialize() +/obj/machinery/telecomms/Initialize() ..() if(autolinkers.len) // Links nearby machines diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index fa8f2e8d084..a1248fc0b6d 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -18,7 +18,7 @@ ..() return -/obj/machinery/computer/teleporter/initialize() +/obj/machinery/computer/teleporter/Initialize() ..() link_power_station() update_icon() @@ -293,7 +293,7 @@ component_parts += new /obj/item/stock_parts/matter_bin/super(null) RefreshParts() -/obj/machinery/teleport/hub/initialize() +/obj/machinery/teleport/hub/Initialize() ..() link_power_station() @@ -472,7 +472,7 @@ RefreshParts() link_console_and_hub() -/obj/machinery/teleport/station/initialize() +/obj/machinery/teleport/station/Initialize() ..() link_console_and_hub() diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 8df55e1bc66..d6ae98cb516 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -64,7 +64,7 @@ A.turret_controls -= src return ..() -/obj/machinery/turretid/initialize() +/obj/machinery/turretid/Initialize() ..() if(!control_area) control_area = get_area(src) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 98e7b6f342d..62928c95be5 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -12,7 +12,6 @@ var/energy_drain = 0 var/obj/mecha/chassis = null var/range = MELEE //bitflags - reliability = 1000 var/salvageable = 1 var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates @@ -90,7 +89,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/start_cooldown() set_ready_state(0) chassis.use_power(energy_drain) - addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1) + addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown) /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target) if(!chassis) diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index 866cb7580f6..7706f3120f0 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -444,7 +444,6 @@ if(!PN) PN = new() - powernets += PN NC.powernet = PN PN.cables += NC NC.mergeConnectedNetworks(NC.d2) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index b14825c7cc0..a34d43098cb 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -177,7 +177,7 @@ return data -/obj/machinery/computer/mech_bay_power_console/initialize() +/obj/machinery/computer/mech_bay_power_console/Initialize() reconnect() update_icon() return ..() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index bb666a63da1..23134bc3144 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -469,15 +469,17 @@ /obj/mecha/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) log_message("Attack by hand/paw. Attacker - [user].",1) if((HULK in user.mutations) && !prob(deflect_chance)) + do_attack_animation(src, ATTACK_EFFECT_SMASH) take_damage(15) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) user.visible_message("[user] hits [name], doing some damage.", "You hit [name] with all your might. The metal creaks and bends.") else + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) user.visible_message("[user] hits [name]. Nothing happens","You hit [name] with no visible effect.") log_append_to_last("Armor saved.") return @@ -1478,3 +1480,15 @@ if(occupant_sight_flags) if(user == occupant) user.sight |= occupant_sight_flags + +/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) + if(!no_effect) + if(selected) + used_item = selected + else if(!visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_SMASH + if(damtype == BURN) + visual_effect_icon = ATTACK_EFFECT_MECHFIRE + else if(damtype == TOX) + visual_effect_icon = ATTACK_EFFECT_MECHTOXIN + ..() \ No newline at end of file diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index 6c455c673f3..2ce732f83ed 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -298,6 +298,7 @@ var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)) as text, MAX_NAME_LEN) if(newname && trim(newname)) name = newname + log_game("[key_name(occupant)] has renamed an exosuit [newname]") else alert(occupant, "nope.avi") return diff --git a/code/game/objects/effects/barsign.dm b/code/game/objects/effects/barsign.dm deleted file mode 100644 index fd66f8028d1..00000000000 --- a/code/game/objects/effects/barsign.dm +++ /dev/null @@ -1,8 +0,0 @@ -/obj/effect/sign/double/barsign - icon = 'icons/obj/barsigns.dmi' - icon_state = "empty" - anchored = 1 - - New() - var/list/valid_states = list("pinkflamingo", "magmasea", "limbo", "rustyaxe", "armokbar", "brokendrum", "meadbay", "thedamnwall", "thecavern", "cindikate", "theorchard", "thesaucyclown", "theclownshead", "whiskeyimplant", "carpecarp", "robustroadhouse", "greytide", "theredshirt") - src.icon_state = "[pick(valid_states)]" diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 02f89f6f0f6..f832b446cd5 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -44,7 +44,7 @@ var/global/list/image/splatter_cache=list() if(B.blood_DNA) blood_DNA |= B.blood_DNA.Copy() qdel(B) - dry_timer = addtimer(src, "dry", DRYING_TIME * (amount+1)) + dry_timer = addtimer(CALLBACK(src, .proc/dry), DRYING_TIME * (amount+1), TIMER_STOPPABLE) /obj/effect/decal/cleanable/blood/Destroy() if(GAMEMODE_IS_CULT) diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index fa65008d307..7fb397297d7 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -51,7 +51,7 @@ would spawn and follow the beaker, even if it is carried or thrown. for(var/i in 1 to number) if(total_effects > 20) return - addtimer(src, "generate_effect", 0) + INVOKE_ASYNC(src, .proc/generate_effect) /datum/effect_system/proc/generate_effect() if(holder) @@ -67,7 +67,7 @@ would spawn and follow the beaker, even if it is carried or thrown. for(var/j in 1 to steps_amt) sleep(5) step(E,direction) - addtimer(src, "decrement_total_effect", 20) + addtimer(CALLBACK(src, .proc/decrement_total_effect), 20) /datum/effect_system/proc/decrement_total_effect() total_effects-- diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index aa3ecd8376b..5ad00157a02 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -58,4 +58,4 @@ /datum/effect_system/explosion/smoke/start() ..() - addtimer(src, "create_smoke", 5) + addtimer(CALLBACK(src, .proc/create_smoke), 5) diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index cb218395735..93763c464e7 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -172,7 +172,7 @@ desc = "A lightweight foamed metal wall." var/metal = MFOAM_ALUMINUM -/obj/structure/foamedmetal/initialize() +/obj/structure/foamedmetal/Initialize() ..() air_update_turf(1) @@ -204,7 +204,7 @@ /obj/structure/foamedmetal/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) if((HULK in user.mutations) || (prob(75 - metal*25))) user.visible_message("[user] smashes through \the [src].", "You smash through \the [src].") qdel(src) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 64421b35fe9..385067e0611 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -39,7 +39,7 @@ /obj/effect/particle_effect/smoke/proc/kill_smoke() processing_objects.Remove(src) - addtimer(src, "fade_out", 0) + INVOKE_ASYNC(src, .proc/fade_out) QDEL_IN(src, 10) /obj/effect/particle_effect/smoke/process() @@ -67,7 +67,7 @@ if(C.smoke_delay) return FALSE C.smoke_delay++ - addtimer(src, "remove_smoke_delay", 10, FALSE, C) + addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10) return TRUE /obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C) diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index 9ecafee37f0..4cf5e79cc77 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -72,7 +72,7 @@ else //if on the floor, glowshroom on-floor sprite icon_state = "[base_icon_state]f" - addtimer(src, "Spread", delay, FALSE) + addtimer(CALLBACK(src, .proc/Spread), delay) /obj/structure/glowshroom/proc/Spread() var/turf/ownturf = get_turf(src) @@ -117,7 +117,7 @@ shrooms_planted++ //if we failed due to generation, don't try to plant one later if(shrooms_planted < myseed.yield) //if we didn't get all possible shrooms planted, try again later myseed.yield -= shrooms_planted - addtimer(src, "Spread", delay, FALSE) + addtimer(CALLBACK(src, .proc/Spread), delay) /obj/structure/glowshroom/proc/CalcDir(turf/location = loc) var/direction = 16 diff --git a/code/game/objects/effects/spawners/windowspawner.dm b/code/game/objects/effects/spawners/windowspawner.dm index a2517d093f8..6d271039070 100644 --- a/code/game/objects/effects/spawners/windowspawner.dm +++ b/code/game/objects/effects/spawners/windowspawner.dm @@ -7,7 +7,8 @@ var/windowtospawn = /obj/structure/window/basic anchored = 1 // No sliding out while you prime -/obj/effect/spawner/window/initialize() +/obj/effect/spawner/window/Initialize() + ..() spawn(0) var/turf/T = get_turf(src) for(var/obj/structure/grille/G in get_turf(src)) diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index ddf5b618bd5..2188337ba77 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -5,8 +5,8 @@ epicenter = get_turf(epicenter.loc) if(log) - message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") - log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") + message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [ADMIN_COORDJMP(epicenter)]") + log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [COORD(epicenter)]") if(heavy_range > 1) new/obj/effect/temp_visual/emp/pulse(epicenter) @@ -29,4 +29,4 @@ T.emp_act(2) else if(distance <= light_range) T.emp_act(2) - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b2d0d6720c7..21bc0453500 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -443,10 +443,11 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d playsound(loc, src.hitsound, 30, 1, -1) + user.do_attack_animation(M) + if(M != user) M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ "[user] stabs you in the eye with [src]!") - user.do_attack_animation(M) else user.visible_message( \ "[user] has stabbed themself in the eyes with [src]!", \ diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 3f56932371d..0e2e3cc3785 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -208,7 +208,7 @@ to_chat(I.owner, "Your photon projector implant overheats and deactivates!") I.Retract() overheat = FALSE - addtimer(src, "cooldown", flashcd * 2) + addtimer(CALLBACK(src, .proc/cooldown), flashcd * 2) /obj/item/flash/armimplant/try_use_flash(mob/user = null) if(overheat) @@ -216,7 +216,7 @@ to_chat(I.owner, "Your photon projector is running too hot to be used again so quickly!") return FALSE overheat = TRUE - addtimer(src, "cooldown", flashcd) + addtimer(CALLBACK(src, .proc/cooldown), flashcd) playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) update_icon(1) return TRUE diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 944a6e0d5f9..e7156cb6888 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -12,7 +12,7 @@ var/on = 0 var/brightness_on = 4 //luminosity when on -/obj/item/flashlight/initialize() +/obj/item/flashlight/Initialize() ..() if(on) icon_state = "[initial(icon_state)]-on" diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index b55efc665b2..3a0f2b6941d 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -21,7 +21,7 @@ user.visible_message("[user] begins to play 'Gloomy Sunday'! It looks like \he's trying to commit suicide!") return (BRUTELOSS) -/obj/item/instrument/initialize(mapload) +/obj/item/instrument/Initialize(mapload) song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded ..() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 55465218b99..51aa645a139 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -21,7 +21,7 @@ ..() internal_channels.Cut() -/obj/item/radio/headset/initialize() +/obj/item/radio/headset/Initialize() ..() if(ks1type) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index d61aea153d7..530156fbd99 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -83,7 +83,8 @@ var/global/list/default_medbay_channels = list( return ..() -/obj/item/radio/initialize() +/obj/item/radio/Initialize() + ..() if(frequency < RADIO_LOW_FREQ || frequency > RADIO_HIGH_FREQ) frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) set_frequency(frequency) @@ -270,7 +271,7 @@ var/global/list/default_medbay_channels = list( universal_speak = 1 /mob/living/automatedannouncer/New() - lifetime_timer = addtimer(src, "autocleanup", SecondsToTicks(10)) + lifetime_timer = addtimer(CALLBACK(src, .proc/autocleanup), SecondsToTicks(10), TIMER_STOPPABLE) ..() /mob/living/automatedannouncer/Destroy() @@ -619,7 +620,7 @@ var/global/list/default_medbay_channels = list( /obj/item/radio/emp_act(severity) on = 0 disable_timer++ - addtimer(src, "enable_radio", rand(100, 200)) + addtimer(CALLBACK(src, .proc/enable_radio), rand(100, 200)) if(listening) visible_message("[src] buzzes violently!") diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index beed9fb75c3..84bad81c015 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -63,7 +63,7 @@ A.holder = src A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - bombers += "[key_name(user)] attached a [A] to a transfer valve." + investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB) msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.") log_game("[key_name_admin(user)] attached [A] to a transfer valve.") attacher = user @@ -204,7 +204,7 @@ var/mob/mob = get_mob_by_key(src.fingerprintslast) - bombers += "Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]" + investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB) message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]") log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") merge_gases() diff --git a/code/game/objects/items/policetape.dm b/code/game/objects/items/policetape.dm deleted file mode 100644 index f9769a64e23..00000000000 --- a/code/game/objects/items/policetape.dm +++ /dev/null @@ -1,203 +0,0 @@ -//Define all tape types in policetape.dm -/obj/item/taperoll - name = "tape roll" - icon = 'icons/policetape.dmi' - icon_state = "rollstart" - w_class = WEIGHT_CLASS_TINY - var/turf/start - var/turf/end - var/tape_type = /obj/item/tape - var/icon_base - -var/list/image/hazard_overlays -var/list/tape_roll_applications = list() - -/obj/item/tape - name = "tape" - icon = 'icons/policetape.dmi' - anchored = 1 - density = 1 - var/icon_base - -/obj/item/tape/New() - ..() - if(!hazard_overlays) - hazard_overlays = list() - hazard_overlays["[NORTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "N") - hazard_overlays["[EAST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "E") - hazard_overlays["[SOUTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "S") - hazard_overlays["[WEST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "W") - -/obj/item/taperoll/New() //just using tape is not enough to guarantee the overlays are genned - ..() - if(!hazard_overlays) - hazard_overlays = list() - hazard_overlays["[NORTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "N") - hazard_overlays["[EAST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "E") - hazard_overlays["[SOUTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "S") - hazard_overlays["[WEST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "W") - -/obj/item/taperoll/police - name = "police tape" - desc = "A roll of police tape used to block off crime scenes from the public." - icon_state = "police_start" - tape_type = /obj/item/tape/police - icon_base = "police" - -/obj/item/tape/police - name = "police tape" - desc = "A length of police tape. Do not cross." - req_one_access = list(access_security,access_forensics_lockers) - icon_base = "police" - -/obj/item/taperoll/engineering - name = "engineering tape" - desc = "A roll of engineering tape used to block off working areas from the public." - icon_state = "engineering_start" - tape_type = /obj/item/tape/engineering - icon_base = "engineering" - -/obj/item/tape/engineering - name = "engineering tape" - desc = "A length of engineering tape. Better not cross it." - req_one_access = list(access_engine,access_atmospherics) - icon_base = "engineering" - -/obj/item/taperoll/attack_self(mob/user as mob) - if(icon_state == "[icon_base]_start") - start = get_turf(src) - to_chat(usr, "You place the first end of the [src].") - icon_state = "[icon_base]_stop" - else - icon_state = "[icon_base]_start" - end = get_turf(src) - if(start.y != end.y && start.x != end.x || start.z != end.z) - to_chat(usr, "[src] can only be laid horizontally or vertically.") - return - - var/turf/cur = start - var/dir - if(start.x == end.x) - var/d = end.y-start.y - if(d) d = d/abs(d) - end = get_turf(locate(end.x,end.y+d,end.z)) - dir = "v" - else - var/d = end.x-start.x - if(d) d = d/abs(d) - end = get_turf(locate(end.x+d,end.y,end.z)) - dir = "h" - - var/can_place = 1 - while(cur!=end && can_place) - if(cur.density == 1) - can_place = 0 - else if(istype(cur, /turf/space)) - can_place = 0 - else - for(var/obj/O in cur) - if(!istype(O, /obj/item/tape) && O.density) - can_place = 0 - break - cur = get_step_towards(cur,end) - if(!can_place) - to_chat(usr, "You can't run \the [src] through that!") - return - - cur = start - var/tapetest = 0 - while(cur!=end) - for(var/obj/item/tape/Ptest in cur) - if(Ptest.icon_state == "[Ptest.icon_base]_[dir]") - tapetest = 1 - if(tapetest != 1) - var/obj/item/tape/P = new tape_type(cur) - P.icon_state = "[P.icon_base]_[dir]" - cur = get_step_towards(cur,end) - //is_blocked_turf(var/turf/T) - to_chat(usr, "You finish placing the [src].")//Git Test - - -/obj/item/taperoll/afterattack(var/atom/A, mob/user as mob, proximity) - if(!proximity) - return - - if(istype(A, /obj/machinery/door/airlock)) - var/turf/T = get_turf(A) - var/obj/item/tape/P = new tape_type(T.x,T.y,T.z) - P.loc = locate(T.x,T.y,T.z) - P.icon_state = "[src.icon_base]_door" - P.layer = 3.2 - to_chat(user, "You finish placing the [src].") - - if(istype(A, /turf/simulated/floor) ||istype(A, /turf/unsimulated/floor)) - var/turf/F = A - var/direction = user.loc == F ? user.dir : turn(user.dir, 180) - var/icon/hazard_overlay = hazard_overlays["[direction]"] - if(tape_roll_applications[F] == null) - tape_roll_applications[F] = 0 - - if(tape_roll_applications[F] & direction) // hazard_overlay in F.overlays wouldn't work. - user.visible_message("[user] uses the adhesive of \the [src] to remove area markings from \the [F].", "You use the adhesive of \the [src] to remove area markings from \the [F].") - F.overlays -= hazard_overlay - tape_roll_applications[F] &= ~direction - else - user.visible_message("[user] applied \the [src] on \the [F] to create area markings.", "You apply \the [src] on \the [F] to create area markings.") - F.overlays |= hazard_overlay - tape_roll_applications[F] |= direction - return - -/obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0) - if(!density) return 1 - if(height==0) return 1 - - if((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing)) - return 1 - else if(ismob(mover) && allowed(mover)) - return 1 - else - return 0 - -/obj/item/tape/attackby(obj/item/W as obj, mob/user as mob, params) - breaktape(W, user) - -/obj/item/tape/attack_hand(mob/user as mob) - if(user.a_intent == INTENT_HELP && src.allowed(user)) - user.visible_message("[user] lifts [src], allowing passage.", "You lift [src], allowing passage.") - src.density = 0 - spawn(200) - src.density = 1 - else - breaktape(/obj/item/soap, user)//cant be null, and can't be sharp. - -/obj/item/tape/attack_alien(mob/user as mob) - breaktape(/obj/item/wirecutters,user) - -/obj/item/tape/proc/breaktape(obj/item/W as obj, mob/user as mob) - if(user.a_intent == INTENT_HELP && ((!is_pointed(W) && src.allowed(user)))) - to_chat(user, "You can't break the [src] with that!") - return - user.visible_message("[user] breaks the [src]!", "You break the [src]!") - - var/dir[2] - var/icon_dir = src.icon_state - if(icon_dir == "[src.icon_base]_h") - dir[1] = EAST - dir[2] = WEST - if(icon_dir == "[src.icon_base]_v") - dir[1] = NORTH - dir[2] = SOUTH - - for(var/i=1;i<3;i++) - var/N = 0 - var/turf/cur = get_step(src,dir[i]) - while(N != 1) - N = 1 - for(var/obj/item/tape/P in cur) - if(P.icon_state == icon_dir) - N = 0 - qdel(P) - cur = get_step(cur,dir[i]) - - qdel(src) - return diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 3382292bc3a..b321721b639 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -303,7 +303,7 @@ /obj/effect/decal/cleanable/ash/snappop_phoenix/New() . = ..() - addtimer(src, "respawn", respawn_time) + addtimer(CALLBACK(src, .proc/respawn), respawn_time) /obj/effect/decal/cleanable/ash/snappop_phoenix/proc/respawn() new /obj/item/toy/snappop/phoenix(get_turf(src)) diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index b52a92112eb..fe132c107b0 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -385,7 +385,7 @@ RCD buzz loudly!
","[src] begins \ vibrating violently!") // 5 seconds to get rid of it - addtimer(src, "detonate_pulse_explode", 50) + addtimer(CALLBACK(src, .proc/detonate_pulse_explode), 50) /obj/item/rcd/proc/detonate_pulse_explode() explosion(src, 0, 0, 3, 1, flame_range = 1) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 762b2151b9c..e018625a971 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -96,7 +96,7 @@ if(istype(W, /obj/item/screwdriver)) if(bcell) - bcell.updateicon() + bcell.update_icon() bcell.loc = get_turf(src.loc) bcell = null to_chat(user, "You remove the cell from the [src].") diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 8ccfed1b517..d93ebcf3214 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -159,7 +159,7 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - bombers += "E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]" + investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB) message_admins("E20 detonated at [A.name] (JMP) with a roll of [result]. Triggered by: [key_name_admin(user)]") log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]") diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 381e6177bb2..6164ed01047 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -85,7 +85,7 @@ target.overlays += image_overlay if(!nadeassembly) to_chat(user, "You plant the bomb. Timer counting down from [det_time].") - addtimer(src, "prime", det_time*10) + addtimer(CALLBACK(src, .proc/prime), det_time*10) /obj/item/grenade/plastic/suicide_act(mob/user) message_admins("[key_name_admin(user)](?) (FLW) suicided with [src.name] at ([user.x],[user.y],[user.z] - JMP)",0,1) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index c6899d71c22..9e836fecc87 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -102,7 +102,7 @@ // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP) [contained].") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].") - bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained]." + investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained].", INVESTIGATE_BOMB) to_chat(user, "You prime the [name]! [det_time / 10] second\s!") playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 @@ -422,7 +422,7 @@ message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).") log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])") else - addtimer(src, "prime", det_time) + addtimer(CALLBACK(src, .proc/prime), det_time) var/turf/DT = get_turf(src) var/area/DA = get_area(DT) log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])") diff --git a/code/game/objects/items/weapons/grenades/emgrenade.dm b/code/game/objects/items/weapons/grenades/emgrenade.dm index 44d21506ee6..5b6d585ef5f 100644 --- a/code/game/objects/items/weapons/grenades/emgrenade.dm +++ b/code/game/objects/items/weapons/grenades/emgrenade.dm @@ -7,5 +7,5 @@ /obj/item/grenade/empgrenade/prime() update_mob() - empulse(src, 4, 10) - qdel(src) \ No newline at end of file + empulse(src, 4, 10, 1) + qdel(src) diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index d24f93736e5..ca6177c04fa 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -49,11 +49,12 @@ var/area/A = get_area(bombturf) message_admins("[ADMIN_LOOKUPFLW(user)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)].") - log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") + log_game("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") + investigate_log("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)])", INVESTIGATE_BOMB) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() - addtimer(src, "prime", det_time) + addtimer(CALLBACK(src, .proc/prime), det_time) /obj/item/grenade/iedcasing/prime() //Blowing that can up update_mob() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index c7ababde601..09fdfe5a27f 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -66,7 +66,7 @@ var/area/A = get_area(bombturf) message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])") - bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])" + investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() diff --git a/code/game/objects/items/weapons/holosign.dm b/code/game/objects/items/weapons/holosign.dm index 30deb5289a4..12767cb9563 100644 --- a/code/game/objects/items/weapons/holosign.dm +++ b/code/game/objects/items/weapons/holosign.dm @@ -1,53 +1,123 @@ /obj/item/holosign_creator name = "holographic sign projector" - desc = "A handy-dandy hologaphic projector that displays a janitorial sign." - icon = 'icons/obj/janitor.dmi' + desc = "A handy-dandy holographic projector that displays a janitorial sign." + icon = 'icons/obj/device.dmi' icon_state = "signmaker" item_state = "electronic" - force = 5 + force = 0 w_class = WEIGHT_CLASS_SMALL throwforce = 0 throw_speed = 3 throw_range = 7 origin_tech = "magnets=1;programming=3" + flags = NOBLUDGEON var/list/signs = list() - var/max_signs = 20 - -/obj/item/holosign_creator/Destroy() - QDEL_LIST(signs) - return ..() + var/max_signs = 10 + var/creation_time = 0 //time to create a holosign in deciseconds. + var/holosign_type = /obj/structure/holosign/wetsign + var/holocreator_busy = FALSE //to prevent placing multiple holo barriers at once /obj/item/holosign_creator/afterattack(atom/target, mob/user, flag) if(flag) + if(!check_allowed_items(target, 1)) + return var/turf/T = get_turf(target) - var/obj/effect/overlay/holograph/H = locate() in T + var/obj/structure/holosign/H = locate(holosign_type) in T if(H) - to_chat(user, "You use [src] to destroy [H].") - signs -= H + to_chat(user, "You use [src] to deactivate [H].") qdel(H) else - if(signs.len < max_signs) - H = new(get_turf(target)) - signs += H - to_chat(user, "You create \a [H] with [src].") - else - to_chat(user, "[src] is projecting at max capacity!") + if(!is_blocked_turf(T, TRUE)) //can't put holograms on a tile that has dense stuff + if(holocreator_busy) + to_chat(user, "[src] is busy creating a hologram.") + return + if(signs.len < max_signs) + playsound(src.loc, 'sound/machines/click.ogg', 20, 1) + if(creation_time) + holocreator_busy = TRUE + if(!do_after(user, creation_time, target = target)) + holocreator_busy = FALSE + return + holocreator_busy = FALSE + if(signs.len >= max_signs) + return + if(is_blocked_turf(T, TRUE)) //don't try to sneak dense stuff on our tile during the wait. + return + H = new holosign_type(get_turf(target), src) + to_chat(user, "You create [H] with [src].") + else + to_chat(user, "[src] is projecting at max capacity!") /obj/item/holosign_creator/attack(mob/living/carbon/human/M, mob/user) return /obj/item/holosign_creator/attack_self(mob/user) if(signs.len) - var/list/L = signs.Copy() - for(var/sign in L) - qdel(sign) - signs -= sign + for(var/H in signs) + qdel(H) to_chat(user, "You clear all active holograms.") -/obj/effect/overlay/holograph - name = "wet floor sign" - desc = "The words flicker as if they mean nothing." - icon = 'icons/obj/janitor.dmi' - icon_state = "holosign" - anchored = 1 - armor = list(melee = 0, bullet = 50, laser = 50, energy = 50, bomb = 0, bio = 0, rad = 0) + +/obj/item/holosign_creator/security + name = "security holobarrier projector" + desc = "A holographic projector that creates holographic security barriers." + icon_state = "signmaker_sec" + holosign_type = /obj/structure/holosign/barrier + creation_time = 30 + max_signs = 6 + +/obj/item/holosign_creator/engineering + name = "engineering holobarrier projector" + desc = "A holographic projector that creates holographic engineering barriers." + icon_state = "signmaker_engi" + holosign_type = /obj/structure/holosign/barrier/engineering + creation_time = 30 + max_signs = 6 + +/obj/item/holosign_creator/atmos + name = "ATMOS holofan projector" + desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions." + icon_state = "signmaker_engi" + holosign_type = /obj/structure/holosign/barrier/atmos + creation_time = 0 + max_signs = 3 + +/obj/item/holosign_creator/cyborg + name = "Energy Barrier Projector" + desc = "A holographic projector that creates fragile energy fields." + creation_time = 15 + max_signs = 9 + holosign_type = /obj/structure/holosign/barrier/cyborg + var/shock = 0 + +/obj/item/holosign_creator/cyborg/attack_self(mob/user) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + + if(shock) + to_chat(user, "You clear all active holograms, and reset your projector to normal.") + holosign_type = /obj/structure/holosign/barrier/cyborg + creation_time = 5 + if(signs.len) + for(var/H in signs) + qdel(H) + shock = 0 + return + else if(R.emagged && !shock) + to_chat(user, "You clear all active holograms, and overload your energy projector!") + holosign_type = /obj/structure/holosign/barrier/cyborg/hacked + creation_time = 30 + if(signs.len) + for(var/H in signs) + qdel(H) + shock = 1 + return + else + if(signs.len) + for(var/H in signs) + qdel(H) + to_chat(user, "You clear all active holograms.") + if(signs.len) + for(var/H in signs) + qdel(H) + to_chat(user, "You clear all active holograms.") \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_misc.dm b/code/game/objects/items/weapons/implants/implant_misc.dm index a657d08847b..9c4049e8904 100644 --- a/code/game/objects/items/weapons/implants/implant_misc.dm +++ b/code/game/objects/items/weapons/implants/implant_misc.dm @@ -58,7 +58,7 @@ /obj/item/implant/emp/activate() uses-- - empulse(imp_in, 3, 5) + empulse(imp_in, 3, 5, 1) if(!uses) qdel(src) diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm index 68ef65664c7..adf988c2dee 100644 --- a/code/game/objects/items/weapons/implants/implant_traitor.dm +++ b/code/game/objects/items/weapons/implants/implant_traitor.dm @@ -59,7 +59,7 @@ var/datum/objective/protect/mindslave/MS = new MS.owner = H.mind MS.target = user.mind - MS.explanation_text = "Obey every order from and protect [user.real_name], the [user.mind.assigned_role=="MODE" ? (user.mind.special_role) : (user.mind.assigned_role)]." + MS.explanation_text = "Obey every order from and protect [user.real_name], the [user.mind.assigned_role == user.mind.special_role ? (user.mind.special_role) : (user.mind.assigned_role)]." H.mind.objectives += MS for(var/datum/objective/objective in H.mind.objectives) to_chat(H, "Objective #1: [objective.explanation_text]") diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm index b238899676b..e6ba57ff8da 100644 --- a/code/game/objects/items/weapons/legcuffs.dm +++ b/code/game/objects/items/weapons/legcuffs.dm @@ -132,7 +132,7 @@ /obj/item/restraints/legcuffs/beartrap/energy/New() ..() - addtimer(src, "dissipate", 100) + addtimer(CALLBACK(src, .proc/dissipate), 100) /obj/item/restraints/legcuffs/beartrap/energy/proc/dissipate() if(!ismob(loc)) diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm deleted file mode 100644 index 5b2d05491bf..00000000000 --- a/code/game/objects/items/weapons/power_cells.dm +++ /dev/null @@ -1,211 +0,0 @@ -/obj/item/stock_parts/cell - name = "power cell" - desc = "A rechargable electrochemical power cell." - icon = 'icons/obj/power.dmi' - icon_state = "cell" - item_state = "cell" - origin_tech = "powerstorage=1" - force = 5 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - var/charge = 0 // note %age conveted to actual charge in New - var/maxcharge = 1000 - materials = list(MAT_METAL=700, MAT_GLASS=50) - var/rigged = 0 // true if rigged to explode - var/chargerate = 100 //how much power is given every tick in a recharger - var/self_recharge = 0 //does it self recharge, over time, or not? - var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. - -/obj/item/stock_parts/cell/New() - ..() - processing_objects.Add(src) - charge = maxcharge - updateicon() - -/obj/item/stock_parts/cell/Destroy() - processing_objects.Remove(src) - return ..() - -/obj/item/stock_parts/cell/vv_edit_var(var_name, var_value) - switch(var_name) - if("self_recharge") - if(var_value) - processing_objects.Add(src) - else - processing_objects.Remove(src) - . = ..() - -/obj/item/stock_parts/cell/suicide_act(mob/user) - to_chat(viewers(user), "[user] is licking the electrodes of the [src.name]! It looks like \he's trying to commit suicide.") - return (FIRELOSS) - -/obj/item/stock_parts/cell/process() - if(self_recharge) - give(chargerate * 0.25) - else - return PROCESS_KILL - -/obj/item/stock_parts/cell/proc/updateicon() - overlays.Cut() - if(grown_battery) - overlays += image('icons/obj/power.dmi', "grown_wires") - if(charge < 0.01) - return - else if(charge/maxcharge >=0.995) - overlays += image('icons/obj/power.dmi', "cell-o2") - else - overlays += image('icons/obj/power.dmi', "cell-o1") - -/obj/item/stock_parts/cell/crap - name = "\improper Nanotrasen brand rechargable AA battery" - desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT - maxcharge = 500 - materials = list(MAT_GLASS=40) - rating = 2 - -/obj/item/stock_parts/cell/crap/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/secborg - name = "\improper Security borg rechargable D battery" - origin_tech = null - maxcharge = 600 //600 max charge / 100 charge per shot = six shots - materials = list(MAT_GLASS=40) - rating = 2.5 - -/obj/item/stock_parts/cell/secborg/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/high - name = "high-capacity power cell" - origin_tech = "powerstorage=2" - icon_state = "hcell" - maxcharge = 10000 - materials = list(MAT_GLASS=60) - rating = 3 - chargerate = 1500 - -/obj/item/stock_parts/cell/high/plus - name = "high-capacity power cell+" - desc = "Where did these come from?" - icon_state = "h+cell" - maxcharge = 15000 - chargerate = 2250 - -/obj/item/stock_parts/cell/high/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/super - name = "super-capacity power cell" - origin_tech = "powerstorage=3;materials=3" - icon_state = "scell" - maxcharge = 20000 - materials = list(MAT_GLASS=300) - rating = 4 - chargerate = 2000 - -/obj/item/stock_parts/cell/super/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/hyper - name = "hyper-capacity power cell" - origin_tech = "powerstorage=4;engineering=4;materials=4" - icon_state = "hpcell" - maxcharge = 30000 - materials = list(MAT_GLASS=400) - rating = 5 - chargerate = 3000 - -/obj/item/stock_parts/cell/hyper/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/bluespace - name = "bluespace power cell" - origin_tech = "powerstorage=5;bluespace=4;materials=4;engineering=4" - icon_state = "bscell" - maxcharge = 40000 - materials = list(MAT_GLASS=600) - rating = 6 - chargerate = 4000 - -/obj/item/stock_parts/cell/bluespace/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/infinite - name = "infinite-capacity power cell!" - icon_state = "icell" - origin_tech = "powerstorage=7" - maxcharge = 30000 - materials = list(MAT_GLASS=1000) - rating = 6 - chargerate = 30000 - -/obj/item/stock_parts/cell/infinite/use() - return 1 - -/obj/item/stock_parts/cell/potato - name = "potato battery" - desc = "A rechargable starch based power cell." - icon = 'icons/obj/hydroponics/harvest.dmi' - icon_state = "potato" - origin_tech = "powerstorage=1;biotech=1" - charge = 100 - maxcharge = 300 - materials = list() - rating = 1 - grown_battery = TRUE //it has the overlays for wires - -/obj/item/stock_parts/cell/high/slime - name = "charged slime core" - desc = "A yellow slime core infused with plasma, it crackles with power." - origin_tech = "powerstorage=5;biotech=4" - icon = 'icons/mob/slimes.dmi' - icon_state = "yellow slime extract" - materials = list() - self_recharge = 1 // Infused slime cores self-recharge, over time - chargerate = 500 - -/obj/item/stock_parts/cell/pulse //200 pulse shots - name = "pulse rifle power cell" - maxcharge = 40000 - rating = 3 - chargerate = 1500 - -/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots - name = "pulse carbine power cell" - maxcharge = 5000 - -/obj/item/stock_parts/cell/pulse/pistol //10 pulse shots - name = "pulse pistol power cell" - maxcharge = 2000 - -/obj/item/stock_parts/cell/ninja - name = "spider-clan power cell" - desc = "A standard ninja-suit power cell." - maxcharge = 10000 - rating = 3 - materials = list(MAT_GLASS=60) - -/obj/item/stock_parts/cell/emproof - name = "\improper EMP-proof cell" - desc = "An EMP-proof cell." - maxcharge = 500 - rating = 2 - -/obj/item/stock_parts/cell/emproof/empty/New() - ..() - charge = 0 - -/obj/item/stock_parts/cell/emproof/emp_act(severity) - return - -/obj/item/stock_parts/cell/emproof/corrupt() - return diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index aa723cba8c0..9d4481952f5 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -58,8 +58,8 @@ /obj/item/stack/cable_coil, /obj/item/t_scanner, /obj/item/analyzer, - /obj/item/taperoll/engineering, - /obj/item/extinguisher/mini) + /obj/item/extinguisher/mini, + /obj/item/holosign_creator) /obj/item/storage/belt/utility/full/New() ..() @@ -192,7 +192,7 @@ /obj/item/melee/baton, /obj/item/melee/classic_baton, /obj/item/flashlight/seclite, - /obj/item/taperoll/police, + /obj/item/holosign_creator/security, /obj/item/melee/classic_baton/telescopic, /obj/item/restraints/legcuffs/bola) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 882852a3632..93f230a07e8 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -421,6 +421,7 @@ hide_from(usr) for(var/obj/item/I in contents) remove_from_storage(I, T) + CHECK_TICK /obj/item/storage/New() can_hold = typecacheof(can_hold) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index da9edab2833..98b8395f161 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -78,7 +78,7 @@ else if(istype(W, /obj/item/screwdriver)) if(bcell) - bcell.updateicon() + bcell.update_icon() bcell.loc = get_turf(src.loc) bcell = null to_chat(user, "You remove the cell from the [src].") diff --git a/code/game/objects/items/weapons/syndie_uplink.dm b/code/game/objects/items/weapons/syndie_uplink.dm deleted file mode 100644 index a09ab0b69a2..00000000000 --- a/code/game/objects/items/weapons/syndie_uplink.dm +++ /dev/null @@ -1,38 +0,0 @@ -/*/obj/item/syndicate_uplink - name = "station bounced radio" - desc = "Remain silent about this..." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - var/temp = null - var/uses = 10.0 - var/selfdestruct = 0.0 - var/traitor_frequency = 0.0 - var/mob/currentUser = null - var/obj/item/radio/origradio = null - flags = CONDUCT | ONBELT - w_class = WEIGHT_CLASS_SMALL - item_state = "radio" - throw_speed = 4 - throw_range = 20 - materials = list(MAT_METAL=100) - origin_tech = "magnets=2;syndicate=3"*/ - -/obj/item/SWF_uplink - name = "station-bounced radio" - desc = "used to comunicate it appears." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - var/temp = null - var/uses = 4.0 - var/selfdestruct = 0.0 - var/traitor_frequency = 0.0 - var/obj/item/radio/origradio = null - flags = CONDUCT - slot_flags = SLOT_BELT - item_state = "radio" - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 4 - throw_range = 20 - materials = list(MAT_METAL=100) - origin_tech = "magnets=1" diff --git a/code/game/objects/items/weapons/wires.dm b/code/game/objects/items/weapons/wires.dm deleted file mode 100644 index 44097096ae0..00000000000 --- a/code/game/objects/items/weapons/wires.dm +++ /dev/null @@ -1,36 +0,0 @@ -// WIRES - -/obj/item/wire - desc = "This is just a simple piece of regular insulated wire." - name = "wire" - icon = 'icons/obj/power.dmi' - icon_state = "item_wire" - var/amount = 1.0 - var/laying = 0.0 - var/old_lay = null - materials = list(MAT_METAL=40) - attack_verb = list("whipped", "lashed", "disciplined", "tickled") - - suicide_act(mob/user) - to_chat(viewers(user), "[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.") - return (OXYLOSS) - - -/obj/item/wire/proc/update() - if(src.amount > 1) - src.icon_state = "spool_wire" - src.desc = text("This is just spool of regular insulated wire. It consists of about [] unit\s of wire.", src.amount) - else - src.icon_state = "item_wire" - src.desc = "This is just a simple piece of regular insulated wire." - return - -/obj/item/wire/attack_self(mob/user as mob) - if(src.laying) - src.laying = 0 - to_chat(user, "You're done laying wire!") - else - to_chat(user, "You are not using this to lay wire...") - return - - diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 0738d57e8fb..fcd233318d5 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -162,7 +162,7 @@ being_shocked = TRUE var/power_bounced = power * 0.5 tesla_zap(src, 3, power_bounced) - addtimer(src, "reset_shocked", 10) + addtimer(CALLBACK(src, .proc/reset_shocked), 10) /obj/proc/reset_shocked() being_shocked = FALSE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index e254d80a39c..fe9e8444378 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -1,7 +1,6 @@ /obj //var/datum/module/mod //not used var/origin_tech = null //Used by R&D to determine what research bonuses it grants. - var/reliability = 100 //Used by SOME devices to determine how reliable they are. var/crit_fail = 0 var/unacidable = 0 //universal "unacidabliness" var, here so you can use it in any obj. animate_movement = 2 diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index c4506396f45..76deeac93e8 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -30,7 +30,7 @@ var/resintype = null smooth = SMOOTH_TRUE -/obj/structure/alien/resin/initialize() +/obj/structure/alien/resin/Initialize() air_update_turf(1) ..() diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index 6c627bb40ce..d392deeec81 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -105,7 +105,7 @@ to_chat(user, "Nothing interesting happens!") return to_chat(user, "You emag the barsign. Takeover in progress...") - addtimer(src, "post_emag", 100) + addtimer(CALLBACK(src, .proc/post_emag), 100) /obj/structure/sign/barsign/proc/post_emag() if(broken || emagged) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 32872e07f12..6548aa8bfca 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -30,8 +30,8 @@ new /obj/item/clothing/suit/storage/hazardvest(src) new /obj/item/clothing/mask/gas(src) new /obj/item/multitool(src) + new /obj/item/holosign_creator/engineering(src) new /obj/item/flash(src) - new /obj/item/taperoll/engineering(src) new /obj/item/clothing/head/beret/eng(src) new /obj/item/door_remote/chief_engineer(src) new /obj/item/rpd(src) @@ -102,6 +102,7 @@ new /obj/item/storage/backpack/satchel_eng(src) new /obj/item/storage/backpack/duffel/engineering(src) new /obj/item/storage/toolbox/mechanical(src) + new /obj/item/holosign_creator/engineering(src) new /obj/item/radio/headset/headset_eng(src) new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/under/rank/engineer/skirt(src) @@ -109,7 +110,6 @@ new /obj/item/clothing/mask/gas(src) new /obj/item/clothing/glasses/meson(src) new /obj/item/cartridge/engineering(src) - new /obj/item/taperoll/engineering(src) new /obj/item/clothing/head/beret/eng(src) @@ -128,7 +128,6 @@ new /obj/item/radio/headset/headset_eng(src) new /obj/item/cartridge/atmos(src) new /obj/item/storage/toolbox/mechanical(src) - new /obj/item/taperoll/engineering(src) if(prob(50)) new /obj/item/storage/backpack/industrial(src) else @@ -138,6 +137,7 @@ new /obj/item/clothing/suit/storage/hazardvest(src) new /obj/item/clothing/mask/gas(src) new /obj/item/tank/emergency_oxygen/engi(src) + new /obj/item/holosign_creator/atmos(src) new /obj/item/watertank/atmos(src) new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 05a3fa5c7ba..2a5639eb081 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -115,11 +115,11 @@ new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/storage/lockbox/mindshield(src) new /obj/item/storage/box/flashbangs(src) + new /obj/item/holosign_creator/security(src) new /obj/item/clothing/mask/gas/sechailer/hos(src) new /obj/item/shield/riot/tele(src) new /obj/item/melee/baton/loaded(src) new /obj/item/storage/belt/security/sec(src) - new /obj/item/taperoll/police(src) new /obj/item/gun/energy/gun/hos(src) new /obj/item/door_remote/head_of_security(src) new /obj/item/reagent_containers/food/drinks/mug/hos(src) @@ -151,8 +151,8 @@ new /obj/item/clothing/under/rank/warden/corp(src) new /obj/item/clothing/under/rank/warden/skirt(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/holosign_creator/security(src) new /obj/item/clothing/mask/gas/sechailer/warden(src) - new /obj/item/taperoll/police(src) new /obj/item/storage/box/zipties(src) new /obj/item/storage/box/flashbangs(src) new /obj/item/reagent_containers/spray/pepper(src) @@ -186,11 +186,11 @@ new /obj/item/flash(src) new /obj/item/grenade/flashbang(src) new /obj/item/storage/belt/security/sec(src) + new /obj/item/holosign_creator/security(src) new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/clothing/head/helmet(src) new /obj/item/melee/baton/loaded(src) - new /obj/item/taperoll/police(src) /obj/structure/closet/secure_closet/brigdoc @@ -344,10 +344,10 @@ new /obj/item/ammo_box/c38(src) new /obj/item/ammo_box/c38(src) new /obj/item/gun/projectile/revolver/detective(src) - new /obj/item/taperoll/police(src) new /obj/item/clothing/accessory/holster/armpit(src) new /obj/item/clothing/glasses/sunglasses/yeah(src) new /obj/item/flashlight/seclite(src) + new /obj/item/holosign_creator/security(src) new /obj/item/clothing/accessory/black(src) new /obj/item/taperecorder(src) new /obj/item/storage/box/tapes(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index f888ee6cc94..0156cac96cc 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -295,7 +295,7 @@ var/global/list/captain_display_cases = list() else if(user.a_intent == INTENT_HARM) user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) + user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user.name] kicks \the [src]!", \ "You kick \the [src]!", \ "You hear glass crack.") diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm index cf6a8e65715..a005e59c5a5 100644 --- a/code/game/objects/structures/engicart.dm +++ b/code/game/objects/structures/engicart.dm @@ -12,7 +12,6 @@ var/obj/item/storage/toolbox/mechanical/mybluetoolbox = null var/obj/item/storage/toolbox/electrical/myyellowtoolbox = null var/obj/item/storage/toolbox/emergency/myredtoolbox = null - var/obj/item/taperoll/engineering/myengitape = null /obj/structure/engineeringcart/Destroy() QDEL_NULL(myglass) @@ -22,7 +21,6 @@ QDEL_NULL(mybluetoolbox) QDEL_NULL(myyellowtoolbox) QDEL_NULL(myredtoolbox) - QDEL_NULL(myengitape) return ..() /obj/structure/engineeringcart/proc/put_in_cart(obj/item/I, mob/user) @@ -83,13 +81,6 @@ update_icon() else to_chat(user, fail_msg) - else if(istype(I, /obj/item/taperoll/engineering/)) - if(!myengitape) - put_in_cart(I, user) - myengitape=I - update_icon() - else - to_chat(user, fail_msg) else if(istype(I, /obj/item/wrench)) if(!anchored && !isinspace()) playsound(src.loc, I.usesound, 50, 1) @@ -125,8 +116,6 @@ dat += "[myredtoolbox.name]
" if(myyellowtoolbox) dat += "[myyellowtoolbox.name]
" - if(myengitape) - dat += "[myengitape.name]
" var/datum/browser/popup = new(user, "engicart", name, 240, 160) popup.set_content(dat) popup.open() @@ -171,16 +160,12 @@ user.put_in_hands(myyellowtoolbox) to_chat(user, "You take [myyellowtoolbox] from [src].") myyellowtoolbox = null - if(href_list["engitape"]) - if(myengitape) - user.put_in_hands(myengitape) - to_chat(user, "You take [myengitape] from [src].") - myengitape = null update_icon() updateUsrDialog() + /obj/structure/engineeringcart/update_icon() - overlays = null + overlays.Cut() if(myglass) overlays += "cart_glass" if(mymetal) @@ -194,6 +179,4 @@ if(myredtoolbox) overlays += "cart_redtoolbox" if(myyellowtoolbox) - overlays += "cart_yellowtoolbox" - if(myengitape) - overlays += "cart_engitape" + overlays += "cart_yellowtoolbox" \ No newline at end of file diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 284001de2bf..0c0c3c1aa0c 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -71,7 +71,7 @@ /obj/structure/grille/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) + user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] kicks [src].", \ "You kick [src].", \ "You hear twisting metal.") @@ -146,6 +146,7 @@ return ..() /obj/structure/grille/proc/build_window(obj/item/stack/sheet/S, mob/user) + var/dir_to_set = NORTH if(!istype(S) || !user) return if(broken) @@ -160,59 +161,40 @@ if(!getRelativeDirection(src, user) && (user.loc != loc)) //essentially a cardinal direction adjacent or sharing same loc check to_chat(user, "You can't reach.") return - if(/obj/structure/window/full in loc) //check for a full window already present (blocks the whole tile) - to_chat(user, "There is already a full window there.") - return - var/selection = alert(user, "What type of window would you like to place?", "Window Construction", "One Direction", "Full", "Cancel") - if(selection == "Cancel") - return - if(selection == "Full") - if(S.get_amount() < 2) - to_chat(user, "You need at least two sheets of glass for that!") + if(loc == user.loc) + dir_to_set = user.dir + else + if(x == user.x) + if(y > user.y) + dir_to_set = SOUTH + else + dir_to_set = NORTH + else if(y == user.y) + if(x > user.x) + dir_to_set = WEST + else + dir_to_set = EAST + for(var/obj/structure/window/WINDOW in loc) + if(WINDOW.dir == dir_to_set) + to_chat(user, "There is already a window facing this way there.") return - if(do_after(user, 20, target = src)) //glass doesn't have a toolspeed, so no multiplier - if(broken || !anchored || !src) //make sure the grille is still intact, anchored, and exists! - return - if(S.get_amount() < 2) //make sure we still have enough for this! - return - if(!getRelativeDirection(src, user) && (user.loc != loc)) //make sure we can still do this from our location - return - var/obj/structure/window/W = new S.full_window(get_turf(src)) - S.use(2) - W.anchored = 0 - W.state = 0 - to_chat(user, "You place [W] on [src].") - W.update_icon() - return - if(selection == "One Direction") - var/dir_selection = input("Which direction will this window face?", "Direction") as null|anything in list("north", "east", "south", "west") - if(!dir_selection) + to_chat(user, "You start placing the window...") + if(do_after(user, 20, target = src)) + if(!loc || !anchored) //Grille destroyed or unanchored while waiting return - var/temp_dir = text2dir(dir_selection) - for(var/obj/structure/window/W in loc) - if(istype(W, /obj/structure/window/full)) //double checking in case a full window was created while selecting direction - to_chat(user, "There is already a full window there.") + for(var/obj/structure/window/WINDOW in loc) + if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting. + to_chat(user, "There is already a window facing this way there.") return - if(W.dir == temp_dir) //to avoid building a window on top of an existing window - to_chat(user, "There is already a window facing this direction there.") - return - if(do_after(user, 20, target = src)) - if(broken || !anchored || !src) //make sure the grille is still intact, anchored, and exists! - return - if(S.get_amount() < 1) //make sure we still have enough fir this! - to_chat(user, "You need at least one sheet of glass for that!") - return - if(!getRelativeDirection(src, user) && (user.loc != loc)) //make sure we can still do this from our location - return - var/obj/structure/window/W = new S.created_window(get_turf(src)) - S.use(1) - W.setDir(temp_dir) - W.ini_dir = temp_dir - W.anchored = 0 - W.state = 0 - to_chat(user, "You place [W] on [src].") - W.update_icon() - return + var/obj/structure/window/W = new S.created_window(get_turf(src)) + S.use(1) + W.setDir(dir_to_set) + W.ini_dir = dir_to_set + W.anchored = 0 + W.state = 0 + to_chat(user, "You place the [W] on [src].") + W.update_icon() + return /obj/structure/grille/attacked_by(obj/item/I, mob/living/user) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm new file mode 100644 index 00000000000..0de1a09a74c --- /dev/null +++ b/code/game/objects/structures/guillotine.dm @@ -0,0 +1,235 @@ +#define GUILLOTINE_BLADE_MAX_SHARP 10 // This is maxiumum sharpness that will decapitate without failure +#define GUILLOTINE_DECAP_MIN_SHARP 7 // Minimum amount of sharpness for decapitation. Any less and it will just deal brute damage +#define GUILLOTINE_ANIMATION_LENGTH 9 // How many deciseconds the animation is +#define GUILLOTINE_BLADE_RAISED 1 +#define GUILLOTINE_BLADE_MOVING 2 +#define GUILLOTINE_BLADE_DROPPED 3 +#define GUILLOTINE_BLADE_SHARPENING 4 +#define GUILLOTINE_HEAD_OFFSET 16 // How much we need to move the player to center their head +#define GUILLOTINE_LAYER_DIFF 1.2 // How much to increase/decrease a head when it's buckled/unbuckled +#define GUILLOTINE_ACTIVATE_DELAY 30 // Delay for executing someone +#define GUILLOTINE_WRENCH_DELAY 10 +#define GUILLOTINE_ACTION_INUSE 5 +#define GUILLOTINE_ACTION_WRENCH 6 + +/obj/structure/guillotine + name = "guillotine" + desc = "A large structure used to remove the heads of traitors and treasonists." + icon = 'icons/obj/guillotine.dmi' + icon_state = "guillotine_raised" + can_buckle = TRUE + anchored = TRUE + density = FALSE + buckle_lying = FALSE + layer = ABOVE_MOB_LAYER + var/blade_status = GUILLOTINE_BLADE_RAISED + var/blade_sharpness = GUILLOTINE_BLADE_MAX_SHARP // How sharp the blade is + var/kill_count = 0 + var/force_clap = FALSE //You WILL clap if I want you to + var/current_action = 0 // What's currently happening to the guillotine + +/obj/structure/guillotine/examine(mob/user) + ..() + + var/msg = "" + + msg += "It is [anchored ? "wrenched to the floor." : "unsecured. A wrench should fix that."]
" + + if(blade_status == GUILLOTINE_BLADE_RAISED) + msg += "The blade is raised, ready to fall, and" + + if(blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP) + msg += " looks sharp enough to decapitate without any resistance." + else + msg += " doesn't look particularly sharp. Perhaps a whetstone can be used to sharpen it." + else + msg += "The blade is hidden inside the stocks." + + if(has_buckled_mobs()) + msg += "
" + msg += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." + + to_chat(user, msg) + + return msg + +/obj/structure/guillotine/attack_hand(mob/user) + add_fingerprint(user) + + // Currently being used by something + if(current_action) + return + + switch(blade_status) + if(GUILLOTINE_BLADE_MOVING) + return + if(GUILLOTINE_BLADE_DROPPED) + blade_status = GUILLOTINE_BLADE_MOVING + icon_state = "guillotine_raise" + addtimer(CALLBACK(src, .proc/raise_blade), GUILLOTINE_ANIMATION_LENGTH) + return + if(GUILLOTINE_BLADE_RAISED) + if(has_buckled_mobs()) + if(user.a_intent == INTENT_HARM) + user.visible_message("[user] begins to pull the lever!", + "You begin to the pull the lever.") + current_action = GUILLOTINE_ACTION_INUSE + + if(do_after(user, GUILLOTINE_ACTIVATE_DELAY, target = src) && blade_status == GUILLOTINE_BLADE_RAISED) + current_action = 0 + blade_status = GUILLOTINE_BLADE_MOVING + icon_state = "guillotine_drop" + playsound(src, 'sound/items/unsheath.ogg', 100, 1) + addtimer(CALLBACK(src, .proc/drop_blade, user), GUILLOTINE_ANIMATION_LENGTH - 2) // Minus two so we play the sound and decap faster + else + current_action = 0 + else + unbuckle_mob() + else + blade_status = GUILLOTINE_BLADE_MOVING + icon_state = "guillotine_drop" + playsound(src, 'sound/items/unsheath.ogg', 100, 1) + addtimer(CALLBACK(src, .proc/drop_blade), GUILLOTINE_ANIMATION_LENGTH) + +/obj/structure/guillotine/proc/raise_blade() + blade_status = GUILLOTINE_BLADE_RAISED + icon_state = "guillotine_raised" + +/obj/structure/guillotine/proc/drop_blade(mob/user) + if(has_buckled_mobs() && blade_sharpness) + var/mob/living/carbon/human/H = buckled_mob + + if(!H) + blade_status = GUILLOTINE_BLADE_DROPPED + icon_state = "guillotine" + return + + var/obj/item/organ/external/head/head = H.get_organ("head") + + if(QDELETED(head)) + blade_status = GUILLOTINE_BLADE_DROPPED + icon_state = "guillotine" + return + + playsound(src, 'sound/weapons/bladeslice.ogg', 100, 1) + if(blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP || head.brute_dam >= 100) + head.droplimb() + add_attack_logs(user, H, "beheaded with [src]") + H.regenerate_icons() + unbuckle_mob() + kill_count += 1 + + var/blood_overlay = "bloody" + + if(kill_count == 2) + blood_overlay = "bloodier" + else if(kill_count > 2) + blood_overlay = "bloodiest" + + blood_overlay = "guillotine_" + blood_overlay + "_overlay" + overlays.Cut() + overlays += mutable_appearance(icon, blood_overlay) + + if(force_clap) + // The crowd is pleased + // The delay is to make large crowds have a longer lasting applause + var/delay_offset = 0 + for(var/mob/living/carbon/human/HM in viewers(src, 7)) + addtimer(CALLBACK(HM, /mob/.proc/emote, "clap"), delay_offset * 0.3) + delay_offset++ + else + H.apply_damage(15 * blade_sharpness, BRUTE, head) + add_attack_logs(user, H, "non-fatally dropped the blade on with [src]") + H.emote("scream") + + if(blade_sharpness > 1) + blade_sharpness -= 1 + + blade_status = GUILLOTINE_BLADE_DROPPED + icon_state = "guillotine" + +/obj/structure/guillotine/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/whetstone)) + add_fingerprint(user) + if(blade_status == GUILLOTINE_BLADE_SHARPENING) + return + + if(blade_status == GUILLOTINE_BLADE_RAISED) + if(blade_sharpness < GUILLOTINE_BLADE_MAX_SHARP) + blade_status = GUILLOTINE_BLADE_SHARPENING + if(do_after(user, 7, target = src)) + blade_status = GUILLOTINE_BLADE_RAISED + user.visible_message("[user] sharpens the large blade of the guillotine.", + "You sharpen the large blade of the guillotine.") + blade_sharpness += 1 + playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) + return + else + blade_status = GUILLOTINE_BLADE_RAISED + return + else + to_chat(user, "The blade is sharp enough!") + return + else + to_chat(user, "You need to raise the blade in order to sharpen it!") + return + if(iswrench(W)) + if(current_action) + return + + current_action = GUILLOTINE_ACTION_WRENCH + + if(do_after(user, GUILLOTINE_WRENCH_DELAY, target = src)) + current_action = 0 + if(has_buckled_mobs()) + to_chat(user, "Can't unfasten, someone's strapped in!") + return + + if(current_action) + return + to_chat(user, "You [anchored ? "un" : ""]secure [src].") + anchored = !anchored + playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + dir = SOUTH + return TRUE + else + current_action = 0 + else + return ..() + +/obj/structure/guillotine/buckle_mob(mob/living/M, force = 0) + if(!anchored) + to_chat(usr, "The [src] needs to be wrenched to the floor!") + return FALSE + + if(!ishuman(M)) + to_chat(usr, "It doesn't look like they can fit into this properly!") + return FALSE // Can't decapitate non-humans + + if(blade_status != GUILLOTINE_BLADE_RAISED) + to_chat(usr, "You need to raise the blade before buckling someone in!") + return FALSE + + if(..()) + M.pixel_y -= GUILLOTINE_HEAD_OFFSET // Offset their body so it looks like they're in the guillotine + M.layer += GUILLOTINE_LAYER_DIFF + +/obj/structure/guillotine/unbuckle_mob(force = 0) + if(buckled_mob) + buckled_mob.pixel_y += GUILLOTINE_HEAD_OFFSET // Move their body back + buckled_mob.layer -= GUILLOTINE_LAYER_DIFF + . = ..() + +#undef GUILLOTINE_BLADE_MAX_SHARP +#undef GUILLOTINE_DECAP_MIN_SHARP +#undef GUILLOTINE_ANIMATION_LENGTH +#undef GUILLOTINE_BLADE_RAISED +#undef GUILLOTINE_BLADE_MOVING +#undef GUILLOTINE_BLADE_DROPPED +#undef GUILLOTINE_BLADE_SHARPENING +#undef GUILLOTINE_HEAD_OFFSET +#undef GUILLOTINE_LAYER_DIFF +#undef GUILLOTINE_ACTIVATE_DELAY +#undef GUILLOTINE_WRENCH_DELAY +#undef GUILLOTINE_ACTION_INUSE +#undef GUILLOTINE_ACTION_WRENCH \ No newline at end of file diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm new file mode 100644 index 00000000000..0b730a539b9 --- /dev/null +++ b/code/game/objects/structures/holosign.dm @@ -0,0 +1,135 @@ + +//holographic signs and barriers + +/obj/structure/holosign + name = "holo sign" + icon = 'icons/effects/effects.dmi' + anchored = TRUE + max_integrity = 1 + armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0) + var/obj/item/holosign_creator/projector + +/obj/structure/holosign/New(loc, source_projector) + if(source_projector) + projector = source_projector + projector.signs += src + ..() + +/obj/structure/holosign/Destroy() + if(projector) + projector.signs -= src + projector = null + return ..() + +/obj/structure/holosign/attack_hand(mob/living/user) + . = ..() + if(.) + return + user.do_attack_animation(src) + user.changeNext_move(CLICK_CD_MELEE) + take_damage(5 , BRUTE, "melee", 1) + +/obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + playsound(loc, 'sound/weapons/egloves.ogg', 80, 1) + if(BURN) + playsound(loc, 'sound/weapons/egloves.ogg', 80, 1) + +/obj/structure/holosign/wetsign + name = "wet floor sign" + desc = "The words flicker as if they mean nothing." + icon_state = "holosign" + +/obj/structure/holosign/barrier + name = "holo barrier" + desc = "A short holographic barrier which can only be passed by walking." + icon_state = "holosign_sec" + pass_flags = LETPASSTHROW + density = TRUE + max_integrity = 20 + var/allow_walk = TRUE //can we pass through it on walk intent + +/obj/structure/holosign/barrier/CanPass(atom/movable/mover, turf/target) + if(!density) + return TRUE + if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE)) + return TRUE + if(iscarbon(mover)) + var/mob/living/carbon/C = mover + if(allow_walk && C.m_intent == MOVE_INTENT_WALK) + return TRUE + +/obj/structure/holosign/barrier/engineering + icon_state = "holosign_engi" + +/obj/structure/holosign/barrier/atmos + name = "holo firelock" + desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out." + icon_state = "holo_firelock" + density = FALSE + layer = ABOVE_MOB_LAYER + anchored = TRUE + layer = ABOVE_MOB_LAYER + alpha = 150 + +/obj/structure/holosign/barrier/atmos/New() + ..() + air_update_turf(TRUE) + +/obj/structure/holosign/barrier/atmos/CanAtmosPass(turf/T) + return FALSE + +/obj/structure/holosign/barrier/atmos/Destroy() + var/turf/T = get_turf(src) + T.air_update_turf(TRUE) + return ..() + +/obj/structure/holosign/barrier/cyborg + name = "Energy Field" + desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles." + density = TRUE + max_integrity = 10 + allow_walk = FALSE + +/obj/structure/holosign/barrier/cyborg/bullet_act(obj/item/projectile/P) + take_damage((P.damage / 5) , BRUTE, "melee", 1) //Doesn't really matter what damage flag it is. + if(istype(P, /obj/item/projectile/energy/electrode)) + take_damage(10, BRUTE, "melee", 1) //Tasers aren't harmful. + if(istype(P, /obj/item/projectile/beam/disabler)) + take_damage(5, BRUTE, "melee", 1) //Disablers aren't harmful. + +/obj/structure/holosign/barrier/cyborg/hacked + name = "Charged Energy Field" + desc = "A powerful energy field that blocks movement. Energy arcs off it." + max_integrity = 20 + var/shockcd = 0 + +/obj/structure/holosign/barrier/cyborg/hacked/bullet_act(obj/item/projectile/P) + take_damage(P.damage, BRUTE, "melee", 1) //Yeah no this doesn't get projectile resistance. + +/obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() + shockcd = FALSE + +/obj/structure/holosign/barrier/cyborg/hacked/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(!shockcd) + if(ismob(user)) + var/mob/living/M = user + M.electrocute_act(15,"Energy Barrier", safety=1) + shockcd = TRUE + addtimer(CALLBACK(src, .proc/cooldown), 5) + +/obj/structure/holosign/barrier/cyborg/hacked/Bumped(atom/movable/AM) + if(shockcd) + return + + if(!isliving(AM)) + return + + var/mob/living/M = AM + M.electrocute_act(15, "Energy Barrier", safety = 1) + shockcd = TRUE + addtimer(CALLBACK(src, .proc/cooldown), 5) diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 6d03ca4fdef..4ea0fc34e2d 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -25,7 +25,7 @@ var/health = 50.0 -/obj/structure/inflatable/initialize(location) +/obj/structure/inflatable/Initialize(location) ..() air_update_turf(1) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index f4a2990918b..e0e9ba1b6a7 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -24,7 +24,7 @@ ..() initial_state = icon_state -/obj/structure/mineral_door/initialize() +/obj/structure/mineral_door/Initialize() ..() air_update_turf(1) diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm index 131a355feb2..6be7bf072d8 100644 --- a/code/game/objects/structures/misc.dm +++ b/code/game/objects/structures/misc.dm @@ -87,7 +87,7 @@ var/atom/attack_atom -/obj/structure/ghost_beacon/initialize() +/obj/structure/ghost_beacon/Initialize() . = ..() last_ghost_alert = world.time attack_atom = src diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 3e5d3386e0a..60ca03ad0f7 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -29,7 +29,7 @@ anchored = 1.0 var/open_sound = 'sound/items/Deconstruct.ogg' -/obj/structure/morgue/initialize() +/obj/structure/morgue/Initialize() . = ..() update() diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index da4c1181f01..b8c28046bd3 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -295,7 +295,7 @@ QDEL_NULL(song) return ..() -/obj/structure/piano/initialize() +/obj/structure/piano/Initialize() song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded ..() diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index caa1bf48b4b..8ea6a3c0cce 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -7,7 +7,8 @@ anchored = 1 var/notices = 0 -/obj/structure/noticeboard/initialize() +/obj/structure/noticeboard/Initialize() + ..() for(var/obj/item/I in loc) if(notices > 4) break if(istype(I, /obj/item/paper)) diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index f0a2c28af85..8d22732e5dd 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -124,7 +124,7 @@ name = "airtight plastic flaps" desc = "Heavy duty, airtight, plastic flaps." -/obj/structure/plasticflaps/mining/initialize() +/obj/structure/plasticflaps/mining/Initialize() air_update_turf(1) ..() diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 315728ddc16..44c9da74b20 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -30,7 +30,8 @@ FLOOR SAFES tumbler_2_open = rand(0, 71) -/obj/structure/safe/initialize() +/obj/structure/safe/Initialize() + ..() for(var/obj/item/I in loc) if(space >= maxspace) return @@ -178,7 +179,7 @@ obj/structure/safe/ex_act(severity) layer = 2.5 -/obj/structure/safe/floor/initialize() +/obj/structure/safe/floor/Initialize() ..() var/turf/T = loc hide(T.intact) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 002bbb566d6..4fedc99f0c5 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -376,7 +376,7 @@ return // Don't break if they're just flying past if(AM.throwing) - addtimer(src, "throw_check", 5, FALSE, AM) + addtimer(CALLBACK(src, .proc/throw_check, AM), 5) else check_break(AM) @@ -616,7 +616,7 @@ if(user.weakened || user.resting || user.lying) return user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) + user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] kicks [src].", \ "You kick [src].") take_damage(rand(4,8), BRUTE, "melee", 1) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 7cc9c97dfdd..3ea23108662 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -249,9 +249,11 @@ var/ismist = 0 //needs a var so we can make it linger~ var/watertemp = "normal" //freezing, normal, or boiling var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process() + var/datum/looping_sound/showering/soundloop /obj/machinery/shower/New(turf/T, newdir = SOUTH, building = FALSE) ..() + soundloop = new(list(src), FALSE) if(building) dir = newdir pixel_x = 0 @@ -264,8 +266,8 @@ layer = FLY_LAYER /obj/machinery/shower/Destroy() - if(mymist) - QDEL_NULL(mymist) + QDEL_NULL(mymist) + QDEL_NULL(soundloop) return ..() //add heat controls? when emagged, you can freeze to death in it? @@ -282,6 +284,7 @@ on = !on update_icon() if(on) + soundloop.start() if(M.loc == loc) wash(M) check_heat(M) @@ -289,6 +292,8 @@ for(var/atom/movable/G in src.loc) G.clean_blood() G.water_act(100, convertHeat(), src) + else + soundloop.stop() /obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params) if(I.type == /obj/item/analyzer) @@ -338,9 +343,9 @@ mist_time = 70 //7 seconds on freezing temperature to disperse existing mist if(watertemp == "boiling") mist_time = 20 //2 seconds on boiling temperature to build up mist - addtimer(src, "update_mist", mist_time) + addtimer(CALLBACK(src, .proc/update_mist), mist_time) else - addtimer(src, "update_mist", 250) //25 seconds for mist to disperse after being turned off + addtimer(CALLBACK(src, .proc/update_mist), 250) //25 seconds for mist to disperse after being turned off /obj/machinery/shower/proc/update_mist() if(on) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index c93a0e5f1b8..aebd111ad26 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -386,7 +386,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f update_nearby_icons() return -/obj/structure/window/initialize() +/obj/structure/window/Initialize() air_update_turf(1) return ..() @@ -454,7 +454,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f update_nearby_icons() return -/obj/structure/window/plasmabasic/initialize() +/obj/structure/window/plasmabasic/Initialize() ..() air_update_turf(1) @@ -483,7 +483,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f update_nearby_icons() return -/obj/structure/window/plasmareinforced/initialize() +/obj/structure/window/plasmareinforced/Initialize() ..() air_update_turf(1) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 9fdf3121b59..a865e4a5ad9 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -104,8 +104,12 @@ var/ert_request_answered = 0 if(index > emergencyresponseteamspawn.len) index = 1 + if(!M || !M.client) + continue var/client/C = M.client var/mob/living/new_commando = C.create_response_team(emergencyresponseteamspawn[index]) + if(!M || !new_commando) + continue new_commando.mind.key = M.key new_commando.key = M.key new_commando.update_icons() @@ -157,17 +161,17 @@ var/ert_request_answered = 0 head_organ.h_style = random_hair_style(M.gender, head_organ.species.name) head_organ.f_style = random_facial_hair_style(M.gender, head_organ.species.name) - M.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]" - M.name = M.real_name + M.rename_character(null, "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]") M.age = rand(23,35) M.regenerate_icons() M.update_body() + M.update_dna() //Creates mind stuff. M.mind = new M.mind.current = M M.mind.original = M - M.mind.assigned_role = "MODE" + M.mind.assigned_role = SPECIAL_ROLE_ERT M.mind.special_role = SPECIAL_ROLE_ERT if(!(M.mind in ticker.minds)) ticker.minds += M.mind //Adds them to regular mind list. @@ -199,13 +203,13 @@ var/ert_request_answered = 0 var/cyborg_unlock = 0 /datum/response_team/proc/setSlots(com, sec, med, eng, jan, par, cyb) - command_slots = com - security_slots = sec - medical_slots = med - engineer_slots = eng - janitor_slots = jan - paranormal_slots = par - cyborg_slots = cyb + command_slots = com || command_slots + security_slots = sec || security_slots + medical_slots = med || medical_slots + engineer_slots = eng || engineer_slots + janitor_slots = jan || janitor_slots + paranormal_slots = par || paranormal_slots + cyborg_slots = cyb || cyborg_slots /datum/response_team/proc/reduceCyborgSlots() cyborg_slots-- @@ -280,8 +284,7 @@ var/ert_request_answered = 0 command_slots = 0 // Override name and age for the commander - M.real_name = "[pick("Lieutenant", "Captain", "Major")] [pick(last_names)]" - M.name = M.real_name + M.rename_character(null, "[pick("Lieutenant", "Captain", "Major")] [pick(last_names)]") M.age = rand(35,45) M.equipOutfit(command_outfit) diff --git a/code/game/skincmd.dm b/code/game/skincmd.dm deleted file mode 100644 index 7d27a1ce6df..00000000000 --- a/code/game/skincmd.dm +++ /dev/null @@ -1,13 +0,0 @@ -/mob/var/skincmds = list() -/obj/proc/SkinCmd(mob/user as mob, var/data as text) - -/proc/SkinCmdRegister(var/mob/user, var/name as text, var/O as obj) - user.skincmds[name] = O - -/mob/verb/skincmd(data as text) - set hidden = 1 - - var/ref = copytext(data, 1, findtext(data, ";")) - if(src.skincmds[ref] != null) - var/obj/a = src.skincmds[ref] - a.SkinCmd(src, copytext(data, findtext(data, ";") + 1)) \ No newline at end of file diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm deleted file mode 100644 index 20dea8de7b0..00000000000 --- a/code/game/smoothwall.dm +++ /dev/null @@ -1,108 +0,0 @@ -// OKAY I DON'T KNOW WHO THE FUCK ORIGINALLY CODED THIS BUT THEY ARE OFFICIALLY FIRED FOR BEING DRUNK AND STUPID -// FUCK YOU MYSTERY CODERS -// FOR THIS SHIT I'M GOING TO MAKE ALL MY COMMENTS IN CAPS - -/atom - var/list/canSmoothWith=list() // TYPE PATHS I CAN SMOOTH WITH~~~~~ - -// MOVED INTO UTILITY FUNCTION FOR LESS DUPLICATED CODE. -/atom/proc/findSmoothingNeighbors() - // THIS IS A BITMAP BECAUSE NORTH/SOUTH/ETC ARE ALL BITFLAGS BECAUSE BYOND IS DUMB AND - // DOESN'T FUCKING MAKE SENSE, BUT IT WORKS TO OUR ADVANTAGE - var/junction = 0 - for(var/cdir in cardinal) - var/turf/T = get_step(src,cdir) - if(isSmoothableNeighbor(T)) - junction |= cdir - continue // NO NEED FOR FURTHER SEARCHING IN THIS TILE - for(var/atom/A in T) - if(isSmoothableNeighbor(A)) - junction |= cdir - break // NO NEED FOR FURTHER SEARCHING IN THIS TILE - - return junction - -/atom/proc/isSmoothableNeighbor(var/atom/A) - return is_type_in_list(A,canSmoothWith) - -/turf/simulated/wall/isSmoothableNeighbor(var/atom/A) - if(is_type_in_list(A,canSmoothWith)) - // COLON OPERATORS ARE TERRIBLE BUT I HAVE NO CHOICE - if(src.mineral == A:mineral) //mineral not walltype so reinf still smooths with normal and vice versa - return 1 - return 0 - -/** - * WALL SMOOTHING SHIT - * - * IN /ATOM BECAUSE /TURFS ARE /ATOMS AND SO ARE /OBJ/STRUCTURE/FALSEWALLS - * THIS IS STUPID BUT IS FAIRLY ELEGANT FOR BYOND - * - * HOWEVER, INSTEAD OF MAKING ONE BIG GODDAMN MONOLITHIC PROC LIKE A FUCKING - * SHITTY FUNCTIONAL PROGRAMMER, WE WILL BE COOL AND MODERN AND USE INHERITANCE. - */ -/atom/proc/relativewall() - return // DOES JACK SHIT BY DEFAULT. OLD BEHAVIOR WAS TO SPAM LOOPS ANYWAY. - -/* - * SEE? NOW WE ONLY HAVE TO PROGRAM THIS SHIT INTO WHAT WE WANT TO SMOOTH - * INSTEAD OF BEING DUMB AND HAVING A BIG FUCKING IFTREE WITH TYPECHECKS - * MY GOD, WE COULD EVEN MOVE THE CODE TO BE WITH THE REST OF THE WALL'S CODE! - * HOW FUCKING INNOVATIVE. ISN'T INHERITANCE NICE? - * - * WE COULD STANDARDIZE THIS BUT EVERYONE'S A FUCKING SNOWFLAKE - */ -/turf/simulated/wall/relativewall() - var/junction=findSmoothingNeighbors() - icon_state = "[walltype][junction]" // WHY ISN'T THIS IN UPDATE_ICON OR SIMILAR - -/atom/proc/relativewall_neighbours(var/sko=0) //SKO: Skip Optimizations - // OPTIMIZE BY NOT CHECKING FOR NEIGHBORS IF WE DON'T FUCKING SMOOTH - if(canSmoothWith.len>0 || sko) - relativewall() - for(var/cdir in cardinal) - var/turf/T = get_step(src,cdir) - if(isSmoothableNeighbor(T) || sko) - T.relativewall() - for(var/atom/A in T) - if(isSmoothableNeighbor(A) || sko) - A.relativewall() - -/turf/simulated/wall/New() - ..() - relativewall_neighbours() - -/turf/simulated/wall/Destroy() - for(var/obj/effect/E in src) - if(E.name == "Wallrot") - qdel(E) - - if(!del_suppress_resmoothing) - spawn(10) - relativewall_neighbours(sko=1) - - // JESUS WHY - for(var/direction in cardinal) - for(var/obj/structure/glowshroom/shroom in get_step(src,direction)) - if(!shroom.floor) //shrooms drop to the floor - shroom.floor = 1 - shroom.icon_state = "glowshroomf" - shroom.pixel_x = 0 - shroom.pixel_y = 0 -/* for(var/obj/effect/supermatter_crystal/crystal in get_step(src,direction)) - if(!crystal.floor) //crystals drop to the floor - crystal.floor = 1 - crystal.icon_state = "supermatter_crystalf" - crystal.pixel_x = 0 - crystal.pixel_y = 0 */ - return ..() - -// DE-HACK -/turf/simulated/wall/vault/relativewall() - return - - -/obj/structure/alien/resin/relativewall() - var/junction = findSmoothingNeighbors() - icon_state = "[resintype][junction]" - return \ No newline at end of file diff --git a/code/game/sound.dm b/code/game/sound.dm index 39bf16bc697..66746ece0ae 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,4 +1,4 @@ -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE) +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE) if(isarea(source)) error("[source] is an area and is trying to make the sound: [soundin]") return @@ -11,7 +11,10 @@ // Looping through the player list has the added bonus of working for mobs inside containers var/sound/S = sound(get_sfx(soundin)) var/maxdistance = (world.view + extrarange) * 3 - for(var/P in player_list) + var/list/listeners = player_list + if(!ignore_walls) //these sounds don't carry through walls + listeners = listeners & hearers(maxdistance, turf_source) + for(var/P in listeners) var/mob/M = P if(!M || !M.client) continue @@ -78,13 +81,15 @@ S.y = 1 S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) - src << S + SEND_SOUND(src, S) -/client/proc/playtitlemusic() - if(!ticker || !ticker.login_music || config.disable_lobby_music) - return - if(prefs.sound & SOUND_LOBBY) - src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS +/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S) + if(!S) + S = sound(get_sfx(soundin)) + for(var/m in player_list) + if(ismob(m) && !isnewplayer(m)) + var/mob/M = m + M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S) /proc/open_sound_channel() var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used @@ -93,7 +98,13 @@ next_channel = 1 /mob/proc/stop_sound_channel(chan) - src << sound(null, repeat = 0, wait = 0, channel = chan) + SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan)) + +/client/proc/playtitlemusic() + if(!ticker || !ticker.login_music || config.disable_lobby_music) + return + if(prefs.sound & SOUND_LOBBY) + SEND_SOUND(src, sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC)) // MAD JAMS /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm index cbb5647f283..cba841ce823 100644 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ b/code/game/turfs/simulated/floor/plasteel_floor.dm @@ -18,8 +18,13 @@ /turf/simulated/floor/plasteel/airless/New() ..() - name = "floor" - + name = "floor" + +/turf/simulated/floor/plasteel/airless/indestructible // For bomb testing range + +/turf/simulated/floor/plasteel/airless/indestructible/ex_act(severity) + return + /turf/simulated/floor/plasteel/goonplaque icon_state = "plaque" name = "Commemorative Plaque" diff --git a/code/game/world.dm b/code/game/world.dm index 4ebeadedc6f..7d592864501 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -16,10 +16,12 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG GLOB.timezoneOffset = text2num(time2text(0, "hh")) * 36000 + makeDatumRefLists() callHook("startup") src.update_status() + . = ..() // Create robolimbs for chargen. @@ -324,6 +326,10 @@ var/world_topic_spam_protect_time = world.timeofday processScheduler.stop() shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. + for(var/client/C in clients) + if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite + C << link("byond://[config.server]") + if(config && config.shutdown_on_reboot) sleep(0) if(shutdown_shell_command) @@ -331,9 +337,6 @@ var/world_topic_spam_protect_time = world.timeofday del(world) return else - for(var/client/C in clients) - if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite - C << link("byond://[config.server]") ..(0) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index b97993d5327..4c905a0b517 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -93,7 +93,7 @@ world/IsBanned(key,address,computer_id) var/appealmessage = "" if(config.banappeals) appealmessage = " You may appeal it at [config.banappeals]." - expires = " The is a permanent ban.[appealmessage]" + expires = " This is a permanent ban.[appealmessage]" var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime].[expires]" diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 21731cc8b7a..5039146b1c3 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -25,8 +25,6 @@ Show current traitors and objectives
Set Night Shift Mode
Bombs
- Bombing List   - Remove all bombs currently in existence [check_rights(R_SERVER, 0) ? "  Toggle bomb cap
" : "
"] Lists
Show last [length(lastsignalers)] signalers   @@ -130,5 +128,3 @@ var/datum/browser/popup = new(usr, "secrets", "
Admin Secrets
", 630, 670) popup.set_content(dat) popup.open(0) - - diff --git a/code/modules/admin/tickets/admintickets.dm b/code/modules/admin/tickets/admintickets.dm index 5ef1f58dbf5..ea5f7003870 100644 --- a/code/modules/admin/tickets/admintickets.dm +++ b/code/modules/admin/tickets/admintickets.dm @@ -104,7 +104,7 @@ var/global/datum/adminTicketHolder/globAdminTicketHolder = new /datum/adminTicke /datum/adminTicketHolder/proc/checkForTicket(var/client/C) var/list/tickets = list() for(var/datum/admin_ticket/T in allTickets) - if(T.clientName == C && T.ticketState == ADMIN_TICKET_OPEN || T.ticketState == ADMIN_TICKET_STALE) + if(T.clientName == C && (T.ticketState == ADMIN_TICKET_OPEN || T.ticketState == ADMIN_TICKET_STALE)) tickets += T if(tickets.len) return tickets diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 44328429dc0..eceb97044c0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1941,7 +1941,7 @@ newtraitor.mind.special_role = SPECIAL_ROLE_TRAITOR var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR] tatorhud.join_hud(newtraitor) - ticker.mode.set_antag_hud(newtraitor, "hudsyndicate") + set_antag_hud(newtraitor, "hudsyndicate") else to_chat(usr, "ERROR: Failed to create a traitor.") return @@ -2957,13 +2957,6 @@ var/ok = 0 switch(href_list["secretsadmin"]) - if("clear_bombs") - //I do nothing - if("list_bombers") - var/dat = "Bombing List
" - for(var/l in bombers) - dat += text("[l]
") - usr << browse(dat, "window=bombers") if("list_signalers") var/dat = "Showing last [length(lastsignalers)] signalers.
" for(var/sig in lastsignalers) @@ -3436,7 +3429,7 @@ hunter_mob.mind.special_role = SPECIAL_ROLE_TRAITOR var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR] tatorhud.join_hud(hunter_mob) - ticker.mode.set_antag_hud(hunter_mob, "hudsyndicate") + set_antag_hud(hunter_mob, "hudsyndicate") /proc/admin_jump_link(var/atom/target) if(!target) return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 2533eab0570..600a53d81eb 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -183,6 +183,8 @@ if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) to_chat(X, "[type]: [key_name(src, TRUE, type)]->[key_name(C, TRUE, type)]: [emoji_msg]") + if(type == "Mentorhelp") + return //Check if the mob being PM'd has any open admin tickets. var/tickets = list() tickets = globAdminTicketHolder.checkForTicket(C) diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index f091e49f60e..2a0f78351e4 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -12,6 +12,7 @@ if(check_rights(R_ADMIN,0)) for(var/client/C in admins) if(R_ADMIN & C.holder.rights) + msg = "[msg]" to_chat(C, "ADMIN: [key_name(usr, 1)] ([admin_jump_link(mob)]): [msg]") feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -38,6 +39,7 @@ display_name = "[holder.fakekey]/([key])" else display_name = holder.fakekey + msg = "[msg]" to_chat(C, "MENTOR: [display_name] ([admin_jump_link(mob)]): [msg]") feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/atmosdebug.dm b/code/modules/admin/verbs/atmosdebug.dm index 85591ee3159..de281d34e68 100644 --- a/code/modules/admin/verbs/atmosdebug.dm +++ b/code/modules/admin/verbs/atmosdebug.dm @@ -51,7 +51,7 @@ return feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - for(var/datum/powernet/PN in powernets) + for(var/datum/powernet/PN in SSmachines.powernets) if(!PN.nodes || !PN.nodes.len) if(PN.cables && (PN.cables.len > 1)) var/obj/structure/cable/C = PN.cables[1] diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 78f9fbd5de1..00966ee31fc 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -387,7 +387,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(!check_rights(R_DEBUG)) return - makepowernets() + SSmachines.makepowernets() log_admin("[key_name(src)] has remade the powernet. makepowernets() called.") message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0) feedback_add_details("admin_verb","MPWN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm index 2ca1d3c27df..6192ad6b2ac 100644 --- a/code/modules/admin/verbs/gimmick_team.dm +++ b/code/modules/admin/verbs/gimmick_team.dm @@ -70,7 +70,7 @@ H.dna.ready_dna(H) H.mind_initialize() - H.mind.assigned_role = "MODE" + H.mind.assigned_role = "Event Character" H.mind.special_role = "Event Character" H.key = thisplayer.key diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm index 36001fb9035..1e72c1836da 100644 --- a/code/modules/admin/verbs/honksquad.dm +++ b/code/modules/admin/verbs/honksquad.dm @@ -91,7 +91,7 @@ var/global/sent_honksquad = 0 //Creates mind stuff. new_honksquad.mind_initialize() - new_honksquad.mind.assigned_role = "MODE" + new_honksquad.mind.assigned_role = SPECIAL_ROLE_HONKSQUAD new_honksquad.mind.special_role = SPECIAL_ROLE_HONKSQUAD new_honksquad.add_language("Clownish") ticker.mode.traitors |= new_honksquad.mind//Adds them to current traitor list. Which is really the extra antagonist list. diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm index dad0141a3bc..a3f30117cdd 100644 --- a/code/modules/admin/verbs/infiltratorteam_syndicate.dm +++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm @@ -109,7 +109,7 @@ var/global/sent_syndicate_infiltration_team = 0 new_syndicate_infiltrator.mind.store_memory("Starting Equipment:
- Syndicate Headset ((.h for your radio))
- Chameleon Jumpsuit ((right click to Change Color))
- Agent ID card ((disguise as another job))
- Uplink Implant ((top left of screen))
- Dust Implant ((destroys your body on death))
- Combat Gloves ((insulated, disguised as black gloves))
- Anything bought with your uplink implant") var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS] opshud.join_hud(new_syndicate_infiltrator.mind.current) - ticker.mode.set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative") + set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative") new_syndicate_infiltrator.regenerate_icons() num_spawned++ if(!teamsize) @@ -127,7 +127,7 @@ var/global/sent_syndicate_infiltration_team = 0 syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate, slot_wear_mask) var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS] opshud.join_hud(syndimgmtmob.mind.current) - ticker.mode.set_antag_hud(syndimgmtmob.mind.current, "hudoperative") + set_antag_hud(syndimgmtmob.mind.current, "hudoperative") syndimgmtmob.mind.special_role = "Syndicate Management Consultant" syndimgmtmob.regenerate_icons() to_chat(syndimgmtmob, "You have spawned as Syndicate Management. You should brief them on their mission before they go.") @@ -149,7 +149,7 @@ var/global/sent_syndicate_infiltration_team = 0 //Creates mind stuff. new_syndicate_infiltrator.mind_initialize() - new_syndicate_infiltrator.mind.assigned_role = "MODE" + new_syndicate_infiltrator.mind.assigned_role = "Syndicate Infiltrator" new_syndicate_infiltrator.mind.special_role = "Syndicate Infiltrator" ticker.mode.traitors |= new_syndicate_infiltrator.mind //Adds them to extra antag list new_syndicate_infiltrator.equip_syndicate_infiltrator(syndicate_leader_selected, uplink_tc, is_mgmt) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 57e5b968178..b3f0a1a15a8 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -411,7 +411,7 @@ client/proc/one_click_antag() //Creates mind stuff. new_syndicate_commando.mind_initialize() - new_syndicate_commando.mind.assigned_role = "MODE" + new_syndicate_commando.mind.assigned_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD new_syndicate_commando.mind.special_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD //Adds them to current traitor list. Which is really the extra antagonist list. diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 29c6111bc02..9eef4331ee0 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -429,7 +429,7 @@ Traitors and the like can also be revived with the previous role mostly intact. //Announces the character on all the systems, based on the record. if(!issilicon(new_character))//If they are not a cyborg/AI. - if(!record_found&&new_character.mind.assigned_role!="MODE")//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. + if(!record_found && new_character.mind.assigned_role != new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. Offstation special characters announced anyway. //Power to the user! if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") data_core.manifest_inject(new_character) diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 020cadeebe3..8eaede660e1 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -5,14 +5,16 @@ var/global/sent_strike_team = 0 /client/proc/strike_team() if(!ticker) - to_chat(usr, "The game hasn't started yet!") + to_chat(usr, "The game hasn't started yet!") return if(sent_strike_team == 1) - to_chat(usr, "CentComm is already sending a team.") + to_chat(usr, "CentComm is already sending a team.") return if(alert("Do you want to send in the CentComm death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes") return - alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") + alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. The first one selected/spawned will be the team leader.") + + message_admins("[key_name_admin(usr)] has started to spawn a CentComm DeathSquad.", 1) var/input = null while(!input) @@ -25,13 +27,7 @@ var/global/sent_strike_team = 0 to_chat(usr, "Looks like someone beat you to it.") return - sent_strike_team = 1 - - shuttle_master.cancelEvac() - var/commando_number = commandos_possible //for selecting a leader - var/leader_selected = 0 //when the leader is chosen. The last person spawned. - -//Code for spawning a nuke auth code. + // Find the nuclear auth code var/nuke_code var/temp_code for(var/obj/machinery/nuclearbomb/N in world) @@ -40,42 +36,69 @@ var/global/sent_strike_team = 0 nuke_code = N.r_code break -//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. - var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world. - var/list/commandos = list() //actual commando ghosts as picked by the user. - for(var/mob/dead/observer/G in player_list) - if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list. - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G.key - for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected. - var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate. - candidates -= candidate //Subtract from candidates. - commandos += candidate//Add their ghost to commandos. + // Find ghosts willing to be DS + var/list/commando_ckeys = pollCandidatesByKeyWithVeto(src, usr, commandos_possible, "Join the DeathSquad?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) + if(!commando_ckeys.len) + to_chat(usr, "Nobody volunteered to join the DeathSquad.") + return -//Spawns commandos and equips them. + sent_strike_team = 1 + + // Spawns commandos and equips them. + var/commando_number = commandos_possible //for selecting a leader + var/is_leader = TRUE // set to FALSE after leader is spawned for(var/obj/effect/landmark/L in landmarks_list) if(commando_number<=0) break if(L.name == "Commando") - leader_selected = commando_number == 1?1:0 - var/mob/living/carbon/human/new_commando = create_death_commando(L, leader_selected) + spawn(0) + var/use_ds_borg = FALSE + var/ghost_key // Ghost ckey that we intend to put into the commando. Can remain undefined if we don't have one. + if(commando_ckeys.len) + ghost_key = pick(commando_ckeys) + commando_ckeys -= ghost_key + if(!is_leader) + var/new_gender = alert(src, "Select Deathsquad Type.", "DS Character Generation", "Organic", "Cyborg") + if(new_gender == "Cyborg") + use_ds_borg = TRUE - if(commandos.len) - new_commando.key = pick(commandos) - commandos -= new_commando.key - new_commando.internal = new_commando.s_store - new_commando.update_action_buttons_icon() - - //So they don't forget their code or mission. - if(nuke_code) - new_commando.mind.store_memory("Nuke Code: [nuke_code].") - new_commando.mind.store_memory("Mission: [input].") - - to_chat(new_commando, "You are a Special Ops. [!leader_selected ? "commando" : "LEADER"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]") + if(use_ds_borg) + var/mob/living/silicon/robot/deathsquad/R = new() + R.forceMove(get_turf(L)) + var/rnum = rand(1,1000) + var/borgname = "Epsilon [rnum]" + R.name = borgname + R.custom_name = borgname + R.real_name = R.name + R.mind = new + R.mind.current = R + R.mind.original = R + R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD + R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD + if(!(R.mind in ticker.minds)) + ticker.minds += R.mind + ticker.mode.traitors += R.mind + if(ghost_key) + R.key = ghost_key + if(nuke_code) + R.mind.store_memory("Nuke Code: [nuke_code].") + R.mind.store_memory("Mission: [input].") + to_chat(R, "You are a Special Operations cyborg, in the service of Central Command. \nYour current mission is: [input]") + else + var/mob/living/carbon/human/new_commando = create_death_commando(L, is_leader) + if(ghost_key) + new_commando.key = ghost_key + new_commando.internal = new_commando.s_store + new_commando.update_action_buttons_icon() + if(nuke_code) + new_commando.mind.store_memory("Nuke Code: [nuke_code].") + new_commando.mind.store_memory("Mission: [input].") + to_chat(new_commando, "You are a Special Ops [is_leader ? "TEAM LEADER" : "commando"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]") + is_leader = FALSE commando_number-- -//Spawns the rest of the commando gear. + //Spawns the rest of the commando gear. for(var/obj/effect/landmark/L in landmarks_list) if(L.name == "Commando_Manual") //new /obj/item/gun/energy/pulse_rifle(L.loc) @@ -92,18 +115,18 @@ var/global/sent_strike_team = 0 new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) qdel(L) - message_admins("[key_name_admin(usr)] has spawned a CentComm strike squad.", 1) + message_admins("[key_name_admin(usr)] has spawned a CentComm DeathSquad.", 1) log_admin("[key_name(usr)] used Spawn Death Squad.") return 1 -/client/proc/create_death_commando(obj/spawn_location, leader_selected = 0) +/client/proc/create_death_commando(obj/spawn_location, is_leader = FALSE) var/mob/living/carbon/human/new_commando = new(spawn_location.loc) var/commando_leader_rank = pick("Lieutenant", "Captain", "Major") var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") var/commando_name = pick(last_names) var/datum/preferences/A = new()//Randomize appearance for the commando. - if(leader_selected) + if(is_leader) A.age = rand(35,45) A.real_name = "[commando_leader_rank] [commando_name]" else @@ -114,21 +137,21 @@ var/global/sent_strike_team = 0 //Creates mind stuff. new_commando.mind_initialize() - new_commando.mind.assigned_role = "MODE" + new_commando.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD new_commando.mind.special_role = SPECIAL_ROLE_DEATHSQUAD ticker.mode.traitors |= new_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list. - new_commando.equip_death_commando(leader_selected) + new_commando.equip_death_commando(is_leader) return new_commando -/mob/living/carbon/human/proc/equip_death_commando(leader_selected = 0) +/mob/living/carbon/human/proc/equip_death_commando(is_leader = FALSE) var/obj/item/radio/R = new /obj/item/radio/headset/alt(src) R.set_frequency(DTH_FREQ) equip_to_slot_or_del(R, slot_l_ear) - if(leader_selected == 0) - equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform) - else + if(is_leader) equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform) + else + equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform) equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(src), slot_shoes) equip_to_slot_or_del(new /obj/item/clothing/suit/space/deathsquad(src), slot_wear_suit) equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves) @@ -143,20 +166,19 @@ var/global/sent_strike_team = 0 equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/storage/box/flashbangs(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/flashlight(src), slot_in_backpack) - if(!leader_selected) - equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack) - else - equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack) + equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack) + if(is_leader) equip_to_slot_or_del(new /obj/item/disk/nuclear(src), slot_in_backpack) + else + equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack) + equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber(src), slot_l_store) equip_to_slot_or_del(new /obj/item/shield/energy(src), slot_r_store) equip_to_slot_or_del(new /obj/item/tank/emergency_oxygen/double/full(src), slot_s_store) equip_to_slot_or_del(new /obj/item/gun/projectile/revolver/mateba(src), slot_belt) - equip_to_slot_or_del(new /obj/item/gun/energy/pulse(src), slot_r_hand) - var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(src) L.implant(src) diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index 943ccd61ca2..ec31632208e 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -17,7 +17,9 @@ var/global/sent_syndicate_strike_team = 0 return if(alert("Do you want to send in the Syndicate Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No") return - alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned syndicates have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") + alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned syndicates have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. The first one selected/spawned will be the team leader.") + + message_admins("[key_name_admin(usr)] has started to spawn a Syndicate Strike Team.", 1) var/input = null while(!input) @@ -30,15 +32,10 @@ var/global/sent_syndicate_strike_team = 0 to_chat(src, "Looks like someone beat you to it.") return - sent_syndicate_strike_team = 1 - - //if(emergency_shuttle.can_recall()) - // emergency_shuttle.recall() //why, exactly? Admins can do this themselves. - var/syndicate_commando_number = syndicate_commandos_possible //for selecting a leader - var/syndicate_leader_selected = 0 //when the leader is chosen. The last person spawned. + var/is_leader = TRUE // set to FALSE after leader is spawned -//Code for spawning a nuke auth code. + // Find the nuclear auth code var/nuke_code var/temp_code for(var/obj/machinery/nuclearbomb/N in world) @@ -47,29 +44,23 @@ var/global/sent_syndicate_strike_team = 0 nuke_code = N.r_code break -//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. - var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world. - var/list/commandos = list() //actual commando ghosts as picked by the user. - for(var/mob/dead/observer/G in player_list) - if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list. - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G.key - for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected. - var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate. - candidates -= candidate //Subtract from candidates. - commandos += candidate//Add their ghost to commandos. + // Find ghosts willing to be SST + var/list/commando_ckeys = pollCandidatesByKeyWithVeto(src, usr, syndicate_commandos_possible, "Join the Syndicate Strike Team?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) + if(!commando_ckeys.len) + to_chat(usr, "Nobody volunteered to join the SST.") + return -//Spawns commandos and equips them. + sent_syndicate_strike_team = 1 + + //Spawns commandos and equips them. for(var/obj/effect/landmark/L in landmarks_list) if(syndicate_commando_number<=0) break if(L.name == "Syndicate-Commando") - syndicate_leader_selected = syndicate_commando_number == 1?1:0 + var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, is_leader) - var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected) - - if(commandos.len) - new_syndicate_commando.key = pick(commandos) - commandos -= new_syndicate_commando.key + if(commando_ckeys.len) + new_syndicate_commando.key = pick(commando_ckeys) + commando_ckeys -= new_syndicate_commando.key new_syndicate_commando.internal = new_syndicate_commando.s_store new_syndicate_commando.update_action_buttons_icon() @@ -78,8 +69,9 @@ var/global/sent_syndicate_strike_team = 0 new_syndicate_commando.mind.store_memory("Nuke Code: [nuke_code].") new_syndicate_commando.mind.store_memory("Mission: [input].") - to_chat(new_syndicate_commando, "You are an Elite Syndicate. [!syndicate_leader_selected ? "commando" : "LEADER"] in the service of the Syndicate. \nYour current mission is: [input]") + to_chat(new_syndicate_commando, "You are an Elite Syndicate [is_leader ? "TEAM LEADER" : "commando"] in the service of the Syndicate. \nYour current mission is: [input]") new_syndicate_commando.faction += "syndicate" + is_leader = FALSE syndicate_commando_number-- for(var/obj/effect/landmark/L in landmarks_list) @@ -91,14 +83,14 @@ var/global/sent_syndicate_strike_team = 0 log_admin("[key_name(usr)] used Spawn Syndicate Squad.") feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) +/client/proc/create_syndicate_death_commando(obj/spawn_location, is_leader = FALSE) var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major") var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") var/syndicate_commando_name = pick(last_names) var/datum/preferences/A = new()//Randomize appearance for the commando. - if(syndicate_leader_selected) + if(is_leader) A.age = rand(35,45) A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]" else @@ -109,29 +101,29 @@ var/global/sent_syndicate_strike_team = 0 //Creates mind stuff. new_syndicate_commando.mind_initialize() - new_syndicate_commando.mind.assigned_role = "MODE" + new_syndicate_commando.mind.assigned_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD new_syndicate_commando.mind.special_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD ticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list. - new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected) + new_syndicate_commando.equip_syndicate_commando(is_leader) qdel(spawn_location) return new_syndicate_commando -/mob/living/carbon/human/proc/equip_syndicate_commando(syndicate_leader_selected = 0) +/mob/living/carbon/human/proc/equip_syndicate_commando(is_leader = FALSE) var/obj/item/radio/R = new /obj/item/radio/headset/syndicate/alt/syndteam(src) R.set_frequency(SYNDTEAM_FREQ) equip_to_slot_or_del(R, slot_l_ear) equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(src), slot_w_uniform) equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/syndie/advance(src), slot_shoes) - if(!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/strike(src), slot_wear_suit) - else + if(is_leader) equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/red/strike(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves) - if(!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/strike(src), slot_head) else + equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/strike(src), slot_wear_suit) + equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves) + if(is_leader) equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/red/strike(src), slot_head) + else + equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/strike(src), slot_head) equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask) equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) @@ -142,13 +134,12 @@ var/global/sent_syndicate_strike_team = 0 equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/flashlight(src), slot_in_backpack) - if(!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/card/emag(src), slot_in_backpack) - else + if(is_leader) equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/disk/nuclear(src), slot_in_backpack) - + else + equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack) + equip_to_slot_or_del(new /obj/item/card/emag(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber(src), slot_l_store) equip_to_slot_or_del(new /obj/item/grenade/empgrenade(src), slot_r_store) equip_to_slot_or_del(new /obj/item/tank/emergency_oxygen/double/full(src), slot_s_store) diff --git a/code/modules/arcade/mob_hunt/battle_computer.dm b/code/modules/arcade/mob_hunt/battle_computer.dm index e5f2af123fb..8ae577fe338 100644 --- a/code/modules/arcade/mob_hunt/battle_computer.dm +++ b/code/modules/arcade/mob_hunt/battle_computer.dm @@ -27,11 +27,11 @@ team = "Blue" avatar_y_offset = 1 -/obj/machinery/computer/mob_battle_terminal/red/initialize() +/obj/machinery/computer/mob_battle_terminal/red/Initialize() ..() check_connection() -/obj/machinery/computer/mob_battle_terminal/blue/initialize() +/obj/machinery/computer/mob_battle_terminal/blue/Initialize() ..() check_connection() diff --git a/code/modules/arcade/mob_hunt/mob_avatar.dm b/code/modules/arcade/mob_hunt/mob_avatar.dm index 42342e0693b..e4ea98a44a6 100644 --- a/code/modules/arcade/mob_hunt/mob_avatar.dm +++ b/code/modules/arcade/mob_hunt/mob_avatar.dm @@ -21,7 +21,7 @@ update_self() forceMove(mob_info.spawn_point) if(!mob_info.is_trap) - addtimer(src, "despawn", mob_info.lifetime) + addtimer(CALLBACK(src, .proc/despawn), mob_info.lifetime) /obj/effect/nanomob/proc/update_self() if(!mob_info) diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index e5f1cb10525..e92330754f2 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -45,13 +45,13 @@ if((istype(W, /obj/item/weldingtool) && W:welding)) if(!status) status = 1 - bombers += "[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]" + investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]") log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]") to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") else status = 0 - bombers += "[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]" + investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) to_chat(user, "The hole has been closed.") add_fingerprint(user) ..() diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index 08601522c5e..785e4549a47 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -28,7 +28,7 @@ if(istype(src.loc.loc, /obj/structure/reagent_dispensers/fueltank/)) var/obj/structure/reagent_dispensers/fueltank/tank = src.loc.loc if(tank) - tank.boom() + tank.boom(TRUE) if(istype(src.loc.loc, /obj/item/reagent_containers/glass/beaker/)) var/obj/item/reagent_containers/glass/beaker/beakerbomb = src.loc.loc if(beakerbomb) @@ -41,4 +41,4 @@ /obj/item/assembly/igniter/attack_self(mob/user as mob) activate() add_fingerprint(user) - return \ No newline at end of file + return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 1886cd4ee65..6a2019b9001 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -23,7 +23,8 @@ if(radio_controller) set_frequency(frequency) -/obj/item/assembly/signaler/initialize() +/obj/item/assembly/signaler/Initialize() + ..() if(radio_controller) set_frequency(frequency) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 5d8c0ed1e98..a585a689f2c 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -114,7 +114,7 @@ timing = !timing if(timing && istype(holder, /obj/item/transfer_valve)) message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].") - bombers += "[key_name(usr)] activated [src] attachment for [loc]" + investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB) log_game("[key_name(usr)] activated [src] attachment for [loc]") update_icon() if(href_list["reset"]) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index e5c42e495f2..94e0ea2acce 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -29,7 +29,8 @@ var/brute_damage = 0 var/oxy_damage = 0 -/obj/effect/landmark/corpse/initialize() +/obj/effect/landmark/corpse/Initialize() + ..() if(istype(src,/obj/effect/landmark/corpse/clown)) var/obj/effect/landmark/corpse/clown/C = src C.chooseRank() diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index d964663298f..d5e2cbcd34d 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -9,7 +9,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null unacidable = 1 var/active = 0 -/obj/machinery/gateway/initialize() +/obj/machinery/gateway/Initialize() ..() update_icon() update_density_from_dir() @@ -44,7 +44,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null if(!the_gateway) the_gateway = src -/obj/machinery/gateway/centerstation/initialize() +/obj/machinery/gateway/centerstation/Initialize() ..() update_icon() wait = world.time + config.gateway_delay //+ thirty minutes default @@ -170,7 +170,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null var/obj/machinery/gateway/centeraway/stationgate = null -/obj/machinery/gateway/centeraway/initialize() +/obj/machinery/gateway/centeraway/Initialize() ..() update_icon() stationgate = locate(/obj/machinery/gateway/centerstation) in world diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm index 49af9a43ce6..6497d62648a 100644 --- a/code/modules/awaymissions/loot.dm +++ b/code/modules/awaymissions/loot.dm @@ -5,7 +5,8 @@ var/lootdoubles = 0 //if the same item can be spawned twice var/loot = "" //a list of possible items to spawn- a string of paths -/obj/effect/spawner/away/lootdrop/initialize() +/obj/effect/spawner/away/lootdrop/Initialize() + ..() var/list/things = params2list(loot) if(things && things.len) diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm index 64350c99737..7618996fdf9 100644 --- a/code/modules/awaymissions/map_rng.dm +++ b/code/modules/awaymissions/map_rng.dm @@ -18,13 +18,8 @@ template_name = tname if(template_name) template = map_templates[template_name] - // Catches the interim-zone of worldstart and roundstart - // I want both the ticker to exist (so mapped-in maploaders don't trip this) - // but also not have started yet (since the zlevel system would handle this on its own otherwise) - if((ticker && ticker.current_state < GAME_STATE_PLAYING)) - attempt_init() -/obj/effect/landmark/map_loader/initialize() +/obj/effect/landmark/map_loader/Initialize() ..() if(template) load(template) @@ -48,7 +43,7 @@ /obj/effect/landmark/map_loader/random var/template_list = "" -/obj/effect/landmark/map_loader/random/initialize() +/obj/effect/landmark/map_loader/random/Initialize() ..() if(template_list) template_name = safepick(splittext(template_list, ";")) diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index b44fd01e45c..5ff625544fd 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -422,13 +422,6 @@ var/global/dmm_suite/preloader/_preloader = new return to_return -//atom creation method that preloads variables at creation -/atom/New() - if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New() - _preloader.load(src) - - . = ..() - /dmm_suite/Destroy() ..() return QDEL_HINT_HARDDEL_NOW diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm index f285d4434da..4d2384ceb67 100644 --- a/code/modules/awaymissions/mission_code/beach.dm +++ b/code/modules/awaymissions/mission_code/beach.dm @@ -12,7 +12,7 @@ var/water_timer = 0 /obj/effect/waterfall/New() - water_timer = addtimer(src, "drip", water_frequency) + water_timer = addtimer(CALLBACK(src, .proc/drip), water_frequency, TIMER_STOPPABLE) /obj/effect/waterfall/Destroy() if(water_timer) @@ -25,4 +25,4 @@ W.dir = dir spawn(1) W.loc = get_step(W, dir) - water_timer = addtimer(src, "drip", water_frequency) \ No newline at end of file + water_timer = addtimer(CALLBACK(src, .proc/drip), water_frequency, TIMER_STOPPABLE) \ No newline at end of file diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm index d9299dfe061..4e4f2628736 100644 --- a/code/modules/awaymissions/mission_code/spacehotel.dm +++ b/code/modules/awaymissions/mission_code/spacehotel.dm @@ -54,7 +54,7 @@ name = "space hotel pamphlet" info = "

Welcome to Deep Space Hotel 419!

Thank you for choosing our hotel. Simply hand your credit or debit card to the concierge and get your room key! To check out, hand your credit card back.

Conditions:

" -/obj/effect/landmark/map_loader/hotel_room/initialize() +/obj/effect/landmark/map_loader/hotel_room/Initialize() ..() // load and randomly assign rooms var/global/list/south_room_templates = list() @@ -238,7 +238,7 @@ return null D.occupant = occupant - D.roomtimer = addtimer(src, "process_room", PAY_INTERVAL, 0, roomid) + D.roomtimer = addtimer(CALLBACK(src, .proc/process_room, roomid), PAY_INTERVAL, TIMER_STOPPABLE) vacant_rooms -= D guests[occupant] = roomid @@ -252,7 +252,7 @@ return if(D.account.charge(100, transaction_purpose = "10 minutes", dest_name = name)) - D.roomtimer = addtimer(src, "process_room", PAY_INTERVAL, 0, roomid) + D.roomtimer = addtimer(CALLBACK(src, .proc/process_room, roomid), PAY_INTERVAL, TIMER_STOPPABLE) else force_checkout(roomid) diff --git a/code/modules/awaymissions/zvis.dm b/code/modules/awaymissions/zvis.dm index 73bbff2198f..4324377149d 100644 --- a/code/modules/awaymissions/zvis.dm +++ b/code/modules/awaymissions/zvis.dm @@ -22,7 +22,7 @@ ..() levels += src -/obj/effect/levelref/initialize() +/obj/effect/levelref/Initialize() ..() for(var/obj/effect/levelref/O in levels) if(id == O.id && O != src) @@ -161,7 +161,7 @@ ..() portals += src -/obj/effect/view_portal/initialize() +/obj/effect/view_portal/Initialize() ..() if(id) for(var/obj/effect/view_portal/O in portals) diff --git a/code/modules/client/preference/loadout/loadout_hat.dm b/code/modules/client/preference/loadout/loadout_hat.dm index d81f1f7e02c..7d6275e09e4 100644 --- a/code/modules/client/preference/loadout/loadout_hat.dm +++ b/code/modules/client/preference/loadout/loadout_hat.dm @@ -152,3 +152,7 @@ /datum/gear/hat/flowerpin display_name = "hair flower" path = /obj/item/clothing/head/hairflower + +/datum/gear/hat/kitty + display_name = "kitty headband" + path = /obj/item/clothing/head/kitty diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 32f86cc6e57..dc1504b80b6 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -132,3 +132,14 @@ cell.forceMove(get_turf(loc)) cell = null update_icon() + +/obj/item/clothing/gloves/fingerless/rapid + name = "Gloves of the north star" + desc = "Just looking at these fills you with an urge to beat the shit out of people." + +/obj/item/clothing/gloves/fingerless/rapid/Touch(mob/living/target, proximity = TRUE) + var/mob/living/M = loc + + if(M.a_intent == INTENT_HARM) + M.changeNext_move(CLICK_CD_RAPID) + .= FALSE \ No newline at end of file diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 84226bd1f3b..f1739750a0a 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -354,3 +354,13 @@ reqs = list(/obj/item/grown/log = 5) result = /obj/structure/bonfire category = CAT_PRIMAL + +/datum/crafting_recipe/guillotine + name = "Guillotine" + result = /obj/structure/guillotine + time = 150 // Building a functioning guillotine takes time + reqs = list(/obj/item/stack/sheet/plasteel = 3, + /obj/item/stack/sheet/wood = 20, + /obj/item/stack/cable_coil = 10) + tools = list(/obj/item/screwdriver, /obj/item/wrench, /obj/item/weldingtool) + category = CAT_MISC \ No newline at end of file diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index f7135acd270..1fe849a4cb0 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -497,8 +497,8 @@ #undef USED_MOD_SUIT /obj/item/fluff/merchant_sallet_modkit //Travelling Merchant: Trav Noble. This is what they spawn in with - name = "sallet modkit" - desc = "A modkit that can make most helmets look like a steel sallet." + name = "SG Helmet modkit" + desc = "A modkit that can make most helmets look like a Shellguard Helmet." icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL force = 0 @@ -649,53 +649,59 @@ icon_state = "kakicharakiti" /obj/item/clothing/head/helmet/fluff/merchant_sallet //Travelling Merchant: Trav Noble. This >>IS NOT<< what they spawn in with - name = "Steel Sallet" - desc = "A heavy steel sallet with the word Noble scratched into the side. Comes with a Bevor attached." + name = "Shellguard Helmet" + desc = "A Shellguard Helmet with the name Noble written on the inside." icon = 'icons/obj/custom_items.dmi' icon_state = "merchant_sallet_visor_bevor" item_state = "merchant_sallet_visor_bevor" actions_types = list(/datum/action/item_action/toggle_helmet_mode) toggle_cooldown = 20 - toggle_sound = 'sound/items/ZippoClose.ogg' + toggle_sound = 'sound/items/change_jaws.ogg' flags = BLOCKHAIR flags_inv = HIDEEYES|HIDEMASK|HIDEFACE|HIDEEARS - var/state = "Visor & Bevor" + var/state = "Soldier Up" /obj/item/clothing/head/helmet/fluff/merchant_sallet/attack_self(mob/user) if(!user.incapacitated() && (world.time > cooldown + toggle_cooldown) && Adjacent(user)) var/list/options = list() - options["Visor & Bevor"] = list( + options["Soldier Up"] = list( "icon_state" = "merchant_sallet_visor_bevor", - "visor_flags" = HIDEEYES, - "mask_flags" = HIDEMASK|HIDEFACE - ) - options["Visor Only"] = list( - "icon_state" = "merchant_sallet_visor", - "visor_flags" = HIDEEYES, - "mask_flags" = HIDEFACE - ) - options["Bevor Only"] = list( - "icon_state" = "merchant_sallet_bevor", - "visor_flags" = null, - "mask_flags" = HIDEMASK|HIDEFACE - ) - options["Neither Visor nor Bevor"] = list( - "icon_state" = "merchant_sallet", "visor_flags" = null, "mask_flags" = null ) + options["Soldier Down"] = list( + "icon_state" = "merchant_sallet_visor", + "visor_flags" = HIDEEYES, + "mask_flags" = HIDEMASK|HIDEFACE + ) + options["Technician Up"] = list( + "icon_state" = "merchant_sallet_bevor", + "visor_flags" = null, + "mask_flags" = null + ) + options["Technician Down"] = list( + "icon_state" = "merchant_sallet", + "visor_flags" = HIDEEYES, + "mask_flags" = HIDEMASK|HIDEFACE + ) - var/choice = input(user, "How would you like to adjust the sallet?", "Adjust Sallet") as null|anything in options + var/choice = input(user, "How would you like to adjust the helmet?", "Adjust Helmet") as null|anything in options if(choice && choice != state && !user.incapacitated() && Adjacent(user)) var/list/new_state = options[choice] icon_state = new_state["icon_state"] state = choice - to_chat(user, "You adjust the sallet.") + to_chat(user, "You adjust the helmet.") playsound(src.loc, "[toggle_sound]", 100, 0, 4) user.update_inv_head() return 1 +/obj/item/clothing/head/beret/fluff/elo //V-Force_Bomber: E.L.O. + name = "E.L.O.'s medical beret" + desc = "E.L.O.s personal medical beret, issued by Nanotrassen and awarded along with her medal." + icon = 'icons/obj/custom_items.dmi' + icon_state = "elo-beret" + //////////// Suits //////////// /obj/item/clothing/suit/fluff icon = 'icons/obj/custom_items.dmi' @@ -1259,6 +1265,8 @@ name = "engraved hand mirror" desc = "A very classy hand mirror, with fancy detailing." icon = 'icons/obj/custom_items.dmi' + lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' icon_state = "hand_mirror" attack_verb = list("smacked") hitsound = 'sound/weapons/tap.ogg' @@ -1305,6 +1313,8 @@ name = "Classy victorian suit" desc = "A blue and black victorian suit with silver buttons, very fancy!" icon = 'icons/obj/custom_items.dmi' + lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' icon_state = "victorianlightfire" item_state = "victorianvest" item_color = "victorianlightfire" @@ -1324,7 +1334,7 @@ to_chat(user, "You can't modify [target]!") return - to_chat(user, "You modify the appearance of [target] based on the kite blueprints.") + to_chat(user, "You modify the appearance of [target] based on the kit blueprints.") var/obj/spacepod/pod = target pod.icon = 'icons/48x48/custom_pod.dmi' pod.icon_state = "pod_dece" @@ -1342,4 +1352,22 @@ righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' icon_state = "teri_horn" item_state = "teri_horn" - honk_sound = 'sound/items/teri_horn.ogg' \ No newline at end of file + honk_sound = 'sound/items/teri_horn.ogg' + +/obj/item/clothing/suit/fluff/vetcoat //Furasian: Fillmoore Grayson + name = "Veteran Coat" + desc = "An old, yet well-kept Nanotrasen uniform. Very few of its kind are still produced." + icon = 'icons/obj/custom_items.dmi' + lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' + icon_state = "alchemistcoatblack" + item_state = "alchemistcoatblack" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +/obj/item/clothing/suit/fluff/vetcoat/red //Furasian: Fillmoore Grayson + icon_state = "alchemistcoatred" + item_state = "alchemistcoatred" + +/obj/item/clothing/suit/fluff/vetcoat/navy //Furasian: Fillmoore Grayson + icon_state = "alchemistcoatnavy" + item_state = "alchemistcoatnavy" \ No newline at end of file diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 014f87ac310..6306fa5a83e 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -38,7 +38,7 @@ log transactions ..() machine_id = "[station_name()] RT #[num_financial_terminals++]" -/obj/machinery/atm/initialize() +/obj/machinery/atm/Initialize() ..() reconnect_database() @@ -122,6 +122,8 @@ log transactions if(issilicon(user)) to_chat(user, "Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per Nanotrasen regulation #1005.") return + if(!linked_db) + reconnect_database() ui_interact(user) /obj/machinery/atm/attack_ghost(mob/user) @@ -199,12 +201,9 @@ log transactions authenticated_account.security_level = new_sec_level if("attempt_auth") if(linked_db) - // check if they have low security enabled - scan_user(usr) - - if(!ticks_left_locked_down && held_card) + if(!ticks_left_locked_down) var/tried_account_num = text2num(href_list["account_num"]) - if(!tried_account_num) + if(!tried_account_num && held_card) tried_account_num = held_card.associated_account_number var/tried_pin = text2num(href_list["account_pin"]) @@ -323,30 +322,3 @@ log transactions //create the most effective combination of notes to make up the requested amount /obj/machinery/atm/proc/withdraw_arbitrary_sum(arbitrary_sum) new /obj/item/stack/spacecash(get_step(get_turf(src), turn(dir, 180)), arbitrary_sum) - -//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri -/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/H) - if(!authenticated_account && linked_db) - if(H.wear_id) - var/obj/item/card/id/I - if(istype(H.wear_id, /obj/item/card/id) ) - I = H.wear_id - else if(istype(H.wear_id, /obj/item/pda) ) - var/obj/item/pda/P = H.wear_id - I = P.id - if(I) - authenticated_account = attempt_account_access(I.associated_account_number) - if(authenticated_account) - to_chat(H, "[bicon(src)]Access granted. Welcome user '[authenticated_account.owner_name].'") - - //create a transaction log entry - var/datum/transaction/T = new() - T.target_name = authenticated_account.owner_name - T.purpose = "Remote terminal access" - T.source_terminal = machine_id - T.date = current_date_string - T.time = station_time_timestamp() - authenticated_account.transaction_log.Add(T) - - view_screen = NO_SCREEN - SSnanoui.update_uis(src) diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index a527367ee2b..09a5d20833e 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -96,7 +96,7 @@ var/total_runtimes_skipped = 0 // Now to actually output the error info... log_world("\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]") - log_runtime_txt("\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]") + log_runtime_txt("Runtime in [e.file],[e.line]: [e]") for(var/line in desclines) log_world(line) log_runtime_txt(line) diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index e35c7de6ee3..6cf5e1b1ce7 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -6,11 +6,11 @@ var/aurora_progress = 0 //this cycles from 1 to 7, slowly changing colors from gentle green to gentle blue /datum/event/aurora_caelus/announce() - event_announcement.Announce("[station_name()]: A harmless cloud of ions is approaching your station, and will exhaust their energy battering the hull.\ -Nanotrasen has approved a short break for all employees to relax and observe this very rare event.\ -During this time, starlight will be bright but gentle, shifting between quiet green and blue colors.\ -Any staff who would like to view these lights for themselves may proceed to the area nearest to them with viewing ports to open space.\ -We hope you enjoy the lights.", "Harmless ions approaching", new_sound = 'sound/misc/notice2.ogg', from = "Nanotrasen Meterology Divison") + event_announcement.Announce("[station_name()]: A harmless cloud of ions is approaching your station, and will exhaust their energy battering the hull. \ +Nanotrasen has approved a short break for all employees to relax and observe this very rare event. \ +During this time, starlight will be bright but gentle, shifting between quiet green and blue colors. \ +Any staff who would like to view these lights for themselves may proceed to the area nearest to them with viewing ports to open space. \ +We hope you enjoy the lights.", "Harmless ions approaching", new_sound = 'sound/misc/notice2.ogg', from = "Nanotrasen Meteorology Division") for(var/V in player_list) var/mob/M = V if((M.client.prefs.toggles & SOUND_MIDI) && is_station_level(M.z)) @@ -37,10 +37,10 @@ We hope you enjoy the lights.", "Harmless ions approaching", new_sound = 'sound/ for(var/s in GLOB.station_level_space_turfs) var/turf/space/S = s fade_to_black(S) - event_announcement.Announce("The aurora caelus event is now ending. Starlight conditions will slowly return to normal.\ -When this has concluded, please return to your workplace and continue work as normal.\ + event_announcement.Announce("The Aurora Caelus event is now ending. Starlight conditions will slowly return to normal. \ +When this has concluded, please return to your workplace and continue work as normal. \ Have a pleasant shift, [station_name()], and thank you for watching with us.", -"Harmless ions approaching", new_sound = 'sound/misc/notice2.ogg', from = "Nanotrasen Meterology Divison") +"Harmless ions approaching", new_sound = 'sound/misc/notice2.ogg', from = "Nanotrasen Meteorology Division") /datum/event/aurora_caelus/proc/fade_to_black(turf/space/S) set waitfor = FALSE @@ -48,4 +48,4 @@ Have a pleasant shift, [station_name()], and thank you for watching with us.", while(S.light_range > new_light) S.set_light(S.light_range - 0.2) sleep(30) - S.set_light(new_light, 1, l_color = "") // we should be able to use `, null` as the last arg but BYOND is a piece of FUCKING SHIT AND SET_LIGHT DOESN'T WORK THAT WAY DESPITE EVERY FUCKING THING ABOUT IT INDICATING THAT IT GODDAMN WELL SHOULD AAAAAAAAAAAAAAAAA \ No newline at end of file + S.set_light(new_light, 1, l_color = "") // we should be able to use `, null` as the last arg but BYOND is a piece of FUCKING SHIT AND SET_LIGHT DOESN'T WORK THAT WAY DESPITE EVERY FUCKING THING ABOUT IT INDICATING THAT IT GODDAMN WELL SHOULD AAAAAAAAAAAAAAAAA diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 520d8805bbd..b4a67ac9850 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -493,7 +493,7 @@ /proc/generate_static_ion_law() /var/list/players = list() for(var/mob/living/carbon/human/player in player_list) - if( !player.mind || player.mind.assigned_role == "MODE" || player.client.inactivity > MinutesToTicks(10)) + if( !player.mind || player.mind.assigned_role == player.mind.special_role || player.client.inactivity > MinutesToTicks(10)) continue players += player.real_name var/random_player = "The Captain" diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index d01b5595d92..6a1d28eaf87 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -11,7 +11,7 @@ dream_images += pick_n_take(dreams) dreaming++ for(var/i in 1 to dream_images.len) - addtimer(src, "experience_dream", ((i - 1) * rand(30,60)), FALSE, dream_images[i], FALSE) + addtimer(CALLBACK(src, .proc/experience_dream, dream_images[i], FALSE), ((i - 1) * rand(30,60))) return TRUE @@ -33,7 +33,7 @@ dream_images += pick_n_take(nightmares) nightmare++ for(var/i in 1 to dream_images.len) - addtimer(src, "experience_dream", ((i - 1) * rand(30,60)), FALSE, nightmares[i], TRUE) + addtimer(CALLBACK(src, .proc/experience_dream, nightmares[i], TRUE), ((i - 1) * rand(30,60))) return TRUE /mob/living/carbon/proc/handle_dreams() diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 621b8ec37ea..d8a1f4f1526 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -339,7 +339,7 @@ Gunshots/explosions/opening doors/less rare audio (done) s.loc = get_step(get_turf(s), get_dir(s, target)) s.Show() s.Eat() - addtimer(src, "wake_and_restore", rand(50, 100)) + addtimer(CALLBACK(src, .proc/wake_and_restore), rand(50, 100)) qdel(s) /obj/effect/hallucination/simple/singularity @@ -365,9 +365,9 @@ Gunshots/explosions/opening doors/less rare audio (done) for(var/i=0,i[src.name] has attacked [my_target] with [weapon_name]!", 1) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 1b8c0b5b989..bc442486d5c 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -1250,7 +1250,14 @@ /obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() if(!QDELETED(src)) visible_message("[src] expands!") - new/mob/living/carbon/human(get_turf(src), monkey_type) + if(fingerprintslast) + log_game("Cube ([monkey_type]) inflated, last touched by: " + fingerprintslast) + else + log_game("Cube ([monkey_type]) inflated, last touched by: NO_DATA") + var/mob/living/carbon/human/creature = new /mob/living/carbon/human(get_turf(src)) + if(LAZYLEN(fingerprintshidden)) + creature.fingerprintshidden = fingerprintshidden.Copy() + creature.set_species(monkey_type) qdel(src) /obj/item/reagent_containers/food/snacks/monkeycube/farwacube diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index a073a8ad64d..86bc8082661 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -109,7 +109,7 @@ var/area/A = get_area(user) user.visible_message("[user] primes the [src]!", "You prime the [src]!") var/message = "[ADMIN_LOOKUPFLW(user)] primed a combustible lemon for detonation at [A] [ADMIN_COORDJMP(user)]" - bombers += message + investigate_log("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].", INVESTIGATE_BOMB) message_admins(message) log_game("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].") if(iscarbon(user)) @@ -117,7 +117,7 @@ C.throw_mode_on() icon_state = "firelemon_active" playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - addtimer(src, "prime", rand(10, 60)) + addtimer(CALLBACK(src, .proc/prime), rand(10, 60)) /obj/item/reagent_containers/food/snacks/grown/firelemon/burn() prime() diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index a0b10f29f38..8df5d593b9b 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -24,7 +24,7 @@ var/tmp/busy = 0 var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/bible, /obj/item/tome) //Things allowed in the bookcase -/obj/structure/bookcase/initialize() +/obj/structure/bookcase/Initialize() ..() for(var/obj/item/I in loc) if(is_type_in_list(I, allowed_books)) diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm index 679f6fb86ef..075e3e47a20 100644 --- a/code/modules/lighting/lighting_atom.dm +++ b/code/modules/lighting/lighting_atom.dm @@ -40,16 +40,6 @@ else light = new /datum/light_source(src, .) -/atom/New() - . = ..() - - if(light_power && light_range) - update_light() - - if(opacity && isturf(loc)) - var/turf/T = loc - T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. - /atom/Destroy() if(light) light.destroy() diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index 6fe55eed0ff..1a421e6d1ad 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -9,7 +9,6 @@ invisibility = INVISIBILITY_LIGHTING color = LIGHTING_BASE_MATRIX icon_state = "light1" - auto_init = 0 // doesn't need special init blend_mode = BLEND_MULTIPLY var/lum_r = 0 diff --git a/code/modules/logic/logic_base.dm b/code/modules/logic/logic_base.dm index db891ab383c..519c47c408b 100644 --- a/code/modules/logic/logic_base.dm +++ b/code/modules/logic/logic_base.dm @@ -50,7 +50,7 @@ component_parts += LG component_parts += new /obj/item/stack/cable_coil(null, 1) -/obj/machinery/logic_gate/initialize() +/obj/machinery/logic_gate/Initialize() ..() set_frequency(frequency) diff --git a/code/modules/martial_arts/brawling.dm b/code/modules/martial_arts/brawling.dm index 9f9fa5236b2..a40a52b86be 100644 --- a/code/modules/martial_arts/brawling.dm +++ b/code/modules/martial_arts/brawling.dm @@ -11,7 +11,7 @@ /datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) var/atk_verb = pick("left hook","right hook","straight punch") @@ -62,7 +62,7 @@ /datum/martial_art/drunk_brawling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) add_attack_logs(A, D, "Melee attacked with [src]") - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) var/atk_verb = pick("jab","uppercut","overhand punch","drunken right hook","drunken left hook") diff --git a/code/modules/martial_arts/krav_maga.dm b/code/modules/martial_arts/krav_maga.dm index d17d1b30495..9e889bdce7a 100644 --- a/code/modules/martial_arts/krav_maga.dm +++ b/code/modules/martial_arts/krav_maga.dm @@ -109,7 +109,6 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi if(check_streak(A,D)) return 1 add_attack_logs(A, D, "Melee attacked with [src]") - A.do_attack_animation(D) var/picked_hit_type = pick("punches", "kicks") var/bonus_damage = 10 if(D.weakened || D.resting || D.lying) @@ -117,8 +116,10 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi picked_hit_type = "stomps on" D.apply_damage(bonus_damage, BRUTE) if(picked_hit_type == "kicks" || picked_hit_type == "stomps") + A.do_attack_animation(D, ATTACK_EFFECT_KICK) playsound(get_turf(D), 'sound/effects/hit_kick.ogg', 50, 1, -1) else + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.visible_message("[A] [picked_hit_type] [D]!", \ "[A] [picked_hit_type] you!") diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 3e1be19b0de..df1753e1dd7 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -33,7 +33,6 @@ /datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) - A.do_attack_animation(D) var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) var/datum/unarmed_attack/attack = A.species.unarmed @@ -41,6 +40,12 @@ if(D.lying) atk_verb = "kick" + switch(atk_verb) + if("kick") + A.do_attack_animation(D, ATTACK_EFFECT_KICK) + else + A.do_attack_animation(D, attack.animation_type) + if(!damage) playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") diff --git a/code/modules/martial_arts/plasma_fist.dm b/code/modules/martial_arts/plasma_fist.dm index d2e047dc08d..5aed9b8e9e1 100644 --- a/code/modules/martial_arts/plasma_fist.dm +++ b/code/modules/martial_arts/plasma_fist.dm @@ -46,7 +46,7 @@ return /datum/martial_art/plasma_fist/proc/Plasma(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) A.say("PLASMA FIST!") D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \ diff --git a/code/modules/martial_arts/sleeping_carp.dm b/code/modules/martial_arts/sleeping_carp.dm index 45f4948bc14..1cd29ac2511 100644 --- a/code/modules/martial_arts/sleeping_carp.dm +++ b/code/modules/martial_arts/sleeping_carp.dm @@ -36,7 +36,7 @@ /datum/martial_art/the_sleeping_carp/proc/wristWrench(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(!D.stat && !D.stunned && !D.weakened) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) D.visible_message("[A] grabs [D]'s wrist and wrenches it sideways!", \ "[A] grabs your wrist and violently wrenches it to the side!") playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) @@ -51,7 +51,7 @@ /datum/martial_art/the_sleeping_carp/proc/backKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(A.dir == D.dir && !D.stat && !D.weakened) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] kicks [D] in the back!", \ "[A] kicks you in the back, making you stumble and fall!") step_to(D,get_step(D,D.dir),1) @@ -64,7 +64,7 @@ /datum/martial_art/the_sleeping_carp/proc/kneeStomach(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(!D.stat && !D.weakened) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] knees [D] in the stomach!", \ "[A] winds you with a knee in the stomach!") D.audible_message("[D] gags!") @@ -78,7 +78,7 @@ /datum/martial_art/the_sleeping_carp/proc/headKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(!D.stat && !D.weakened) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] kicks [D] in the head!", \ "[A] kicks you in the jaw!") D.apply_damage(20, BRUTE, "head") @@ -92,7 +92,7 @@ /datum/martial_art/the_sleeping_carp/proc/elbowDrop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(D.weakened || D.resting || D.stat) - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) D.visible_message("[A] elbow drops [D]!", \ "[A] piledrives you with their elbow!") if(D.stat) @@ -117,7 +117,7 @@ add_to_streak("H",D) if(check_streak(A,D)) return 1 - A.do_attack_animation(D) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") D.visible_message("[A] [atk_verb] [D]!", \ "[A] [atk_verb] you!") diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 5e9c9a88b6d..364a918c0ff 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -45,7 +45,7 @@ name = harvested_name desc = harvested_desc harvested = TRUE - addtimer(src, "regrow", rand(regrowth_time_low, regrowth_time_high)) + addtimer(CALLBACK(src, .proc/regrow), rand(regrowth_time_low, regrowth_time_high)) return 1 /obj/structure/flora/ash/proc/regrow() diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index a844e7ff551..33334d49382 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -6,26 +6,26 @@ icon_state = "orebox0" name = "ore box" desc = "A heavy wooden box, which can be filled with a lot of ores." - density = 1 - pressure_resistance = 5*ONE_ATMOSPHERE + density = TRUE + pressure_resistance = 5 * ONE_ATMOSPHERE -/obj/structure/ore_box/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/structure/ore_box/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/t_scanner/adv_mining_scanner)) attack_hand(user) return if(istype(W, /obj/item/ore)) if(!user.drop_item()) return - W.loc = src + W.forceMove(src) if(istype(W, /obj/item/storage)) var/obj/item/storage/S = W S.hide_from(usr) for(var/obj/item/ore/O in S.contents) S.remove_from_storage(O, src) //This will move the item to this item's contents + CHECK_TICK to_chat(user, "You empty the satchel into the box.") - return -/obj/structure/ore_box/attack_hand(mob/user as mob) +/obj/structure/ore_box/attack_hand(mob/user) var/amt_gold = 0 var/amt_silver = 0 var/amt_diamond = 0 @@ -90,20 +90,19 @@ var/datum/browser/popup = new(user, "orebox", name, 400, 400) popup.set_content(dat) popup.open(0) - return /obj/structure/ore_box/Topic(href, href_list) if(..()) return usr.set_machine(src) - src.add_fingerprint(usr) + add_fingerprint(usr) if(href_list["removeall"]) for(var/obj/item/ore/O in contents) contents -= O - O.loc = src.loc + O.forceMove(loc) + CHECK_TICK to_chat(usr, "You empty the box.") - src.updateUsrDialog() - return + updateUsrDialog() obj/structure/ore_box/ex_act(severity, target) if(prob(100 / severity) && severity < 3) @@ -115,11 +114,11 @@ obj/structure/ore_box/ex_act(severity, target) set category = "Object" set src in view(1) - if(!istype(usr, /mob/living/carbon/human)) //Only living, intelligent creatures with hands can empty ore boxes. + if(!ishuman(usr)) //Only living, intelligent creatures with hands can empty ore boxes. to_chat(usr, "You are physically incapable of emptying the ore box.") return - if( usr.stat || usr.restrained() ) + if(usr.incapacitated()) return if(!Adjacent(usr)) //You can only empty the box if you can physically reach it @@ -134,7 +133,6 @@ obj/structure/ore_box/ex_act(severity, target) for(var/obj/item/ore/O in contents) contents -= O - O.loc = src.loc - to_chat(usr, "You empty the ore box.") - - return + O.forceMove(loc) + CHECK_TICK + to_chat(usr, "You empty the ore box.") \ No newline at end of file diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 4ab29741ef6..933ef9a6403 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -106,7 +106,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi Transfer_mind is there to check if mob is being deleted/not going to have a body. Works together with spawning an observer, noted above. */ -/mob/dead/observer/Life() +/mob/dead/observer/Life(seconds, times_fired) ..() if(!loc) return if(!client) return 0 @@ -419,7 +419,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(.) update_following() -/mob/Life() +/mob/Life(seconds, times_fired) // to catch teleports etc which directly set loc update_following() return ..() diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 22954451834..0d9c50ba5cc 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -29,7 +29,7 @@ In all, this is a lot like the monkey code. /N else if(health > 0) - M.do_attack_animation(src) + M.do_attack_animation(src, ATTACK_EFFECT_BITE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) var/damage = 1 visible_message("[M.name] bites [src]!", \ @@ -52,8 +52,10 @@ In all, this is a lot like the monkey code. /N help_shake_act(M) if(INTENT_GRAB) grabbedby(M) - if(INTENT_HARM, INTENT_DISARM) - M.do_attack_animation(src) + if(INTENT_HARM) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + if(INTENT_DISARM) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) return 1 return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 0056bb709a5..41ebc8d8247 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -43,3 +43,8 @@ else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to disarm [src]!") + +/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) + if(!no_effect && !visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_CLAW + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index a13fce956da..180d6bd8072 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/humanoid/Life() +/mob/living/carbon/alien/humanoid/Life(seconds, times_fired) . = ..() update_icons() diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index fc7fa22510b..ef38327b5ee 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -22,3 +22,8 @@ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to kick [src]!", \ "[M] has attempted to kick [src]!") + +/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) + if(!no_effect && !visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_BITE + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 4faa957163c..5bbb31c00d1 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/larva/Life() +/mob/living/carbon/alien/larva/Life(seconds, times_fired) if(..()) //still breathing // GROW! if(amount_grown < max_grown) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index ae03f103e86..e09340872b9 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -96,7 +96,7 @@ if(ticker && ticker.mode) ticker.mode.xenos += new_xeno.mind new_xeno.mind.name = new_xeno.name - new_xeno.mind.assigned_role = "MODE" + new_xeno.mind.assigned_role = SPECIAL_ROLE_XENOMORPH new_xeno.mind.special_role = SPECIAL_ROLE_XENOMORPH new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100)//To get the player's attention diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 7e6f427e069..5df7407ec71 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -42,7 +42,7 @@ if(lying && surgeries.len) if(user.a_intent == INTENT_HELP) for(var/datum/surgery/S in surgeries) - if(S.next_step(user, user.a_intent)) + if(S.next_step(user, src)) return 1 return 0 diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 97ff899abe6..a15a0dbd0bf 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -102,6 +102,8 @@ on_CD = handle_emote_CD() if("sneeze", "sneezes") on_CD = handle_emote_CD() + if("clap", "claps") + on_CD = handle_emote_CD() //Everything else, including typos of the above emotes else on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown @@ -302,11 +304,30 @@ message = "[src] makes a peculiar noise." m_type = 2 if("clap", "claps") - if(!restrained()) - message = "[src] claps." + if(miming) + message = "[src] claps silently." + m_type = 1 + else m_type = 2 - if(miming) - m_type = 1 + var/obj/item/organ/external/L = get_organ("l_hand") + var/obj/item/organ/external/R = get_organ("r_hand") + + var/left_hand_good = FALSE + var/right_hand_good = FALSE + + if(L && (!(L.status & ORGAN_SPLINTED)) && (!(L.status & ORGAN_BROKEN))) + left_hand_good = TRUE + if(R && (!(R.status & ORGAN_SPLINTED)) && (!(R.status & ORGAN_BROKEN))) + right_hand_good = TRUE + + if(left_hand_good && right_hand_good) + message = "[src] claps." + var/clap = pick('sound/misc/clap1.ogg', 'sound/misc/clap2.ogg', 'sound/misc/clap3.ogg', 'sound/misc/clap4.ogg') + playsound(loc, clap, 50, 1, -1) + + else + to_chat(usr, "You need your hands working in order to clap.") + if("flap", "flaps") if(!restrained()) message = "[src] flaps \his wings." @@ -805,34 +826,34 @@ return // playsound(loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun if(locate(/obj/item/storage/bible) in get_turf(src)) - to_chat(viewers(src), "[src] farts on the Bible!") - var/image/cross = image('icons/obj/storage.dmi',"bible") - var/adminbfmessage = "\blue [bicon(cross)] Bible Fart: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SMITE):" + to_chat(viewers(src), "[src] farts on the Bible!") + var/image/cross = image('icons/obj/storage.dmi', "bible") + var/adminbfmessage = "[bicon(cross)] Bible Fart: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SMITE):
" for(var/client/X in admins) - if(check_rights(R_EVENT,0,X.mob)) + if(check_rights(R_EVENT, 0, X.mob)) to_chat(X, adminbfmessage) else if(TOXIC_FARTS in mutations) - message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." + message = "[src] unleashes a [pick("horrible", "terrible", "foul", "disgusting", "awful")] fart." else if(SUPER_FART in mutations) - message = "[src] unleashes a [pick("loud","deafening")] fart." - newtonian_move(dir) + message = "[src] unleashes a [pick("loud", "deafening")] fart." else - message = "[src] [pick("passes wind","farts")]." + message = "[src] [pick("passes wind", "farts")]." m_type = 2 var/turf/location = get_turf(src) - var/aoe_range=2 // Default // Process toxic farts first. if(TOXIC_FARTS in mutations) - for(var/mob/M in range(location,aoe_range)) - if(M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT)) + for(var/mob/living/carbon/C in range(location, 2)) + if(C.internal != null && C.wear_mask && (C.wear_mask.flags & AIRTIGHT)) continue - // Now, we don't have this: - //new /obj/effects/fart_cloud(T,L) - if(M == src) + if(C == src) continue - M.reagents.add_reagent("jenkem", 1) + C.reagents.add_reagent("jenkem", 1) + + // Farting as a form of locomotion in space + if(SUPER_FART in mutations) + newtonian_move(dir) if("hem") message = "[src] hems." diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5a47bb052d5..e0f90aacdd0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -10,8 +10,12 @@ var/datum/species/species //Contains icon generation and language information, set during New(). var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call. -/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna = 0) +/mob/living/carbon/human/New(loc) + if(length(args) > 1) + log_runtime(EXCEPTION("human/New called with more than 1 argument (REPORT THIS ENTIRE RUNTIME TO A CODER)")) + . = ..() +/mob/living/carbon/human/Initialize(mapload, new_species = null) if(!dna) dna = new /datum/dna(null) // Species name is handled by set_species() @@ -40,7 +44,7 @@ faction |= "\ref[M]" //what // Set up DNA. - if(!delay_ready_dna && dna) + if(dna) dna.ready_dna(src) dna.real_name = real_name sync_organ_dna(1) @@ -69,80 +73,80 @@ real_name = "Test Dummy" status_flags = GODMODE|CANPUSH -/mob/living/carbon/human/skrell/New(var/new_loc) - ..(new_loc, "Skrell") +/mob/living/carbon/human/skrell/Initialize(mapload) + ..(mapload, "Skrell") -/mob/living/carbon/human/tajaran/New(var/new_loc) - ..(new_loc, "Tajaran") +/mob/living/carbon/human/tajaran/Initialize(mapload) + ..(mapload, "Tajaran") -/mob/living/carbon/human/vulpkanin/New(var/new_loc) - ..(new_loc, "Vulpkanin") +/mob/living/carbon/human/vulpkanin/Initialize(mapload) + ..(mapload, "Vulpkanin") -/mob/living/carbon/human/unathi/New(var/new_loc) - ..(new_loc, "Unathi") +/mob/living/carbon/human/unathi/Initialize(mapload) + ..(mapload, "Unathi") -/mob/living/carbon/human/vox/New(var/new_loc) - ..(new_loc, "Vox") +/mob/living/carbon/human/vox/Initialize(mapload) + ..(mapload, "Vox") -/mob/living/carbon/human/voxarmalis/New(var/new_loc) - ..(new_loc, "Vox Armalis") +/mob/living/carbon/human/voxarmalis/Initialize(mapload) + ..(mapload, "Vox Armalis") -/mob/living/carbon/human/skeleton/New(var/new_loc) - ..(new_loc, "Skeleton") +/mob/living/carbon/human/skeleton/Initialize(mapload) + ..(mapload, "Skeleton") -/mob/living/carbon/human/kidan/New(var/new_loc) - ..(new_loc, "Kidan") +/mob/living/carbon/human/kidan/Initialize(mapload) + ..(mapload, "Kidan") -/mob/living/carbon/human/plasma/New(var/new_loc) - ..(new_loc, "Plasmaman") +/mob/living/carbon/human/plasma/Initialize(mapload) + ..(mapload, "Plasmaman") -/mob/living/carbon/human/slime/New(var/new_loc) - ..(new_loc, "Slime People") +/mob/living/carbon/human/slime/Initialize(mapload) + ..(mapload, "Slime People") -/mob/living/carbon/human/grey/New(var/new_loc) - ..(new_loc, "Grey") +/mob/living/carbon/human/grey/Initialize(mapload) + ..(mapload, "Grey") -/mob/living/carbon/human/abductor/New(var/new_loc) - ..(new_loc, "Abductor") +/mob/living/carbon/human/abductor/Initialize(mapload) + ..(mapload, "Abductor") -/mob/living/carbon/human/human/New(var/new_loc) - ..(new_loc, "Human") +/mob/living/carbon/human/human/Initialize(mapload) + ..(mapload, "Human") -/mob/living/carbon/human/diona/New(var/new_loc) - ..(new_loc, "Diona") +/mob/living/carbon/human/diona/Initialize(mapload) + ..(mapload, "Diona") -/mob/living/carbon/human/machine/New(var/new_loc) - ..(new_loc, "Machine") +/mob/living/carbon/human/machine/Initialize(mapload) + ..(mapload, "Machine") -/mob/living/carbon/human/shadow/New(var/new_loc) - ..(new_loc, "Shadow") +/mob/living/carbon/human/shadow/Initialize(mapload) + ..(mapload, "Shadow") -/mob/living/carbon/human/golem/New(var/new_loc) - ..(new_loc, "Golem") +/mob/living/carbon/human/golem/Initialize(mapload) + ..(mapload, "Golem") -/mob/living/carbon/human/wryn/New(var/new_loc) - ..(new_loc, "Wryn") +/mob/living/carbon/human/wryn/Initialize(mapload) + ..(mapload, "Wryn") -/mob/living/carbon/human/nucleation/New(var/new_loc) - ..(new_loc, "Nucleation") +/mob/living/carbon/human/nucleation/Initialize(mapload) + ..(mapload, "Nucleation") -/mob/living/carbon/human/drask/New(var/new_loc) - ..(new_loc, "Drask") +/mob/living/carbon/human/drask/Initialize(mapload) + ..(mapload, "Drask") -/mob/living/carbon/human/monkey/New(var/new_loc) - ..(new_loc, "Monkey") +/mob/living/carbon/human/monkey/Initialize(mapload) + ..(mapload, "Monkey") -/mob/living/carbon/human/farwa/New(var/new_loc) - ..(new_loc, "Farwa") +/mob/living/carbon/human/farwa/Initialize(mapload) + ..(mapload, "Farwa") -/mob/living/carbon/human/wolpin/New(var/new_loc) - ..(new_loc, "Wolpin") +/mob/living/carbon/human/wolpin/Initialize(mapload) + ..(mapload, "Wolpin") -/mob/living/carbon/human/neara/New(var/new_loc) - ..(new_loc, "Neara") +/mob/living/carbon/human/neara/Initialize(mapload) + ..(mapload, "Neara") -/mob/living/carbon/human/stok/New(var/new_loc) - ..(new_loc, "Stok") +/mob/living/carbon/human/stok/Initialize(mapload) + ..(mapload, "Stok") /mob/living/carbon/human/Stat() ..() diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index c216badda93..5ed14b3a18e 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -372,7 +372,6 @@ This function restores all organs. dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1) flick_overlay(dmgIcon, attack_bubble_recipients, 9) - receiving_damage() if(BURN) damageoverlaytemp = 20 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 64395954672..00de7814170 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/human/Life() +/mob/living/carbon/human/Life(seconds, times_fired) life_tick++ voice = GetVoice() @@ -32,7 +32,7 @@ //Update our name based on whether our face is obscured/disfigured name = get_visible_name() - pulse = handle_pulse() + pulse = handle_pulse(times_fired) if(mind && mind.vampire) mind.vampire.handle_vampire() @@ -902,9 +902,8 @@ hud_used.lingchemdisplay.invisibility = 101 -/mob/living/carbon/human/proc/handle_pulse() - - if(mob_master.current_cycle % 5) +/mob/living/carbon/human/proc/handle_pulse(times_fired) + if(times_fired % 5 == 1) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) if(NO_BLOOD in species.species_traits) diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm index b66a0ee52ba..c21c1990cbe 100644 --- a/code/modules/mob/living/carbon/human/npcs.dm +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -5,9 +5,8 @@ item_color = "punpun" species_restricted = list("Monkey") -/mob/living/carbon/human/monkey/punpun/New() +/mob/living/carbon/human/monkey/punpun/Initialize(mapload) ..() - spawn(1) - name = "Pun Pun" - real_name = name - equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform) \ No newline at end of file + name = "Pun Pun" + real_name = name + equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform) diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index 3e1bb968c81..8aeb6f88a3d 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -6,7 +6,6 @@ path = /mob/living/carbon/human/abductor language = "Abductor Mindlink" default_language = "Abductor Mindlink" - unarmed_type = /datum/unarmed_attack/punch eyes = "blank_eyes" has_organ = list( "heart" = /obj/item/organ/internal/heart, diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index 6c37da34395..5a3e1d4cde9 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -5,7 +5,6 @@ deform = 'icons/mob/human_races/r_wryn.dmi' language = "Wryn Hivemind" tail = "wryntail" - unarmed_type = /datum/unarmed_attack/punch/weak punchdamagelow = 0 punchdamagehigh = 1 //primitive = /mob/living/carbon/monkey/wryn @@ -82,7 +81,6 @@ name = "Nucleation" name_plural = "Nucleations" icobase = 'icons/mob/human_races/r_nucleation.dmi' - unarmed_type = /datum/unarmed_attack/punch blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \ supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index c289ba3a19e..74f3e97d879 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -13,7 +13,6 @@ dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG - unarmed_type = /datum/unarmed_attack/punch punchdamagelow = 5 punchdamagehigh = 14 punchstunthreshold = 11 //about 40% chance to stun diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index 07d3215126e..c5003b21330 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -28,8 +28,7 @@ reagent_tag = PROCESS_ORG //Has standard darksight of 2. - //unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws) - //inherent_verbs = list(/mob/living/proc/ventcrawl) + unarmed_type = /datum/unarmed_attack/bite total_health = 75 brute_mod = 1.5 diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 620d49254f3..692a23c470a 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -4,7 +4,6 @@ icobase = 'icons/mob/human_races/r_plasmaman_sb.dmi' deform = 'icons/mob/human_races/r_plasmaman_pb.dmi' // TODO: Need deform. //language = "Clatter" - unarmed_type = /datum/unarmed_attack/punch species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING) dietflags = DIET_OMNI diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index d207dc20703..9da4d1222f6 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -8,7 +8,6 @@ deform = 'icons/mob/human_races/r_skeleton.dmi' path = /mob/living/carbon/human/skeleton default_language = "Galactic Common" - unarmed_type = /datum/unarmed_attack/punch blood_color = "#FFFFFF" flesh_color = "#E6E6C6" diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 50f969cae45..25d3fd342c5 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -356,7 +356,7 @@ else var/datum/unarmed_attack/attack = user.species.unarmed - user.do_attack_animation(target) + user.do_attack_animation(target, attack.animation_type) add_attack_logs(user, target, "Melee attacked with fists", admin_notify = target.ckey ? TRUE : FALSE) if(!iscarbon(user)) @@ -396,7 +396,7 @@ return 1 else add_attack_logs(user, target, "Disarmed", admin_notify = FALSE) - user.do_attack_animation(target) + user.do_attack_animation(target, ATTACK_EFFECT_DISARM) if(target.w_uniform) target.w_uniform.add_fingerprint(user) var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting)) @@ -500,17 +500,12 @@ //Species unarmed attacks /datum/unarmed_attack - var/attack_verb = list("attack") // Empty hand hurt intent verb. + var/attack_verb = list("punch") // Empty hand hurt intent verb. var/damage = 0 // How much flat bonus damage an attack will do. This is a *bonus* guaranteed damage amount on top of the random damage attacks do. var/attack_sound = "punch" var/miss_sound = 'sound/weapons/punchmiss.ogg' - var/sharp = 0 - -/datum/unarmed_attack/punch - attack_verb = list("punch") - -/datum/unarmed_attack/punch/weak - attack_verb = list("flail") + var/sharp = FALSE + var/animation_type = ATTACK_EFFECT_PUNCH /datum/unarmed_attack/diona attack_verb = list("lash", "bludgeon") @@ -519,7 +514,14 @@ attack_verb = list("scratch", "claw") attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' - sharp = 1 + sharp = TRUE + animation_type = ATTACK_EFFECT_CLAW + +/datum/unarmed_attack/bite + attack_verb = list("chomp") + attack_sound = 'sound/weapons/bite.ogg' + sharp = TRUE + animation_type = ATTACK_EFFECT_BITE /datum/unarmed_attack/claws/armalis attack_verb = list("slash", "claw") diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 05e989afa50..015f1515683 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -10,7 +10,6 @@ clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS dietflags = DIET_OMNI - unarmed_type = /datum/unarmed_attack/punch blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ colonies across a wide swathe of space. They hold a wide range of forms and creeds.

\ While the central Sol government maintains control of its far-flung people, powerful corporate \ @@ -237,7 +236,6 @@ default_language = "Galactic Common" language = "Skrellian" primitive_form = "Neara" - unarmed_type = /datum/unarmed_attack/punch blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ the royals' or 'Light of the Crown'.

Skrell are a highly advanced and logical race who live under the rule \ @@ -546,7 +544,6 @@ icobase = 'icons/mob/human_races/r_slime.dmi' deform = 'icons/mob/human_races/r_slime.dmi' path = /mob/living/carbon/human/slime - unarmed_type = /datum/unarmed_attack/punch remains_type = /obj/effect/decal/remains/slime // More sensitive to the cold @@ -749,7 +746,6 @@ deform = 'icons/mob/human_races/r_def_grey.dmi' default_language = "Galactic Common" language = "Psionic Communication" - unarmed_type = /datum/unarmed_attack/punch eyes = "grey_eyes_s" butt_sprite = "grey" @@ -931,7 +927,6 @@ path = /mob/living/carbon/human/machine default_language = "Galactic Common" language = "Trinary" - unarmed_type = /datum/unarmed_attack/punch remains_type = /obj/effect/decal/remains/robot eyes = "blank_eyes" @@ -1015,7 +1010,6 @@ path = /mob/living/carbon/human/drask default_language = "Galactic Common" language = "Orluum" - unarmed_type = /datum/unarmed_attack/punch eyes = "drask_eyes_s" speech_sounds = list('sound/voice/DraskTalk.ogg') diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index f61c5431fab..3023d6538a8 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/Life() +/mob/living/carbon/Life(seconds, times_fired) set invisibility = 0 set background = BACKGROUND_ENABLED @@ -14,7 +14,7 @@ O.on_life() handle_changeling() - handle_wetness() + handle_wetness(times_fired) // Increase germ_level regularly if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level @@ -26,8 +26,8 @@ /////////////// //Start of a breath chain, calls breathe() -/mob/living/carbon/handle_breathing() - if(mob_master.current_cycle % 4 == 2 || failed_last_breath) +/mob/living/carbon/handle_breathing(times_fired) + if(times_fired % 4 == 2 || failed_last_breath) breathe() //Breathe per 4 ticks, unless suffocating else if(istype(loc, /obj/)) @@ -241,11 +241,11 @@ reagents.metabolize(src) -/mob/living/carbon/proc/handle_wetness() - if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so +/mob/living/carbon/proc/handle_wetness(times_fired) + if(times_fired % 20==2) //dry off a bit once every 20 ticks or so wetlevel = max(wetlevel - 1,0) -/mob/living/carbon/handle_stomach() +/mob/living/carbon/handle_stomach(times_fired) for(var/mob/living/M in stomach_contents) if(M.loc != src) stomach_contents.Remove(M) @@ -255,7 +255,7 @@ stomach_contents.Remove(M) qdel(M) continue - if(mob_master.current_cycle%3==1) + if(times_fired % 3 == 1) M.adjustBruteLoss(5) nutrition += 10 diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm index ced452ab652..80ed9fdbffd 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -5,7 +5,7 @@ var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while var/SStun = 0 // stun variable -/mob/living/carbon/slime/Life() +/mob/living/carbon/slime/Life(seconds, times_fired) if(..()) handle_nutrition() handle_targets() diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index ecb233a2ebf..79bcd54775b 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -236,6 +236,7 @@ /mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M) if(Victim) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) if(Victim == M) if(prob(60)) visible_message("[M] attempts to wrestle \the [name] off!") @@ -259,7 +260,6 @@ return else - M.do_attack_animation(src) if(prob(30)) visible_message("[M] attempts to wrestle \the [name] off of [Victim]!") playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) @@ -297,7 +297,7 @@ grabbedby(M) else - M.do_attack_animation(src) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) var/damage = rand(1, 9) attacked += 10 if(prob(90)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 8c414636349..f02065b3a0a 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -1,4 +1,4 @@ -/mob/living/Life() +/mob/living/Life(seconds, times_fired) set invisibility = 0 set background = BACKGROUND_ENABLED @@ -22,7 +22,7 @@ handle_mutations_and_radiation() //Breathing, if applicable - handle_breathing() + handle_breathing(times_fired) //Random events (vomiting etc) handle_random_events() @@ -38,7 +38,7 @@ handle_fire() //stuff in the stomach - handle_stomach() + handle_stomach(times_fired) update_gravity(mob_has_gravity()) @@ -61,7 +61,7 @@ ..() -/mob/living/proc/handle_breathing() +/mob/living/proc/handle_breathing(times_fired) return /mob/living/proc/handle_mutations_and_radiation() @@ -80,7 +80,7 @@ /mob/living/proc/handle_environment(datum/gas_mixture/environment) return -/mob/living/proc/handle_stomach() +/mob/living/proc/handle_stomach(times_fired) return /mob/living/proc/update_pulling() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 964dba89a47..2f0d341f697 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -793,7 +793,7 @@ /mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash) if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND))) overlay_fullscreen("flash", type) - addtimer(src, "clear_fullscreen", 25, FALSE, "flash", 25) + addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25) return 1 /mob/living/proc/check_eye_prot() @@ -852,81 +852,11 @@ makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 1) spawn_dust() gib() - return -/atom/movable/proc/do_attack_animation(atom/A, end_pixel_y) - var/pixel_x_diff = 0 - var/pixel_y_diff = 0 - var/final_pixel_y = initial(pixel_y) - if(end_pixel_y) - final_pixel_y = end_pixel_y - - var/direction = get_dir(src, A) - if(direction & NORTH) - pixel_y_diff = 8 - else if(direction & SOUTH) - pixel_y_diff = -8 - - if(direction & EAST) - pixel_x_diff = 8 - else if(direction & WEST) - pixel_x_diff = -8 - - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2) - - -/mob/living/do_attack_animation(atom/A) - var/final_pixel_y = get_standard_pixel_y_offset(lying) - ..(A, final_pixel_y) - floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. - - // What icon do we use for the attack? - var/image/I - if(hand && l_hand) // Attacked with item in left hand. - I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 1) - else if(!hand && r_hand) // Attacked with item in right hand. - I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 1) - else // Attacked with a fist? - return - - // Who can see the attack? - var/list/viewing = list() - for(var/mob/M in viewers(A)) - if(M.client && M.client.prefs.show_ghostitem_attack) - viewing |= M.client - flick_overlay(I, viewing, 5) // 5 ticks/half a second - - // Scale the icon. - I.transform *= 0.75 - // The icon should not rotate. - I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA - - // Set the direction of the icon animation. - var/direction = get_dir(src, A) - if(direction & NORTH) - I.pixel_y = -16 - else if(direction & SOUTH) - I.pixel_y = 16 - - if(direction & EAST) - I.pixel_x = -16 - else if(direction & WEST) - I.pixel_x = 16 - - if(!direction) // Attacked self?! - I.pixel_z = 16 - - // And animate the attack! - animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) - -/atom/movable/proc/receiving_damage(atom/A) - var/pixel_x_diff = rand(-3,3) - var/pixel_y_diff = rand(-3,3) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = initial(pixel_x), pixel_y = initial(pixel_y), time = 2) - -/mob/living/receiving_damage(atom/A) +/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) + end_pixel_y = get_standard_pixel_y_offset(lying) + if(!used_item) + used_item = get_active_hand() ..() floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 38065ac1f2c..d734272e905 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -333,6 +333,9 @@ if(INTENT_GRAB) grabbedby(M) return FALSE - else + if(INTENT_HARM) M.do_attack_animation(src) return TRUE + if(INTENT_DISARM) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + return TRUE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index c84c7bdbbed..09b62f1c89c 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -268,6 +268,9 @@ var/list/ai_verbs_default = list( shuttle_caller_list -= src shuttle_master.autoEvac() QDEL_NULL(eyeobj) // No AI, no Eye + if(malfhacking) + deltimer(malfhacking) + malfhacking = null malfhack = null return ..() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 13b5308bc86..1755674b4f6 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -3,7 +3,7 @@ #define POWER_RESTORATION_SEARCH_APC 2 #define POWER_RESTORATION_APC_FOUND 3 -/mob/living/silicon/ai/Life() +/mob/living/silicon/ai/Life(seconds, times_fired) //doesn't call parent because it's a horrible mess if(stat == DEAD) return @@ -29,8 +29,10 @@ if(malfhack && malfhack.aidisabled) to_chat(src, "ERROR: APC access disabled, hack attempt canceled.") - malfhacking = 0 - malfhack = null + deltimer(malfhacking) + // This proc handles cleanup of screen notifications and + // messenging the client + malfhacked(malfhack) if(aiRestorePowerRoutine) adjustOxyLoss(1) diff --git a/code/modules/mob/living/silicon/decoy/life.dm b/code/modules/mob/living/silicon/decoy/life.dm index ade3c535506..353bf4259ff 100644 --- a/code/modules/mob/living/silicon/decoy/life.dm +++ b/code/modules/mob/living/silicon/decoy/life.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/decoy/Life() +/mob/living/silicon/decoy/Life(seconds, times_fired) if(src.stat == 2) return else diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index ec40dff7739..abcfc6bd643 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/pai/Life() +/mob/living/silicon/pai/Life(seconds, times_fired) . = ..() if(.) //if(secHUD == 1) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index d0733547cc8..adf6e2f7682 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -146,7 +146,7 @@ wrapped = A.cell A.cell.add_fingerprint(user) - A.cell.updateicon() + A.cell.update_icon() A.cell.forceMove(src) A.cell = null diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index f42f19b67fa..afa10c1772b 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/robot/Life() +/mob/living/silicon/robot/Life(seconds, times_fired) set invisibility = 0 set background = BACKGROUND_ENABLED diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 701909d87ea..444c4c23949 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -52,6 +52,9 @@ var/list/robot_verbs_default = list( var/custom_panel = null var/list/custom_panel_names = list("Cricket") var/emagged = 0 + var/is_emaggable = TRUE + var/eye_protection = 0 + var/ear_protection = 0 var/list/force_modules = list() var/allow_rename = TRUE @@ -762,7 +765,9 @@ var/list/robot_verbs_default = list( return var/mob/living/M = user if(!opened)//Cover is closed - if(locked) + if(!is_emaggable) + to_chat(user, "The emag sparks, and flashes red. This mechanism does not appear to be emaggable.") + else if(locked) to_chat(user, "You emag the cover lock.") locked = 0 else @@ -878,9 +883,10 @@ var/list/robot_verbs_default = list( icon_state = "[base_icon]-roll" else icon_state = base_icon - for(var/obj/item/borg/combat/shield/S in module.modules) - if(activated(S)) - overlays += "[base_icon]-shield" + if(module) + for(var/obj/item/borg/combat/shield/S in module.modules) + if(activated(S)) + overlays += "[base_icon]-shield" update_fire() /mob/living/silicon/robot/proc/installed_modules() @@ -1241,16 +1247,19 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/deathsquad base_icon = "nano_bloodhound" icon_state = "nano_bloodhound" + designation = "SpecOps" lawupdate = 0 scrambledcodes = 1 - pdahide = 1 - modtype = "Commando" - faction = list("nanotrasen") - designation = "Nanotrasen Combat" req_access = list(access_cent_specops) ionpulse = 1 magpulse = 1 - var/searching_for_ckey = 0 + pdahide = 1 + eye_protection = 2 // Immunity to flashes and the visual part of flashbangs + ear_protection = 1 // Immunity to the audio part of flashbangs + allow_rename = FALSE + modtype = "Commando" + faction = list("nanotrasen") + is_emaggable = FALSE /mob/living/silicon/robot/deathsquad/New(loc) ..() @@ -1267,26 +1276,7 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) -/mob/living/silicon/robot/deathsquad/attack_hand(mob/user) - if(isnull(ckey) && !searching_for_ckey) - searching_for_ckey = 1 - to_chat(user, "Now checking for possible borgs.") - var/list/borg_candidates = pollCandidates("Do you want to play as a Nanotrasen Combat borg?") - if(borg_candidates.len > 0 && isnull(ckey)) - searching_for_ckey = 0 - var/mob/M = pick(borg_candidates) - M.mind.transfer_to(src) - M.mind.assigned_role = "MODE" - M.mind.special_role = SPECIAL_ROLE_DEATHSQUAD - ticker.mode.traitors |= M.mind // Adds them to current traitor list. Which is really the extra antagonist list. - key = M.key - else - searching_for_ckey = 0 - to_chat(user, "Unable to connect to Central Command. Please wait and try again later.") - return - else - to_chat(user, "[src] is already checking for possible borgs.") - return + /mob/living/silicon/robot/syndicate base_icon = "syndie_bloodhound" @@ -1392,7 +1382,7 @@ var/list/robot_verbs_default = list( mind = new mind.current = src mind.original = src - mind.assigned_role = "MODE" + mind.assigned_role = SPECIAL_ROLE_ERT mind.special_role = SPECIAL_ROLE_ERT if(cyborg_unlock) crisis = 1 @@ -1447,3 +1437,9 @@ var/list/robot_verbs_default = list( var/static/all_borg_icon_states = icon_states('icons/mob/custom_synthetic/custom-synthetic.dmi') if(spritename in all_borg_icon_states) . = TRUE + +/mob/living/silicon/robot/check_eye_prot() + return eye_protection + +/mob/living/silicon/robot/check_ear_prot() + return ear_protection \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 033b244cf8c..e18ca8d6a17 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -1,7 +1,7 @@ /mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M) if(M.a_intent == INTENT_DISARM) if(!lying) - M.do_attack_animation(src) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) if(prob(85)) Stun(7) step(src, get_dir(M,src)) @@ -42,7 +42,7 @@ if(opened && !wiresexposed && !issilicon(user)) if(cell) - cell.updateicon() + cell.update_icon() cell.add_fingerprint(user) user.put_in_active_hand(cell) to_chat(user, "You remove \the [cell].") diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index f549c07b66a..e9aadf5086a 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -198,7 +198,7 @@ modules += new /obj/item/multitool/cyborg(src) modules += new /obj/item/t_scanner(src) modules += new /obj/item/analyzer(src) - modules += new /obj/item/taperoll/engineering(src) + modules += new /obj/item/holosign_creator/engineering(src) modules += new /obj/item/gripper(src) modules += new /obj/item/matter_decompiler(src) modules += new /obj/item/floor_painter(src) @@ -222,7 +222,7 @@ modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src) modules += new /obj/item/melee/baton/loaded(src) modules += new /obj/item/gun/energy/disabler/cyborg(src) - modules += new /obj/item/taperoll/police(src) + modules += new /obj/item/holosign_creator/security(src) modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src) emag = new /obj/item/gun/energy/laser/cyborg(src) diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 480c9442bd7..070ed327163 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -49,7 +49,7 @@ if("grab") grabbedby(M) else - M.do_attack_animation(src) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(loc, 'sound/effects/bang.ogg', 10, 1) if(HULK in M.mutations) var/damage = rand(10,15) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index b122decd322..972759812b4 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -11,7 +11,7 @@ grabbedby(M) if(INTENT_HARM, INTENT_DISARM) - M.do_attack_animation(src) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) visible_message("[M] [response_harm] [src]!") playsound(loc, "punch", 25, 1, -1) attack_threshold_check(harm_intent_damage) @@ -58,3 +58,11 @@ visible_message("[src] looks unharmed.") else apply_damage(damage, damagetype) + +/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) + if(!no_effect && !visual_effect_icon && melee_damage_upper) + if(melee_damage_upper < 10) + visual_effect_icon = ATTACK_EFFECT_PUNCH + else + visual_effect_icon = ATTACK_EFFECT_SMASH + ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index c040fbe1ed2..986795ccd1e 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -193,6 +193,9 @@ bots_list -= src QDEL_NULL(Radio) QDEL_NULL(access_card) + if(reset_access_timer_id) + deltimer(reset_access_timer_id) + reset_access_timer_id = null if(radio_controller && bot_filter) radio_controller.remove_object(bot_core, control_freq) QDEL_NULL(bot_core) @@ -527,7 +530,7 @@ Pass a positive integer as an argument to override a bot's default speed. turn_on() //Saves the AI the hassle of having to activate a bot manually. access_card = all_access //Give the bot all-access while under the AI's command. if(client) - reset_access_timer_id = addtimer(src, "bot_reset", 600) //if the bot is player controlled, they get the extra access for a limited time + reset_access_timer_id = addtimer(CALLBACK (src, .proc/bot_reset), 600, TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time to_chat(src, "Priority waypoint set by [calling_ai] [caller]. Proceed to [end_area.name].
[path.len-1] meters to destination. You have been granted additional door access for 60 seconds.
") if(message) to_chat(calling_ai, "[bicon(src)] [name] called to [end_area.name]. [path.len-1] meters to destination.") diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 1ced2db841c..9e96a16fb0f 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -30,9 +30,10 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") //Edbot Assembly @@ -53,9 +54,10 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") return switch(build_step) @@ -253,10 +255,11 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") /obj/item/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params) ..() @@ -272,10 +275,11 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") //Medbot Assembly /obj/item/firstaid_arm_assembly @@ -347,9 +351,10 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") else switch(build_step) if(0) @@ -457,9 +462,10 @@ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && loc != usr) + if(!in_range(src, user) && loc != user) return created_name = t + log_game("[key_name(user)] has renamed a robot to [t]") else if(istype(I, /obj/item/screwdriver)) if(!build_step) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 1f38c83b502..3243061273f 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -188,7 +188,7 @@ visible_message("[usr] switches [on ? "on" : "off"] [src].") if("cellremove") if(open && cell && !usr.get_active_hand()) - cell.updateicon() + cell.update_icon() usr.put_in_active_hand(cell) cell.add_fingerprint(usr) cell = null diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index c292d33f39a..ef5de1908a8 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -267,7 +267,7 @@ Auto Patrol: []"}, C.visible_message("[src] has [harmbaton ? "beaten" : "stunned"] [C]!",\ "[src] has [harmbaton ? "beaten" : "stunned"] you!") -/mob/living/simple_animal/bot/secbot/Life() +/mob/living/simple_animal/bot/secbot/Life(seconds, times_fired) . = ..() if(flashing_lights) switch(light_color) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index b942ce4107b..a6fcf4b5a20 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -285,7 +285,7 @@ AIStatus = AI_ON environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP -/mob/living/simple_animal/hostile/construct/behemoth/Life() +/mob/living/simple_animal/hostile/construct/behemoth/Life(seconds, times_fired) weakened = 0 return ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 7afa9debe25..ea7db302c43 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -46,7 +46,7 @@ Read_Memory() ..() -/mob/living/simple_animal/pet/cat/Runtime/Life() +/mob/living/simple_animal/pet/cat/Runtime/Life(seconds, times_fired) if(!cats_deployed && ticker.current_state >= GAME_STATE_SETTING_UP) Deploy_The_Cats() if(!stat && ticker.current_state == GAME_STATE_FINISHED && !memory_saved) diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 24772ff473c..613f91e024c 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -37,7 +37,7 @@ if(gender == NEUTER) gender = pick(MALE, FEMALE) -/mob/living/simple_animal/pet/corgi/Life() +/mob/living/simple_animal/pet/corgi/Life(seconds, times_fired) . = ..() regenerate_icons() @@ -612,7 +612,7 @@ A.fire() return -/mob/living/simple_animal/pet/corgi/Ian/borgi/Life() +/mob/living/simple_animal/pet/corgi/Ian/borgi/Life(seconds, times_fired) ..() if(emagged && prob(25)) var/mob/living/carbon/target = locate() in view(10,src) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 99db2236612..665afa16cb2 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -34,7 +34,7 @@ Move(get_step(src, east_vs_west), east_vs_west) turns_since_move = 0 -/mob/living/simple_animal/crab/Life() +/mob/living/simple_animal/crab/Life(seconds, times_fired) . = ..() regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index ab1a94cbcc6..a8784a6d150 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -52,7 +52,7 @@ if(SV) SV.eat(src) -/mob/living/simple_animal/hostile/retaliate/goat/Life() +/mob/living/simple_animal/hostile/retaliate/goat/Life(seconds, times_fired) . = ..() if(stat == CONSCIOUS && prob(5)) milk_content = min(50, milk_content+rand(5, 10)) @@ -132,7 +132,7 @@ else ..() -/mob/living/simple_animal/cow/Life() +/mob/living/simple_animal/cow/Life(seconds, times_fired) . = ..() if(stat == CONSCIOUS && prob(5)) milk_content = min(50, milk_content+rand(5, 10)) @@ -188,7 +188,7 @@ pixel_x = rand(-6, 6) pixel_y = rand(0, 10) -/mob/living/simple_animal/chick/Life() +/mob/living/simple_animal/chick/Life(seconds, times_fired) . =..() if(.) amount_grown += rand(1,2) @@ -267,7 +267,7 @@ var/global/chicken_count = 0 else ..() -/mob/living/simple_animal/chicken/Life() +/mob/living/simple_animal/chicken/Life(seconds, times_fired) . = ..() if((. && prob(3) && eggsleft > 0) && egg_type) visible_message("[src] [pick(layMessage)]") diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 5972d0f6e4b..a7a62c74c0b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -39,7 +39,7 @@ for(var/mob/M in view()) M << 'sound/effects/mousesqueek.ogg' -/mob/living/simple_animal/mouse/Life() +/mob/living/simple_animal/mouse/Life(seconds, times_fired) . = ..() if(stat == UNCONSCIOUS) if(ckey || prob(1)) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index a06ea9bd80d..283936acb44 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -57,7 +57,7 @@ target = null return ..() -/mob/living/simple_animal/hostile/Life() +/mob/living/simple_animal/hostile/Life(seconds, times_fired) . = ..() if(!.) walk(src, 0) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 50c24f0ac0b..3c72042efce 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -75,7 +75,7 @@ Difficulty: Hard /obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in() return TRUE -/mob/living/simple_animal/hostile/megafauna/bubblegum/Life() +/mob/living/simple_animal/hostile/megafauna/bubblegum/Life(seconds, times_fired) ..() move_to_delay = Clamp((health/maxHealth) * 10, 5, 10) @@ -117,7 +117,7 @@ Difficulty: Hard bloodspell.phased = 1 internal_gps = new/obj/item/gps/internal/bubblegum(src) -/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon) +/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) if(!charging) ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 8d249c7f9e2..fe80846935d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -76,7 +76,7 @@ Difficulty: Hard internal_gps = new/obj/item/gps/internal/hierophant(src) spawned_rune = new(loc) -/mob/living/simple_animal/hostile/megafauna/hierophant/Life() +/mob/living/simple_animal/hostile/megafauna/hierophant/Life(seconds, times_fired) . = ..() if(. && spawned_rune && !client) if(target || loc == spawned_rune.loc) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 9dab58daa4a..5832f7bdd60 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -51,7 +51,7 @@ var/attempt_open = 0 // Pickup loot -/mob/living/simple_animal/hostile/mimic/crate/initialize() +/mob/living/simple_animal/hostile/mimic/crate/Initialize() ..() for(var/obj/item/I in loc) I.loc = src diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index e38ed7624ba..3063c5a8ce1 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -62,7 +62,7 @@ /obj/item/organ/internal/hivelord_core/New() ..() - addtimer(src, "inert_check", 2400) + addtimer(CALLBACK(src, .proc/inert_check), 2400) /obj/item/organ/internal/hivelord_core/proc/inert_check() if(!owner && !preserved) @@ -151,7 +151,7 @@ /mob/living/simple_animal/hostile/asteroid/hivelordbrood/New() ..() - addtimer(src, "death", 100) + addtimer(CALLBACK(src, .proc/death), 100) /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood name = "blood brood" @@ -269,7 +269,7 @@ stat_attack = 1 robust_searching = 1 -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life() +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life(seconds, times_fired) if(isturf(loc)) for(var/mob/living/carbon/human/H in view(src,1)) //Only for corpse right next to/on same tile if(H.stat == UNCONSCIOUS) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 7346473de94..2c775074253 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -42,7 +42,7 @@ else to_chat(user, "It looks like it's been roughed up.") -/mob/living/simple_animal/hostile/mushroom/Life() +/mob/living/simple_animal/hostile/mushroom/Life(seconds, times_fired) ..() if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten adjustBruteLoss(-2) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index 0e1d5eddd71..90586bb43c6 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -62,7 +62,7 @@ return ..() //self repair systems have a chance to bring the drone back to life -/mob/living/simple_animal/hostile/retaliate/malf_drone/Life() +/mob/living/simple_animal/hostile/retaliate/malf_drone/Life(seconds, times_fired) //emps and lots of damage can temporarily shut us down if(disabled > 0) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm index 14b1af87b0a..f9516739e6f 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm @@ -56,7 +56,7 @@ if(.) custom_emote(1, "wails at [.]") -/mob/living/simple_animal/hostile/retaliate/ghost/Life() +/mob/living/simple_animal/hostile/retaliate/ghost/Life(seconds, times_fired) if(target) invisibility = pick(0,0,60,invisibility) else diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm index 27bd2f3ee1c..cdbc64eea1e 100644 --- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm +++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm @@ -190,7 +190,7 @@ SW.death() -/mob/living/simple_animal/hostile/spaceWorm/Life() +/mob/living/simple_animal/hostile/spaceWorm/Life(seconds, times_fired) if(nextWorm && !(Adjacent(nextWorm))) Detach(0) @@ -328,7 +328,7 @@ //Jiggle the whole worm forwards towards the next segment -/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A) +/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) ..() if(previousWorm) previousWorm.do_attack_animation(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm index c9309715443..5c483b4e3e9 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm @@ -48,7 +48,7 @@ visible_message("[src] chitters in the direction of [Q]!") . = ..() -/mob/living/simple_animal/hostile/poison/terror_spider/purple/Life() +/mob/living/simple_animal/hostile/poison/terror_spider/purple/Life(seconds, times_fired) . = ..() if(.) // if mob is NOT dead if(!degenerate && spider_myqueen) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm index 5edcbe919c2..9133b8cc14c 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm @@ -61,7 +61,7 @@ spider_growinstantly = 1 spider_spawnfrequency = 150 -/mob/living/simple_animal/hostile/poison/terror_spider/queen/Life() +/mob/living/simple_animal/hostile/poison/terror_spider/queen/Life(seconds, times_fired) . = ..() if(.) // if mob is NOT dead if(ckey && canlay < 12 && hasnested) // max 12 eggs worth stored at any one time, realistically that's tons. diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index 2a1e0f17ef4..ef456ddcb0e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -270,8 +270,8 @@ var/global/list/ts_spiderling_list = list() else ts_count_alive_station++ // after 30 seconds, assuming nobody took control of it yet, offer it to ghosts. - addtimer(src, "CheckFaction", 150) - addtimer(src, "announcetoghosts", 300) + addtimer(CALLBACK(src, .proc/CheckFaction), 150) + addtimer(CALLBACK(src, .proc/announcetoghosts), 300) var/datum/atom_hud/U = huds[DATA_HUD_MEDICAL_ADVANCED] U.add_hud_to(src) @@ -292,7 +292,7 @@ var/global/list/ts_spiderling_list = list() handle_dying() return ..() -/mob/living/simple_animal/hostile/poison/terror_spider/Life() +/mob/living/simple_animal/hostile/poison/terror_spider/Life(seconds, times_fired) . = ..() if(!.) // if mob is dead if(prob(2)) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 9e6396dbde0..57412eb5a0d 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -22,7 +22,7 @@ for(var/turf/T in anchors) var/datum/beam/B = Beam(T, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine) B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow) - addtimer(src, "bear_fruit", growth_time) + addtimer(CALLBACK(src, .proc/bear_fruit), growth_time) /obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit() visible_message("the plant has borne fruit!") diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index c206f1499d9..dba62b4744c 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -276,7 +276,7 @@ /* * AI - Not really intelligent, but I'm calling it AI anyway. */ -/mob/living/simple_animal/parrot/Life() +/mob/living/simple_animal/parrot/Life(seconds, times_fired) ..() //Sprite and AI update for when a parrot gets pulled diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm index 2e9d1b94bf2..22901f4d29a 100644 --- a/code/modules/mob/living/simple_animal/posessed_object.dm +++ b/code/modules/mob/living/simple_animal/posessed_object.dm @@ -26,7 +26,7 @@ to_chat(usr, "[src] appears to be having trouble staying afloat!") -/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A) +/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) ..() animate_ghostly_presence(src, -1, 20, 1) // Restart the floating animation after the attack animation, as it will be cancelled. @@ -60,7 +60,7 @@ qdel(src) -/mob/living/simple_animal/possessed_object/Life() +/mob/living/simple_animal/possessed_object/Life(seconds, times_fired) ..() if(!possessed_item) // If we're a donut and someone's eaten us, for instance. diff --git a/code/modules/mob/living/simple_animal/tribbles.dm b/code/modules/mob/living/simple_animal/tribbles.dm index 5a38929b88d..3e7f1722a41 100644 --- a/code/modules/mob/living/simple_animal/tribbles.dm +++ b/code/modules/mob/living/simple_animal/tribbles.dm @@ -68,7 +68,7 @@ var/global/totaltribbles = 0 //global variable so it updates for all tribbles, gestation = 0 -/mob/living/simple_animal/tribble/Life() +/mob/living/simple_animal/tribble/Life(seconds, times_fired) ..() if(src.health > 0) //no mostly dead procreation if(gestation != null) //neuter check diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index bb590e730f5..db84df47f52 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -169,7 +169,17 @@ /mob/proc/movement_delay() return 0 -/mob/proc/Life() +/mob/proc/Life(seconds, times_fired) + if(forced_look) + if(!isnum(forced_look)) + var/atom/A = locateUID(forced_look) + if(istype(A)) + var/view = client ? client.view : world.view + if(get_dist(src, A) > view || !(src in viewers(view, A))) + forced_look = null + to_chat(src, "Your direction target has left your view, you are no longer facing anything.") + return + setDir() // handle_typing_indicator() return @@ -533,6 +543,17 @@ var/list/slot_equipment_priority = list( \ client.screen = list() hud_used.show_hud(hud_used.hud_version) +/mob/setDir(new_dir) + if(forced_look) + if(isnum(forced_look)) + dir = forced_look + else + var/atom/A = locateUID(forced_look) + if(istype(A)) + dir = get_cardinal_dir(src, A) + return + . = ..() + /mob/proc/show_inv(mob/user) user.set_machine(src) var/dat = {" @@ -1308,4 +1329,4 @@ var/list/slot_equipment_priority = list( \ if(WEST) D = NORTH setDir(D) - spintime -= speed \ No newline at end of file + spintime -= speed diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 9154591c2fe..57b5aeb4996 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -198,3 +198,5 @@ var/list/progressbars = null //for stacking do_after bars var/list/tkgrabbed_objects = list() // Assoc list of items to TK grabs + + var/forced_look = null // This can either be a numerical direction or a soft object reference (UID). It makes the mob always face towards the selected thing. \ No newline at end of file diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index a92e548d42b..f26961eace9 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -268,6 +268,8 @@ else . = ..() + mob.setDir(direct) + for(var/obj/item/grab/G in mob) if(G.state == GRAB_NECK) mob.setDir(reverse_dir[direct]) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index bf6526c856e..fdd9266c128 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -326,7 +326,7 @@ if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) if(character.mind) - if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE")) + if((character.mind.assigned_role != "Cyborg") && (character.mind.assigned_role != character.mind.special_role)) if(character.mind.role_alt_title) rank = character.mind.role_alt_title var/arrivalmessage = announcer.arrivalmsg @@ -338,7 +338,7 @@ announcer.say(";[arrivalmessage]") else if(character.mind) - if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE")) + if((character.mind.assigned_role != "Cyborg") && (character.mind.assigned_role != character.mind.special_role)) if(character.mind.role_alt_title) rank = character.mind.role_alt_title global_announcer.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") @@ -351,12 +351,12 @@ if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) if(character.mind) - if((character.mind.special_role != "MODE")) + if(character.mind.assigned_role != character.mind.special_role) var/arrivalmessage = "A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"]." announcer.say(";[arrivalmessage]") else if(character.mind) - if((character.mind.special_role != "MODE")) + if(character.mind.assigned_role != character.mind.special_role) // can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc. global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm index 6ebf9228848..b570687569a 100644 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -238,7 +238,7 @@ jobdatum = J break if(!jobdatum) - to_chat(usr, "\red No log exists for this job: [t1]") + to_chat(usr, "No log exists for this job: [t1]") return access = jobdatum.get_access() diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index e3c625593c5..30841f94c69 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -30,7 +30,8 @@ icon_state = "tallcabinet" -/obj/structure/filingcabinet/initialize() +/obj/structure/filingcabinet/Initialize() + ..() for(var/obj/item/I in loc) if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo)) I.loc = src diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 0d176753ad4..41799958c4f 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -316,11 +316,11 @@ return src.add_fingerprint(user) if(target == user && !user.incapacitated()) - visible_message("[usr] jumps onto the photocopier!") + visible_message("[usr] jumps onto [src]!") else if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis) if(target.anchored) return if(!ishuman(user)) return - visible_message("[usr] drags [target.name] onto the photocopier!") + visible_message("[usr] drags [target.name] onto [src]!") target.forceMove(get_turf(src)) ass = target if(copyitem) @@ -344,9 +344,9 @@ /obj/machinery/photocopier/emag_act(user as mob) if(!emagged) emagged = 1 - to_chat(user, "You overload the photocopier's laser printing mechanism.") + to_chat(user, "You overload [src]'s laser printing mechanism.") else - to_chat(user, "The photocopier's laser printing mechanism is already overloaded!") + to_chat(user, "[src]'s laser printing mechanism is already overloaded!") /obj/item/toner name = "toner cartridge" diff --git a/code/modules/pda/cart.dm b/code/modules/pda/cart.dm index c50ae0758f4..53c61f4e27f 100644 --- a/code/modules/pda/cart.dm +++ b/code/modules/pda/cart.dm @@ -14,15 +14,6 @@ var/list/programs = list() var/list/messenger_plugins = list() -/obj/item/cartridge/New() - if(ticker && ticker.current_state >= GAME_STATE_SETTING_UP) - initialize() - -/obj/item/cartridge/initialize() - if(radio) - radio.initialize() - ..() - /obj/item/cartridge/Destroy() QDEL_NULL(radio) QDEL_LIST(programs) @@ -68,7 +59,7 @@ new/datum/data/pda/app/crew_records/security, new/datum/data/pda/app/secbot_control) -/obj/item/cartridge/security/initialize() +/obj/item/cartridge/security/Initialize() radio = new /obj/item/integrated_radio/beepsky(src) ..() @@ -118,7 +109,7 @@ desc = "A data cartridge with an integrated radio signaler module." programs = list(new/datum/data/pda/app/signaller) -/obj/item/cartridge/signal/initialize() +/obj/item/cartridge/signal/Initialize() radio = new /obj/item/integrated_radio/signal(src) ..() @@ -141,7 +132,7 @@ new/datum/data/pda/app/supply, new/datum/data/pda/app/mule_control) -/obj/item/cartridge/quartermaster/initialize() +/obj/item/cartridge/quartermaster/Initialize() radio = new /obj/item/integrated_radio/mule(src) ..() @@ -163,7 +154,7 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/hop/initialize() +/obj/item/cartridge/hop/Initialize() radio = new /obj/item/integrated_radio/mule(src) ..() @@ -176,7 +167,7 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/hos/initialize() +/obj/item/cartridge/hos/Initialize() radio = new /obj/item/integrated_radio/beepsky(src) ..() @@ -214,7 +205,7 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/rd/initialize() +/obj/item/cartridge/rd/Initialize() radio = new /obj/item/integrated_radio/signal(src) ..() @@ -242,7 +233,7 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/captain/initialize() +/obj/item/cartridge/captain/Initialize() radio = new /obj/item/integrated_radio/beepsky(src) ..() @@ -279,7 +270,7 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/centcom/initialize() +/obj/item/cartridge/centcom/Initialize() radio = new /obj/item/integrated_radio/beepsky(src) ..() diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index 3c89c291300..b9dfe8ff7e4 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -173,7 +173,7 @@ radio_connection = null return ..() -/obj/item/integrated_radio/signal/initialize() +/obj/item/integrated_radio/signal/Initialize() if(!radio_controller) return if(src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 23c6e2a1f15..3ba1a4b5210 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -682,7 +682,7 @@ else user.put_in_hands(cell) cell.add_fingerprint(user) - cell.updateicon() + cell.update_icon() src.cell = null user.visible_message("[user.name] removes the power cell from [src.name]!", "You remove the power cell.") @@ -1004,8 +1004,7 @@ return to_chat(malf, "Beginning override of APC systems. This takes some time, and you cannot perform other actions during the process.") malf.malfhack = src - malf.malfhacking = addtimer(malf, "malfhacked", 600, FALSE, src) - + malf.malfhacking = addtimer(CALLBACK(malf, /mob/living/silicon/ai/.proc/malfhacked, src), 600, TIMER_STOPPABLE) var/obj/screen/alert/hackingapc/A A = malf.throw_alert("hackingapc", /obj/screen/alert/hackingapc) A.target = src diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c5b014576fc..7580621834f 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -72,19 +72,13 @@ By design, d1 is the smallest direction and d2 is the highest var/turf/T = src.loc // hide if turf is not intact if(level==1) hide(T.intact) - cable_list += src //add it to the global cable list - - // Catches the interim-zone of worldstart and roundstart - // I want both the ticker to exist (so mapped-in cables don't trip this) - // but also not have started yet (since the zlevel system would handle this on its own otherwise) - if((ticker && ticker.current_state < GAME_STATE_PLAYING)) - attempt_init() + LAZYADD(GLOB.cable_list, src) //add it to the global cable list /obj/structure/cable/Destroy() // called when a cable is deleted if(powernet) cut_cable_from_powernet() // update the powernets - cable_list -= src //remove it from global cable list + LAZYREMOVE(GLOB.cable_list, src) //remove it from global cable list return ..() // then go ahead and delete the cable /////////////////////////////////// @@ -462,7 +456,7 @@ obj/structure/cable/proc/cable_color(var/colorC) powernet.remove_cable(src) //remove the cut cable from its powernet // queue it to rebuild - deferred_powernet_rebuilds += O + SSmachines.deferred_powernet_rebuilds += O // Disconnect machines connected to nodes if(d1 == 0) // if we cut a node (O-X) cable diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index f08e008089b..ff7ee7b6784 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -1,8 +1,64 @@ -// the power cell -// charge from 0 to 100% -// fits in APC to provide backup power +/obj/item/stock_parts/cell + name = "power cell" + desc = "A rechargeable electrochemical power cell." + icon = 'icons/obj/power.dmi' + icon_state = "cell" + item_state = "cell" + origin_tech = "powerstorage=1" + force = 5 + throwforce = 5 + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + var/charge = 0 // note %age conveted to actual charge in New + var/maxcharge = 1000 + materials = list(MAT_METAL = 700, MAT_GLASS = 50) + var/rigged = FALSE // true if rigged to explode + var/chargerate = 100 //how much power is given every tick in a recharger + var/self_recharge = 0 //does it self recharge, over time, or not? + var/ratingdesc = TRUE + var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. + +/obj/item/stock_parts/cell/New() + ..() + processing_objects.Add(src) + charge = maxcharge + if(ratingdesc) + desc += " This one has a power rating of [DisplayPower(maxcharge)], and you should not swallow it." + update_icon() + +/obj/item/stock_parts/cell/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/stock_parts/cell/vv_edit_var(var_name, var_value) + switch(var_name) + if("self_recharge") + if(var_value) + processing_objects.Add(src) + else + processing_objects.Remove(src) + . = ..() + +/obj/item/stock_parts/cell/process() + if(self_recharge) + give(chargerate * 0.25) + else + return PROCESS_KILL + +/obj/item/stock_parts/cell/update_icon() + overlays.Cut() + if(grown_battery) + overlays += image('icons/obj/power.dmi', "grown_wires") + if(charge < 0.01) + return + else if(charge/maxcharge >=0.995) + overlays += "cell-o2" + else + overlays += "cell-o1" + /obj/item/stock_parts/cell/proc/percent() // return % charge of cell - return 100.0*charge/maxcharge + return 100 * charge / maxcharge // use power from a cell /obj/item/stock_parts/cell/proc/use(amount) @@ -20,24 +76,23 @@ explode() return 0 if(maxcharge < amount) - return 0 - var/power_used = min(maxcharge-charge,amount) + amount = maxcharge + var/power_used = min(maxcharge - charge, amount) charge += power_used return power_used /obj/item/stock_parts/cell/examine(mob/user) - if(..(user, 1)) - if(maxcharge <= 2500) - to_chat(user, "[desc]\nThe manufacturer's label states this cell has a power rating of [maxcharge], and that you should not swallow it.\nThe charge meter reads [round(src.percent() )]%.") - else - to_chat(user, "This power cell has an exciting chrome finish, as it is an uber-capacity cell type! It has a power rating of [maxcharge]!\nThe charge meter reads [round(src.percent() )]%.") + ..() + if(rigged) + to_chat(user, "This power cell seems to be faulty!") + else + to_chat(user, "The charge meter reads [round(percent() )]%.") -/obj/item/stock_parts/cell/attack_self(mob/user as mob) - src.add_fingerprint(user) - return +/obj/item/stock_parts/cell/suicide_act(mob/user) + to_chat(viewers(user), "[user] is licking the electrodes of the [src]! It looks like \he's trying to commit suicide.") + return (FIRELOSS) /obj/item/stock_parts/cell/attackby(obj/item/W, mob/user, params) - ..() if(istype(W, /obj/item/reagent_containers/syringe)) var/obj/item/reagent_containers/syringe/S = W @@ -45,34 +100,29 @@ if(S.reagents.has_reagent("plasma", 5) || S.reagents.has_reagent("plasma_dust", 5)) - rigged = 1 + rigged = TRUE log_admin("LOG: [key_name(user)] injected a power cell with plasma, rigging it to explode.") message_admins("LOG: [key_name_admin(user)] injected a power cell with plasma, rigging it to explode.") S.reagents.clear_reagents() + else + return ..() /obj/item/stock_parts/cell/proc/explode() - var/turf/T = get_turf(src.loc) -/* - * 1000-cell explosion(T, -1, 0, 1, 1) - * 2500-cell explosion(T, -1, 0, 1, 1) - * 10000-cell explosion(T, -1, 1, 3, 3) - * 15000-cell explosion(T, -1, 2, 4, 4) - * */ - if(charge==0) + var/turf/T = get_turf(loc) + if(charge == 0) return var/devastation_range = -1 //round(charge/11000) - var/heavy_impact_range = round(sqrt(charge)/60) - var/light_impact_range = round(sqrt(charge)/30) + var/heavy_impact_range = round(sqrt(charge) / 60) + var/light_impact_range = round(sqrt(charge) / 30) var/flash_range = light_impact_range - if(light_impact_range==0) - rigged = 0 + if(light_impact_range == 0) + rigged = FALSE corrupt() return //explosion(T, 0, 1, 2, 2) - log_admin("LOG: Rigged power cell explosion, last touched by [fingerprintslast]") message_admins("LOG: Rigged power cell explosion, last touched by [fingerprintslast]") @@ -81,70 +131,242 @@ /obj/item/stock_parts/cell/proc/corrupt() charge /= 2 - maxcharge /= 2 + maxcharge = max(maxcharge / 2, chargerate) if(prob(10)) - rigged = 1 //broken batterys are dangerous + rigged = TRUE //broken batterys are dangerous /obj/item/stock_parts/cell/emp_act(severity) charge -= 1000 / severity if(charge < 0) charge = 0 - if(reliability != 100 && prob(50/severity)) - reliability -= 10 / severity ..() /obj/item/stock_parts/cell/ex_act(severity) - switch(severity) - if(1.0) + if(EXPLODE_DEVASTATE) qdel(src) - return - if(2.0) + if(EXPLODE_HEAVY) if(prob(50)) qdel(src) return if(prob(50)) corrupt() - if(3.0) + if(EXPLODE_LIGHT) if(prob(25)) qdel(src) return if(prob(25)) corrupt() - return /obj/item/stock_parts/cell/blob_act() - ex_act(1) + ex_act(EXPLODE_DEVASTATE) /obj/item/stock_parts/cell/proc/get_electrocute_damage() switch(charge) -/* if(9000 to INFINITY) - return min(rand(90,150),rand(90,150)) - if(2500 to 9000-1) - return min(rand(70,145),rand(70,145)) - if(1750 to 2500-1) - return min(rand(35,110),rand(35,110)) - if(1500 to 1750-1) - return min(rand(30,100),rand(30,100)) - if(750 to 1500-1) - return min(rand(25,90),rand(25,90)) - if(250 to 750-1) - return min(rand(20,80),rand(20,80)) - if(100 to 250-1) - return min(rand(20,65),rand(20,65))*/ if(5000000 to INFINITY) - return min(rand(200,300),rand(200,300)) - if(4000000 to 5000000-1) - return min(rand(80,180),rand(80,180)) - if(1000000 to 4000000-1) - return min(rand(50,160),rand(50,160)) - if(200000 to 1000000-1) - return min(rand(25,80),rand(25,80)) - if(100000 to 200000-1)//Ave powernet - return min(rand(20,60),rand(20,60)) - if(50000 to 100000-1) - return min(rand(15,40),rand(15,40)) - if(1000 to 50000-1) - return min(rand(10,20),rand(10,20)) + return min(rand(200, 300),rand(200, 300)) + if(4000000 to 5000000 - 1) + return min(rand(80, 180),rand(80, 180)) + if(1000000 to 4000000 - 1) + return min(rand(50, 160),rand(50, 160)) + if(200000 to 1000000 - 1) + return min(rand(25, 80),rand(25, 80)) + if(100000 to 200000 - 1)//Ave powernet + return min(rand(20, 60),rand(20, 60)) + if(50000 to 100000 - 1) + return min(rand(15, 40),rand(15, 40)) + if(1000 to 50000 - 1) + return min(rand(10, 20),rand(10, 20)) else return 0 + +// Cell variants +/obj/item/stock_parts/cell/empty/New() + ..() + charge = 0 + +/obj/item/stock_parts/cell/crap + name = "\improper Nanotrasen brand rechargeable AA battery" + desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT + maxcharge = 500 + materials = list(MAT_GLASS = 40) + rating = 2 + +/obj/item/stock_parts/cell/crap/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/upgraded + name = "upgraded power cell" + desc = "A power cell with a slightly higher capacity than normal!" + maxcharge = 2500 + materials = list(MAT_GLASS = 50) + rating = 2 + chargerate = 1000 + +/obj/item/stock_parts/cell/upgraded/plus + name = "upgraded power cell+" + desc = "A power cell with an even higher capacity than the base model!" + maxcharge = 5000 + +/obj/item/stock_parts/cell/secborg + name = "security borg rechargeable D battery" + origin_tech = null + maxcharge = 600 //600 max charge / 100 charge per shot = six shots + materials = list(MAT_GLASS = 40) + rating = 2.5 + +/obj/item/stock_parts/cell/secborg/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/pulse //200 pulse shots + name = "pulse rifle power cell" + maxcharge = 40000 + rating = 3 + chargerate = 1500 + +/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots + name = "pulse carbine power cell" + maxcharge = 5000 + +/obj/item/stock_parts/cell/pulse/pistol //10 pulse shots + name = "pulse pistol power cell" + maxcharge = 2000 + +/obj/item/stock_parts/cell/high + name = "high-capacity power cell" + origin_tech = "powerstorage=2" + icon_state = "hcell" + maxcharge = 10000 + materials = list(MAT_GLASS = 60) + rating = 3 + chargerate = 1500 + +/obj/item/stock_parts/cell/high/plus + name = "high-capacity power cell+" + desc = "Where did these come from?" + icon_state = "h+cell" + maxcharge = 15000 + chargerate = 2250 + +/obj/item/stock_parts/cell/high/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/super + name = "super-capacity power cell" + origin_tech = "powerstorage=3;materials=3" + icon_state = "scell" + maxcharge = 20000 + materials = list(MAT_GLASS = 300) + rating = 4 + chargerate = 2000 + +/obj/item/stock_parts/cell/super/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/hyper + name = "hyper-capacity power cell" + origin_tech = "powerstorage=4;engineering=4;materials=4" + icon_state = "hpcell" + maxcharge = 30000 + materials = list(MAT_GLASS = 400) + rating = 5 + chargerate = 3000 + +/obj/item/stock_parts/cell/hyper/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/bluespace + name = "bluespace power cell" + desc = "A rechargeable transdimensional power cell." + origin_tech = "powerstorage=5;bluespace=4;materials=4;engineering=4" + icon_state = "bscell" + maxcharge = 40000 + materials = list(MAT_GLASS = 600) + rating = 6 + chargerate = 4000 + +/obj/item/stock_parts/cell/bluespace/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/infinite + name = "infinite-capacity power cell!" + icon_state = "icell" + origin_tech = "powerstorage=7" + maxcharge = 30000 + materials = list(MAT_GLASS=1000) + rating = 6 + chargerate = 30000 + +/obj/item/stock_parts/cell/infinite/use() + return 1 + +/obj/item/stock_parts/cell/infinite/abductor + name = "void core" + desc = "An alien power cell that produces energy seemingly out of nowhere." + icon = 'icons/obj/abductor.dmi' + icon_state = "cell" + maxcharge = 50000 + rating = 12 + ratingdesc = FALSE + +/obj/item/stock_parts/cell/infinite/abductor/update_icon() + return + + +/obj/item/stock_parts/cell/potato + name = "potato battery" + desc = "A rechargeable starch based power cell." + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "potato" + origin_tech = "powerstorage=1;biotech=1" + charge = 100 + maxcharge = 300 + materials = list() + rating = 1 + grown_battery = TRUE //it has the overlays for wires + +/obj/item/stock_parts/cell/high/slime + name = "charged slime core" + desc = "A yellow slime core infused with plasma, it crackles with power." + origin_tech = "powerstorage=5;biotech=4" + icon = 'icons/mob/slimes.dmi' + icon_state = "yellow slime extract" + materials = list() + rating = 5 //self-recharge makes these desirable + self_recharge = 1 // Infused slime cores self-recharge, over time + chargerate = 500 + +/obj/item/stock_parts/cell/emproof + name = "\improper EMP-proof cell" + desc = "An EMP-proof cell." + maxcharge = 500 + rating = 3 + +/obj/item/stock_parts/cell/emproof/empty/New() + ..() + charge = 0 + update_icon() + +/obj/item/stock_parts/cell/emproof/emp_act(severity) + return + +/obj/item/stock_parts/cell/emproof/corrupt() + return + +/obj/item/stock_parts/cell/ninja + name = "spider-clan power cell" + desc = "A standard ninja-suit power cell." + maxcharge = 10000 + materials = list(MAT_GLASS = 60) \ No newline at end of file diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 4def1c3b067..8c9ee3eda0d 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -35,7 +35,7 @@ if(powernet) disconnect_from_network() -/obj/machinery/power/generator/initialize() +/obj/machinery/power/generator/Initialize() ..() connect() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index ad73a6ff0ad..42f7cbde657 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -85,20 +85,12 @@ var/const/GRAV_NEEDS_WRENCH = 3 // Generator which spawns with the station. // -/obj/machinery/gravity_generator/main/station/initialize() +/obj/machinery/gravity_generator/main/station/Initialize() ..() setup_parts() middle.overlays += "activated" update_list() -// -// Generator an admin can spawn -// - -/obj/machinery/gravity_generator/main/station/admin/New() - ..() - initialize() - // // Main Generator with the main code // diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 72e30b9d29a..2892d0245b2 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -112,7 +112,7 @@ var/temperature = 0 //The current temperature var/overheating = 0 //if this gets high enough the generator explodes -/obj/machinery/power/port_gen/pacman/initialize() +/obj/machinery/power/port_gen/pacman/Initialize() ..() if(anchored) connect_to_network() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index fd5946b7dc4..15b47a47635 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -232,26 +232,6 @@ . += C return . -/hook/startup/proc/buildPowernets() - return makepowernets() - -// rebuild all power networks from scratch - only called at world creation or by the admin verb -/proc/makepowernets() - for(var/datum/powernet/PN in powernets) - qdel(PN) - powernets.Cut() - - for(var/obj/structure/cable/PC in cable_list) - makepowernet_for(PC) - - return 1 - -/proc/makepowernet_for(var/obj/structure/cable/PC) - if(!PC.powernet) - var/datum/powernet/NewPN = new() - NewPN.add_cable(PC) - propagate_network(PC,PC.powernet) - //remove the old powernet and replace it with a new one throughout the network. /proc/propagate_network(var/obj/O, var/datum/powernet/PN) //log_world("propagating new network") diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index 416de55f6c3..a07d854380d 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -16,7 +16,7 @@ /datum/powernet/New() - powernets += src + SSmachines.powernets += src ..() /datum/powernet/Destroy() @@ -28,7 +28,7 @@ nodes -= M M.powernet = null - powernets -= src + SSmachines.powernets -= src return ..() //Returns the amount of excess power (before refunding to SMESs) from last tick. diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 58cecbc8ecc..70cd75bf85d 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -76,12 +76,13 @@ return rotate() -/obj/machinery/power/emitter/initialize() +/obj/machinery/power/emitter/Initialize() ..() if(state == 2 && anchored) connect_to_network() if(frequency) set_frequency(frequency) + /obj/machinery/power/emitter/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {"