diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 882acf789d..fc3f2852fc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,15 +6,15 @@ #deathride58 /modular_citadel/ @deathride58 -/code/citadel/ @deathride58 #LetterJay /modular_citadel/code/modules/client/loadout/__donator.dm @LetterJay #Poojawa -/code/modules/vore @Poojawa -/code/citadel/dogborgstuff.dmm @Poojawa +/modular_citadel/code/modules/vore @Poojawa +/code/game/objects/items/devices/dogborg_sleeper.dm @Poojawa +/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @Poojawa /tgui/ @Poojawa /modular_citadel/code/modules/clothing/spacesuits/flightsuit.dm @Poojawa /modular_citadel/code/game/objects/ids.dm @Poojawa diff --git a/_maps/cit_map_files/BoxStation/BoxStation.dmm b/_maps/cit_map_files/BoxStation/BoxStation.dmm index a0d27ff1da..279f479f10 100644 --- a/_maps/cit_map_files/BoxStation/BoxStation.dmm +++ b/_maps/cit_map_files/BoxStation/BoxStation.dmm @@ -932,7 +932,6 @@ pixel_x = 3; pixel_y = -3 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/turf_decal/bot{ dir = 2 }, @@ -4573,15 +4572,13 @@ /area/engine/atmos) "aln" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; name = "Labor Camp Shuttle Airlock"; - req_access_txt = "2"; - shuttledocked = 1 + req_access_txt = "2" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/processing) "alp" = ( /turf/open/floor/plating, @@ -5349,7 +5346,7 @@ /area/maintenance/fore/secondary) "anE" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; req_access_txt = "13" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -5388,17 +5385,6 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port/fore) -"anN" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; - name = "Labor Camp Shuttle Airlock"; - shuttledocked = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/plating, -/area/security/processing) "anO" = ( /obj/docking_port/stationary{ dir = 8; @@ -34457,13 +34443,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"bIP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/chair/comfy/black, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "bIQ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -37312,7 +37291,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/structure/chair/comfy/black, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bPz" = ( @@ -37339,15 +37317,13 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bPA" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 1 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/table/glass, /turf/open/floor/plasteel, /area/science/xenobiology) "bPB" = ( @@ -37437,10 +37413,10 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bPI" = ( -/obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel, /area/science/xenobiology) "bPJ" = ( @@ -38378,6 +38354,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bRZ" = ( @@ -40083,6 +40062,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bWn" = ( @@ -41554,6 +41536,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bZX" = ( @@ -42796,14 +42781,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"ccP" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"ccQ" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/science/xenobiology) "ccR" = ( /obj/machinery/portable_atmospherics/pump, /obj/effect/turf_decal/bot{ @@ -43709,20 +43686,6 @@ /obj/item/caution, /turf/open/floor/plating, /area/maintenance/aft) -"cfr" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; - external_pressure_bound = 140; - pressure_checks = 0; - name = "killroom vent" - }, -/obj/machinery/camera{ - c_tag = "Xenobiology Kill Room"; - dir = 4; - network = list("ss13","rd") - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cfs" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Air Supply Maintenance"; @@ -43760,15 +43723,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating/airless, /area/maintenance/solars/port/aft) -"cfy" = ( -/obj/structure/rack, -/obj/item/clothing/shoes/winterboots, -/obj/item/clothing/suit/hooded/wintercoat, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cfz" = ( /obj/structure/cable{ icon_state = "4-8" @@ -44004,9 +43958,6 @@ }, /turf/open/floor/plating, /area/maintenance/aft) -"cgi" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cgj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/barricade/wooden, @@ -44015,18 +43966,19 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cgk" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/biohazard, -/turf/open/floor/plating, -/area/science/xenobiology) "cgl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; - external_pressure_bound = 120; - name = "killroom vent" +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/circuit/killroom, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, /area/science/xenobiology) "cgm" = ( /obj/structure/cable{ @@ -44037,17 +43989,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cgn" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - target_temperature = 80; - dir = 2; - on = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cgo" = ( /obj/structure/cable{ icon_state = "4-8" @@ -44425,13 +44366,6 @@ }, /turf/open/floor/plasteel/floorgrime, /area/maintenance/disposal/incinerator) -"cho" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "chp" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -44441,43 +44375,22 @@ }, /turf/closed/wall, /area/maintenance/starboard/aft) -"chq" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"chr" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Kill Chamber"; +"chs" = ( +/obj/machinery/door/window/northleft{ + base_state = "right"; + dir = 8; + icon_state = "right"; + name = "Containment Pen"; req_access_txt = "55" }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plating, -/area/science/xenobiology) -"chs" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/general/visible, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cht" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"chu" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/turf/open/floor/engine, /area/science/xenobiology) "chv" = ( /obj/structure/cable{ @@ -45267,18 +45180,6 @@ /obj/item/cigbutt/roach, /turf/open/floor/plating, /area/maintenance/aft) -"cjB" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, -/obj/structure/table, -/obj/item/folder/white, -/obj/item/pen, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cjC" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -45388,7 +45289,7 @@ req_access = null; req_access_txt = "10;13" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/engineering) "cjS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -45555,11 +45456,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/aft) -"ckn" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/science/xenobiology) "cko" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall, @@ -48100,8 +47996,8 @@ /area/space/nearstation) "csk" = ( /obj/structure/disposalpipe/segment, -/turf/open/floor/plating/airless, -/area/space/nearstation) +/turf/closed/wall/r_wall, +/area/science/xenobiology) "csl" = ( /obj/structure/transit_tube/curved{ dir = 4 @@ -49949,7 +49845,7 @@ /area/shuttle/pod_1) "cxG" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; name = "Escape Pod Three"; req_access_txt = "0" }, @@ -49959,15 +49855,21 @@ /turf/open/floor/plating, /area/security/main) "cxJ" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 8; +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ name = "Labor Camp Shuttle Airlock"; req_access_txt = "2" }, +/obj/machinery/button/door{ + id = "prison release"; + name = "Labor Camp Shuttle Lockdown"; + pixel_y = -25; + req_access_txt = "2" + }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/processing) "cxN" = ( /obj/structure/cable{ @@ -49983,16 +49885,6 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) -"cxP" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 8; - name = "Labor Camp Shuttle Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/plating, -/area/security/processing) "cxR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -50331,11 +50223,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) -"czQ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "czR" = ( /obj/structure/cable{ icon_state = "1-2" @@ -52439,18 +52326,6 @@ }, /turf/open/floor/plating, /area/science/xenobiology) -"cTY" = ( -/obj/structure/sign/poster/official/safety_internals{ - pixel_x = -32 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"cTZ" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "cVb" = ( /turf/closed/wall, /area/hallway/secondary/service) @@ -52644,6 +52519,11 @@ }, /turf/open/floor/plasteel, /area/quartermaster/miningdock) +"fdi" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space) "fgi" = ( /turf/closed/wall, /area/crew_quarters/cryopod) @@ -52659,6 +52539,26 @@ /obj/machinery/bookbinder, /turf/open/floor/plasteel/white, /area/science/circuit) +"fmO" = ( +/obj/structure/window/reinforced, +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "xenobio7"; + name = "Containment Blast Doors"; + pixel_y = 4; + req_access_txt = "55" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "fmW" = ( /obj/effect/turf_decal/loading_area/white, /obj/effect/turf_decal/stripes/white/corner{ @@ -52882,7 +52782,7 @@ /obj/effect/turf_decal/bot{ dir = 2 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/engine/engineering) "hCi" = ( /obj/structure/lattice, @@ -53142,7 +53042,7 @@ /area/hallway/secondary/service) "khB" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; req_access_txt = "13" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -53190,9 +53090,6 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"kAr" = ( -/turf/open/floor/plating/airless, -/area/space) "kDA" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -53410,6 +53307,18 @@ /obj/structure/falsewall, /turf/open/floor/plating, /area/maintenance/bar) +"mHe" = ( +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, +/area/science/xenobiology) "mLm" = ( /obj/structure/cable{ icon_state = "1-8" @@ -53453,6 +53362,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/fore/secondary) +"mWO" = ( +/turf/open/floor/plating/airless, +/area/space) "mXj" = ( /turf/open/floor/plasteel/showroomfloor, /area/space) @@ -53470,6 +53382,26 @@ dir = 8 }, /area/security/brig) +"nvr" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "xenobio0"; + name = "Containment Blast Doors"; + pixel_y = 4; + req_access_txt = "55" + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/light, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "nwx" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, @@ -53557,10 +53489,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"nXy" = ( -/obj/structure/lattice, -/turf/open/space, -/area/space) "nYI" = ( /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; @@ -54000,7 +53928,7 @@ /obj/effect/turf_decal/bot{ dir = 2 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/engine/engineering) "srd" = ( /turf/open/floor/plasteel/red/corner{ @@ -54024,6 +53952,25 @@ /obj/item/shovel/spade, /turf/open/floor/plasteel/hydrofloor, /area/hallway/secondary/service) +"syV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "sAz" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -54132,11 +54079,6 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) -"tfw" = ( -/obj/structure/lattice, -/obj/structure/grille, -/turf/open/space/basic, -/area/space) "thu" = ( /obj/structure/cable{ icon_state = "1-2" @@ -54691,6 +54633,10 @@ /obj/effect/landmark/start/atmospheric_technician, /turf/open/floor/plasteel, /area/engine/atmos) +"yck" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space) "ycu" = ( /obj/structure/cable{ icon_state = "2-4" @@ -54715,6 +54661,9 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/security/armory) +"ymd" = ( +/turf/open/floor/plasteel/dark, +/area/security/processing) (1,1,1) = {" aaa @@ -77939,7 +77888,7 @@ aln aiU aaa aiU -anN +aln aiU aaa aaa @@ -78192,11 +78141,11 @@ aaf aaf aaf aiU -alp +ymd aiU aaa aiU -alp +ymd aiU aaf aaf @@ -78453,7 +78402,7 @@ cxJ aiU aiT aiU -cxP +cxJ aiU aiV aiT @@ -81393,7 +81342,7 @@ mzz mzz ccw uvy -nXy +yck aaa aaa aaa @@ -81907,7 +81856,7 @@ gre iqO ccw uvy -tfw +fdi aaa aaa aaa @@ -82408,15 +82357,15 @@ csP gre gre cAq -kAr +mWO cSH -kAr +mWO cSH -kAr +mWO cSH -kAr +mWO cSH -kAr +mWO gre gre ccw @@ -82674,7 +82623,7 @@ aaa aoV aoV cFK -kAr +mWO gre ccw uvy @@ -82931,7 +82880,7 @@ aaa aoV aoV aoV -kAr +mWO gre ccw uvy @@ -83188,7 +83137,7 @@ aaa aaa aoV aoV -kAr +mWO gre ccw uvy @@ -83445,7 +83394,7 @@ sWi aaa hCi cFK -kAr +mWO gre ccw uvy @@ -83702,7 +83651,7 @@ tHc aaf aaf gXs -kAr +mWO gre ccw uvy @@ -83959,7 +83908,7 @@ ieW aaa aaa aaa -kAr +mWO gre ccw uvy @@ -84216,7 +84165,7 @@ aaa aaa aoV aoV -kAr +mWO gre ccw uvy @@ -84473,7 +84422,7 @@ hCi aaa aoV aoV -kAr +mWO gre ccw uvy @@ -84730,7 +84679,7 @@ cFK aoV aoV cFK -kAr +mWO gre ccw uvy @@ -84978,15 +84927,15 @@ csP gre gre cAq -kAr +mWO cSK -kAr +mWO cSK -kAr +mWO cSK -kAr +mWO cSK -kAr +mWO gre gre ccw @@ -86019,7 +85968,7 @@ mzz mzz ccw uvy -nXy +yck aaf aaa aaa @@ -86532,7 +86481,7 @@ uvy uvy uvy aaa -nXy +yck hCi aaa aaa @@ -96780,7 +96729,7 @@ bDb bDb bDb bDb -cNW +bDb cNW cQB czY @@ -97033,11 +96982,11 @@ bJN bRT bEm bEm +bJN +bRT +bEm +bEm bDb -cfr -cho -bDb -aaa cNW cQB czY @@ -97276,7 +97225,7 @@ bJJ bKY bMi bNo -bIP +bOx bPA bJN bRU @@ -97290,12 +97239,12 @@ bJN bRU bEm bEm +bJN +bRU +bEm +bEm bDb -cgi -chq -ccQ -aaa -cOT +cNW cQB czY cOT @@ -97547,12 +97496,12 @@ bJN bRU bEm cBz +bJN +bRU +bEm +cBz bDb -cgi -chq -ccQ -aaa -cOT +cNW cQB czY cOT @@ -97791,7 +97740,7 @@ bLa bMi bNo bPy -bPA +syV bJN bRW bTb @@ -97804,11 +97753,11 @@ bJN bZV caV cbS -bDb +bJN cgl chs +mHe bDb -aaa cNW cQB czY @@ -98061,11 +98010,11 @@ bVi bRV bTa cbR +bVi +bRV +bTa +nvr bDb -cgk -chr -bDb -aaa cNW cBN czY @@ -98318,12 +98267,12 @@ bZa bMi bMi bRZ -cTY -cTZ -chu -ccQ -aaf -cOT +bZa +bMi +bMi +bRZ +bDb +cNW cQB cAa cOT @@ -98574,13 +98523,13 @@ bUf bTc bRX bTc +bUf +bTc +bRX +bTc cbT -ccP -ccP -cht -ckn csk -czQ +cko czU czZ cOT @@ -98832,12 +98781,12 @@ bZb bRZ bMi bMi -cfy -cgn -cjB -ccQ -aaf -cOT +bZb +bRZ +bMi +bMi +bDb +cNW cgm czY cOT @@ -99089,11 +99038,11 @@ bVi bZW bTd bUg +bVi +fmO +bTd +bUg bDb -bDb -bDb -bDb -aaa cNW cgm czY @@ -99346,11 +99295,11 @@ bJN bZX caW cbU +bJN +bWn +bXg +bYh bDb -aaf -aaf -aaa -aaa cNW cgm czY @@ -99603,12 +99552,12 @@ bJN bEm bEm bRU +bJN +bEm +bEm +bRU bDb -aaf -aaa -aaa -aaa -cOT +cNW cgm czY cOT @@ -99860,12 +99809,12 @@ bJN bEm bEm bRU +bJN +bEm +bEm +bRU bDb -aaf -aaa -aaa -aaa -cOT +cNW cgm czY cOT @@ -100117,12 +100066,12 @@ bJN bEm bEm bUi +bJN +bEm +bEm +bUi bDb -aaf -aaf -aaa -aaa -cOT +cNW cgm czY cOT @@ -100375,10 +100324,10 @@ bDb bDb bDb bDb -cNW -cNW -cNW -cNW +bDb +bDb +bDb +bDb cNW czX cAc diff --git a/_maps/cit_map_files/Deltastation/DeltaStation2.dmm b/_maps/cit_map_files/Deltastation/DeltaStation2.dmm index 4493d6b2dd..70f7862e09 100644 --- a/_maps/cit_map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/cit_map_files/Deltastation/DeltaStation2.dmm @@ -67532,9 +67532,6 @@ dir = 5 }, /area/science/xenobiology) -"cNh" = ( -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) "cNi" = ( /obj/machinery/light/small{ dir = 1 @@ -67545,7 +67542,9 @@ name = "xenobiology camera"; network = list("ss13","xeno","rd") }, -/turf/open/floor/plasteel/vault/killroom, +/turf/open/floor/plasteel/vault{ + dir = 5 + }, /area/science/xenobiology) "cNj" = ( /obj/structure/closet/crate{ @@ -68261,26 +68260,6 @@ "cON" = ( /turf/open/floor/circuit/green, /area/science/xenobiology) -"cOO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; - external_pressure_bound = 140; - name = "killroom vent"; - pressure_checks = 0 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cOP" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cOQ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; - external_pressure_bound = 120; - name = "server vent" - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cOR" = ( /turf/closed/wall/r_wall, /area/science/research) @@ -69036,24 +69015,6 @@ dir = 1 }, /area/science/xenobiology) -"cQw" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) -"cQx" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) -"cQy" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) "cQz" = ( /obj/structure/closet/wardrobe/science_white, /obj/machinery/light/small{ @@ -69757,7 +69718,6 @@ icon_state = "0-4" }, /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/open/floor/plating, /area/science/xenobiology) "cSg" = ( @@ -69768,7 +69728,7 @@ icon_state = "2-8" }, /obj/machinery/door/airlock/research/glass{ - name = "Xenobiology Kill Room"; + name = "Xenobiology Isolation Pin"; req_access_txt = "47" }, /obj/effect/turf_decal/stripes/line{ @@ -70558,13 +70518,19 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cTR" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 1; - min_temperature = 80; - on = 1; - target_temperature = 80 +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 }, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/xenobiology) "cTS" = ( @@ -72260,9 +72226,6 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cXm" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, /obj/machinery/status_display{ pixel_x = 32 }, @@ -72450,13 +72413,6 @@ dir = 8 }, /area/medical/medbay/central) -"cXG" = ( -/obj/structure/table, -/obj/item/folder/white, -/turf/open/floor/plasteel/whiteblue/corner{ - dir = 8 - }, -/area/medical/medbay/central) "cXH" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -73261,12 +73217,11 @@ id = "chemisttop"; name = "Chemistry Lobby Shutters" }, -/obj/machinery/door/window/southleft{ +/obj/item/folder/yellow, +/obj/machinery/door/window/northleft{ name = "Chemistry Desk"; req_access_txt = "5; 33" }, -/obj/item/folder/yellow, -/obj/machinery/door/window/northleft, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/medical/medbay/central) @@ -100778,6 +100733,25 @@ dir = 4 }, /area/science/misc_lab) +"fzH" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "fGq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, @@ -100792,17 +100766,13 @@ }, /turf/open/floor/plating, /area/maintenance/port) -"giB" = ( -/obj/structure/particle_accelerator/end_cap{ - icon_state = "end_cap"; - dir = 8 - }, -/turf/open/floor/plating, -/area/engine/engineering) "gmj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/science/circuit) +"gsR" = ( +/turf/open/space, +/area/space) "gKr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -100841,12 +100811,6 @@ dir = 10 }, /area/science/circuit) -"hiz" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, -/turf/open/floor/plating/airless, -/area/space/nearstation) "hrP" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -100899,6 +100863,9 @@ dir = 9 }, /area/science/circuit) +"hRG" = ( +/turf/open/space/basic, +/area/space/nearstation) "iQh" = ( /obj/structure/bodycontainer/morgue{ dir = 1 @@ -100957,6 +100924,9 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/neutral, /area/medical/morgue) +"jKb" = ( +/turf/open/space, +/area/space/nearstation) "kwx" = ( /obj/effect/turf_decal/loading_area, /turf/open/floor/plasteel/whitepurple/corner, @@ -100982,6 +100952,9 @@ dir = 5 }, /area/crew_quarters/locker) +"lkn" = ( +/turf/open/floor/plating/airless, +/area/space/nearstation) "loI" = ( /obj/machinery/autolathe, /obj/machinery/door/window/southleft{ @@ -100997,6 +100970,10 @@ dir = 4 }, /area/science/lab) +"lxv" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "lEl" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -101041,6 +101018,13 @@ dir = 1 }, /area/science/circuit) +"mqk" = ( +/obj/structure/particle_accelerator/end_cap{ + icon_state = "end_cap"; + dir = 8 + }, +/turf/open/floor/plating, +/area/engine/engineering) "mvm" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/white{ @@ -101052,14 +101036,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/circuit/green, /area/science/research/abandoned) -"mId" = ( +"nJG" = ( +/obj/structure/lattice, /turf/open/space/basic, -/area/space/nearstation) -"mRo" = ( -/turf/open/floor/plating/airless, -/area/space/nearstation) -"nBz" = ( -/turf/open/floor/plating/airless, /area/space) "oZC" = ( /obj/machinery/door/firedoor, @@ -101074,6 +101053,13 @@ }, /turf/open/floor/wood, /area/bridge/showroom/corporate) +"pfd" = ( +/obj/structure/particle_accelerator/particle_emitter/center{ + icon_state = "emitter_center"; + dir = 8 + }, +/turf/open/floor/plating, +/area/engine/engineering) "pmQ" = ( /obj/structure/table/reinforced, /obj/machinery/newscaster{ @@ -101134,27 +101120,15 @@ dir = 6 }, /area/science/circuit) -"rQf" = ( -/obj/structure/particle_accelerator/particle_emitter/center{ - icon_state = "emitter_center"; - dir = 8 - }, -/turf/open/floor/plating, -/area/engine/engineering) -"sar" = ( -/obj/structure/lattice, -/turf/open/space/basic, -/area/space) "saw" = ( /turf/closed/wall, /area/science/circuit) -"taK" = ( -/obj/structure/particle_accelerator/power_box{ - icon_state = "power_box"; - dir = 8 +"tdp" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 }, -/turf/open/floor/plating, -/area/engine/engineering) +/turf/open/floor/plating/airless, +/area/space/nearstation) "tmi" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -101169,9 +101143,6 @@ dir = 10 }, /area/science/misc_lab) -"tTq" = ( -/turf/open/space, -/area/space/nearstation) "upk" = ( /obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" @@ -101196,6 +101167,9 @@ /obj/structure/reagent_dispensers/water_cooler, /turf/open/floor/plasteel/whitepurple/side, /area/science/misc_lab) +"uDN" = ( +/turf/open/floor/plating/airless, +/area/space) "uYS" = ( /obj/machinery/door/airlock/atmos/glass{ heat_proof = 1; @@ -101217,9 +101191,13 @@ dir = 5 }, /area/medical/morgue) -"vYn" = ( -/turf/open/space, -/area/space) +"vyI" = ( +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/structure/reagent_dispensers/watertank/high, +/turf/open/floor/circuit/green, +/area/science/xenobiology) "wei" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, @@ -101256,6 +101234,13 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) +"xwB" = ( +/obj/structure/particle_accelerator/power_box{ + icon_state = "power_box"; + dir = 8 + }, +/turf/open/floor/plating, +/area/engine/engineering) "xwK" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -101281,6 +101266,13 @@ }, /turf/open/floor/plasteel, /area/science/research/abandoned) +"xJl" = ( +/obj/structure/table, +/obj/item/folder/white, +/turf/open/floor/plasteel/whiteblue/corner{ + dir = 8 + }, +/area/medical/medbay/central) "xMn" = ( /obj/structure/disposalpipe/trunk, /obj/machinery/disposal/bin, @@ -101289,10 +101281,6 @@ }, /turf/open/floor/plasteel/white/side, /area/science/circuit) -"xSx" = ( -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) "yjc" = ( /obj/machinery/power/apc{ areastring = "/area/science/research/abandoned"; @@ -121745,13 +121733,13 @@ aaa cja ckw clS -tTq -tTq +jKb +jKb clS -sar -mId -tTq -tTq +nJG +hRG +jKb +jKb clS ctn cja @@ -122001,15 +121989,15 @@ cfA aad cjb cky -tTq -vYn -vYn -xSx +jKb +gsR +gsR +lxv aad -mId -vYn -vYn -tTq +hRG +gsR +gsR +jKb czq cAI aad @@ -122258,15 +122246,15 @@ cfA aaa cja ckw -tTq -vYn -mId -mId +jKb +gsR +hRG +hRG aad -mId -mId -vYn -tTq +hRG +hRG +gsR +jKb ctn cja aaa @@ -122515,14 +122503,14 @@ cfA abj cjb cky -mId -mId -mId +hRG +hRG +hRG cqo clR ctm -mId -xSx +hRG +lxv clS czq cAI @@ -122772,15 +122760,15 @@ cdC aad cja ckw -sar +nJG aad aad ckw crJ -hiz +tdp aad aad -sar +nJG ctn cja aad @@ -123030,14 +123018,14 @@ abj cjb cky clS -xSx -mId +lxv +hRG cqp crK cto -mId -mId -mId +hRG +hRG +hRG czq cAI abj @@ -123286,15 +123274,15 @@ cfA aaa cja ckw -tTq -vYn -mId -mId +jKb +gsR +hRG +hRG aad -mId -mId -vYn -tTq +hRG +hRG +gsR +jKb ctn cja aaa @@ -123543,15 +123531,15 @@ cfA aad cjb cky -tTq -vYn +jKb +gsR aaa -mId +hRG aad -xSx +lxv aaa -vYn -tTq +gsR +jKb czq cAI aad @@ -123801,13 +123789,13 @@ aaa cja ckw clS -tTq -mId -mId -sar +jKb +hRG +hRG +nJG clS -tTq -tTq +jKb +jKb clS ctn cja @@ -124311,8 +124299,8 @@ car cbT cdG cfB -nBz -mRo +uDN +lkn aaa aad cjd @@ -124324,8 +124312,8 @@ cjd cjd aad aaa -mRo -nBz +lkn +uDN cDV cFL cHg @@ -124832,7 +124820,7 @@ cje cjd cpa cqr -rQf +pfd ctp cuQ cjd @@ -125089,7 +125077,7 @@ chv cnC cpa cqs -taK +xwB ctq cuR cnC @@ -125603,7 +125591,7 @@ clX cnE cpc cqu -giB +mqk cts cuT cnE @@ -128456,7 +128444,7 @@ das dcd cMY deX -dgo +fzH dhR lKu tmi @@ -132556,9 +132544,9 @@ cHA cjp cKl cLI -cNh -cNh -cNh +cNd +cNd +cNd cNc cTQ cVI @@ -132813,9 +132801,9 @@ cHB cjp cKj cLI -cNh -cOO -cQw +cNd +cNd +cNd cSf cTR cVP @@ -133071,8 +133059,8 @@ caE cKm cLI cNi -cOP -cQx +cNd +cNd cSg cTS cVQ @@ -133327,9 +133315,9 @@ cHB cjp cKk cLI -cNh -cOQ -cQy +cNd +cNd +cNd cSh cTT cVR @@ -133584,9 +133572,9 @@ cHA ceb cKk cLI -cNh -cNh -cNh +cNd +cNd +cNd cNc cTU cVS @@ -133849,7 +133837,7 @@ cTV cVT cXm cZb -cXm +vyI dcu ddV cMY @@ -141300,7 +141288,7 @@ cQT cSE cUt cWj -cXG +xJl cZt dbc dcO diff --git a/_maps/cit_map_files/MetaStation/MetaStation.dmm b/_maps/cit_map_files/MetaStation/MetaStation.dmm index 0a66de578c..b158c0e3b4 100644 --- a/_maps/cit_map_files/MetaStation/MetaStation.dmm +++ b/_maps/cit_map_files/MetaStation/MetaStation.dmm @@ -35104,9 +35104,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/department/science/xenobiology) "bvU" = ( @@ -40977,11 +40974,8 @@ /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) "bIv" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 10 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "bIw" = ( /obj/machinery/light, /obj/machinery/camera{ @@ -67904,15 +67898,6 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/aft) -"cLE" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 1; - name = "euthanization chamber freezer"; - on = 1; - target_temperature = 80 - }, -/turf/open/floor/plating, -/area/science/xenobiology) "cLF" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -71590,7 +71575,7 @@ "cTT" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall/r_wall, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "cUH" = ( /obj/structure/table/optable, /turf/open/floor/plasteel/white, @@ -72062,9 +72047,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) -"cZv" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cZR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ @@ -72210,9 +72192,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, /obj/machinery/light/small{ dir = 1 }, @@ -72222,24 +72201,14 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) -"daR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1; - external_pressure_bound = 140; - name = "server vent"; - pressure_checks = 0 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "daS" = ( /obj/structure/disposalpipe/segment, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/turf/open/floor/plating{ + icon_state = "platingdmg2" + }, +/area/maintenance/department/science/xenobiology) "daW" = ( /obj/machinery/button/door{ id = "engpa"; @@ -72374,17 +72343,10 @@ "dbv" = ( /obj/structure/disposalpipe/segment, /obj/machinery/light/small, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"dbw" = ( -/obj/machinery/camera{ - c_tag = "Xenobiology Lab - Kill Chamber"; - dir = 1; - network = list("ss13","rd","xeno"); - start_active = 1 +/turf/open/floor/plating{ + icon_state = "platingdmg2" }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dbE" = ( /obj/machinery/plantgenes, /obj/effect/turf_decal/stripes/line{ @@ -72791,15 +72753,18 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcm" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/computer/camera_advanced/xenobio, /obj/effect/turf_decal/stripes/line{ - dir = 9 + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 }, /turf/open/floor/plasteel, /area/science/xenobiology) @@ -72823,7 +72788,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/obj/machinery/computer/camera_advanced/xenobio, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -72893,9 +72857,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/structure/chair/comfy/black{ - dir = 1 - }, /obj/effect/turf_decal/stripes/line{ dir = 10 }, @@ -72910,9 +72871,6 @@ /area/science/xenobiology) "dcx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair/comfy/black{ - dir = 1 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -72990,18 +72948,13 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcJ" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/item/extinguisher{ - pixel_x = 4; - pixel_y = 3 - }, -/obj/item/extinguisher, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcK" = ( @@ -73427,11 +73380,8 @@ }, /obj/structure/chair, /obj/item/cigbutt, -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 1 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "ddy" = ( /turf/open/floor/plating{ icon_state = "platingdmg1" @@ -73439,9 +73389,8 @@ /area/maintenance/department/science/xenobiology) "ddz" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/turf/open/floor/plating, -/area/science/xenobiology) +/turf/closed/wall/r_wall, +/area/maintenance/department/science/xenobiology) "ddA" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, @@ -73451,23 +73400,15 @@ opacity = 0; req_access_txt = "55" }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"ddB" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 1; - external_pressure_bound = 120; - name = "server vent" - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/turf/closed/wall/r_wall, +/area/maintenance/department/science/xenobiology) "ddC" = ( /obj/structure/disposalpipe/trunk{ dir = 1 }, /obj/structure/disposaloutlet, /turf/open/floor/plating/airless, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "ddE" = ( /obj/effect/landmark/start/cook, /obj/machinery/holopad, @@ -73781,6 +73722,12 @@ /obj/item/clothing/glasses/meson/engine, /turf/open/floor/plasteel, /area/engine/engineering) +"dgA" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) "dgI" = ( /turf/closed/wall/mineral/plastitanium, /area/space/nearstation) @@ -74884,9 +74831,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/machinery/door/airlock/research{ glass = 1; name = "Slime Euthanization Chamber"; @@ -74897,7 +74841,7 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dmr" = ( /obj/machinery/door/airlock/research{ glass = 1; @@ -74909,7 +74853,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dmD" = ( /obj/structure/displaycase/trophy, /turf/open/floor/wood, @@ -76182,6 +76126,13 @@ }, /turf/open/floor/plating/airless, /area/engine/engineering) +"dPp" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engine/engineering) "dYu" = ( /obj/machinery/door/airlock/external{ name = "Auxiliary Airlock" @@ -76283,12 +76234,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/office) -"eHX" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/engineering) "eXy" = ( /obj/machinery/airalarm{ pixel_y = 32 @@ -76496,6 +76441,10 @@ dir = 4 }, /area/engine/engineering) +"iYY" = ( +/obj/machinery/light/small, +/turf/open/floor/plating, +/area/engine/engineering) "jjF" = ( /obj/structure/cable/white{ icon_state = "2-8" @@ -76536,6 +76485,10 @@ }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) +"jzw" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/department/science/xenobiology) "jFx" = ( /obj/machinery/door/airlock/external{ req_access_txt = "13" @@ -76560,6 +76513,12 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"jYQ" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/engine/engineering) "kfu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/white, @@ -76914,14 +76873,6 @@ /obj/item/pen, /turf/open/floor/plasteel/white, /area/science/circuit) -"oWo" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg2" - }, -/area/maintenance/starboard/fore) "pvA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -76977,13 +76928,6 @@ }, /turf/open/floor/plating/airless, /area/engine/engineering) -"pYA" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/light, -/turf/open/floor/plasteel, -/area/engine/engineering) "qnJ" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -76998,12 +76942,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/plating, /area/science/circuit) -"qoX" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating, -/area/engine/engineering) "qqg" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 @@ -77055,6 +76993,12 @@ }, /turf/open/floor/plating, /area/engine/engineering) +"rFx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/engine/engineering) "rQK" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -77107,10 +77051,6 @@ /obj/structure/grille, /turf/open/floor/plating/airless, /area/space/nearstation) -"swQ" = ( -/obj/machinery/light/small, -/turf/open/floor/plating, -/area/engine/engineering) "sGh" = ( /obj/structure/cable{ icon_state = "1-2" @@ -77144,12 +77084,14 @@ "sSU" = ( /turf/closed/wall/r_wall, /area/space) -"sZQ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +"tdB" = ( +/obj/machinery/light/small{ + dir = 8 }, -/turf/closed/wall, -/area/engine/engineering) +/turf/open/floor/plating{ + icon_state = "platingdmg2" + }, +/area/maintenance/starboard/fore) "tjH" = ( /obj/structure/table/reinforced, /obj/machinery/computer/libraryconsole/bookmanagement, @@ -77271,7 +77213,7 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/space) -"vHD" = ( +"vAk" = ( /obj/machinery/light/small{ dir = 1 }, @@ -110317,7 +110259,7 @@ cRi cRi cRi daP -cLE +cTA dlV aaa aaa @@ -110574,10 +110516,10 @@ daF daJ cRi bvT -cRi -cRi -cRi -cRi +dlV +dlV +dlV +dlV aaa aai aaa @@ -110831,10 +110773,10 @@ cSn cSn cRi dmq -cRi -cZv -cZv -cRi +dlV +ddj +ddj +dlV aaf aag aaa @@ -111089,9 +111031,9 @@ cSn cRi ddx ddz -daR -cZv -cRe +ddj +ddj +jzw aaa aaa aaa @@ -111603,9 +111545,9 @@ daK cRi bIv ddz -ddB -cZv -cRe +ddj +ddj +jzw aaa aaf aaa @@ -111859,10 +111801,10 @@ cSn daN cRi dmr -cRi -cZv -dbw -cRi +dlV +ddj +ddj +dlV aaa aag aaa @@ -112116,10 +112058,10 @@ daI daM cRi cTA -cRi -cRi -cRi -cRi +dlV +dlV +dlV +dlV aaf aag aaa @@ -117899,7 +117841,7 @@ arJ arI dnh dqu -oWo +tdB axO axY aAo @@ -118945,8 +118887,8 @@ dfh aBO aBO aBK -pYA -sZQ +dPp +rFx axY aYu aYu @@ -119959,7 +119901,7 @@ axY axY ayW bTq -eHX +dgA aBO aBO aFC @@ -119972,7 +119914,7 @@ aNu axY dfp aBO -eHX +dgA dfP dfY axY @@ -120470,7 +120412,7 @@ ati ajb avB axY -qoX +jYQ bUw aJu axY @@ -120489,7 +120431,7 @@ axY axY aJu bUw -swQ +iYY axY alq alq @@ -121495,7 +121437,7 @@ apn aqy arT apm -vHD +vAk avB axY goZ diff --git a/_maps/cit_map_files/PubbyStation/PubbyStation.dmm b/_maps/cit_map_files/PubbyStation/PubbyStation.dmm index 3eebcbf5e1..6bf52ab60a 100644 --- a/_maps/cit_map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/cit_map_files/PubbyStation/PubbyStation.dmm @@ -26613,12 +26613,6 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"bpp" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "bpq" = ( /obj/structure/sign/warning/electricshock, /turf/closed/wall/r_wall, @@ -27817,9 +27811,6 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "brQ" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, /obj/machinery/camera{ c_tag = "Xenobiology Port"; dir = 8; @@ -28611,11 +28602,11 @@ /turf/open/floor/plating, /area/science/xenobiology) "btD" = ( -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "btE" = ( /obj/effect/decal/remains/xeno, -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "btF" = ( /obj/structure/chair{ @@ -29236,12 +29227,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Xenobiology Kill Room"; - dir = 8; - network = list("ss13","rd") - }, -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "bva" = ( /turf/closed/wall, @@ -31308,16 +31294,22 @@ /turf/open/floor/plasteel/whitepurple/side, /area/science/xenobiology) "bzi" = ( -/obj/item/extinguisher{ - pixel_x = 4; - pixel_y = 3 +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/obj/item/extinguisher, /obj/structure/table/glass, -/turf/open/floor/plasteel/whitepurple/side, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, /area/science/xenobiology) "bzj" = ( -/obj/structure/reagent_dispensers/watertank, /obj/machinery/requests_console{ department = "Science"; departmentType = 2; @@ -31325,6 +31317,7 @@ pixel_x = 32; receive_ore_updates = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel/whitepurple/side, /area/science/xenobiology) "bzk" = ( @@ -93288,7 +93281,7 @@ bkE aht bnd boh -bpp +bpn bqx brQ btr diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index eb44fb01e6..fd936f5205 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -932,7 +932,6 @@ pixel_x = 3; pixel_y = -3 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/turf_decal/bot{ dir = 2 }, @@ -4573,15 +4572,13 @@ /area/engine/atmos) "aln" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; name = "Labor Camp Shuttle Airlock"; - req_access_txt = "2"; - shuttledocked = 1 + req_access_txt = "2" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/processing) "alp" = ( /turf/open/floor/plating, @@ -5349,7 +5346,7 @@ /area/maintenance/fore/secondary) "anE" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; req_access_txt = "13" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -5388,17 +5385,6 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port/fore) -"anN" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; - name = "Labor Camp Shuttle Airlock"; - shuttledocked = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/plating, -/area/security/processing) "anO" = ( /obj/docking_port/stationary{ dir = 8; @@ -34457,13 +34443,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"bIP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/chair/comfy/black, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "bIQ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -37312,7 +37291,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/structure/chair/comfy/black, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bPz" = ( @@ -37339,15 +37317,13 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bPA" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 1 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/table/glass, /turf/open/floor/plasteel, /area/science/xenobiology) "bPB" = ( @@ -37437,10 +37413,10 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bPI" = ( -/obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel, /area/science/xenobiology) "bPJ" = ( @@ -38378,6 +38354,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bRZ" = ( @@ -40083,6 +40062,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bWn" = ( @@ -41554,6 +41536,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bZX" = ( @@ -42796,14 +42781,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"ccP" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"ccQ" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/science/xenobiology) "ccR" = ( /obj/machinery/portable_atmospherics/pump, /obj/effect/turf_decal/bot{ @@ -43709,20 +43686,6 @@ /obj/item/caution, /turf/open/floor/plating, /area/maintenance/aft) -"cfr" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; - external_pressure_bound = 140; - pressure_checks = 0; - name = "killroom vent" - }, -/obj/machinery/camera{ - c_tag = "Xenobiology Kill Room"; - dir = 4; - network = list("ss13","rd") - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cfs" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Air Supply Maintenance"; @@ -43760,15 +43723,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating/airless, /area/maintenance/solars/port/aft) -"cfy" = ( -/obj/structure/rack, -/obj/item/clothing/shoes/winterboots, -/obj/item/clothing/suit/hooded/wintercoat, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cfz" = ( /obj/structure/cable{ icon_state = "4-8" @@ -44004,9 +43958,6 @@ }, /turf/open/floor/plating, /area/maintenance/aft) -"cgi" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cgj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/barricade/wooden, @@ -44015,18 +43966,19 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cgk" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/biohazard, -/turf/open/floor/plating, -/area/science/xenobiology) "cgl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; - external_pressure_bound = 120; - name = "killroom vent" +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/circuit/killroom, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, /area/science/xenobiology) "cgm" = ( /obj/structure/cable{ @@ -44037,17 +43989,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cgn" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - target_temperature = 80; - dir = 2; - on = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cgo" = ( /obj/structure/cable{ icon_state = "4-8" @@ -44425,13 +44366,6 @@ }, /turf/open/floor/plasteel/floorgrime, /area/maintenance/disposal/incinerator) -"cho" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "chp" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -44441,43 +44375,22 @@ }, /turf/closed/wall, /area/maintenance/starboard/aft) -"chq" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"chr" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Kill Chamber"; +"chs" = ( +/obj/machinery/door/window/northleft{ + base_state = "right"; + dir = 8; + icon_state = "right"; + name = "Containment Pen"; req_access_txt = "55" }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plating, -/area/science/xenobiology) -"chs" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/general/visible, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cht" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"chu" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/turf/open/floor/engine, /area/science/xenobiology) "chv" = ( /obj/structure/cable{ @@ -45267,18 +45180,6 @@ /obj/item/cigbutt/roach, /turf/open/floor/plating, /area/maintenance/aft) -"cjB" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, -/obj/structure/table, -/obj/item/folder/white, -/obj/item/pen, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/science/xenobiology) "cjC" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -45388,7 +45289,7 @@ req_access = null; req_access_txt = "10;13" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/engineering) "cjS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -45555,11 +45456,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/aft) -"ckn" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/science/xenobiology) "cko" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall, @@ -48100,8 +47996,8 @@ /area/space/nearstation) "csk" = ( /obj/structure/disposalpipe/segment, -/turf/open/floor/plating/airless, -/area/space/nearstation) +/turf/closed/wall/r_wall, +/area/science/xenobiology) "csl" = ( /obj/structure/transit_tube/curved{ dir = 4 @@ -49949,7 +49845,7 @@ /area/shuttle/pod_1) "cxG" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; name = "Escape Pod Three"; req_access_txt = "0" }, @@ -49959,15 +49855,21 @@ /turf/open/floor/plating, /area/security/main) "cxJ" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 8; +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ name = "Labor Camp Shuttle Airlock"; req_access_txt = "2" }, +/obj/machinery/button/door{ + id = "prison release"; + name = "Labor Camp Shuttle Lockdown"; + pixel_y = -25; + req_access_txt = "2" + }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/processing) "cxN" = ( /obj/structure/cable{ @@ -49983,16 +49885,6 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) -"cxP" = ( -/obj/machinery/door/airlock/external{ - cyclelinkeddir = 8; - name = "Labor Camp Shuttle Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/plating, -/area/security/processing) "cxR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -50331,11 +50223,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) -"czQ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "czR" = ( /obj/structure/cable{ icon_state = "1-2" @@ -52439,18 +52326,6 @@ }, /turf/open/floor/plating, /area/science/xenobiology) -"cTY" = ( -/obj/structure/sign/poster/official/safety_internals{ - pixel_x = -32 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"cTZ" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "cVb" = ( /turf/closed/wall, /area/hallway/secondary/service) @@ -52511,6 +52386,37 @@ dir = 6 }, /area/security/brig) +"dnf" = ( +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xenobio0"; + name = "containment blast door" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, +/area/science/xenobiology) +"dos" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "dAS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -52518,6 +52424,9 @@ /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/maintenance/fore/secondary) +"dBk" = ( +/turf/open/floor/plasteel/dark, +/area/security/processing) "dLQ" = ( /turf/open/floor/plasteel/red/corner{ dir = 1 @@ -52610,6 +52519,26 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/quartermaster/miningdock) +"ezw" = ( +/obj/structure/window/reinforced, +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "xenobio7"; + name = "Containment Blast Doors"; + pixel_y = 4; + req_access_txt = "55" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "eBn" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 1 @@ -52887,7 +52816,7 @@ /obj/effect/turf_decal/bot{ dir = 2 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/engine/engineering) "hCi" = ( /obj/structure/lattice, @@ -53147,7 +53076,7 @@ /area/hallway/secondary/service) "khB" = ( /obj/machinery/door/airlock/external{ - cyclelinkeddir = 4; + cyclelinkeddir = 0; req_access_txt = "13" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -54001,7 +53930,7 @@ /obj/effect/turf_decal/bot{ dir = 2 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/engine/engineering) "srd" = ( /turf/open/floor/plasteel/red/corner{ @@ -54409,6 +54338,26 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/white, /area/science/circuit) +"vDd" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "xenobio0"; + name = "Containment Blast Doors"; + pixel_y = 4; + req_access_txt = "55" + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/light, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "vHQ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -77939,7 +77888,7 @@ aln aiU aaa aiU -anN +aln aiU aaa aaa @@ -78192,11 +78141,11 @@ aaf aaf aaf aiU -alp +dBk aiU aaa aiU -alp +dBk aiU aaf aaf @@ -78453,7 +78402,7 @@ cxJ aiU aiT aiU -cxP +cxJ aiU aiV aiT @@ -96780,7 +96729,7 @@ bDb bDb bDb bDb -cNW +bDb cNW cQB czY @@ -97033,11 +96982,11 @@ bJN bRT bEm bEm +bJN +bRT +bEm +bEm bDb -cfr -cho -bDb -aaa cNW cQB czY @@ -97276,7 +97225,7 @@ bJJ bKY bMi bNo -bIP +bOx bPA bJN bRU @@ -97290,12 +97239,12 @@ bJN bRU bEm bEm +bJN +bRU +bEm +bEm bDb -cgi -chq -ccQ -aaa -cOT +cNW cQB czY cOT @@ -97547,12 +97496,12 @@ bJN bRU bEm cBz +bJN +bRU +bEm +cBz bDb -cgi -chq -ccQ -aaa -cOT +cNW cQB czY cOT @@ -97791,7 +97740,7 @@ bLa bMi bNo bPy -bPA +dos bJN bRW bTb @@ -97804,11 +97753,11 @@ bJN bZV caV cbS -bDb +bJN cgl chs +dnf bDb -aaa cNW cQB czY @@ -98061,11 +98010,11 @@ bVi bRV bTa cbR +bVi +bRV +bTa +vDd bDb -cgk -chr -bDb -aaa cNW cBN czY @@ -98318,12 +98267,12 @@ bZa bMi bMi bRZ -cTY -cTZ -chu -ccQ -aaf -cOT +bZa +bMi +bMi +bRZ +bDb +cNW cQB cAa cOT @@ -98574,13 +98523,13 @@ bUf bTc bRX bTc +bUf +bTc +bRX +bTc cbT -ccP -ccP -cht -ckn csk -czQ +cko czU czZ cOT @@ -98832,12 +98781,12 @@ bZb bRZ bMi bMi -cfy -cgn -cjB -ccQ -aaf -cOT +bZb +bRZ +bMi +bMi +bDb +cNW cgm czY cOT @@ -99089,11 +99038,11 @@ bVi bZW bTd bUg +bVi +ezw +bTd +bUg bDb -bDb -bDb -bDb -aaa cNW cgm czY @@ -99346,11 +99295,11 @@ bJN bZX caW cbU +bJN +bWn +bXg +bYh bDb -aaf -aaf -aaa -aaa cNW cgm czY @@ -99603,12 +99552,12 @@ bJN bEm bEm bRU +bJN +bEm +bEm +bRU bDb -aaf -aaa -aaa -aaa -cOT +cNW cgm czY cOT @@ -99860,12 +99809,12 @@ bJN bEm bEm bRU +bJN +bEm +bEm +bRU bDb -aaf -aaa -aaa -aaa -cOT +cNW cgm czY cOT @@ -100117,12 +100066,12 @@ bJN bEm bEm bUi +bJN +bEm +bEm +bUi bDb -aaf -aaf -aaa -aaa -cOT +cNW cgm czY cOT @@ -100375,10 +100324,10 @@ bDb bDb bDb bDb -cNW -cNW -cNW -cNW +bDb +bDb +bDb +bDb cNW czX cAc diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 4777dc3e29..b1b3f234f9 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -67532,9 +67532,6 @@ dir = 5 }, /area/science/xenobiology) -"cNh" = ( -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) "cNi" = ( /obj/machinery/light/small{ dir = 1 @@ -67545,7 +67542,9 @@ name = "xenobiology camera"; network = list("ss13","xeno","rd") }, -/turf/open/floor/plasteel/vault/killroom, +/turf/open/floor/plasteel/vault{ + dir = 5 + }, /area/science/xenobiology) "cNj" = ( /obj/structure/closet/crate{ @@ -68261,26 +68260,6 @@ "cON" = ( /turf/open/floor/circuit/green, /area/science/xenobiology) -"cOO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; - external_pressure_bound = 140; - name = "killroom vent"; - pressure_checks = 0 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cOP" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"cOQ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; - external_pressure_bound = 120; - name = "server vent" - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cOR" = ( /turf/closed/wall/r_wall, /area/science/research) @@ -69036,24 +69015,6 @@ dir = 1 }, /area/science/xenobiology) -"cQw" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) -"cQx" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) -"cQy" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel/vault/killroom, -/area/science/xenobiology) "cQz" = ( /obj/structure/closet/wardrobe/science_white, /obj/machinery/light/small{ @@ -69757,7 +69718,6 @@ icon_state = "0-4" }, /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/open/floor/plating, /area/science/xenobiology) "cSg" = ( @@ -69768,7 +69728,7 @@ icon_state = "2-8" }, /obj/machinery/door/airlock/research/glass{ - name = "Xenobiology Kill Room"; + name = "Xenobiology Isolation Pin"; req_access_txt = "47" }, /obj/effect/turf_decal/stripes/line{ @@ -70558,13 +70518,19 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cTR" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 1; - min_temperature = 80; - on = 1; - target_temperature = 80 +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 }, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/xenobiology) "cTS" = ( @@ -72260,9 +72226,6 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cXm" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, /obj/machinery/status_display{ pixel_x = 32 }, @@ -100850,6 +100813,25 @@ }, /turf/open/floor/plasteel, /area/maintenance/port/aft) +"htt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "hGT" = ( /obj/machinery/door/firedoor, /obj/structure/cable/white{ @@ -101141,6 +101123,13 @@ "saw" = ( /turf/closed/wall, /area/science/circuit) +"shc" = ( +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/structure/reagent_dispensers/watertank/high, +/turf/open/floor/circuit/green, +/area/science/xenobiology) "tdp" = ( /obj/effect/turf_decal/stripes/line{ dir = 2 @@ -128455,7 +128444,7 @@ das dcd cMY deX -dgo +htt dhR lKu tmi @@ -132555,9 +132544,9 @@ cHA cjp cKl cLI -cNh -cNh -cNh +cNd +cNd +cNd cNc cTQ cVI @@ -132812,9 +132801,9 @@ cHB cjp cKj cLI -cNh -cOO -cQw +cNd +cNd +cNd cSf cTR cVP @@ -133070,8 +133059,8 @@ caE cKm cLI cNi -cOP -cQx +cNd +cNd cSg cTS cVQ @@ -133326,9 +133315,9 @@ cHB cjp cKk cLI -cNh -cOQ -cQy +cNd +cNd +cNd cSh cTT cVR @@ -133583,9 +133572,9 @@ cHA ceb cKk cLI -cNh -cNh -cNh +cNd +cNd +cNd cNc cTU cVS @@ -133848,7 +133837,7 @@ cTV cVT cXm cZb -cXm +shc dcu ddV cMY diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 016b1dd128..e32792718e 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -35104,9 +35104,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/department/science/xenobiology) "bvU" = ( @@ -40977,11 +40974,8 @@ /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) "bIv" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 10 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "bIw" = ( /obj/machinery/light, /obj/machinery/camera{ @@ -67904,15 +67898,6 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/aft) -"cLE" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 1; - name = "euthanization chamber freezer"; - on = 1; - target_temperature = 80 - }, -/turf/open/floor/plating, -/area/science/xenobiology) "cLF" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -71590,7 +71575,7 @@ "cTT" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall/r_wall, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "cUH" = ( /obj/structure/table/optable, /turf/open/floor/plasteel/white, @@ -72062,9 +72047,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) -"cZv" = ( -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) "cZR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ @@ -72210,9 +72192,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, /obj/machinery/light/small{ dir = 1 }, @@ -72222,24 +72201,14 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) -"daR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1; - external_pressure_bound = 140; - name = "server vent"; - pressure_checks = 0 - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "daS" = ( /obj/structure/disposalpipe/segment, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/turf/open/floor/plating{ + icon_state = "platingdmg2" + }, +/area/maintenance/department/science/xenobiology) "daW" = ( /obj/machinery/button/door{ id = "engpa"; @@ -72374,17 +72343,10 @@ "dbv" = ( /obj/structure/disposalpipe/segment, /obj/machinery/light/small, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) -"dbw" = ( -/obj/machinery/camera{ - c_tag = "Xenobiology Lab - Kill Chamber"; - dir = 1; - network = list("ss13","rd","xeno"); - start_active = 1 +/turf/open/floor/plating{ + icon_state = "platingdmg2" }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dbE" = ( /obj/machinery/plantgenes, /obj/effect/turf_decal/stripes/line{ @@ -72791,15 +72753,18 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcm" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/computer/camera_advanced/xenobio, /obj/effect/turf_decal/stripes/line{ - dir = 9 + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 }, /turf/open/floor/plasteel, /area/science/xenobiology) @@ -72823,7 +72788,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/obj/machinery/computer/camera_advanced/xenobio, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -72893,9 +72857,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/structure/chair/comfy/black{ - dir = 1 - }, /obj/effect/turf_decal/stripes/line{ dir = 10 }, @@ -72910,9 +72871,6 @@ /area/science/xenobiology) "dcx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair/comfy/black{ - dir = 1 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -72990,18 +72948,13 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcJ" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/item/extinguisher{ - pixel_x = 4; - pixel_y = 3 - }, -/obj/item/extinguisher, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcK" = ( @@ -73427,11 +73380,8 @@ }, /obj/structure/chair, /obj/item/cigbutt, -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 1 - }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "ddy" = ( /turf/open/floor/plating{ icon_state = "platingdmg1" @@ -73439,9 +73389,8 @@ /area/maintenance/department/science/xenobiology) "ddz" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/turf/open/floor/plating, -/area/science/xenobiology) +/turf/closed/wall/r_wall, +/area/maintenance/department/science/xenobiology) "ddA" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, @@ -73451,23 +73400,15 @@ opacity = 0; req_access_txt = "55" }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) -"ddB" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 1; - external_pressure_bound = 120; - name = "server vent" - }, -/turf/open/floor/circuit/killroom, -/area/science/xenobiology) +/turf/closed/wall/r_wall, +/area/maintenance/department/science/xenobiology) "ddC" = ( /obj/structure/disposalpipe/trunk{ dir = 1 }, /obj/structure/disposaloutlet, /turf/open/floor/plating/airless, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "ddE" = ( /obj/effect/landmark/start/cook, /obj/machinery/holopad, @@ -74890,9 +74831,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/machinery/door/airlock/research{ glass = 1; name = "Slime Euthanization Chamber"; @@ -74903,7 +74841,7 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dmr" = ( /obj/machinery/door/airlock/research{ glass = 1; @@ -74915,7 +74853,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/science/xenobiology) +/area/maintenance/department/science/xenobiology) "dmD" = ( /obj/structure/displaycase/trophy, /turf/open/floor/wood, @@ -76517,6 +76455,10 @@ }, /turf/open/floor/plating/airless, /area/engine/engineering) +"jot" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/department/science/xenobiology) "jwW" = ( /turf/closed/wall/mineral/plastitanium, /area/crew_quarters/fitness/recreation) @@ -110317,7 +110259,7 @@ cRi cRi cRi daP -cLE +cTA dlV aaa aaa @@ -110574,10 +110516,10 @@ daF daJ cRi bvT -cRi -cRi -cRi -cRi +dlV +dlV +dlV +dlV aaa aai aaa @@ -110831,10 +110773,10 @@ cSn cSn cRi dmq -cRi -cZv -cZv -cRi +dlV +ddj +ddj +dlV aaf aag aaa @@ -111089,9 +111031,9 @@ cSn cRi ddx ddz -daR -cZv -cRe +ddj +ddj +jot aaa aaa aaa @@ -111603,9 +111545,9 @@ daK cRi bIv ddz -ddB -cZv -cRe +ddj +ddj +jot aaa aaf aaa @@ -111859,10 +111801,10 @@ cSn daN cRi dmr -cRi -cZv -dbw -cRi +dlV +ddj +ddj +dlV aaa aag aaa @@ -112116,10 +112058,10 @@ daI daM cRi cTA -cRi -cRi -cRi -cRi +dlV +dlV +dlV +dlV aaf aag aaa diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 3eebcbf5e1..6bf52ab60a 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -26613,12 +26613,6 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) -"bpp" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/science/xenobiology) "bpq" = ( /obj/structure/sign/warning/electricshock, /turf/closed/wall/r_wall, @@ -27817,9 +27811,6 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "brQ" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 8 - }, /obj/machinery/camera{ c_tag = "Xenobiology Port"; dir = 8; @@ -28611,11 +28602,11 @@ /turf/open/floor/plating, /area/science/xenobiology) "btD" = ( -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "btE" = ( /obj/effect/decal/remains/xeno, -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "btF" = ( /obj/structure/chair{ @@ -29236,12 +29227,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Xenobiology Kill Room"; - dir = 8; - network = list("ss13","rd") - }, -/turf/open/floor/plating/airless, +/turf/open/floor/plating, /area/science/xenobiology) "bva" = ( /turf/closed/wall, @@ -31308,16 +31294,22 @@ /turf/open/floor/plasteel/whitepurple/side, /area/science/xenobiology) "bzi" = ( -/obj/item/extinguisher{ - pixel_x = 4; - pixel_y = 3 +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/obj/item/extinguisher, /obj/structure/table/glass, -/turf/open/floor/plasteel/whitepurple/side, +/obj/item/extinguisher, +/obj/item/extinguisher{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/extinguisher{ + pixel_x = 5; + pixel_y = 5 + }, +/turf/open/floor/plasteel, /area/science/xenobiology) "bzj" = ( -/obj/structure/reagent_dispensers/watertank, /obj/machinery/requests_console{ department = "Science"; departmentType = 2; @@ -31325,6 +31317,7 @@ pixel_x = 32; receive_ore_updates = 1 }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel/whitepurple/side, /area/science/xenobiology) "bzk" = ( @@ -93288,7 +93281,7 @@ bkE aht bnd boh -bpp +bpn bqx brQ btr diff --git a/cfg/admin.txt b/cfg/admin.txt index 8b13789179..fcc587124a 100644 --- a/cfg/admin.txt +++ b/cfg/admin.txt @@ -1 +1 @@ - +poojawa role=admin diff --git a/code/citadel/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm similarity index 100% rename from code/citadel/_cit_helpers.dm rename to code/__HELPERS/_cit_helpers.dm diff --git a/code/_globalvars/tooltips.dm b/code/_globalvars/tooltips.dm deleted file mode 100755 index 58bb6bcea5..0000000000 --- a/code/_globalvars/tooltips.dm +++ /dev/null @@ -1 +0,0 @@ -GLOBAL_VAR_INIT(enable_examine_tips, TRUE) \ No newline at end of file diff --git a/code/_onclick/god.dm b/code/_onclick/god.dm deleted file mode 100644 index 24629a0635..0000000000 --- a/code/_onclick/god.dm +++ /dev/null @@ -1,8 +0,0 @@ -/mob/camera/god/UnarmedAttack(atom/A) - A.attack_god(src) - -/mob/camera/god/RangedAttack(atom/A) - A.attack_god(src) - -/atom/proc/attack_god(mob/user) - return diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm deleted file mode 100644 index fa2a4ebf31..0000000000 --- a/code/_onclick/hud/other_mobs.dm +++ /dev/null @@ -1,13 +0,0 @@ - -/datum/hud/brain/show_hud(version = 0) - if(!ismob(mymob)) - return 0 - if(!mymob.client) - return 0 - mymob.client.screen = list() - mymob.client.screen += mymob.client.void - -/mob/living/brain/create_mob_hud() - if(client && !hud_used) - hud_used = new /datum/hud/brain(src) - diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm deleted file mode 100644 index 3b0f86dae4..0000000000 --- a/code/citadel/cit_guns.dm +++ /dev/null @@ -1,1249 +0,0 @@ -/obj/item/gun/energy/laser/carbine - name = "laser carbine" - desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal laser gun." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "lasernew" - item_state = "laser" - force = 10 - throwforce = 10 - ammo_type = list(/obj/item/ammo_casing/energy/lasergun) - cell_type = /obj/item/stock_parts/cell/lascarbine - resistance_flags = FIRE_PROOF | ACID_PROOF - -/obj/item/gun/energy/laser/carbine/nopin - pin = null - -/obj/item/stock_parts/cell/lascarbine - name = "laser carbine power supply" - maxcharge = 2500 - -/datum/design/lasercarbine - name = "Laser Carbine" - desc = "Beefed up version of a standard laser gun." - id = "lasercarbine" - build_type = PROTOLATHE - materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000) - build_path = /obj/item/gun/energy/laser/carbine/nopin - category = list("Weapons") - -////////////Anti Tank Pistol//////////// - -/obj/item/gun/ballistic/automatic/pistol/antitank - name = "Anti Tank Pistol" - desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate your wrist." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "atp" - item_state = "pistol" - recoil = 4 - mag_type = /obj/item/ammo_box/magazine/sniper_rounds - fire_delay = 50 - burst_size = 1 - can_suppress = 0 - w_class = WEIGHT_CLASS_NORMAL - actions_types = list() - fire_sound = 'sound/weapons/blastcannon.ogg' - spread = 20 //damn thing has no rifling. - -/obj/item/gun/ballistic/automatic/pistol/antitank/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("atp-mag") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -/obj/item/gun/ballistic/automatic/pistol/antitank/syndicate - name = "Syndicate Anti Tank Pistol" - desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing." - pin = /obj/item/device/firing_pin/implant/pindicate - -/////////////spinfusor stuff//////////////// - -/obj/item/projectile/bullet/spinfusor - name ="spinfusor disk" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state= "spinner" - damage = 30 - dismemberment = 25 - -/obj/item/projectile/bullet/spinfusor/on_hit(atom/target, blocked = FALSE) //explosion to emulate the spinfusor's AOE - ..() - explosion(target, -1, -1, 2, 0, -1) - return 1 - -/obj/item/ammo_casing/caseless/spinfusor - name = "spinfusor disk" - desc = "A magnetic disk designed specifically for the Stormhammer magnetic cannon. Warning: extremely volatile!" - projectile_type = /obj/item/projectile/bullet/spinfusor - caliber = "spinfusor" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "disk" - throwforce = 15 //still deadly when thrown - throw_speed = 3 - -/obj/item/ammo_casing/caseless/spinfusor/throw_impact(atom/target) //disks detonate when thrown - if(!..()) // not caught in mid-air - visible_message("[src] detonates!") - playsound(src.loc, "sparks", 50, 1) - explosion(target, -1, -1, 1, 1, -1) - qdel(src) - return 1 - -/obj/item/ammo_box/magazine/internal/spinfusor - name = "spinfusor internal magazine" - ammo_type = /obj/item/ammo_casing/caseless/spinfusor - caliber = "spinfusor" - max_ammo = 1 - -/obj/item/gun/ballistic/automatic/spinfusor - name = "Stormhammer Magnetic Cannon" - desc = "An innovative weapon utilizing mag-lev technology to spin up a magnetic fusor and launch it at extreme velocities." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "spinfusor" - item_state = "spinfusor" - mag_type = /obj/item/ammo_box/magazine/internal/spinfusor - fire_sound = 'sound/weapons/rocketlaunch.ogg' - w_class = WEIGHT_CLASS_BULKY - can_suppress = 0 - burst_size = 1 - fire_delay = 40 - select = 0 - actions_types = list() - casing_ejector = 0 - -/obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params) - var/num_loaded = magazine.attackby(A, user, params, 1) - if(num_loaded) - to_chat(user, "You load [num_loaded] disk\s into \the [src].") - update_icon() - chamber_round() - -/obj/item/gun/ballistic/automatic/spinfusor/attack_self(mob/living/user) - return //caseless rounds are too glitchy to unload properly. Best to make it so that you cannot remove disks from the spinfusor - -/obj/item/gun/ballistic/automatic/spinfusor/update_icon() - ..() - icon_state = "spinfusor[magazine ? "-[get_ammo(1)]" : ""]" - -/obj/item/ammo_box/aspinfusor - name = "ammo box (spinfusor disks)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "spinfusorbox" - ammo_type = /obj/item/ammo_casing/caseless/spinfusor - max_ammo = 8 - -/datum/supply_pack/security/armory/spinfusor - name = "Stormhammer Spinfusor Crate" - cost = 14000 - contains = list(/obj/item/gun/ballistic/automatic/spinfusor, - /obj/item/gun/ballistic/automatic/spinfusor) - crate_name = "spinfusor crate" - -/datum/supply_pack/security/armory/spinfusorammo - name = "Spinfusor Disk Crate" - cost = 7000 - contains = list(/obj/item/ammo_box/aspinfusor, - /obj/item/ammo_box/aspinfusor, - /obj/item/ammo_box/aspinfusor, - /obj/item/ammo_box/aspinfusor) - crate_name = "spinfusor disk crate" - -///////XCOM X9 AR/////// - -/obj/item/gun/ballistic/automatic/x9 //will be adminspawn only so ERT or something can use them - name = "\improper X9 Assault Rifle" - desc = "A rather old design of a cheap, reliable assault rifle made for combat against unknown enemies. Uses 5.56mm ammo." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "x9" - item_state = "arg" - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG - fire_sound = 'sound/weapons/gunshot_smg.ogg' - can_suppress = 0 - burst_size = 6 //in line with XCOMEU stats. This can fire 5 bursts from a full magazine. - fire_delay = 1 - spread = 30 //should be 40 for XCOM memes, but since its adminspawn only, might as well make it useable - recoil = 1 - -///toy memes/// - -/obj/item/ammo_box/magazine/toy/x9 - name = "foam force X9 magazine" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "toy9magazine" - max_ammo = 30 - multiple_sprites = 2 - materials = list(MAT_METAL = 200) - -/obj/item/gun/ballistic/automatic/x9/toy - name = "\improper Foam Force X9" - desc = "An old but reliable assault rifle made for combat against unknown enemies. Appears to be hastily converted. Ages 8 and up." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "toy9" - can_suppress = 0 - obj_flags = 0 - mag_type = /obj/item/ammo_box/magazine/toy/x9 - casing_ejector = 0 - spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) - w_class = WEIGHT_CLASS_BULKY - weapon_weight = WEAPON_HEAVY - -////////XCOM2 Magpistol///////// - -//////projectiles////// - -/obj/item/projectile/bullet/mags - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile" - damage = 15 - armour_penetration = 10 - light_range = 2 - speed = 0.6 - range = 25 - light_color = LIGHT_COLOR_RED - -/obj/item/projectile/bullet/nlmags //non-lethal boolets - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile-nl" - damage = 0 - knockdown = 0 - stamina = 25 - armour_penetration = -10 - light_range = 2 - speed = 0.7 - range = 25 - light_color = LIGHT_COLOR_BLUE - - -/////actual ammo///// - -/obj/item/ammo_casing/caseless/amags - desc = "A ferromagnetic slug intended to be launched out of a compatible weapon." - caliber = "mags" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mag-casing-live" - projectile_type = /obj/item/projectile/bullet/mags - -/obj/item/ammo_casing/caseless/anlmags - desc = "A specialized ferromagnetic slug designed with a less-than-lethal payload." - caliber = "mags" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mag-casing-live" - projectile_type = /obj/item/projectile/bullet/nlmags - -//////magazines///// - -/obj/item/ammo_box/magazine/mmag/small - name = "magpistol magazine (non-lethal disabler)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "nlmagmag" - ammo_type = /obj/item/ammo_casing/caseless/anlmags - caliber = "mags" - max_ammo = 15 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/mmag/small/lethal - name = "magpistol magazine (lethal)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "smallmagmag" - ammo_type = /obj/item/ammo_casing/caseless/amags - -//////the gun itself////// - -/obj/item/gun/ballistic/automatic/pistol/mag - name = "magpistol" - desc = "A handgun utilizing maglev technologies to propel a ferromagnetic slug to extreme velocities." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magpistol" - force = 10 - fire_sound = 'sound/weapons/magpistol.ogg' - mag_type = /obj/item/ammo_box/magazine/mmag/small - can_suppress = 0 - casing_ejector = 0 - fire_delay = 2 - recoil = 0.2 - -/obj/item/gun/ballistic/automatic/pistol/mag/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("magpistol-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -///research memes/// - -/obj/item/gun/ballistic/automatic/pistol/mag/nopin - pin = null - spawnwithmagazine = FALSE - -/datum/design/magpistol - name = "Magpistol" - desc = "A weapon which fires ferromagnetic slugs." - id = "magpisol" - build_type = PROTOLATHE - materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) - build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_magpistol - name = "Magpistol Magazine" - desc = "A 14 round magazine for the Magpistol." - id = "mag_magpistol" - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_SILVER = 500) - build_path = /obj/item/ammo_box/magazine/mmag/small/lethal - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_magpistol/nl - name = "Magpistol Magazine (Non-Lethal)" - desc = "A 14 round non-lethal magazine for the Magpistol." - id = "mag_magpistol_nl" - materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) - build_path = /obj/item/ammo_box/magazine/mmag/small - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -//////toy memes///// - -/obj/item/projectile/bullet/reusable/foam_dart/mag - name = "magfoam dart" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile-toy" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag - light_range = 2 - light_color = LIGHT_COLOR_YELLOW - -/obj/item/ammo_casing/caseless/foam_dart/mag - name = "magfoam dart" - desc = "A foam dart with fun light-up projectiles powered by magnets!" - projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/mag - -/obj/item/ammo_box/magazine/internal/shot/toy/mag - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag - max_ammo = 14 - -/obj/item/gun/ballistic/shotgun/toy/mag - name = "foam force magpistol" - desc = "A fancy toy sold alongside light-up foam force darts. Ages 8 and up." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "toymag" - item_state = "gun" - mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/mag - fire_sound = 'sound/weapons/magpistol.ogg' - slot_flags = SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - -/obj/item/ammo_box/foambox/mag - name = "ammo box (Magnetic Foam Darts)" - icon = 'icons/obj/guns/toy.dmi' - icon_state = "foambox" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag - max_ammo = 42 - -//////Magrifle////// - -///projectiles/// - -/obj/item/projectile/bullet/magrifle - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile-large" - damage = 20 - armour_penetration = 25 - light_range = 3 - speed = 0.7 - range = 35 - light_color = LIGHT_COLOR_RED - -/obj/item/projectile/bullet/nlmagrifle //non-lethal boolets - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile-large-nl" - damage = 0 - knockdown = 0 - stamina = 25 - armour_penetration = -10 - light_range = 3 - speed = 0.65 - range = 35 - light_color = LIGHT_COLOR_BLUE - -///ammo casings/// - -/obj/item/ammo_casing/caseless/amagm - desc = "A large ferromagnetic slug intended to be launched out of a compatible weapon." - caliber = "magm" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mag-casing-live" - projectile_type = /obj/item/projectile/bullet/magrifle - -/obj/item/ammo_casing/caseless/anlmagm - desc = "A large, specialized ferromagnetic slug designed with a less-than-lethal payload." - caliber = "magm" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mag-casing-live" - projectile_type = /obj/item/projectile/bullet/nlmagrifle - -///magazines/// - -/obj/item/ammo_box/magazine/mmag/ - name = "magrifle magazine (non-lethal disabler)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mediummagmag" - ammo_type = /obj/item/ammo_casing/caseless/anlmagm - caliber = "magm" - max_ammo = 24 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/mmag/lethal - name = "magrifle magazine (lethal)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "mediummagmag" - ammo_type = /obj/item/ammo_casing/caseless/amagm - max_ammo = 24 - -///the gun itself/// - -/obj/item/gun/ballistic/automatic/magrifle - name = "\improper Magnetic Rifle" - desc = "A simple upscalling of the technologies used in the magpistol, the magrifle is capable of firing slightly larger slugs in bursts. Compatible with the magpistol's slugs." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magrifle" - item_state = "arg" - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/mmag - fire_sound = 'sound/weapons/magrifle.ogg' - can_suppress = 0 - burst_size = 3 - fire_delay = 2 - spread = 5 - recoil = 0.15 - casing_ejector = 0 - -///research/// - -/obj/item/gun/ballistic/automatic/magrifle/nopin - pin = null - spawnwithmagazine = FALSE - -/datum/design/magrifle - name = "Magrifle" - desc = "An upscaled Magpistol in rifle form." - id = "magrifle" - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000) - build_path = /obj/item/gun/ballistic/automatic/magrifle/nopin - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_magrifle - name = "Magrifle Magazine (Lethal)" - desc = "A 24-round magazine for the Magrifle." - id = "mag_magrifle" - build_type = PROTOLATHE - materials = list(MAT_METAL = 8000, MAT_SILVER = 1000) - build_path = /obj/item/ammo_box/magazine/mmag/lethal - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_magrifle/nl - name = "Magrifle Magazine (Non-Lethal)" - desc = "A 24- round non-lethal magazine for the Magrifle." - id = "mag_magrifle_nl" - materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) - build_path = /obj/item/ammo_box/magazine/mmag - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -///foamagrifle/// - -/obj/item/ammo_box/magazine/toy/foamag - name = "foam force magrifle magazine" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "foamagmag" - max_ammo = 24 - multiple_sprites = 2 - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag - materials = list(MAT_METAL = 200) - -/obj/item/gun/ballistic/automatic/magrifle/toy - name = "foamag rifle" - desc = "A foam launching magnetic rifle. Ages 8 and up." - icon_state = "foamagrifle" - obj_flags = 0 - mag_type = /obj/item/ammo_box/magazine/toy/foamag - casing_ejector = FALSE - spread = 60 - w_class = WEIGHT_CLASS_BULKY - weapon_weight = WEAPON_HEAVY - -/* -// TECHWEBS IMPLEMENTATION -*/ - -/datum/techweb_node/magnetic_weapons - id = "magnetic_weapons" - display_name = "Magnetic Weapons" - description = "Weapons using magnetic technology" - prereq_ids = list("weaponry", "adv_weaponry", "emp_adv") - design_ids = list("magrifle", "magpisol", "mag_magrifle", "mag_magrifle_nl", "mag_magpistol", "mag_magpistol_nl") - research_cost = 2500 - export_price = 5000 - - -//////Hyper-Burst Rifle////// - -///projectiles/// - -/obj/item/projectile/bullet/mags/hyper - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile" - damage = 10 - armour_penetration = 10 - stamina = 10 - forcedodge = TRUE - range = 6 - light_range = 1 - light_color = LIGHT_COLOR_RED - -/obj/item/projectile/bullet/mags/hyper/inferno - icon_state = "magjectile-large" - stamina = 0 - forcedodge = FALSE - range = 25 - light_range = 4 - -/obj/item/projectile/bullet/mags/hyper/inferno/on_hit(atom/target, blocked = FALSE) - ..() - explosion(target, -1, 1, 2, 4, 5) - return 1 - -///ammo casings/// - -/obj/item/ammo_casing/caseless/ahyper - desc = "A large block of speciallized ferromagnetic material designed to be fired out of the experimental Hyper-Burst Rifle." - caliber = "hypermag" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "hyper-casing-live" - projectile_type = /obj/item/projectile/bullet/mags/hyper - pellets = 12 - variance = 40 - -/obj/item/ammo_casing/caseless/ahyper/inferno - projectile_type = /obj/item/projectile/bullet/mags/hyper/inferno - pellets = 1 - variance = 0 - -///magazines/// - -/obj/item/ammo_box/magazine/mhyper - name = "hyper-burst rifle magazine" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "hypermag-4" - ammo_type = /obj/item/ammo_casing/caseless/ahyper - caliber = "hypermag" - desc = "A magazine for the Hyper-Burst Rifle. Loaded with a special slug that fragments into 12 smaller shards which can absolutely puncture anything, but has rather short effective range." - max_ammo = 4 - -/obj/item/ammo_box/magazine/mhyper/update_icon() - ..() - icon_state = "hypermag-[ammo_count() ? "4" : "0"]" - -/obj/item/ammo_box/magazine/mhyper/inferno - name = "hyper-burst rifle magazine (inferno)" - ammo_type = /obj/item/ammo_casing/caseless/ahyper/inferno - desc = "A magazine for the Hyper-Burst Rifle. Loaded with a special slug that violently reacts with whatever surface it strikes, generating a massive amount of heat and light." - -///gun itself/// - -/obj/item/gun/ballistic/automatic/hyperburst - name = "\improper Hyper-Burst Rifle" - desc = "An extremely beefed up version of a stolen Nanotrasen weapon prototype, this 'rifle' is more like a cannon, with an extremely large bore barrel capable of generating several smaller magnetic 'barrels' to simultaneously launch multiple projectiles at once." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "hyperburst" - item_state = "arg" - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/mhyper - fire_sound = 'sound/weapons/magburst.ogg' - can_suppress = 0 - burst_size = 1 - fire_delay = 40 - recoil = 2 - casing_ejector = 0 - weapon_weight = WEAPON_HEAVY - -/obj/item/gun/ballistic/automatic/hyperburst/update_icon() - ..() - icon_state = "hyperburst[magazine ? "-[get_ammo()]" : ""][chambered ? "" : "-e"]" - -///toy memes/// - -/obj/item/projectile/beam/lasertag/mag //the projectile, compatible with regular laser tag armor - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "magjectile-toy" - name = "lasertag magbolt" - forcedodge = TRUE //for penetration memes - range = 5 //so it isn't super annoying - light_range = 2 - light_color = LIGHT_COLOR_YELLOW - eyeblur = 0 - -/obj/item/ammo_casing/energy/laser/magtag - projectile_type = /obj/item/projectile/beam/lasertag/mag - select_name = "magtag" - pellets = 3 - variance = 30 - e_cost = 1000 - fire_sound = 'sound/weapons/magburst.ogg' - -/obj/item/gun/energy/laser/practice/hyperburst - name = "toy hyper-burst launcher" - desc = "A toy laser with a unique beam shaping lens that projects harmless bolts capable of going through objects. Compatible with existing laser tag systems." - ammo_type = list(/obj/item/ammo_casing/energy/laser/magtag) - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "toyburst" - clumsy_check = FALSE - obj_flags = 0 - fire_delay = 40 - weapon_weight = WEAPON_HEAVY - selfcharge = TRUE - charge_delay = 2 - recoil = 2 - cell_type = /obj/item/stock_parts/cell/toymagburst - -/obj/item/stock_parts/cell/toymagburst - name = "toy mag burst rifle power supply" - maxcharge = 4000 - -/* made redundant by reskinnable stetchkins -//////Stealth Pistol////// - -/obj/item/gun/ballistic/automatic/pistol/stealth - name = "stealth pistol" - desc = "A unique bullpup pistol with a compact frame. Has an integrated surpressor." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "stealthpistol" - w_class = WEIGHT_CLASS_SMALL - mag_type = /obj/item/ammo_box/magazine/m10mm - can_suppress = 0 - fire_sound = 'sound/weapons/gunshot_silenced.ogg' - suppressed = 1 - burst_size = 1 - -/obj/item/gun/ballistic/automatic/pistol/stealth/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("stealthpistol-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -*/ - -///foam stealth pistol/// - -/obj/item/gun/ballistic/automatic/toy/pistol/stealth - name = "foam force stealth pistol" - desc = "A small, easily concealable toy bullpup handgun. Ages 8 and up." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "foamsp" - w_class = WEIGHT_CLASS_SMALL - mag_type = /obj/item/ammo_box/magazine/toy/pistol - can_suppress = FALSE - fire_sound = 'sound/weapons/gunshot_silenced.ogg' - suppressed = TRUE - burst_size = 1 - fire_delay = 0 - spread = 20 - actions_types = list() - -/obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("foamsp-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -//////10mm soporific bullets////// - -obj/item/projectile/bullet/c10mm/soporific - name ="10mm soporific bullet" - armour_penetration = 0 - nodamage = TRUE - dismemberment = 0 - knockdown = 0 - -/obj/item/projectile/bullet/c10mm/soporific/on_hit(atom/target, blocked = FALSE) - if((blocked != 100) && isliving(target)) - var/mob/living/L = target - L.blur_eyes(6) - if(L.getStaminaLoss() >= 60) - L.Sleeping(300) - else - L.adjustStaminaLoss(25) - return 1 - -/obj/item/ammo_casing/c10mm/soporific - name = ".10mm soporific bullet casing" - desc = "A 10mm soporific bullet casing." - projectile_type = /obj/item/projectile/bullet/c10mm/soporific - -/obj/item/ammo_box/magazine/m10mm/soporific - name = "pistol magazine (10mm soporific)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "9x19pS" - desc = "A gun magazine. Loaded with rounds which inject the target with a variety of illegal substances to induce sleep in the target." - ammo_type = /obj/item/ammo_casing/c10mm/soporific - -/obj/item/ammo_box/c10mm/soporific - name = "ammo box (10mm soporific)" - ammo_type = /obj/item/ammo_casing/c10mm/soporific - max_ammo = 24 - -//////Flechette Launcher////// - -///projectiles/// - -/obj/item/projectile/bullet/cflechetteap //shreds armor - name = "flechette (armor piercing)" - damage = 8 - armour_penetration = 80 - -/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding - name = "flechette (serrated)" - damage = 15 - dismemberment = 10 - armour_penetration = -80 - -/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE) - if((blocked != 100) && iscarbon(target)) - var/mob/living/carbon/C = target - C.bleed(10) - return ..() - -///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)/// - -/obj/item/ammo_casing/caseless/flechetteap - name = "flechette (armor piercing)" - desc = "A flechette made with a tungsten alloy." - projectile_type = /obj/item/projectile/bullet/cflechetteap - caliber = "flechette" - throwforce = 1 - throw_speed = 3 - -/obj/item/ammo_casing/caseless/flechettes - name = "flechette (serrated)" - desc = "A serrated flechette made of a special alloy intended to deform drastically upon penetration of human flesh." - projectile_type = /obj/item/projectile/bullet/cflechettes - caliber = "flechette" - throwforce = 2 - throw_speed = 3 - embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 40, "embedded_fall_chance" = 10) - -///magazine/// - -/obj/item/ammo_box/magazine/flechette - name = "flechette magazine (armor piercing)" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "flechettemag" - ammo_type = /obj/item/ammo_casing/caseless/flechetteap - caliber = "flechette" - max_ammo = 40 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/flechette/s - name = "flechette magazine (serrated)" - ammo_type = /obj/item/ammo_casing/caseless/flechettes - -///the gun itself/// - -/obj/item/gun/ballistic/automatic/flechette - name = "\improper CX Flechette Launcher" - desc = "A flechette launching machine pistol with an unconventional bullpup frame." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "flechettegun" - item_state = "gun" - w_class = WEIGHT_CLASS_NORMAL - slot_flags = 0 - /obj/item/device/firing_pin/implant/pindicate - mag_type = /obj/item/ammo_box/magazine/flechette/ - fire_sound = 'sound/weapons/gunshot_smg.ogg' - can_suppress = 0 - burst_size = 5 - fire_delay = 1 - casing_ejector = 0 - spread = 10 - recoil = 0.05 - -/obj/item/gun/ballistic/automatic/flechette/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("flechettegun-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -///unique variant/// - -/obj/item/projectile/bullet/cflechetteshredder - name = "flechette (shredder)" - damage = 5 - dismemberment = 40 - -/obj/item/ammo_casing/caseless/flechetteshredder - name = "flechette (shredder)" - desc = "A serrated flechette made of a special alloy that forms a monofilament edge." - projectile_type = /obj/item/projectile/bullet/cflechettes - -/obj/item/ammo_box/magazine/flechette/shredder - name = "flechette magazine (shredder)" - icon_state = "shreddermag" - ammo_type = /obj/item/ammo_casing/caseless/flechetteshredder - -/obj/item/gun/ballistic/automatic/flechette/shredder - name = "\improper CX Shredder" - desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes." - w_class = WEIGHT_CLASS_SMALL - mag_type = /obj/item/ammo_box/magazine/flechette/shredder - spread = 15 - recoil = 0.1 - -/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon() - ..() - if(magazine) - cut_overlays() - add_overlay("shreddergun-magazine") - else - cut_overlays() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" - -//////modular pistol////// (reskinnable stetchkins) - -/obj/item/gun/ballistic/automatic/pistol/modular - name = "modular pistol" - desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "cde" - can_unsuppress = TRUE - obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "cde", - "NT-99" = "n99", - "Stealth" = "stealthpistol", - "HKVP-78" = "vp78", - "Luger" = "p08b", - "Mk.58" = "secguncomp", - "PX4 Storm" = "px4" - ) - -/obj/item/gun/ballistic/automatic/pistol/modular/update_icon() - ..() - if(current_skin) - icon_state = "[unique_reskin[current_skin]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" - else - icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" - if(magazine && suppressed) - cut_overlays() - add_overlay("[unique_reskin[current_skin]]-magazine-sup") //Yes, this means the default iconstate can't have a magazine overlay - else if (magazine) - cut_overlays() - add_overlay("[unique_reskin[current_skin]]-magazine") - else - cut_overlays() - -/////////RAYGUN MEMES///////// - -/obj/item/projectile/beam/lasertag/ray //the projectile, compatible with regular laser tag armor - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "ray" - name = "ray bolt" - eyeblur = 0 - -/obj/item/ammo_casing/energy/laser/raytag - projectile_type = /obj/item/projectile/beam/lasertag/ray - select_name = "raytag" - fire_sound = 'sound/weapons/raygun.ogg' - -/obj/item/gun/energy/laser/practice/raygun - name = "toy ray gun" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "raygun" - desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems." - ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag) - selfcharge = TRUE - -/*///////////////////////////////////////////////////////////////////////////////////////////// - The Recolourable Gun -*////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/item/gun/ballistic/automatic/pistol/p37 - name = "\improper CX Mk.37P" - desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. \ - This model is coated with a special polychromic material. \ - Has a small warning on the receiver that boldly states 'WARNING: WILL DETONATE UPON UNAUTHORIZED USE'. \ - Uses 9mm bullets loaded into proprietary magazines." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "p37" - w_class = WEIGHT_CLASS_NORMAL - spawnwithmagazine = FALSE - mag_type = /obj/item/ammo_box/magazine/m9mm/p37 - can_suppress = FALSE - pin = /obj/item/device/firing_pin/dna/dredd //goes boom if whoever isn't DNA locked to it tries to use it - actions_types = list(/datum/action/item_action/pick_color) - - var/frame_color = "#808080" //RGB - var/receiver_color = "#808080" - var/body_color = "#0098FF" - var/barrel_color = "#808080" - var/tip_color = "#808080" - var/arm_color = "#808080" - var/grip_color = "#00FFCB" //Does not actually colour the grip, just the lights surrounding it - var/energy_color = "#00FFCB" - -///Defining all the colourable bits and displaying them/// - -/obj/item/gun/ballistic/automatic/pistol/p37/update_icon() - var/mutable_appearance/frame_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_frame") - var/mutable_appearance/receiver_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_receiver") - var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_body") - var/mutable_appearance/barrel_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_barrel") - var/mutable_appearance/tip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_tip") - var/mutable_appearance/grip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_grip") - var/mutable_appearance/energy_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_light") - var/mutable_appearance/arm_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm") - var/mutable_appearance/arm_overlay_e = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm-e") - - if(frame_color) - frame_overlay.color = frame_color - if(receiver_color) - receiver_overlay.color = receiver_color - if(body_color) - body_overlay.color = body_color - if(barrel_color) - barrel_overlay.color = barrel_color - if(tip_color) - tip_overlay.color = tip_color - if(grip_color) - grip_overlay.color = grip_color - if(energy_color) - energy_overlay.color = energy_color - if(arm_color) - arm_overlay.color = arm_color - if(arm_color) - arm_overlay_e.color = arm_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(frame_overlay) - add_overlay(receiver_overlay) - add_overlay(body_overlay) - add_overlay(barrel_overlay) - add_overlay(tip_overlay) - add_overlay(grip_overlay) - add_overlay(energy_overlay) - - if(magazine) //does not need a cut_overlays proc call here because it's already called further up - add_overlay("p37_mag") - - if(chambered) - cut_overlay(arm_overlay_e) - add_overlay(arm_overlay) - else - cut_overlay(arm_overlay) - add_overlay(arm_overlay_e) - -///letting you actually recolor things/// - -/obj/item/gun/ballistic/automatic/pistol/p37/ui_action_click(mob/user, var/datum/action/A) - if(istype(A, /datum/action/item_action/pick_color)) - - var/choice = input(user,"Mk.37P polychrome options", "Gun Recolor") in list("Frame Color","Receiver Color","Body Color", - "Barrel Color", "Barrel Tip Color", "Grip Light Color", - "Light Color", "Arm Color", "*CANCEL*") - - switch(choice) - - if("Frame Color") - var/frame_color_input = input(usr,"","Choose Frame Color",frame_color) as color|null - if(frame_color_input) - frame_color = sanitize_hexcolor(frame_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Receiver Color") - var/receiver_color_input = input(usr,"","Choose Receiver Color",receiver_color) as color|null - if(receiver_color_input) - receiver_color = sanitize_hexcolor(receiver_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Body Color") - var/body_color_input = input(usr,"","Choose Body Color",body_color) as color|null - if(body_color_input) - body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Barrel Color") - var/barrel_color_input = input(usr,"","Choose Barrel Color",barrel_color) as color|null - if(barrel_color_input) - barrel_color = sanitize_hexcolor(barrel_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Barrel Tip Color") - var/tip_color_input = input(usr,"","Choose Barrel Tip Color",tip_color) as color|null - if(tip_color_input) - tip_color = sanitize_hexcolor(tip_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Grip Light Color") - var/grip_color_input = input(usr,"","Choose Grip Light Color",grip_color) as color|null - if(grip_color_input) - grip_color = sanitize_hexcolor(grip_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Light Color") - var/energy_color_input = input(usr,"","Choose Light Color",energy_color) as color|null - if(energy_color_input) - energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - - if("Arm Color") - var/arm_color_input = input(usr,"","Choose Arm Color",arm_color) as color|null - if(arm_color_input) - arm_color = sanitize_hexcolor(arm_color_input, desired_format=6, include_crunch=1) - update_icon() - A.UpdateButtonIcon() - - else - ..() - -///boolets/// - -/obj/item/projectile/bullet/c9mm/frangible - name = "9mm frangible bullet" - damage = 15 - stamina = 0 - speed = 1.0 - range = 20 - armour_penetration = -25 - -/obj/item/projectile/bullet/c9mm/rubber - name = "9mm rubber bullet" - damage = 5 - stamina = 30 - speed = 1.2 - range = 14 - knockdown = 0 - -/obj/item/ammo_casing/c9mm/frangible - name = "9mm frangible bullet casing" - desc = "A 9mm frangible bullet casing." - projectile_type = /obj/item/projectile/bullet/c9mm/frangible - -/obj/item/ammo_casing/c9mm/rubber - name = "9mm rubber bullet casing" - desc = "A 9mm rubber bullet casing." - projectile_type = /obj/item/projectile/bullet/c9mm/rubber - -/obj/item/ammo_box/magazine/m9mm/p37 - name = "\improper P37 magazine (9mm frangible)" - desc = "A gun magazine. Loaded with plastic composite rounds which fragment upon impact to minimize collateral damage." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "11mm" //topkek - ammo_type = /obj/item/ammo_casing/c9mm/frangible - caliber = "9mm" - max_ammo = 11 - multiple_sprites = 1 - -/obj/item/ammo_box/magazine/m9mm/p37/fmj - name = "\improper P37 magazine (9mm)" - ammo_type = /obj/item/ammo_casing/c9mm - desc = "A gun magazine. Loaded with conventional full metal jacket rounds." - -/obj/item/ammo_box/magazine/m9mm/p37/rubber - name = "\improper P37 magazine (9mm Non-Lethal Rubbershot)" - ammo_type = /obj/item/ammo_casing/c9mm/rubber - desc = "A gun magazine. Loaded with less-than-lethal rubber bullets." - -/obj/item/ammo_box/c9mm/frangible - name = "ammo box (9mm frangible)" - ammo_type = /obj/item/ammo_casing/c9mm/frangible - -/obj/item/ammo_box/c9mm/rubber - name = "ammo box (9mm non-lethal rubbershot)" - ammo_type = /obj/item/ammo_casing/c9mm/rubber - -/datum/design/c9mmfrag - name = "Box of 9mm Frangible Bullets" - id = "9mm_frag" - build_type = AUTOLATHE - materials = list(MAT_METAL = 25000) - build_path = /obj/item/ammo_box/c9mm/frangible - category = list("hacked", "Security") - -/datum/design/c9mmrubber - name = "Box of 9mm Rubber Bullets" - id = "9mm_rubber" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/ammo_box/c9mm/rubber - category = list("initial", "Security") - - -///Security Variant/// - -/obj/item/gun/ballistic/automatic/pistol/p37/sec - name = "\improper CX Mk.37S" - desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. Uses 9mm bullets loaded into proprietary magazines." - spawnwithmagazine = FALSE - pin = /obj/item/device/firing_pin/implant/mindshield - actions_types = list() //so you can't recolor it - - frame_color = "#808080" //RGB - receiver_color = "#808080" - body_color = "#282828" - barrel_color = "#808080" - tip_color = "#808080" - arm_color = "#800000" - grip_color = "#FFFF00" //Does not actually colour the grip, just the lights surrounding it - energy_color = "#FFFF00" - -///Foam Variant because WE NEED MEMES/// - -/obj/item/gun/ballistic/automatic/pistol/p37/foam - name = "\improper Foam Force Mk.37F" - desc = "A licensed foam-firing reproduction of a handgun with a toggle-locking mechanism manufactured by CX Armories. This model is coated with a special polychromic material. Uses standard foam pistol magazines." - icon_state = "p37_foam" - pin = /obj/item/device/firing_pin - spawnwithmagazine = TRUE - obj_flags = 0 - casing_ejector = FALSE - mag_type = /obj/item/ammo_box/magazine/toy/pistol - can_suppress = FALSE - actions_types = list(/datum/action/item_action/pick_color) - -/*///////////////////////////////////////////////////////////////////////////////////////////// - The Recolourable Energy Gun -*////////////////////////////////////////////////////////////////////////////////////////////// - -obj/item/gun/energy/e_gun/cx - name = "\improper CX Model D Energy Gun" - desc = "An overpriced hybrid energy gun with two settings: disable, and kill. Manufactured by CX Armories. Has a polychromic coating." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "cxe" - lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi' - righthand_file = 'icons/mob/citadel/guns_righthand.dmi' - ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) - flight_x_offset = 15 - flight_y_offset = 10 - var/body_color = "#252528" - -obj/item/gun/energy/e_gun/cx/update_icon() - ..() - var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "cxegun_body") - if(body_color) - body_overlay.color = body_color - add_overlay(body_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -obj/item/gun/energy/e_gun/cx/AltClick(mob/living/user) - if(!in_range(src, user)) //Basic checks to prevent abuse - return - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(alert("Are you sure you want to repaint your gun?", "Confirm Repaint", "Yes", "No") == "Yes") - var/body_color_input = input(usr,"","Choose Body Color",body_color) as color|null - if(body_color_input) - body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) - update_icon() - -obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(isinhands) - var/mutable_appearance/body_inhand = mutable_appearance(icon_file, "cxe_body") - body_inhand.color = body_color - . += body_inhand - -/obj/item/ammo_box/magazine/toy/pistol //forcing this might be a bad idea, but it'll fix the foam gun infinite material exploit - materials = list(MAT_METAL = 200) - -/*///////////////////////////////////////////////////////////// -//////////////////////// Zero's Meme ////////////////////////// -*////////////////////////////////////////////////////////////// -/obj/item/ammo_box/magazine/toy/AM4B - name = "foam force AM4-B magazine" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "AM4MAG-60" - max_ammo = 60 - multiple_sprites = 0 - materials = list(MAT_METAL = 200) - -/obj/item/gun/ballistic/automatic/AM4B - name = "AM4-B" - desc = "A Relic from a bygone age. Nobody quite knows why it's here. Has a polychromic coating." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "AM4" - item_state = "arg" - mag_type = /obj/item/ammo_box/magazine/toy/AM4B - can_suppress = 0 - item_flags = NEEDS_PERMIT - casing_ejector = 0 - spread = 30 //Assault Rifleeeeeee - w_class = WEIGHT_CLASS_NORMAL - burst_size = 4 //Shh. - fire_delay = 1 - var/body_color = "#3333aa" - -/obj/item/gun/ballistic/automatic/AM4B/update_icon() - ..() - var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "AM4-Body") - if(body_color) - body_overlay.color = body_color - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - add_overlay(body_overlay) - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() -/obj/item/gun/ballistic/automatic/AM4B/AltClick(mob/living/user) - if(!in_range(src, user)) //Basic checks to prevent abuse - return - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(alert("Are you sure you want to recolor your gun?", "Confirm Repaint", "Yes", "No") == "Yes") - var/body_color_input = input(usr,"","Choose Shroud Color",body_color) as color|null - if(body_color_input) - body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) - update_icon() -/obj/item/gun/ballistic/automatic/AM4B/examine(mob/user) - ..() - to_chat(user, "Alt-click to recolor it.") - -/obj/item/ammo_box/magazine/toy/AM4C - name = "foam force AM4-C magazine" - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "AM4MAG-32" - max_ammo = 32 - multiple_sprites = 0 - materials = list(MAT_METAL = 200) - -/obj/item/gun/ballistic/automatic/AM4C - name = "AM4-C" - desc = "A Relic from a bygone age. This one seems newer, yet less effective." - icon = 'icons/obj/guns/cit_guns.dmi' - icon_state = "AM4C" - item_state = "arg" - mag_type = /obj/item/ammo_box/magazine/toy/AM4C - can_suppress = 0 - item_flags = NEEDS_PERMIT - casing_ejector = 0 - spread = 45 //Assault Rifleeeeeee - w_class = WEIGHT_CLASS_NORMAL - burst_size = 4 //Shh. - fire_delay = 1 diff --git a/code/citadel/cit_uniforms.dm b/code/citadel/cit_uniforms.dm deleted file mode 100644 index fc7e03a676..0000000000 --- a/code/citadel/cit_uniforms.dm +++ /dev/null @@ -1,40 +0,0 @@ -/obj/item/clothing/under/bb_sweater - name = "cream sweater" - desc = "Why trade style for comfort? Now you can go commando down south and still be cozy up north." - icon_state = "bb_turtle" - item_state = "w_suit" - item_color = "bb_turtle" - body_parts_covered = CHEST|ARMS - can_adjust = 1 - icon = 'icons/obj/clothing/turtlenecks.dmi' - icon_override = 'icons/mob/citadel/uniforms.dmi' - -/obj/item/clothing/under/bb_sweater/black - name = "black sweater" - icon_state = "bb_turtleblk" - item_state = "bl_suit" - item_color = "bb_turtleblk" - -/obj/item/clothing/under/bb_sweater/purple - name = "purple sweater" - icon_state = "bb_turtlepur" - item_state = "p_suit" - item_color = "bb_turtlepur" - -/obj/item/clothing/under/bb_sweater/green - name = "green sweater" - icon_state = "bb_turtlegrn" - item_state = "g_suit" - item_color = "bb_turtlegrn" - -/obj/item/clothing/under/bb_sweater/red - name = "red sweater" - icon_state = "bb_turtlered" - item_state = "r_suit" - item_color = "bb_turtlered" - -/obj/item/clothing/under/bb_sweater/blue - name = "blue sweater" - icon_state = "bb_turtleblu" - item_state = "b_suit" - item_color = "bb_turtleblu" diff --git a/code/citadel/cit_vendors.dm b/code/citadel/cit_vendors.dm deleted file mode 100644 index c8ae48c251..0000000000 --- a/code/citadel/cit_vendors.dm +++ /dev/null @@ -1,102 +0,0 @@ -#define STANDARD_CHARGE 1 -#define CONTRABAND_CHARGE 2 -#define COIN_CHARGE 3 - -/obj/machinery/vending/kink - name = "KinkMate" - desc = "A vending machine for all your unmentionable desires." - icon = 'icons/obj/citvending.dmi' - icon_state = "kink" - product_slogans = "Kinky!;Sexy!;Check me out, big boy!" - vend_reply = "Have fun, you shameless pervert!" - products = list( - /obj/item/clothing/under/maid = 5, - /obj/item/clothing/under/stripper_pink = 5, - /obj/item/clothing/under/stripper_green = 5, - /obj/item/dildo/custom = 5 - ) - contraband = list(/obj/item/restraints/handcuffs/fake/kinky = 5, - /obj/item/clothing/neck/petcollar = 5, - /obj/item/clothing/under/mankini = 1, - /obj/item/dildo/flared/huge = 1 - ) - premium = list(/obj/item/device/electropack/shockcollar = 1) - refill_canister = /obj/item/vending_refill/kink -/* -/obj/machinery/vending/nazivend - name = "Nazivend" - desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\"" - icon = 'icons/obj/citvending.dmi' - icon_state = "nazi" - vend_reply = "SIEG HEIL!" - product_slogans = "Das Vierte Reich wird zuruckkehren!;ENTFERNEN JUDEN!;Billiger als die Juden jemals geben!;Rader auf dem adminbus geht rund und rund.;Warten Sie, warum wir wieder hassen Juden?- *BZZT*" - products = list( - /obj/item/clothing/head/stalhelm = 20, - /obj/item/clothing/head/panzer = 20, - /obj/item/clothing/suit/soldiercoat = 20, - // /obj/item/clothing/under/soldieruniform = 20, - /obj/item/clothing/shoes/jackboots = 20 - ) - contraband = list( - /obj/item/clothing/head/naziofficer = 10, - // /obj/item/clothing/suit/officercoat = 10, - // /obj/item/clothing/under/officeruniform = 10, - /obj/item/clothing/suit/space/hardsuit/nazi = 3, - /obj/item/gun/energy/plasma/MP40k = 4 - ) - premium = list() - - refill_canister = /obj/item/vending_refill/nazi -*/ -/obj/machinery/vending/sovietvend - name = "KomradeVendtink" - desc = "Rodina-mat' zovyot!" - icon = 'icons/obj/citvending.dmi' - icon_state = "soviet" - vend_reply = "The fascist and capitalist svin'ya shall fall, komrade!" - product_slogans = "Quality worth waiting in line for!; Get Hammer and Sickled!; Sosvietsky soyuz above all!; With capitalist pigsky, you would have paid a fortunetink! ; Craftink in Motherland herself!" - products = list( - /obj/item/clothing/under/soviet = 20, - /obj/item/clothing/head/ushanka = 20, - /obj/item/clothing/shoes/jackboots = 20, - /obj/item/clothing/head/squatter_hat = 20, - /obj/item/clothing/under/squatter_outfit = 20, - /obj/item/clothing/under/russobluecamooutfit = 20, - /obj/item/clothing/head/russobluecamohat = 20 - ) - contraband = list( - /obj/item/clothing/under/syndicate/tacticool = 4, - /obj/item/clothing/mask/balaclava = 4, - /obj/item/clothing/suit/russofurcoat = 4, - /obj/item/clothing/head/russofurhat = 4, - /obj/item/clothing/suit/space/hardsuit/soviet = 3, - /obj/item/gun/energy/laser/LaserAK = 4 - ) - premium = list() - - refill_canister = /obj/item/vending_refill/soviet - - -#undef STANDARD_CHARGE -#undef CONTRABAND_CHARGE -#undef COIN_CHARGE - - -/obj/item/vending_refill/kink - machine_name = "KinkMate" - icon = 'modular_citadel/icons/vending_restock.dmi' - icon_state = "refill_kink" - charges = list(8, 5, 0)// of 20 standard, 12 contraband, 0 premium - init_charges = list(8, 5, 0) - -/obj/item/vending_refill/nazi - machine_name = "nazivend" - icon_state = "refill_nazi" - charges = list(33, 13, 0) - init_charges = list(33, 13, 0) - -/obj/item/vending_refill/soviet - machine_name = "sovietvend" - icon_state = "refill_soviet" - charges = list(47, 7, 0) - init_charges = list(47, 7, 0) diff --git a/code/citadel/discordbot.dm b/code/citadel/discordbot.dm deleted file mode 100644 index 41c0f21b49..0000000000 --- a/code/citadel/discordbot.dm +++ /dev/null @@ -1,13 +0,0 @@ -/proc/send2maindiscord(var/msg) - send2discord(msg, FALSE) - -/proc/send2admindiscord(var/msg, var/ping = FALSE) - send2discord(msg, TRUE, ping) - -/proc/send2discord(var/msg, var/admin = FALSE, var/ping = FALSE) -// if (!config.discord_url || !config.discord_password) -// return - -// var/url = "[config.discord_url]?pass=[url_encode(config.discord_password)]&admin=[admin ? "true" : "false"]&content=[url_encode(msg)]&ping=[ping ? "true" : "false"]" -// world.Export(url) - return \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm deleted file mode 100644 index 1e4a574e13..0000000000 --- a/code/controllers/configuration.dm +++ /dev/null @@ -1,287 +0,0 @@ -GLOBAL_VAR_INIT(config_dir, "config/") -GLOBAL_PROTECT(config_dir) - -/datum/controller/configuration - name = "Configuration" - - var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it - var/list/entries - var/list/entries_by_type - - var/list/maplist - var/datum/map_config/defaultmap - - var/list/modes // allowed modes - var/list/gamemode_cache - var/list/votable_modes // votable modes - var/list/mode_names - var/list/mode_reports - var/list/mode_false_report_weight - -/datum/controller/configuration/New() - config = src - var/list/config_files = InitEntries() - LoadModes() - for(var/I in config_files) - LoadEntries(I) - if(Get(/datum/config_entry/flag/maprotation)) - loadmaplist(CONFIG_MAPS_FILE) - -/datum/controller/configuration/Destroy() - entries_by_type.Cut() - QDEL_LIST_ASSOC_VAL(entries) - QDEL_LIST_ASSOC_VAL(maplist) - QDEL_NULL(defaultmap) - - config = null - - return ..() - -/datum/controller/configuration/proc/InitEntries() - var/list/_entries = list() - entries = _entries - var/list/_entries_by_type = list() - entries_by_type = _entries_by_type - - . = list() - - for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case - var/datum/config_entry/E = I - if(initial(E.abstract_type) == I) - continue - E = new I - _entries_by_type[I] = E - var/esname = E.name - var/datum/config_entry/test = _entries[esname] - if(test) - log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") - qdel(E) - continue - _entries[esname] = E - .[E.resident_file] = TRUE - -/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) - entries -= CE.name - entries_by_type -= CE.type - -/datum/controller/configuration/proc/LoadEntries(filename) - log_config("Loading config file [filename]...") - var/list/lines = world.file2list("[GLOB.config_dir][filename]") - var/list/_entries = entries - for(var/L in lines) - if(!L) - continue - - if(copytext(L, 1, 2) == "#") - continue - - var/pos = findtext(L, " ") - var/entry = null - var/value = null - - if(pos) - entry = lowertext(copytext(L, 1, pos)) - value = copytext(L, pos + 1) - else - entry = lowertext(L) - - if(!entry) - continue - - var/datum/config_entry/E = _entries[entry] - if(!E) - log_config("Unknown setting in configuration: '[entry]'") - continue - - if(filename != E.resident_file) - log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") - continue - - var/validated = E.ValidateAndSet(value) - if(!validated) - log_config("Failed to validate setting \"[value]\" for [entry]") - else if(E.modified && !E.dupes_allowed) - log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") - - if(validated) - E.modified = TRUE - -/datum/controller/configuration/can_vv_get(var_name) - return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() - -/datum/controller/configuration/vv_edit_var(var_name, var_value) - return !(var_name in list("entries_by_type", "entries")) && ..() - -/datum/controller/configuration/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Edit", src) - stat("[name]:", statclick) - -/datum/controller/configuration/proc/Get(entry_type) - if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]") - log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") - return - var/datum/config_entry/E = entry_type - var/entry_is_abstract = initial(E.abstract_type) == entry_type - if(entry_is_abstract) - CRASH("Tried to retrieve an abstract config_entry: [entry_type]") - E = entries_by_type[entry_type] - if(!E) - CRASH("Missing config entry for [entry_type]!") - return E.value - -/datum/controller/configuration/proc/Set(entry_type, new_val) - if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]") - log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") - return - var/datum/config_entry/E = entry_type - var/entry_is_abstract = initial(E.abstract_type) == entry_type - if(entry_is_abstract) - CRASH("Tried to retrieve an abstract config_entry: [entry_type]") - E = entries_by_type[entry_type] - if(!E) - CRASH("Missing config entry for [entry_type]!") - return E.ValidateAndSet(new_val) - -/datum/controller/configuration/proc/LoadModes() - gamemode_cache = typecacheof(/datum/game_mode, TRUE) - modes = list() - mode_names = list() - mode_reports = list() - mode_false_report_weight = list() - votable_modes = list() - var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) - for(var/T in gamemode_cache) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - var/datum/game_mode/M = new T() - - if(M.config_tag) - if(!(M.config_tag in modes)) // ensure each mode is added only once - modes += M.config_tag - mode_names[M.config_tag] = M.name - probabilities[M.config_tag] = M.probability - mode_reports[M.config_tag] = M.generate_report() - mode_false_report_weight[M.config_tag] = M.false_report_weight - if(M.votable) - votable_modes += M.config_tag - qdel(M) - votable_modes += "secret" - -/datum/controller/configuration/proc/loadmaplist(filename) - filename = "[GLOB.config_dir][filename]" - var/list/Lines = world.file2list(filename) - - var/datum/map_config/currentmap = null - for(var/t in Lines) - if(!t) - continue - - t = trim(t) - if(length(t) == 0) - continue - else if(copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/command = null - var/data = null - - if(pos) - command = lowertext(copytext(t, 1, pos)) - data = copytext(t, pos + 1) - else - command = lowertext(t) - - if(!command) - continue - - if (!currentmap && command != "map") - continue - - switch (command) - if ("map") - currentmap = new ("_maps/[data].json") - if(currentmap.defaulted) - log_config("Failed to load map config for [data]!") - if ("minplayers","minplayer") - currentmap.config_min_users = text2num(data) - if ("maxplayers","maxplayer") - currentmap.config_max_users = text2num(data) - if ("weight","voteweight") - currentmap.voteweight = text2num(data) - if ("default","defaultmap") - defaultmap = currentmap - if ("endmap") - LAZYINITLIST(maplist) - maplist[currentmap.map_name] = currentmap - currentmap = null - if ("disabled") - currentmap = null - else - WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'") - - -/datum/controller/configuration/proc/pick_mode(mode_name) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - // ^ This guy didn't try hard enough - for(var/T in gamemode_cache) - var/datum/game_mode/M = T - var/ct = initial(M.config_tag) - if(ct && ct == mode_name) - return new T - return new /datum/game_mode/extended() - -/datum/controller/configuration/proc/get_runnable_modes() - var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) - var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) - var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) - var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) - for(var/T in gamemode_cache) - var/datum/game_mode/M = new T() - if(!(M.config_tag in modes)) - qdel(M) - continue - if(probabilities[M.config_tag]<=0) - qdel(M) - continue - if(min_pop[M.config_tag]) - M.required_players = min_pop[M.config_tag] - if(max_pop[M.config_tag]) - M.maximum_players = max_pop[M.config_tag] - if(M.can_start()) - var/final_weight = probabilities[M.config_tag] - if(SSpersistence.saved_modes.len == 3 && repeated_mode_adjust.len == 3) - var/recent_round = min(SSpersistence.saved_modes.Find(M.config_tag),3) - var/adjustment = 0 - while(recent_round) - adjustment += repeated_mode_adjust[recent_round] - recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0) - final_weight *= ((100-adjustment)/100) - runnable_modes[M] = final_weight - return runnable_modes - -/datum/controller/configuration/proc/get_runnable_midround_modes(crew) - var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) - var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) - var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) - for(var/T in (gamemode_cache - SSticker.mode.type)) - var/datum/game_mode/M = new T() - if(!(M.config_tag in modes)) - qdel(M) - continue - if(probabilities[M.config_tag]<=0) - qdel(M) - continue - if(min_pop[M.config_tag]) - M.required_players = min_pop[M.config_tag] - if(max_pop[M.config_tag]) - M.maximum_players = max_pop[M.config_tag] - if(M.required_players <= crew) - if(M.maximum_players >= 0 && M.maximum_players < crew) - continue - runnable_modes[M] = probabilities[M.config_tag] - return runnable_modes diff --git a/code/controllers/hooks-defs.dm b/code/controllers/hooks-defs.dm deleted file mode 100644 index 42212e266c..0000000000 --- a/code/controllers/hooks-defs.dm +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Startup hook. - * Called in world.dm when the server starts. - */ -/hook/startup - -/** - * Roundstart hook. - * Called in gameticker.dm when a round starts. - */ -/hook/roundstart - -/** - * Roundend hook. - * Called in gameticker.dm when a round ends. - */ -/hook/roundend - -/** - * Death hook. - * Called in death.dm when someone dies. - * Parameters: var/mob/living/carbon/human, var/gibbed - */ -/hook/death - -/** - * Cloning hook. - * Called in cloning.dm when someone is brought back by the wonders of modern science. - * Parameters: var/mob/living/carbon/human - */ -/hook/clone - -/** - * Debrained hook. - * Called in brain_item.dm when someone gets debrained. - * Parameters: var/obj/item/organ/brain - */ -/hook/debrain - -/** - * Borged hook. - * Called in robot_parts.dm when someone gets turned into a cyborg. - * Parameters: var/mob/living/silicon/robot - */ -/hook/borgify - -/** - * Podman hook. - * Called in podmen.dm when someone is brought back as a Diona. - * Parameters: var/mob/living/carbon/alien/diona - */ -/hook/harvest_podman - -/** - * Payroll revoked hook. - * Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/revoke_payroll - -/** - * Account suspension hook. - * Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/change_account_status - -/** - * Employee reassignment hook. - * Called in card.dm when someone's card is reassigned at the HoP's desk. - * Parameters: var/obj/item/card/id - */ -/hook/reassign_employee - -/** - * Employee terminated hook. - * Called in card.dm when someone's card is terminated at the HoP's desk. - * Parameters: var/obj/item/card/id - */ -/hook/terminate_employee - -/** - * Crate sold hook. - * Called in supplyshuttle.dm when a crate is sold on the shuttle. - * Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle - */ -/hook/sell_crate diff --git a/code/controllers/subsystem/explosion.dm b/code/controllers/subsystem/explosion.dm deleted file mode 100644 index 1e3a6f8a6e..0000000000 --- a/code/controllers/subsystem/explosion.dm +++ /dev/null @@ -1,510 +0,0 @@ -SUBSYSTEM_DEF(explosion) - priority = 99 - wait = 1 - flags = SS_TICKER|SS_NO_INIT - - var/list/explosions - - var/rebuild_tick_split_count = FALSE - var/tick_portions_required = 0 - - var/list/logs - - var/list/zlevels_that_ignore_bombcap - var/list/doppler_arrays - - //legacy caps, set by config - var/devastation_cap = 3 - var/heavy_cap = 7 - var/light_cap = 14 - var/flash_cap = 14 - var/flame_cap = 14 - var/dyn_ex_scale = 0.5 - - var/id_counter = 0 - -/datum/controller/subsystem/explosion/PreInit() - doppler_arrays = list() - logs = list() - explosions = list() - zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]") - -/datum/controller/subsystem/explosion/Shutdown() - QDEL_LIST(explosions) - QDEL_LIST(logs) - zlevels_that_ignore_bombcap.Cut() - -/datum/controller/subsystem/explosion/Recover() - explosions = SSexplosion.explosions - logs = SSexplosion.logs - id_counter = SSexplosion.id_counter - rebuild_tick_split_count = TRUE - zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap - doppler_arrays = SSexplosion.doppler_arrays - - devastation_cap = SSexplosion.devastation_cap - heavy_cap = SSexplosion.heavy_cap - light_cap = SSexplosion.light_cap - flash_cap = SSexplosion.flash_cap - flame_cap = SSexplosion.flame_cap - dyn_ex_scale = SSexplosion.dyn_ex_scale - -/datum/controller/subsystem/explosion/fire() - var/list/cached_explosions = explosions - var/num_explosions = cached_explosions.len - if(!num_explosions) - return - - //figure exactly how many tick splits are required - var/num_splits - if(rebuild_tick_split_count) - var/reactionary = config.reactionary_explosions - num_splits = num_explosions - for(var/I in cached_explosions) - var/datum/explosion/E = I - if(!E.turfs_processed) - ++num_splits - if(reactionary && !E.densities_processed) - ++num_splits - tick_portions_required = num_splits - else - num_splits = tick_portions_required - - MC_SPLIT_TICK_INIT(num_splits) - - for(var/I in cached_explosions) - var/datum/explosion/E = I - - var/etp = E.turfs_processed - if(!etp) - if(GatherTurfs(E)) - --tick_portions_required - etp = TRUE - MC_SPLIT_TICK - - var/edp = E.densities_processed - if(!edp) - if(DensityCalculate(E, etp)) - --tick_portions_required - edp = TRUE - MC_SPLIT_TICK - - if(ProcessExplosion(E, edp)) //splits the tick - --tick_portions_required - explosions -= E - logs += E - NotifyDopplers(E) - MC_SPLIT_TICK - -/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E) - for(var/array in doppler_arrays) - var/obj/machinery/doppler_array/A = array - A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range) - -/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE) - epicenter = get_turf(epicenter) - if(!epicenter) - return - - if(adminlog) - message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") - log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") - - var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap) - - if(heavy_impact_range > 1) - var/datum/effect_system/explosion/Eff - if(smoke) - Eff = new /datum/effect_system/explosion/smoke - else - Eff = new - Eff.set_up(epicenter) - Eff.start() - - //flash mobs - if(flash_range) - for(var/mob/living/L in viewers(flash_range, epicenter)) - L.flash_act() - - if(!silent) - ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent) - - //add to SS - if(E.extent) - tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0) - explosions += E - else - logs += E //Already done processing - -/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE) - if(!power) - return - var/range = round((2 * power) ** dyn_ex_scale) - Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke) - -// Using default dyn_ex scale: -// 100 explosion power is a (5, 10, 20) explosion. -// 75 explosion power is a (4, 8, 17) explosion. -// 50 explosion power is a (3, 7, 14) explosion. -// 25 explosion power is a (2, 5, 10) explosion. -// 10 explosion power is a (1, 3, 6) explosion. -// 5 explosion power is a (0, 1, 3) explosion. -// 1 explosion power is a (0, 0, 1) explosion. - -/datum/explosion - var/explosion_id - var/turf/epicenter - - var/started_at - var/finished_at - var/tick_started - var/tick_finished - - var/turfs_processed = FALSE - var/densities_processed = FALSE - - var/orig_dev_range - var/orig_heavy_range - var/orig_light_range - var/orig_flash_range - var/orig_flame_range - - var/devastation - var/heavy - var/light - var/extent - - var/flash - var/flame - - var/gather_dist = 0 - - var/list/gathered_turfs - var/list/calculated_turfs - - var/list/unsafe_turfs - -/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap) - explosion_id = id - epicenter = epi - - densities_processed = !config.reactionary_explosions - - orig_dev_range = devastation_range - orig_heavy_range = heavy_impact_range - orig_light_range = light_impact_range - orig_flash_range = flash_range - orig_flame_range = flame_range - - if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap)) - //Clamp all values - devastation_range = min(SSexplosion.devastation_cap, devastation_range) - heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range) - light_impact_range = min(SSexplosion.light_cap, light_impact_range) - flash_range = min(SSexplosion.flash_cap, flash_range) - flame_range = min(SSexplosion.flame_cap, flame_range) - - //store this - devastation = devastation_range - heavy = heavy_impact_range - light = light_impact_range - - extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) - - flash = flash_range - flame = flame_range - - started_at = REALTIMEOFDAY - tick_started = world.time - - gathered_turfs = list() - calculated_turfs = list() - unsafe_turfs = list() - -// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. -// Stereo users will also hear the direction of the explosion! - -// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions. -// 3/7/14 will calculate to 80 + 35 -/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent) - var/far_dist = 0 - far_dist += heavy_impact_range * 5 - far_dist += devastation_range * 20 - - var/z0 = epicenter.z - - var/frequency = get_rand_frequency() - var/ex_sound = get_sfx("explosion") - for(var/mob/M in GLOB.player_list) - // Double check for client - var/turf/M_turf = get_turf(M) - if(M_turf && M_turf.z == z0) - var/dist = get_dist(M_turf, epicenter) - // If inside the blast radius + world.view - 2 - if(dist <= round(extent + world.view - 2, 1)) - M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5) - // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. - else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist - far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion - M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) - -/datum/explosion/Destroy() - SSexplosion.explosions -= src - SSexplosion.logs -= src - LAZYCLEARLIST(gathered_turfs) - LAZYCLEARLIST(calculated_turfs) - LAZYCLEARLIST(unsafe_turfs) - return ..() - -/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E) - var/turf/epicenter = E.epicenter - - var/x0 = epicenter.x - var/y0 = epicenter.y - var/z0 = epicenter.z - - var/c_dist = E.gather_dist - var/dist = E.extent - - var/list/L = E.gathered_turfs - - if(!c_dist) - L += epicenter - ++c_dist - - while( c_dist <= dist ) - var/y = y0 + c_dist - var/x = x0 - c_dist + 1 - for(x in x to x0 + c_dist) - var/turf/T = locate(x, y, z0) - if(T) - L += T - - y = y0 + c_dist - 1 - x = x0 + c_dist - for(y in y0 - c_dist to y) - var/turf/T = locate(x, y, z0) - if(T) - L += T - - y = y0 - c_dist - x = x0 + c_dist - 1 - for(x in x0 - c_dist to x) - var/turf/T = locate(x, y, z0) - if(T) - L += T - - y = y0 - c_dist + 1 - x = x0 - c_dist - for(y in y to y0 + c_dist) - var/turf/T = locate(x, y, z0) - if(T) - L += T - ++c_dist - - if(MC_TICK_CHECK) - break - - if(c_dist > dist) - E.turfs_processed = TRUE - return TRUE - else - E.gather_dist = c_dist - return FALSE - -/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs) - var/list/L = E.calculated_turfs - var/cut_to = 1 - for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area - var/turf/T = I - ++cut_to - - var/current_exp_block = T.density ? T.explosion_block : 0 - - for(var/obj/machinery/door/D in T) - if(D.density) - current_exp_block += D.explosion_block - - for(var/obj/structure/window/W in T) - if(W.reinf && W.fulltile) - current_exp_block += W.explosion_block - - for(var/obj/structure/blob/B in T) - current_exp_block += B.explosion_block - - L[T] = current_exp_block - - if(MC_TICK_CHECK) - E.gathered_turfs.Cut(1, cut_to) - return FALSE - - E.gathered_turfs.Cut() - return done_gathering_turfs - -/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs) - //cache shit for speed - var/id = E.explosion_id - - var/list/cached_unsafe = E.unsafe_turfs - var/list/cached_exp_block = E.calculated_turfs - var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs - - var/devastation_range = E.devastation - var/heavy_impact_range = E.heavy - var/light_impact_range = E.light - - var/flame_range = E.flame - var/throw_range_max = E.extent - - var/turf/epi = E.epicenter - - var/x0 = epi.x - var/y0 = epi.y - - var/cut_to = 1 - for(var/TI in affected_turfs) - var/turf/T = TI - ++cut_to - - var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0) - var/dist = init_dist - - if(cached_exp_block) - var/turf/Trajectory = T - while(Trajectory != epi) - Trajectory = get_step_towards(Trajectory, epi) - dist += cached_exp_block[Trajectory] - - var/flame_dist = dist < flame_range - var/throw_dist = dist - - if(dist < devastation_range) - dist = 1 - else if(dist < heavy_impact_range) - dist = 2 - else if(dist < light_impact_range) - dist = 3 - else - dist = 0 - - //------- EX_ACT AND TURF FIRES ------- - - if(flame_dist && prob(40) && !isspaceturf(T) && !T.density) - new /obj/effect/hotspot(T) //Mostly for ambience! - - if(dist > 0) - T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it - T.explosion_id = id - T.ex_act(dist) - cached_unsafe += T - - //--- THROW ITEMS AROUND --- - - var/throw_dir = get_dir(epi, T) - for(var/obj/item/I in T) - if(!I.anchored) - var/throw_range = rand(throw_dist, throw_range_max) - var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range) - I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything) - I.throw_at(throw_at, throw_range, 4) - - if(MC_TICK_CHECK) - var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps - if(cached_unsafe.len > circumference) //only do this every revolution - for(var/Unexplode in cached_unsafe) - var/turf/UnexplodeT = Unexplode - UnexplodeT.explosion_level = 0 - cached_unsafe.Cut() - done_calculating_turfs = FALSE - break - - affected_turfs.Cut(1, cut_to) - - if(!done_calculating_turfs) - return FALSE - - //unfuck the shit - for(var/Unexplode in cached_unsafe) - var/turf/UnexplodeT = Unexplode - UnexplodeT.explosion_level = 0 - cached_unsafe.Cut() - - E.finished_at = REALTIMEOFDAY - E.tick_finished = world.time - - return TRUE - -/client/proc/check_bomb_impacts() - set name = "Check Bomb Impact" - set category = "Debug" - - var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No") - var/turf/epicenter = get_turf(mob) - if(!epicenter) - return - - var/x0 = epicenter.x - var/y0 = epicenter.y - - var/dev = 0 - var/heavy = 0 - var/light = 0 - var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb") - var/choice = input("Bomb Size?") in choices - switch(choice) - if(null) - return 0 - if("Small Bomb") - dev = 1 - heavy = 2 - light = 3 - if("Medium Bomb") - dev = 2 - heavy = 3 - light = 4 - if("Big Bomb") - dev = 3 - heavy = 5 - light = 7 - if("Custom Bomb") - dev = input("Devestation range (Tiles):") as num - heavy = input("Heavy impact range (Tiles):") as num - light = input("Light impact range (Tiles):") as num - else - return - - var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE) - - while(!SSexplosion.GatherTurfs(E)) - stoplag() - var/list/turfs - if(newmode) - while(!SSexplosion.DensityCalculate(E, TRUE)) - stoplag() - turfs = E.calculated_turfs.Copy() - else - turfs = E.gathered_turfs.Copy() - - qdel(E) - - for(var/I in turfs) - var/turf/T = I - var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T] - - if(dist < dev) - T.color = "red" - T.maptext = "Dev" - else if (dist < heavy) - T.color = "yellow" - T.maptext = "Heavy" - else if (dist < light) - T.color = "blue" - T.maptext = "Light" - CHECK_TICK - - sleep(100) - for(var/I in turfs) - var/turf/T = I - T.color = null - T.maptext = null diff --git a/code/controllers/subsystem/ping.dm b/code/controllers/subsystem/ping.dm deleted file mode 100644 index a6b444c4e7..0000000000 --- a/code/controllers/subsystem/ping.dm +++ /dev/null @@ -1,42 +0,0 @@ -#define PING_BUFFER_TIME 25 - -SUBSYSTEM_DEF(ping) - name = "Ping" - wait = 6 - flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY - priority = 10 - var/list/currentrun - -/datum/controller/subsystem/ping/Initialize() - if (config.hub) - world.visibility = 1 - ..() - -/datum/controller/subsystem/ping/fire(resumed = FALSE) - if (!resumed) - src.currentrun = GLOB.clients.Copy() - - var/round_started = Master.round_started - var/list/currentrun = src.currentrun - while (length(currentrun)) - var/client/C = currentrun[currentrun.len] - currentrun.len-- - if (!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)) - if (MC_TICK_CHECK) - return - continue - - if(round_started && C.is_afk(INACTIVITY_KICK)) - if(!istype(C.mob, /mob/dead)) - log_access("AFK: [key_name(C)]") - to_chat(C, "You have been inactive for more than 10 minutes and have been disconnected.") - qdel(C) - - winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]") - - if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check - return - - currentrun = null - -#undef PING_BUFFER_TIME diff --git a/code/datums/antagonists/abductor.dm b/code/datums/antagonists/abductor.dm deleted file mode 100644 index fde8d0059b..0000000000 --- a/code/datums/antagonists/abductor.dm +++ /dev/null @@ -1,182 +0,0 @@ -#define ABDUCTOR_MAX_TEAMS 4 - -/datum/antagonist/abductor - name = "Abductor" - roundend_category = "abductors" - antagpanel_category = "Abductor" - job_rank = ROLE_ABDUCTOR - show_in_antagpanel = FALSE //should only show subtypes - var/datum/team/abductor_team/team - var/sub_role - var/outfit - var/landmark_type - var/greet_text - - -/datum/antagonist/abductor/agent - name = "Abductor Agent" - sub_role = "Agent" - outfit = /datum/outfit/abductor/agent - landmark_type = /obj/effect/landmark/abductor/agent - greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve." - show_in_antagpanel = TRUE - -/datum/antagonist/abductor/scientist - name = "Abductor Scientist" - sub_role = "Scientist" - outfit = /datum/outfit/abductor/scientist - landmark_type = /obj/effect/landmark/abductor/scientist - greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve." - show_in_antagpanel = TRUE - -/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team) - if(!new_team) - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - team = new_team - -/datum/antagonist/abductor/get_team() - return team - -/datum/antagonist/abductor/on_gain() - SSticker.mode.abductors += owner - owner.special_role = "[name] [sub_role]" - owner.assigned_role = "[name] [sub_role]" - owner.objectives += team.objectives - finalize_abductor() - return ..() - -/datum/antagonist/abductor/on_removal() - SSticker.mode.abductors -= owner - owner.objectives -= team.objectives - if(owner.current) - to_chat(owner.current,"You are no longer the [owner.special_role]!") - owner.special_role = null - return ..() - -/datum/antagonist/abductor/greet() - to_chat(owner.current, "You are the [owner.special_role]!") - to_chat(owner.current, "With the help of your teammate, kidnap and experiment on station crew members!") - to_chat(owner.current, "[greet_text]") - owner.announce_objectives() - -/datum/antagonist/abductor/proc/finalize_abductor() - //Equip - var/mob/living/carbon/human/H = owner.current - H.set_species(/datum/species/abductor) - H.real_name = "[team.name] [sub_role]" - H.equipOutfit(outfit) - - //Teleport to ship - for(var/obj/effect/landmark/abductor/LM in GLOB.landmarks_list) - if(istype(LM, landmark_type) && LM.team_number == team.team_number) - H.forceMove(LM.loc) - break - - SSticker.mode.update_abductor_icons_added(owner) - -/datum/antagonist/abductor/scientist/finalize_abductor() - ..() - var/mob/living/carbon/human/H = owner.current - var/datum/species/abductor/A = H.dna.species - A.scientist = TRUE - -/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin) - var/list/current_teams = list() - for(var/datum/team/abductor_team/T in get_all_teams(/datum/team/abductor_team)) - current_teams[T.name] = T - var/choice = input(admin,"Add to which team ?") as null|anything in (current_teams + "new team") - if (choice == "new team") - team = new - else if(choice in current_teams) - team = current_teams[choice] - else - return - new_owner.add_antag_datum(src) - log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!") - message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !") - -/datum/antagonist/abductor/get_admin_commands() - . = ..() - .["Equip"] = CALLBACK(src,.proc/admin_equip) - -/datum/antagonist/abductor/proc/admin_equip(mob/admin) - if(!ishuman(owner.current)) - to_chat(admin, "This only works on humans!") - return - var/mob/living/carbon/human/H = owner.current - var/gear = alert(admin,"Agent or Scientist Gear","Gear","Agent","Scientist") - if(gear) - if(gear=="Agent") - H.equipOutfit(/datum/outfit/abductor/agent) - else - H.equipOutfit(/datum/outfit/abductor/scientist) - -/datum/team/abductor_team - member_name = "abductor" - var/team_number - var/list/datum/mind/abductees = list() - var/static/team_count = 1 - -/datum/team/abductor_team/New() - ..() - team_number = team_count++ - name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names - add_objective(new/datum/objective/experiment) - -/datum/team/abductor_team/is_solo() - return FALSE - -/datum/team/abductor_team/proc/add_objective(datum/objective/O) - O.team = src - O.update_explanation_text() - objectives += O - -/datum/team/abductor_team/roundend_report() - var/list/result = list() - - var/won = TRUE - for(var/datum/objective/O in objectives) - if(!O.check_completion()) - won = FALSE - if(won) - result += "[name] team fulfilled its mission!" - else - result += "[name] team failed its mission." - - result += "The abductors of [name] were:" - for(var/datum/mind/abductor_mind in members) - result += printplayer(abductor_mind) - result += printobjectives(abductor_mind) - - return result.Join("
") - -/datum/antagonist/abductee - name = "Abductee" - roundend_category = "abductees" - antagpanel_category = "Abductee" - -/datum/antagonist/abductee/on_gain() - give_objective() - . = ..() - -/datum/antagonist/abductee/greet() - to_chat(owner, "Your mind snaps!") - to_chat(owner, "You can't remember how you got here...") - owner.announce_objectives() - -/datum/antagonist/abductee/proc/give_objective() - var/mob/living/carbon/human/H = owner.current - if(istype(H)) - H.gain_trauma_type(BRAIN_TRAUMA_MILD) - var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) - var/datum/objective/abductee/O = new objtype() - objectives += O - owner.objectives += objectives - -/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) - SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner) - -/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) - SSticker.mode.update_abductor_icons_removed(mob_override ? mob_override.mind : owner) \ No newline at end of file diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm deleted file mode 100644 index 5f12d02398..0000000000 --- a/code/datums/antagonists/antag_datum.dm +++ /dev/null @@ -1,246 +0,0 @@ -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 - - //Antag panel properties - var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind - var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED - -/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 = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current) - if(LAZYLEN(candidates)) - var/client/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() - 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 - - -//ADMIN TOOLS - -//Called when using admin tools to give antag status -/datum/antagonist/proc/admin_add(datum/mind/new_owner,mob/admin) - message_admins("[key_name_admin(admin)] made [new_owner.current] into [name].") - log_admin("[key_name(admin)] made [new_owner.current] into [name].") - new_owner.add_antag_datum(src) - -//Called when removing antagonist using admin tools -/datum/antagonist/proc/admin_remove(mob/user) - if(!user) - return - message_admins("[key_name_admin(user)] has removed [name] antagonist status from [owner.current].") - log_admin("[key_name(user)] has removed [name] antagonist status from [owner.current].") - on_removal() - -//gamemode/proc/is_mode_antag(antagonist/A) => TRUE/FALSE - -//Additional data to display in antagonist panel section -//nuke disk code, genome count, etc -/datum/antagonist/proc/antag_panel_data() - return "" - -/datum/antagonist/proc/enabled_in_preferences(datum/mind/M) - if(job_rank) - if(M.current && M.current.client && (job_rank in M.current.client.prefs.be_special)) - return TRUE - else - return FALSE - return TRUE - -// List if ["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution -/datum/antagonist/proc/get_admin_commands() - . = list() - -/datum/antagonist/Topic(href,href_list) - if(!check_rights(R_ADMIN)) - return - //Antag memory edit - if (href_list["memory_edit"]) - edit_memory(usr) - owner.traitor_panel() - return - - //Some commands might delete/modify this datum clearing or changing owner - var/datum/mind/persistent_owner = owner - - var/commands = get_admin_commands() - for(var/admin_command in commands) - if(href_list["command"] == admin_command) - var/datum/callback/C = commands[admin_command] - C.Invoke(usr) - persistent_owner.traitor_panel() - return - -/datum/antagonist/proc/edit_memory(mob/user) - var/new_memo = copytext(trim(input(user,"Write new memory", "Memory", antag_memory) as null|message),1,MAX_MESSAGE_LEN) - if (isnull(new_memo)) - return - antag_memory = new_memo - -//Should probably be on ticker or job ss ? -/proc/get_antagonists(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 - -//This datum will autofill the name with special_role -//Used as placeholder for minor antagonists, please create proper datums for these -/datum/antagonist/auto_custom - show_in_antagpanel = FALSE - antagpanel_category = "Other" - -/datum/antagonist/auto_custom/on_gain() - ..() - name = owner.special_role - //Add all objectives not already owned by other datums to this one. - var/list/already_registered_objectives = list() - for(var/datum/antagonist/A in owner.antag_datums) - if(A == src) - continue - else - already_registered_objectives |= A.objectives - objectives = owner.objectives - already_registered_objectives - -/datum/antagonist/auto_custom/antag_listing_name() - return ..() + "([name])" - -//This one is created by admin tools for custom objectives -/datum/antagonist/custom - antagpanel_category = "Custom" - -/datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin) - var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist") - if(custom_name) - name = custom_name - else - return - ..() - -/datum/antagonist/custom/antag_listing_name() - return ..() + "([name])" \ No newline at end of file diff --git a/code/datums/antagonists/blob.dm b/code/datums/antagonists/blob.dm deleted file mode 100644 index 964bc99311..0000000000 --- a/code/datums/antagonists/blob.dm +++ /dev/null @@ -1,67 +0,0 @@ -/datum/antagonist/blob - name = "Blob" - roundend_category = "blobs" - antagpanel_category = "Blob" - job_rank = ROLE_BLOB - - var/datum/action/innate/blobpop/pop_action - var/starting_points_human_blob = 60 - var/point_rate_human_blob = 2 - -/datum/antagonist/blob/roundend_report() - var/basic_report = ..() - //Display max blobpoints for blebs that lost - if(isovermind(owner.current)) //embarrasing if not - var/mob/camera/blob/overmind = owner.current - if(!overmind.victory_in_progress) //if it won this doesn't really matter - var/point_report = "
[owner.name] took over [overmind.max_count] tiles at the height of its growth." - return basic_report+point_report - return basic_report - -/datum/antagonist/blob/greet() - if(!isovermind(owner.current)) - to_chat(owner,"You feel bloated.") - -/datum/antagonist/blob/on_gain() - create_objectives() - . = ..() - -/datum/antagonist/blob/proc/create_objectives() - var/datum/objective/blob_takeover/main = new - main.owner = owner - objectives += main - owner.objectives |= objectives - -/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override) - if(!isovermind(owner.current)) - if(!pop_action) - pop_action = new - pop_action.Grant(owner.current) - -/datum/objective/blob_takeover - explanation_text = "Reach critical mass!" - -//Non-overminds get this on blob antag assignment -/datum/action/innate/blobpop - name = "Pop" - desc = "Unleash the blob" - icon_icon = 'icons/mob/blob.dmi' - button_icon_state = "blob" - -/datum/action/innate/blobpop/Activate() - var/mob/old_body = owner - var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob) - if(!blobtag) - Remove() - return - var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob) - owner.mind.transfer_to(B) - old_body.gib() - B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE) - -/datum/antagonist/blob/antag_listing_status() - . = ..() - if(owner && owner.current) - var/mob/camera/blob/B = owner.current - if(istype(B)) - . += "(Progress: [B.blobs_legit.len]/[B.blobwincount])" \ No newline at end of file diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm deleted file mode 100644 index d8371d3751..0000000000 --- a/code/datums/antagonists/brother.dm +++ /dev/null @@ -1,154 +0,0 @@ -/datum/antagonist/brother - name = "Brother" - antagpanel_category = "Brother" - job_rank = ROLE_BROTHER - var/special_role = ROLE_BROTHER - var/datum/team/brother_team/team - -/datum/antagonist/brother/create_team(datum/team/brother_team/new_team) - if(!new_team) - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - team = new_team - -/datum/antagonist/brother/get_team() - return team - -/datum/antagonist/brother/on_gain() - SSticker.mode.brothers += owner - objectives += team.objectives - owner.objectives += objectives - owner.special_role = special_role - finalize_brother() - return ..() - -/datum/antagonist/brother/on_removal() - SSticker.mode.brothers -= owner - owner.objectives -= objectives - if(owner.current) - to_chat(owner.current,"You are no longer the [special_role]!") - owner.special_role = null - return ..() - -/datum/antagonist/brother/proc/give_meeting_area() - if(!owner.current || !team || !team.meeting_area) - return - to_chat(owner.current, "Your designated meeting area: [team.meeting_area]") - antag_memory += "Meeting Area: [team.meeting_area]
" - -/datum/antagonist/brother/greet() - var/brother_text = "" - var/list/brothers = team.members - owner - for(var/i = 1 to brothers.len) - var/datum/mind/M = brothers[i] - brother_text += M.name - if(i == brothers.len - 1) - brother_text += " and " - else if(i != brothers.len) - brother_text += ", " - to_chat(owner.current, "You are the [owner.special_role] of [brother_text].") - to_chat(owner.current, "The Syndicate only accepts those that have proven themself. Prove yourself and prove your [team.member_name]s by completing your objectives together!") - owner.announce_objectives() - give_meeting_area() - -/datum/antagonist/brother/proc/finalize_brother() - SSticker.mode.update_brother_icons_added(owner) - -/datum/antagonist/brother/admin_add(datum/mind/new_owner,mob/admin) - //show list of possible brothers - var/list/candidates = list() - for(var/mob/living/L in GLOB.alive_mob_list) - if(!L.mind || L.mind == new_owner || !can_be_owned(L.mind)) - continue - candidates[L.mind.name] = L.mind - - var/choice = input(admin,"Choose the blood brother.", "Brother") as null|anything in candidates - if(!choice) - return - var/datum/mind/bro = candidates[choice] - var/datum/team/brother_team/T = new - T.add_member(new_owner) - T.add_member(bro) - T.pick_meeting_area() - T.forge_brother_objectives() - new_owner.add_antag_datum(/datum/antagonist/brother,T) - bro.add_antag_datum(/datum/antagonist/brother, T) - T.update_name() - message_admins("[key_name_admin(admin)] made [new_owner.current] and [bro.current] into blood brothers.") - log_admin("[key_name(admin)] made [new_owner.current] and [bro.current] into blood brothers.") - -/datum/team/brother_team - name = "brotherhood" - member_name = "blood brother" - var/meeting_area - var/static/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library") - -/datum/team/brother_team/is_solo() - return FALSE - -/datum/team/brother_team/proc/pick_meeting_area() - meeting_area = pick(meeting_areas) - meeting_areas -= meeting_area - -/datum/team/brother_team/proc/update_name() - var/list/last_names = list() - for(var/datum/mind/M in members) - var/list/split_name = splittext(M.name," ") - last_names += split_name[split_name.len] - - name = last_names.Join(" & ") - -/datum/team/brother_team/roundend_report() - var/list/parts = list() - - parts += "The blood brothers of [name] were:" - for(var/datum/mind/M in members) - parts += printplayer(M) - var/win = TRUE - var/objective_count = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - parts += "Objective #[objective_count]: [objective.explanation_text] Success!" - else - parts += "Objective #[objective_count]: [objective.explanation_text] Fail." - win = FALSE - objective_count++ - if(win) - parts += "The blood brothers were successful!" - else - parts += "The blood brothers have failed!" - - return "
[parts.Join("
")]
" - -/datum/team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) - O.team = src - if(needs_target) - O.find_target() - O.update_explanation_text() - objectives += O - -/datum/team/brother_team/proc/forge_brother_objectives() - objectives = list() - var/is_hijacker = prob(10) - for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) - forge_single_objective() - if(is_hijacker) - if(!locate(/datum/objective/hijack) in objectives) - add_objective(new/datum/objective/hijack) - else if(!locate(/datum/objective/escape) in objectives) - add_objective(new/datum/objective/escape) - -/datum/team/brother_team/proc/forge_single_objective() - if(prob(50)) - if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) - add_objective(new/datum/objective/destroy, TRUE) - else if(prob(30)) - add_objective(new/datum/objective/maroon, TRUE) - else - add_objective(new/datum/objective/assassinate, TRUE) - else - add_objective(new/datum/objective/steal, TRUE) - -/datum/team/brother_team/antag_listing_name() - return "[name] blood brothers" \ No newline at end of file diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm deleted file mode 100644 index 2bc4900ac5..0000000000 --- a/code/datums/antagonists/changeling.dm +++ /dev/null @@ -1,545 +0,0 @@ -#define LING_FAKEDEATH_TIME 400 //40 seconds -#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead. -#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob - -/datum/antagonist/changeling - name = "Changeling" - roundend_category = "changelings" - antagpanel_category = "Changeling" - job_rank = ROLE_CHANGELING - - var/you_are_greet = TRUE - var/give_objectives = TRUE - var/team_mode = FALSE //Should assign team objectives ? - - //Changeling Stuff - - var/list/stored_profiles = list() //list of datum/changelingprofile - var/datum/changelingprofile/first_prof = null - var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation. - var/absorbedcount = 0 - var/chem_charges = 20 - var/chem_storage = 75 - var/chem_recharge_rate = 1 - var/chem_recharge_slowdown = 0 - var/sting_range = 2 - var/changelingID = "Changeling" - var/geneticdamage = 0 - var/isabsorbing = 0 - var/islinking = 0 - var/geneticpoints = 10 - var/purchasedpowers = list() - var/mimicing = "" - var/canrespec = 0 - var/changeling_speak = 0 - var/datum/dna/chosen_dna - var/obj/effect/proc_holder/changeling/sting/chosen_sting - var/datum/cellular_emporium/cellular_emporium - var/datum/action/innate/cellular_emporium/emporium_action - - // wip stuff - var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE) - - -/datum/antagonist/changeling/Destroy() - QDEL_NULL(cellular_emporium) - QDEL_NULL(emporium_action) - . = ..() - -/datum/antagonist/changeling/proc/generate_name() - var/honorific - if(owner.current.gender == FEMALE) - honorific = "Ms." - else - honorific = "Mr." - if(GLOB.possible_changeling_IDs.len) - changelingID = pick(GLOB.possible_changeling_IDs) - GLOB.possible_changeling_IDs -= changelingID - changelingID = "[honorific] [changelingID]" - else - changelingID = "[honorific] [rand(1,999)]" - -/datum/antagonist/changeling/proc/create_actions() - cellular_emporium = new(src) - emporium_action = new(cellular_emporium) - -/datum/antagonist/changeling/on_gain() - generate_name() - create_actions() - reset_powers() - create_initial_profile() - if(give_objectives) - if(team_mode) - forge_team_objectives() - forge_objectives() - remove_clownmut() - . = ..() - -/datum/antagonist/changeling/on_removal() - //We'll be using this from now on - var/mob/living/carbon/C = owner.current - if(istype(C)) - var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN) - if(B && (B.decoy_override != initial(B.decoy_override))) - B.vital = TRUE - B.decoy_override = FALSE - remove_changeling_powers() - owner.objectives -= objectives - . = ..() - -/datum/antagonist/changeling/proc/remove_clownmut() - if (owner) - var/mob/living/carbon/human/H = owner.current - if(istype(H) && owner.assigned_role == "Clown") - to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.") - H.dna.remove_mutation(CLOWNMUT) - -/datum/antagonist/changeling/proc/reset_properties() - changeling_speak = 0 - chosen_sting = null - geneticpoints = initial(geneticpoints) - sting_range = initial(sting_range) - chem_storage = initial(chem_storage) - chem_recharge_rate = initial(chem_recharge_rate) - chem_charges = min(chem_charges, chem_storage) - chem_recharge_slowdown = initial(chem_recharge_slowdown) - mimicing = "" - -/datum/antagonist/changeling/proc/remove_changeling_powers() - if(ishuman(owner.current) || ismonkey(owner.current)) - reset_properties() - for(var/obj/effect/proc_holder/changeling/p in purchasedpowers) - if(p.always_keep) - continue - purchasedpowers -= p - p.on_refund(owner.current) - - //MOVE THIS - if(owner.current.hud_used) - owner.current.hud_used.lingstingdisplay.icon_state = null - owner.current.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT - -/datum/antagonist/changeling/proc/reset_powers() - if(purchasedpowers) - remove_changeling_powers() - //Repurchase free powers. - for(var/path in all_powers) - var/obj/effect/proc_holder/changeling/S = new path() - if(!S.dna_cost) - if(!has_sting(S)) - purchasedpowers += S - S.on_purchase(owner.current,TRUE) - -/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power) - for(var/obj/effect/proc_holder/changeling/P in purchasedpowers) - if(initial(power.name) == P.name) - return TRUE - return FALSE - - -/datum/antagonist/changeling/proc/purchase_power(sting_name) - var/obj/effect/proc_holder/changeling/thepower = null - - for(var/path in all_powers) - var/obj/effect/proc_holder/changeling/S = path - if(initial(S.name) == sting_name) - thepower = new path() - break - - if(!thepower) - to_chat(owner.current, "This is awkward. Changeling power purchase failed, please report this bug to a coder!") - return - - if(absorbedcount < thepower.req_dna) - to_chat(owner.current, "We lack the energy to evolve this ability!") - return - - if(has_sting(thepower)) - to_chat(owner.current, "We have already evolved this ability!") - return - - if(thepower.dna_cost < 0) - to_chat(owner.current, "We cannot evolve this ability.") - return - - if(geneticpoints < thepower.dna_cost) - to_chat(owner.current, "We have reached our capacity for abilities.") - return - - if(owner.current.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist. - to_chat(owner.current, "We lack the energy to evolve new abilities right now.") - return - - geneticpoints -= thepower.dna_cost - purchasedpowers += thepower - thepower.on_purchase(owner.current) - -/datum/antagonist/changeling/proc/readapt() - if(!ishuman(owner.current)) - to_chat(owner.current, "We can't remove our evolutions in this form!") - return - if(canrespec) - to_chat(owner.current, "We have removed our evolutions from this form, and are now ready to readapt.") - reset_powers() - canrespec = 0 - SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt") - return 1 - else - to_chat(owner.current, "You lack the power to readapt your evolutions!") - return 0 - -//Called in life() -/datum/antagonist/changeling/proc/regenerate() - var/mob/living/carbon/the_ling = owner.current - if(istype(the_ling)) - emporium_action.Grant(the_ling) - if(the_ling.stat == DEAD) - chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5)) - geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1) - else //not dead? no chem/geneticdamage caps. - chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage) - geneticdamage = max(0, geneticdamage-1) - - -/datum/antagonist/changeling/proc/get_dna(dna_owner) - for(var/datum/changelingprofile/prof in stored_profiles) - if(dna_owner == prof.name) - return prof - -/datum/antagonist/changeling/proc/has_dna(datum/dna/tDNA) - for(var/datum/changelingprofile/prof in stored_profiles) - if(tDNA.is_same_as(prof.dna)) - return TRUE - return FALSE - -/datum/antagonist/changeling/proc/can_absorb_dna(mob/living/carbon/human/target, var/verbose=1) - var/mob/living/carbon/user = owner.current - if(!istype(user)) - return - if(stored_profiles.len) - var/datum/changelingprofile/prof = stored_profiles[1] - if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it. - if(verbose) - to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") - return - if(!target) - return - if(NO_DNA_COPY in target.dna.species.species_traits) - if(verbose) - to_chat(user, "[target] is not compatible with our biology.") - return - if((target.has_disability(DISABILITY_NOCLONE)) || (target.has_disability(DISABILITY_NOCLONE))) - if(verbose) - to_chat(user, "DNA of [target] is ruined beyond usability!") - return - if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway! - if(verbose) - to_chat(user, "We could gain no benefit from absorbing a lesser creature.") - return - if(has_dna(target.dna)) - if(verbose) - to_chat(user, "We already have this DNA in storage!") - return - if(!target.has_dna()) - if(verbose) - to_chat(user, "[target] is not compatible with our biology.") - return - return 1 - - -/datum/antagonist/changeling/proc/create_profile(mob/living/carbon/human/H, protect = 0) - var/datum/changelingprofile/prof = new - - H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set. - var/datum/dna/new_dna = new H.dna.type - H.dna.copy_dna(new_dna) - prof.dna = new_dna - prof.name = H.real_name - prof.protected = protect - - prof.underwear = H.underwear - prof.undershirt = H.undershirt - prof.socks = H.socks - - var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store") - for(var/slot in slots) - if(slot in H.vars) - var/obj/item/I = H.vars[slot] - if(!I) - continue - prof.name_list[slot] = I.name - prof.appearance_list[slot] = I.appearance - prof.flags_cover_list[slot] = I.flags_cover - prof.item_color_list[slot] = I.item_color - prof.item_state_list[slot] = I.item_state - prof.exists_list[slot] = 1 - else - continue - - return prof - -/datum/antagonist/changeling/proc/add_profile(datum/changelingprofile/prof) - if(stored_profiles.len > dna_max) - if(!push_out_profile()) - return - - if(!first_prof) - first_prof = prof - - stored_profiles += prof - absorbedcount++ - -/datum/antagonist/changeling/proc/add_new_profile(mob/living/carbon/human/H, protect = 0) - var/datum/changelingprofile/prof = create_profile(H, protect) - add_profile(prof) - return prof - -/datum/antagonist/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0) - for(var/datum/changelingprofile/prof in stored_profiles) - if(H.real_name == prof.name) - if(prof.protected && !force) - continue - stored_profiles -= prof - qdel(prof) - -/datum/antagonist/changeling/proc/get_profile_to_remove() - for(var/datum/changelingprofile/prof in stored_profiles) - if(!prof.protected) - return prof - -/datum/antagonist/changeling/proc/push_out_profile() - var/datum/changelingprofile/removeprofile = get_profile_to_remove() - if(removeprofile) - stored_profiles -= removeprofile - return 1 - return 0 - - -/datum/antagonist/changeling/proc/create_initial_profile() - var/mob/living/carbon/C = owner.current //only carbons have dna now, so we have to typecaste - if(ishuman(C)) - add_new_profile(C) - -/datum/antagonist/changeling/apply_innate_effects() - //Brains optional. - var/mob/living/carbon/C = owner.current - if(istype(C)) - var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN) - if(B) - B.vital = FALSE - B.decoy_override = TRUE - update_changeling_icons_added() - return - -/datum/antagonist/changeling/remove_innate_effects() - update_changeling_icons_removed() - return - - -/datum/antagonist/changeling/greet() - if (you_are_greet) - to_chat(owner.current, "You are [changelingID], a changeling! You have absorbed and taken the form of a human.") - to_chat(owner.current, "Use say \":g message\" to communicate with your fellow changelings.") - to_chat(owner.current, "You must complete the following tasks:") - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE) - - owner.announce_objectives() - -/datum/antagonist/changeling/farewell() - to_chat(owner.current, "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!") - -/datum/antagonist/changeling/proc/forge_team_objectives() - if(GLOB.changeling_team_objective_type) - var/datum/objective/changeling_team_objective/team_objective = new GLOB.changeling_team_objective_type - team_objective.owner = owner - objectives += team_objective - return - -/datum/antagonist/changeling/proc/forge_objectives() - //OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft". - //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting - //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone - - var/escape_objective_possible = TRUE - - //if there's a team objective, check if it's compatible with escape objectives - for(var/datum/objective/changeling_team_objective/CTO in objectives) - if(!CTO.escape_objective_compatible) - escape_objective_possible = FALSE - break - - var/datum/objective/absorb/absorb_objective = new - absorb_objective.owner = owner - absorb_objective.gen_amount_goal(6, 8) - objectives += absorb_objective - - if(prob(60)) - if(prob(85)) - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - objectives += steal_objective - else - var/datum/objective/download/download_objective = new - download_objective.owner = owner - download_objective.gen_amount_goal() - objectives += download_objective - - var/list/active_ais = active_ais() - if(active_ais.len && prob(100/GLOB.joined_player_list.len)) - var/datum/objective/destroy/destroy_objective = new - destroy_objective.owner = owner - destroy_objective.find_target() - objectives += destroy_objective - else - if(prob(70)) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - if(team_mode) //No backstabbing while in a team - kill_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1) - else - kill_objective.find_target() - objectives += kill_objective - else - var/datum/objective/maroon/maroon_objective = new - maroon_objective.owner = owner - if(team_mode) - maroon_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1) - else - maroon_objective.find_target() - objectives += maroon_objective - - if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible) - var/datum/objective/escape/escape_with_identity/identity_theft = new - identity_theft.owner = owner - identity_theft.target = maroon_objective.target - identity_theft.update_explanation_text() - objectives += identity_theft - escape_objective_possible = FALSE - - if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible) - if(prob(50)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - objectives += escape_objective - else - var/datum/objective/escape/escape_with_identity/identity_theft = new - identity_theft.owner = owner - if(team_mode) - identity_theft.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1) - else - identity_theft.find_target() - objectives += identity_theft - escape_objective_possible = FALSE - - owner.objectives |= objectives - -/datum/antagonist/changeling/proc/update_changeling_icons_added() - var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING] - hud.join_hud(owner.current) - set_antag_hud(owner.current, "changling") - -/datum/antagonist/changeling/proc/update_changeling_icons_removed() - var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING] - hud.leave_hud(owner.current) - set_antag_hud(owner.current, null) - -/datum/antagonist/changeling/admin_add(datum/mind/new_owner,mob/admin) - . = ..() - to_chat(new_owner.current, "Our powers have awoken. A flash of memory returns to us...we are [changelingID], a changeling!") - -/datum/antagonist/changeling/get_admin_commands() - . = ..() - if(stored_profiles.len && (owner.current.real_name != first_prof.name)) - .["Transform to initial appearance."] = CALLBACK(src,.proc/admin_restore_appearance) - -/datum/antagonist/changeling/proc/admin_restore_appearance(mob/admin) - if(!stored_profiles.len || !iscarbon(owner.current)) - to_chat(admin, "Resetting DNA failed!") - else - var/mob/living/carbon/C = owner.current - first_prof.dna.transfer_identity(C, transfer_SE=1) - C.real_name = first_prof.name - C.updateappearance(mutcolor_update=1) - C.domutcheck() - -// Profile - -/datum/changelingprofile - var/name = "a bug" - - var/protected = 0 - - var/datum/dna/dna = null - var/list/name_list = list() //associative list of slotname = itemname - var/list/appearance_list = list() - var/list/flags_cover_list = list() - var/list/exists_list = list() - var/list/item_color_list = list() - var/list/item_state_list = list() - - var/underwear - var/undershirt - var/socks - -/datum/changelingprofile/Destroy() - qdel(dna) - . = ..() - -/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile) - newprofile.name = name - newprofile.protected = protected - newprofile.dna = new dna.type - dna.copy_dna(newprofile.dna) - newprofile.name_list = name_list.Copy() - newprofile.appearance_list = appearance_list.Copy() - newprofile.flags_cover_list = flags_cover_list.Copy() - newprofile.exists_list = exists_list.Copy() - newprofile.item_color_list = item_color_list.Copy() - newprofile.item_state_list = item_state_list.Copy() - newprofile.underwear = underwear - newprofile.undershirt = undershirt - newprofile.socks = socks - - -/datum/antagonist/changeling/xenobio - name = "Xenobio Changeling" - give_objectives = FALSE - show_in_roundend = FALSE //These are here for admin tracking purposes only - you_are_greet = FALSE - -/datum/antagonist/changeling/roundend_report() - var/list/parts = list() - - var/changelingwin = 1 - if(!owner.current) - changelingwin = 0 - - parts += printplayer(owner) - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - parts += "Changeling ID: [changelingID]." - parts += "Genomes Extracted: [absorbedcount]" - parts += " " - if(objectives.len) - var/count = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - parts += "Objective #[count]: [objective.explanation_text] Success!
" - else - parts += "Objective #[count]: [objective.explanation_text] Fail." - changelingwin = 0 - count++ - - if(changelingwin) - parts += "The changeling was successful!" - else - parts += "The changeling has failed." - - return parts.Join("
") - -/datum/antagonist/changeling/antag_listing_name() - return ..() + "([changelingID])" - -/datum/antagonist/changeling/xenobio/antag_listing_name() - return ..() + "(Xenobio)" \ No newline at end of file diff --git a/code/datums/antagonists/clockcult.dm b/code/datums/antagonists/clockcult.dm deleted file mode 100644 index 067801677b..0000000000 --- a/code/datums/antagonists/clockcult.dm +++ /dev/null @@ -1,219 +0,0 @@ -//CLOCKCULT PROOF OF CONCEPT -/datum/antagonist/clockcult - name = "Clock Cultist" - roundend_category = "clock cultists" - antagpanel_category = "Clockcult" - job_rank = ROLE_SERVANT_OF_RATVAR - var/datum/action/innate/hierophant/hierophant_network = new() - var/datum/team/clockcult/clock_team - var/make_team = TRUE //This should be only false for tutorial scarabs - -/datum/antagonist/clockcult/silent - silent = TRUE - show_in_antagpanel = FALSE //internal - -/datum/antagonist/clockcult/Destroy() - qdel(hierophant_network) - return ..() - -/datum/antagonist/clockcult/get_team() - return clock_team - -/datum/antagonist/clockcult/create_team(datum/team/clockcult/new_team) - if(!new_team && make_team) - //TODO blah blah same as the others, allow multiple - for(var/datum/antagonist/clockcult/H in GLOB.antagonists) - if(!H.owner) - continue - if(H.clock_team) - clock_team = H.clock_team - return - clock_team = new /datum/team/clockcult - return - if(make_team && !istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - clock_team = new_team - -/datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner) - . = ..() - if(.) - . = is_eligible_servant(new_owner.current) - -/datum/antagonist/clockcult/greet() - if(!owner.current || silent) - return - owner.current.visible_message("[owner.current]'s eyes glow a blazing yellow!", null, null, 7, owner.current) //don't show the owner this message - to_chat(owner.current, "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork \ - Justiciar above all else. Perform his every whim without hesitation.") - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 70, FALSE, pressure_affected = FALSE) - -/datum/antagonist/clockcult/on_gain() - var/mob/living/current = owner.current - SSticker.mode.servants_of_ratvar += owner - SSticker.mode.update_servant_icons_added(owner) - owner.special_role = ROLE_SERVANT_OF_RATVAR - owner.current.log_message("Has been converted to the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG) - if(issilicon(current)) - if(iscyborg(current) && !silent) - var/mob/living/silicon/robot/R = current - if(R.connected_ai && !is_servant_of_ratvar(R.connected_ai)) - to_chat(R, "You have been desynced from your master AI.
\ - In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.
") - else - to_chat(R, "Your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.") - if(isAI(current)) - to_chat(current, "You are now able to use your cameras to listen in on conversations, but can no longer speak in anything but Ratvarian.") - to_chat(current, "You can communicate with other servants by using the Hierophant Network action button in the upper left.") - else if(isbrain(current) || isclockmob(current)) - to_chat(current, "You can communicate with other servants by using the Hierophant Network action button in the upper left.") - ..() - to_chat(current, "This is Ratvar's will: [CLOCKCULT_OBJECTIVE]") - antag_memory += "Ratvar's will: [CLOCKCULT_OBJECTIVE]
" //Memorize the objectives - -/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(istype(mob_override)) - current = mob_override - GLOB.all_clockwork_mobs += current - current.faction |= "ratvar" - current.grant_language(/datum/language/ratvar) - current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons - if(issilicon(current)) - var/mob/living/silicon/S = current - if(iscyborg(S)) - var/mob/living/silicon/robot/R = S - if(!R.shell) - R.UnlinkSelf() - R.module.rebuild_modules() - else if(isAI(S)) - var/mob/living/silicon/ai/A = S - A.can_be_carded = FALSE - A.requires_power = POWER_REQ_CLOCKCULT - var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame - for(var/d in GLOB.cardinals) - AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow - A.add_overlay(AI_frame) - if(!A.lacks_power()) - A.ai_restore_power() - if(A.eyeobj) - A.eyeobj.relay_speech = TRUE - for(var/mob/living/silicon/robot/R in A.connected_robots) - if(R.connected_ai == A) - add_servant_of_ratvar(R) - S.laws = new/datum/ai_laws/ratvar - S.laws.associate(S) - S.update_icons() - S.show_laws() - hierophant_network.title = "Silicon" - hierophant_network.span_for_name = "nezbere" - hierophant_network.span_for_message = "brass" - else if(isbrain(current)) - hierophant_network.title = "Vessel" - hierophant_network.span_for_name = "nezbere" - hierophant_network.span_for_message = "alloy" - else if(isclockmob(current)) - hierophant_network.title = "Construct" - hierophant_network.span_for_name = "nezbere" - hierophant_network.span_for_message = "brass" - hierophant_network.Grant(current) - current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump) - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G.active && ishuman(current)) - current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)) - -/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override) - var/mob/living/current = owner.current - if(istype(mob_override)) - current = mob_override - GLOB.all_clockwork_mobs -= current - current.faction -= "ratvar" - current.remove_language(/datum/language/ratvar) - current.clear_alert("clockinfo") - for(var/datum/action/innate/clockwork_armaments/C in owner.current.actions) //Removes any bound clockwork armor - qdel(C) - for(var/datum/action/innate/call_weapon/W in owner.current.actions) //and weapons too - qdel(W) - if(issilicon(current)) - var/mob/living/silicon/S = current - if(isAI(S)) - var/mob/living/silicon/ai/A = S - A.can_be_carded = initial(A.can_be_carded) - A.requires_power = initial(A.requires_power) - A.cut_overlays() - S.make_laws() - S.update_icons() - S.show_laws() - var/mob/living/temp_owner = current - ..() - if(iscyborg(temp_owner)) - var/mob/living/silicon/robot/R = temp_owner - R.module.rebuild_modules() - if(temp_owner) - temp_owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons - temp_owner.cut_overlays() - temp_owner.regenerate_icons() - -/datum/antagonist/clockcult/on_removal() - SSticker.mode.servants_of_ratvar -= owner - SSticker.mode.update_servant_icons_removed(owner) - if(!silent) - owner.current.visible_message("[owner] seems to have remembered their true allegiance!", null, null, null, owner.current) - to_chat(owner, "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.") - owner.current.log_message("Has renounced the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG) - owner.special_role = null - if(iscyborg(owner.current)) - to_chat(owner.current, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.") - . = ..() - - -/datum/antagonist/clockcult/admin_add(datum/mind/new_owner,mob/admin) - add_servant_of_ratvar(new_owner.current, TRUE) - message_admins("[key_name_admin(admin)] has made [new_owner.current] into a servant of Ratvar.") - log_admin("[key_name(admin)] has made [new_owner.current] into a servant of Ratvar.") - -/datum/antagonist/clockcult/admin_remove(mob/user) - remove_servant_of_ratvar(owner.current, TRUE) - message_admins("[key_name_admin(user)] has removed clockwork servant status from [owner.current].") - log_admin("[key_name(user)] has removed clockwork servant status from [owner.current].") - -/datum/antagonist/clockcult/get_admin_commands() - . = ..() - .["Give slab"] = CALLBACK(src,.proc/admin_give_slab) - -/datum/antagonist/clockcult/proc/admin_give_slab(mob/admin) - if(!SSticker.mode.equip_servant(owner.current)) - to_chat(admin, "Failed to outfit [owner.current]!") - else - to_chat(admin, "Successfully gave [owner.current] servant equipment!") - -/datum/team/clockcult - name = "Clockcult" - var/list/objective - var/datum/mind/eminence - -/datum/team/clockcult/proc/check_clockwork_victory() - if(GLOB.clockwork_gateway_activated) - return TRUE - return FALSE - -/datum/team/clockcult/roundend_report() - var/list/parts = list() - - if(check_clockwork_victory()) - parts += "Ratvar's servants defended the Ark until its activation!" - else - parts += "The Ark was destroyed! Ratvar will rust away for all eternity!" - parts += " " - parts += "The servants' objective was: [CLOCKCULT_OBJECTIVE]." - parts += "Construction Value(CV) was: [GLOB.clockwork_construction_value]" - for(var/i in SSticker.scripture_states) - if(i != SCRIPTURE_DRIVER) - parts += "[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" - if(eminence) - parts += "The Eminence was: [printplayer(eminence)]" - if(members.len) - parts += "Ratvar's servants were:" - parts += printplayerlist(members - eminence) - - return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm deleted file mode 100644 index 3b9fa7b8c4..0000000000 --- a/code/datums/antagonists/cult.dm +++ /dev/null @@ -1,329 +0,0 @@ -#define SUMMON_POSSIBILITIES 3 - -/datum/antagonist/cult - name = "Cultist" - roundend_category = "cultists" - antagpanel_category = "Cult" - var/datum/action/innate/cult/comm/communion = new - var/datum/action/innate/cult/mastervote/vote = new - job_rank = ROLE_CULTIST - var/ignore_implant = FALSE - var/give_equipment = FALSE - - var/datum/team/cult/cult_team - -/datum/antagonist/cult/get_team() - return cult_team - -/datum/antagonist/cult/create_team(datum/team/cult/new_team) - if(!new_team) - //todo remove this and allow admin buttons to create more than one cult - for(var/datum/antagonist/cult/H in GLOB.antagonists) - if(!H.owner) - continue - if(H.cult_team) - cult_team = H.cult_team - return - cult_team = new /datum/team/cult - cult_team.setup_objectives() - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - cult_team = new_team - -/datum/antagonist/cult/proc/add_objectives() - objectives |= cult_team.objectives - owner.objectives |= objectives - -/datum/antagonist/cult/proc/remove_objectives() - owner.objectives -= objectives - -/datum/antagonist/cult/Destroy() - QDEL_NULL(communion) - QDEL_NULL(vote) - return ..() - -/datum/antagonist/cult/can_be_owned(datum/mind/new_owner) - . = ..() - if(. && !ignore_implant) - . = is_convertable_to_cult(new_owner.current,cult_team) - -/datum/antagonist/cult/greet() - to_chat(owner, "You are a member of the cult!") - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change - owner.announce_objectives() - -/datum/antagonist/cult/on_gain() - . = ..() - var/mob/living/current = owner.current - add_objectives() - if(give_equipment) - equip_cultist() - SSticker.mode.cult += owner // Only add after they've been given objectives - SSticker.mode.update_cult_icons_added(owner) - current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - - if(cult_team.blood_target && cult_team.blood_target_image && current.client) - current.client.images += cult_team.blood_target_image - - -/datum/antagonist/cult/proc/equip_cultist(tome=FALSE) - var/mob/living/carbon/H = owner.current - if(!istype(H)) - return - if (owner.assigned_role == "Clown") - to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - H.dna.remove_mutation(CLOWNMUT) - - if(tome) - . += cult_give_item(/obj/item/tome, H) - else - . += cult_give_item(/obj/item/paper/talisman/supply, H) - to_chat(owner, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") - - -/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) - var/list/slots = list( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - - var/T = new item_path(mob) - var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) - if(!where) - to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") - return 0 - else - to_chat(mob, "You have a [item_name] in your [where].") - if(where == "backpack") - var/obj/item/storage/B = mob.back - B.orient2hud(mob) - B.show_to(mob) - return 1 - -/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - current.faction |= "cult" - current.grant_language(/datum/language/narsie) - current.verbs += /mob/living/proc/cult_help - if(!cult_team.cult_mastered) - vote.Grant(current) - communion.Grant(current) - current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) - -/datum/antagonist/cult/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - current.faction -= "cult" - current.remove_language(/datum/language/narsie) - current.verbs -= /mob/living/proc/cult_help - vote.Remove(current) - communion.Remove(current) - current.clear_alert("bloodsense") - -/datum/antagonist/cult/on_removal() - remove_objectives() - SSticker.mode.cult -= owner - SSticker.mode.update_cult_icons_removed(owner) - if(!silent) - owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!", null, null, null, owner.current) - to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") - owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) - owner.current.client.images -= cult_team.blood_target_image - . = ..() - -/datum/antagonist/cult/admin_add(datum/mind/new_owner,mob/admin) - give_equipment = FALSE - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has cult'ed [new_owner.current].") - log_admin("[key_name(admin)] has cult'ed [new_owner.current].") - -/datum/antagonist/cult/admin_remove(mob/user) - message_admins("[key_name_admin(user)] has decult'ed [owner.current].") - log_admin("[key_name(user)] has decult'ed [owner.current].") - SSticker.mode.remove_cultist(owner,silent=TRUE) //disgusting - -/datum/antagonist/cult/get_admin_commands() - . = ..() - .["Tome"] = CALLBACK(src,.proc/admin_give_tome) - .["Amulet"] = CALLBACK(src,.proc/admin_give_amulet) - -/datum/antagonist/cult/proc/admin_give_tome(mob/admin) - if(equip_cultist(owner.current,1)) - to_chat(admin, "Spawning tome failed!") - -/datum/antagonist/cult/proc/admin_give_amulet(mob/admin) - if (equip_cultist(owner.current)) - to_chat(admin, "Spawning amulet failed!") - -/datum/antagonist/cult/master - ignore_implant = TRUE - show_in_antagpanel = FALSE //Feel free to add this later - var/datum/action/innate/cult/master/finalreck/reckoning = new - var/datum/action/innate/cult/master/cultmark/bloodmark = new - var/datum/action/innate/cult/master/pulse/throwing = new - -/datum/antagonist/cult/master/Destroy() - QDEL_NULL(reckoning) - QDEL_NULL(bloodmark) - QDEL_NULL(throwing) - return ..() - -/datum/antagonist/cult/master/on_gain() - . = ..() - var/mob/living/current = owner.current - set_antag_hud(current, "cultmaster") - -/datum/antagonist/cult/master/greet() - to_chat(owner.current, "You are the cult's Master. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \ - targets, such as a location or a noncultist, to direct the cult to them, and, finally, you are capable of summoning the entire living cult to your location once.") - to_chat(owner.current, "Use these abilities to direct the cult to victory at any cost.") - -/datum/antagonist/cult/master/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - if(!cult_team.reckoning_complete) - reckoning.Grant(current) - bloodmark.Grant(current) - throwing.Grant(current) - current.update_action_buttons_icon() - current.apply_status_effect(/datum/status_effect/cult_master) - -/datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - reckoning.Remove(current) - bloodmark.Remove(current) - throwing.Remove(current) - current.update_action_buttons_icon() - current.remove_status_effect(/datum/status_effect/cult_master) - -/datum/team/cult - name = "Cult" - - var/blood_target - var/image/blood_target_image - var/blood_target_reset_timer - - var/cult_vote_called = FALSE - var/cult_mastered = FALSE - var/reckoning_complete = FALSE - - -/datum/team/cult/proc/setup_objectives() - //SAC OBJECTIVE , todo: move this to objective internals - var/list/target_candidates = list() - var/datum/objective/sacrifice/sac_objective = new - sac_objective.team = src - - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD) - target_candidates += player.mind - - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD) - target_candidates += player.mind - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - sac_objective.target = pick(target_candidates) - sac_objective.update_explanation_text() - - var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) - var/datum/preferences/sacface = sac_objective.target.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - sac_objective.sac_image = reshape - - objectives += sac_objective - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - - - //SUMMON OBJECTIVE - - var/datum/objective/eldergod/summon_objective = new() - summon_objective.team = src - objectives += summon_objective - -/datum/objective/sacrifice - var/sacced = FALSE - var/sac_image - -/datum/objective/sacrifice/check_completion() - return sacced || completed - -/datum/objective/sacrifice/update_explanation_text() - if(target) - explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." - else - explanation_text = "The veil has already been weakened here, proceed to the final objective." - -/datum/objective/eldergod - var/summoned = FALSE - var/list/summon_spots = list() - -/datum/objective/eldergod/New() - ..() - var/sanity = 0 - while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100) - var/area/summon = pick(GLOB.sortedAreas - summon_spots) - if(summon && is_station_level(summon.z) && summon.valid_territory) - summon_spots += summon - sanity++ - update_explanation_text() - -/datum/objective/eldergod/update_explanation_text() - explanation_text = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin." - -/datum/objective/eldergod/check_completion() - return summoned || completed - -/datum/team/cult/proc/check_cult_victory() - for(var/datum/objective/O in objectives) - if(!O.check_completion()) - return FALSE - return TRUE - -/datum/team/cult/roundend_report() - var/list/parts = list() - - if(check_cult_victory()) - parts += "The cult has succeeded! Nar-sie has snuffed out another torch in the void!" - else - parts += "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!" - - if(objectives.len) - parts += "The cultists' objectives were:" - var/count = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - parts += "Objective #[count]: [objective.explanation_text] Success!" - else - parts += "Objective #[count]: [objective.explanation_text] Fail." - count++ - - if(members.len) - parts += "The cultists were:" - parts += printplayerlist(members) - - return "
[parts.Join("
")]
" - -/datum/team/cult/is_gamemode_hero() - return SSticker.mode.name == "cult" \ No newline at end of file diff --git a/code/datums/antagonists/datum_iaa.dm b/code/datums/antagonists/datum_iaa.dm deleted file mode 100644 index fd2c4e89a0..0000000000 --- a/code/datums/antagonists/datum_iaa.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/antagonist/iaa - -/datum/antagonist/iaa/apply_innate_effects() - .=..() //in case the base is used in future - if(owner&&owner.current) - give_pinpointer(owner.current) - -/datum/antagonist/iaa/remove_innate_effects() - .=..() - if(owner&&owner.current) - owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer) \ No newline at end of file diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm deleted file mode 100644 index da34debf95..0000000000 --- a/code/datums/antagonists/datum_traitor.dm +++ /dev/null @@ -1,352 +0,0 @@ -/datum/antagonist/traitor - name = "Traitor" - roundend_category = "traitors" - antagpanel_category = "Traitor" - job_rank = ROLE_TRAITOR - var/should_specialise = TRUE //do we split into AI and human, set to true on inital assignment only - var/ai_datum = /datum/antagonist/traitor/AI - var/human_datum = /datum/antagonist/traitor/human - var/special_role = ROLE_TRAITOR - var/employer = "The Syndicate" - var/give_objectives = TRUE - var/should_give_codewords = TRUE - - - -/datum/antagonist/traitor/human - show_in_antagpanel = FALSE - should_specialise = FALSE - var/should_equip = TRUE - - -/datum/antagonist/traitor/AI - show_in_antagpanel = FALSE - should_specialise = FALSE - -/datum/antagonist/traitor/specialization(datum/mind/new_owner) - if(should_specialise) - if(new_owner.current && isAI(new_owner.current)) - return new ai_datum() - else - return new human_datum() - else - return ..() - -/datum/antagonist/traitor/on_gain() - SSticker.mode.traitors += owner - owner.special_role = special_role - if(give_objectives) - forge_traitor_objectives() - finalize_traitor() - ..() - -/datum/antagonist/traitor/apply_innate_effects() - if(owner.assigned_role == "Clown") - var/mob/living/carbon/human/traitor_mob = owner.current - if(traitor_mob && istype(traitor_mob)) - if(!silent) - to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - traitor_mob.dna.remove_mutation(CLOWNMUT) - -/datum/antagonist/traitor/remove_innate_effects() - if(owner.assigned_role == "Clown") - var/mob/living/carbon/human/traitor_mob = owner.current - if(traitor_mob && istype(traitor_mob)) - traitor_mob.dna.add_mutation(CLOWNMUT) - -/datum/antagonist/traitor/on_removal() - SSticker.mode.traitors -= owner - for(var/O in objectives) - owner.objectives -= O - objectives = list() - if(!silent && owner.current) - to_chat(owner.current," You are no longer the [special_role]! ") - owner.special_role = null - ..() - -/datum/antagonist/traitor/AI/on_removal() - if(owner.current && isAI(owner.current)) - var/mob/living/silicon/ai/A = owner.current - A.set_zeroth_law("") - A.verbs -= /mob/living/silicon/ai/proc/choose_modules - A.malf_picker.remove_malf_verbs(A) - qdel(A.malf_picker) - ..() - -/datum/antagonist/traitor/proc/add_objective(var/datum/objective/O) - owner.objectives += O - objectives += O - -/datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O) - owner.objectives -= O - objectives -= O - -/datum/antagonist/traitor/proc/forge_traitor_objectives() - return - -/datum/antagonist/traitor/human/forge_traitor_objectives() - var/is_hijacker = FALSE - if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks - is_hijacker = prob(10) - var/martyr_chance = prob(20) - var/objective_count = is_hijacker //Hijacking counts towards number of objectives - if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors - if(!SSticker.mode.exchange_red) - SSticker.mode.exchange_red = owner - else - SSticker.mode.exchange_blue = owner - assign_exchange_role(SSticker.mode.exchange_red) - assign_exchange_role(SSticker.mode.exchange_blue) - objective_count += 1 //Exchange counts towards number of objectives - var/toa = CONFIG_GET(number/traitor_objectives_amount) - for(var/i = objective_count, i < toa, i++) - forge_single_objective() - - if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount - if (!(locate(/datum/objective/hijack) in owner.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = owner - add_objective(hijack_objective) - return - - - var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead. - for(var/datum/objective/O in owner.objectives) - if(!O.martyr_compatible) - martyr_compatibility = 0 - break - - if(martyr_compatibility && martyr_chance) - var/datum/objective/martyr/martyr_objective = new - martyr_objective.owner = owner - add_objective(martyr_objective) - return - - else - if(!(locate(/datum/objective/escape) in owner.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) - return - -/datum/antagonist/traitor/AI/forge_traitor_objectives() - var/objective_count = 0 - - if(prob(30)) - objective_count += forge_single_objective() - - for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - add_objective(kill_objective) - - var/datum/objective/survive/exist/exist_objective = new - exist_objective.owner = owner - add_objective(exist_objective) -/datum/antagonist/traitor/proc/forge_single_objective() - return 0 -/datum/antagonist/traitor/human/forge_single_objective() //Returns how many objectives are added - .=1 - if(prob(50)) - var/list/active_ais = active_ais() - if(active_ais.len && prob(100/GLOB.joined_player_list.len)) - var/datum/objective/destroy/destroy_objective = new - destroy_objective.owner = owner - destroy_objective.find_target() - add_objective(destroy_objective) - else if(prob(30)) - var/datum/objective/maroon/maroon_objective = new - maroon_objective.owner = owner - maroon_objective.find_target() - add_objective(maroon_objective) - else - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - add_objective(kill_objective) - else - if(prob(15) && !(locate(/datum/objective/download in owner.objectives))) - var/datum/objective/download/download_objective = new - download_objective.owner = owner - download_objective.gen_amount_goal() - add_objective(download_objective) - else - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - add_objective(steal_objective) - -/datum/antagonist/traitor/AI/forge_single_objective() - .=1 - var/special_pick = rand(1,4) - switch(special_pick) - if(1) - var/datum/objective/block/block_objective = new - block_objective.owner = owner - add_objective(block_objective) - if(2) - var/datum/objective/purge/purge_objective = new - purge_objective.owner = owner - add_objective(purge_objective) - if(3) - var/datum/objective/robot_army/robot_objective = new - robot_objective.owner = owner - add_objective(robot_objective) - if(4) //Protect and strand a target - var/datum/objective/protect/yandere_one = new - yandere_one.owner = owner - add_objective(yandere_one) - yandere_one.find_target() - var/datum/objective/maroon/yandere_two = new - yandere_two.owner = owner - yandere_two.target = yandere_one.target - yandere_two.update_explanation_text() // normally called in find_target() - add_objective(yandere_two) - .=2 - -/datum/antagonist/traitor/greet() - to_chat(owner.current, "You are the [owner.special_role].") - owner.announce_objectives() - if(should_give_codewords) - give_codewords() - -/datum/antagonist/traitor/proc/finalize_traitor() - SSticker.mode.update_traitor_icons_added(owner) - return - -/datum/antagonist/traitor/AI/finalize_traitor() - ..() - add_law_zero() - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE) - owner.current.grant_language(/datum/language/codespeak) - -/datum/antagonist/traitor/human/finalize_traitor() - ..() - if(should_equip) - equip(silent) - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE) - -/datum/antagonist/traitor/proc/give_codewords() - if(!owner.current) - return - var/mob/traitor_mob=owner.current - - to_chat(traitor_mob, "The Syndicate provided you with the following information on how to identify their agents:") - to_chat(traitor_mob, "Code Phrase: [GLOB.syndicate_code_phrase]") - to_chat(traitor_mob, "Code Response: [GLOB.syndicate_code_response]") - - antag_memory += "Code Phrase: [GLOB.syndicate_code_phrase]
" - antag_memory += "Code Response: [GLOB.syndicate_code_response]
" - - to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.") - -/datum/antagonist/traitor/AI/proc/add_law_zero() - var/mob/living/silicon/ai/killer = owner.current - if(!killer || !istype(killer)) - return - var/law = "Accomplish your objectives at all costs." - var/law_borg = "Accomplish your AI's objectives at all costs." - killer.set_zeroth_law(law, law_borg) - killer.set_syndie_radio() - to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!") - killer.add_malf_picker() - -/datum/antagonist/traitor/proc/equip(var/silent = FALSE) - return - -/datum/antagonist/traitor/human/equip(var/silent = FALSE) - owner.equip_traitor(employer, silent, src) - -/datum/antagonist/traitor/human/proc/assign_exchange_role() - //set faction - var/faction = "red" - if(owner == SSticker.mode.exchange_blue) - faction = "blue" - - //Assign objectives - var/datum/objective/steal/exchange/exchange_objective = new - exchange_objective.set_faction(faction,((faction == "red") ? SSticker.mode.exchange_blue : SSticker.mode.exchange_red)) - exchange_objective.owner = owner - add_objective(exchange_objective) - - if(prob(20)) - var/datum/objective/steal/exchange/backstab/backstab_objective = new - backstab_objective.set_faction(faction) - backstab_objective.owner = owner - add_objective(backstab_objective) - - //Spawn and equip documents - var/mob/living/carbon/human/mob = owner.current - - var/obj/item/folder/syndicate/folder - if(owner == SSticker.mode.exchange_red) - folder = new/obj/item/folder/syndicate/red(mob.loc) - else - folder = new/obj/item/folder/syndicate/blue(mob.loc) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - - var/where = "At your feet" - var/equipped_slot = mob.equip_in_one_of_slots(folder, slots) - if (equipped_slot) - where = "In your [equipped_slot]" - to_chat(mob, "

[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
") - -//TODO Collate -/datum/antagonist/traitor/roundend_report() - var/list/result = list() - - var/traitorwin = TRUE - - result += printplayer(owner) - - var/TC_uses = 0 - var/uplink_true = FALSE - var/purchases = "" - var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[owner.key] - if(H) - TC_uses = H.total_spent - uplink_true = TRUE - purchases += H.generate_render(FALSE) - - var/objectives_text = "" - if(objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - objectives_text += "
Objective #[count]: [objective.explanation_text] Success!" - else - objectives_text += "
Objective #[count]: [objective.explanation_text] Fail." - traitorwin = FALSE - count++ - - if(uplink_true) - var/uplink_text = "(used [TC_uses] TC) [purchases]" - if(TC_uses==0 && traitorwin) - var/static/icon/badass = icon('icons/badass.dmi', "badass") - uplink_text += "[icon2html(badass, world)]" - result += uplink_text - - result += objectives_text - - var/special_role_text = lowertext(name) - - if(traitorwin) - result += "The [special_role_text] was successful!" - else - result += "The [special_role_text] has failed!" - SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg') - - return result.Join("
") - -/datum/antagonist/traitor/roundend_report_footer() - return "
The code phrases were: [GLOB.syndicate_code_phrase]
\ - The code responses were: [GLOB.syndicate_code_response]
" - -/datum/antagonist/traitor/is_gamemode_hero() - return SSticker.mode.name == "traitor" \ No newline at end of file diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm deleted file mode 100644 index 858b2d1ef1..0000000000 --- a/code/datums/antagonists/devil.dm +++ /dev/null @@ -1,582 +0,0 @@ -#define BLOOD_THRESHOLD 3 //How many souls are needed per stage. -#define TRUE_THRESHOLD 7 -#define ARCH_THRESHOLD 12 - -#define BASIC_DEVIL 0 -#define BLOOD_LIZARD 1 -#define TRUE_DEVIL 2 -#define ARCH_DEVIL 3 - -#define LOSS_PER_DEATH 2 - -#define SOULVALUE soulsOwned.len-reviveNumber - -#define DEVILRESURRECTTIME 600 - -GLOBAL_LIST_EMPTY(allDevils) -GLOBAL_LIST_INIT(lawlorify, list ( - LORE = list( - OBLIGATION_FOOD = "This devil seems to always offer its victims food before slaughtering them.", - OBLIGATION_FIDDLE = "This devil will never turn down a musical challenge.", - OBLIGATION_DANCEOFF = "This devil will never turn down a dance off.", - OBLIGATION_GREET = "This devil seems to only be able to converse with people it knows the name of.", - OBLIGATION_PRESENCEKNOWN = "This devil seems to be unable to attack from stealth.", - OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.", - OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.", - OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.", - BANE_SILVER = "Silver seems to gravely injure this devil.", - BANE_SALT = "Throwing salt at this devil will hinder his ability to use infernal powers temporarily.", - BANE_LIGHT = "Bright flashes will disorient the devil, likely causing him to flee.", - BANE_IRON = "Cold iron will slowly injure him, until he can purge it from his system.", - BANE_WHITECLOTHES = "Wearing clean white clothing will help ward off this devil.", - BANE_HARVEST = "Presenting the labors of a harvest will disrupt the devil.", - BANE_TOOLBOX = "That which holds the means of creation also holds the means of the devil's undoing.", - BAN_HURTWOMAN = "This devil seems to prefer hunting men.", - BAN_CHAPEL = "This devil avoids holy ground.", - BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.", - BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.", - BAN_STRIKEUNCONSCIOUS = "This devil only shows interest in those who are awake.", - BAN_HURTLIZARD = "This devil will not strike a lizardman first.", - BAN_HURTANIMAL = "This devil avoids hurting animals.", - BANISH_WATER = "To banish the devil, you must infuse its body with holy water.", - BANISH_COFFIN = "This devil will return to life if its remains are not placed within a coffin.", - BANISH_FORMALDYHIDE = "To banish the devil, you must inject its lifeless body with embalming fluid.", - BANISH_RUNES = "This devil will resurrect after death, unless its remains are within a rune.", - BANISH_CANDLES = "A large number of nearby lit candles will prevent it from resurrecting.", - BANISH_DESTRUCTION = "Its corpse must be utterly destroyed to prevent resurrection.", - BANISH_FUNERAL_GARB = "If clad in funeral garments, this devil will be unable to resurrect. Should the clothes not fit, lay them gently on top of the devil's corpse." - ), - LAW = list( - OBLIGATION_FOOD = "When not acting in self defense, you must always offer your victim food before harming them.", - OBLIGATION_FIDDLE = "When not in immediate danger, if you are challenged to a musical duel, you must accept it. You are not obligated to duel the same person twice.", - OBLIGATION_DANCEOFF = "When not in immediate danger, if you are challenged to a dance off, you must accept it. You are not obligated to face off with the same person twice.", - OBLIGATION_GREET = "You must always greet other people by their last name before talking with them.", - OBLIGATION_PRESENCEKNOWN = "You must always make your presence known before attacking.", - OBLIGATION_SAYNAME = "You must always say your true name after you kill someone.", - OBLIGATION_ANNOUNCEKILL = "Upon killing someone, you must make your deed known to all within earshot, over comms if reasonably possible.", - OBLIGATION_ANSWERTONAME = "If you are not under attack, you must always respond to your true name.", - BAN_HURTWOMAN = "You must never harm a female outside of self defense.", - BAN_CHAPEL = "You must never attempt to enter the chapel.", - BAN_HURTPRIEST = "You must never attack a priest.", - BAN_AVOIDWATER = "You must never willingly touch a wet surface.", - BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.", - BAN_HURTLIZARD = "You must never harm a lizardman outside of self defense.", - BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.", - BANE_SILVER = "Silver, in all of its forms shall be your downfall.", - BANE_SALT = "Salt will disrupt your magical abilities.", - BANE_LIGHT = "Blinding lights will prevent you from using offensive powers for a time.", - BANE_IRON = "Cold wrought iron shall act as poison to you.", - BANE_WHITECLOTHES = "Those clad in pristine white garments will strike you true.", - BANE_HARVEST = "The fruits of the harvest shall be your downfall.", - BANE_TOOLBOX = "Toolboxes are bad news for you, for some reason.", - BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.", - BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.", - BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.", - BANISH_RUNES = "If your corpse is placed within a rune, you will be unable to resurrect.", - BANISH_CANDLES = "If your corpse is near lit candles, you will be unable to resurrect.", - BANISH_DESTRUCTION = "If your corpse is destroyed, you will be unable to resurrect.", - BANISH_FUNERAL_GARB = "If your corpse is clad in funeral garments, you will be unable to resurrect." - ) - )) - -//These are also used in the codex gigas, so let's declare them globally. -GLOBAL_LIST_INIT(devil_pre_title, list("Dark ", "Hellish ", "Fallen ", "Fiery ", "Sinful ", "Blood ", "Fluffy ")) -GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept ")) -GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa")) -GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) -/datum/antagonist/devil - name = "Devil" - roundend_category = "devils" - antagpanel_category = "Devil" - job_rank = ROLE_DEVIL - //Don't delete upon mind destruction, otherwise soul re-selling will break. - delete_on_mind_deletion = FALSE - var/obligation - var/ban - var/bane - var/banish - var/truename - var/list/datum/mind/soulsOwned = new - var/reviveNumber = 0 - var/form = BASIC_DEVIL - var/static/list/devil_spells = typecacheof(list( - /obj/effect/proc_holder/spell/aimed/fireball/hellish, - /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork, - /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater, - /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended, - /obj/effect/proc_holder/spell/targeted/infernal_jaunt, - /obj/effect/proc_holder/spell/targeted/sintouch, - /obj/effect/proc_holder/spell/targeted/sintouch/ascended, - /obj/effect/proc_holder/spell/targeted/summon_contract, - /obj/effect/proc_holder/spell/targeted/conjure_item/violin, - /obj/effect/proc_holder/spell/targeted/summon_dancefloor)) - var/ascendable = FALSE - -/datum/antagonist/devil/can_be_owned(datum/mind/new_owner) - . = ..() - return . && (ishuman(new_owner.current) || iscyborg(new_owner.current)) - -/datum/antagonist/devil/get_admin_commands() - . = ..() - .["Toggle ascendable"] = CALLBACK(src,.proc/admin_toggle_ascendable) - - -/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin) - ascendable = !ascendable - message_admins("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable]") - log_admin("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable])") - -/datum/antagonist/devil/admin_add(datum/mind/new_owner,mob/admin) - switch(alert(admin,"Should the devil be able to ascend",,"Yes","No","Cancel")) - if("Yes") - ascendable = TRUE - if("No") - ascendable = FALSE - else - return - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]") - log_admin("[key_name(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]") - -/datum/antagonist/devil/antag_listing_name() - return ..() + "([truename])" - -/proc/devilInfo(name) - if(GLOB.allDevils[lowertext(name)]) - return GLOB.allDevils[lowertext(name)] - else - var/datum/fakeDevil/devil = new /datum/fakeDevil(name) - GLOB.allDevils[lowertext(name)] = devil - return devil - -/proc/randomDevilName() - var/name = "" - if(prob(65)) - if(prob(35)) - name = pick(GLOB.devil_pre_title) - name += pick(GLOB.devil_title) - var/probability = 100 - name += pick(GLOB.devil_syllable) - while(prob(probability)) - name += pick(GLOB.devil_syllable) - probability -= 20 - if(prob(40)) - name += pick(GLOB.devil_suffix) - return name - -/proc/randomdevilobligation() - return pick(OBLIGATION_FOOD, OBLIGATION_FIDDLE, OBLIGATION_DANCEOFF, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME) - -/proc/randomdevilban() - return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL) - -/proc/randomdevilbane() - return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX) - -/proc/randomdevilbanish() - return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB) - -/datum/antagonist/devil/proc/add_soul(datum/mind/soul) - if(soulsOwned.Find(soul)) - return - soulsOwned += soul - owner.current.nutrition = NUTRITION_LEVEL_FULL - to_chat(owner.current, "You feel satiated as you received a new soul.") - update_hud() - switch(SOULVALUE) - if(0) - to_chat(owner.current, "Your hellish powers have been restored.") - give_appropriate_spells() - if(BLOOD_THRESHOLD) - increase_blood_lizard() - if(TRUE_THRESHOLD) - increase_true_devil() - if(ARCH_THRESHOLD) - increase_arch_devil() - -/datum/antagonist/devil/proc/remove_soul(datum/mind/soul) - if(soulsOwned.Remove(soul)) - check_regression() - to_chat(owner.current, "You feel as though a soul has slipped from your grasp.") - update_hud() - -/datum/antagonist/devil/proc/check_regression() - if(form == ARCH_DEVIL) - return //arch devil can't regress - //Yes, fallthrough behavior is intended, so I can't use a switch statement. - if(form == TRUE_DEVIL && SOULVALUE < TRUE_THRESHOLD) - regress_blood_lizard() - if(form == BLOOD_LIZARD && SOULVALUE < BLOOD_THRESHOLD) - regress_humanoid() - if(SOULVALUE < 0) - give_appropriate_spells() - to_chat(owner.current, "As punishment for your failures, all of your powers except contract creation have been revoked.") - -/datum/antagonist/devil/proc/regress_humanoid() - to_chat(owner.current, "Your powers weaken, have more contracts be signed to regain power.") - if(ishuman(owner.current)) - var/mob/living/carbon/human/H = owner.current - H.set_species(/datum/species/human, 1) - H.regenerate_icons() - give_appropriate_spells() - if(istype(owner.current.loc, /obj/effect/dummy/slaughter/)) - owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted. - form = BASIC_DEVIL - -/datum/antagonist/devil/proc/regress_blood_lizard() - var/mob/living/carbon/true_devil/D = owner.current - to_chat(D, "Your powers weaken, have more contracts be signed to regain power.") - D.oldform.forceMove(D.drop_location()) - owner.transfer_to(D.oldform) - give_appropriate_spells() - qdel(D) - form = BLOOD_LIZARD - update_hud() - - -/datum/antagonist/devil/proc/increase_blood_lizard() - to_chat(owner.current, "You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.") - sleep(50) - if(ishuman(owner.current)) - var/mob/living/carbon/human/H = owner.current - H.set_species(/datum/species/lizard, 1) - H.underwear = "Nude" - H.undershirt = "Nude" - H.socks = "Nude" - H.dna.features["mcolor"] = "511" //A deep red - H.regenerate_icons() - else //Did the devil get hit by a staff of transmutation? - owner.current.color = "#501010" - give_appropriate_spells() - form = BLOOD_LIZARD - - - -/datum/antagonist/devil/proc/increase_true_devil() - to_chat(owner.current, "You feel as though your current form is about to shed. You will soon turn into a true devil.") - sleep(50) - var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc) - A.faction |= "hell" - owner.current.forceMove(A) - A.oldform = owner.current - owner.transfer_to(A) - A.set_name() - give_appropriate_spells() - form = TRUE_DEVIL - update_hud() - -/datum/antagonist/devil/proc/increase_arch_devil() - if(!ascendable) - return - var/mob/living/carbon/true_devil/D = owner.current - to_chat(D, "You feel as though your form is about to ascend.") - sleep(50) - if(!D) - return - D.visible_message("[D]'s skin begins to erupt with spikes.", \ - "Your flesh begins creating a shield around yourself.") - sleep(100) - if(!D) - return - D.visible_message("The horns on [D]'s head slowly grow and elongate.", \ - "Your body continues to mutate. Your telepathic abilities grow.") - sleep(90) - if(!D) - return - D.visible_message("[D]'s body begins to violently stretch and contort.", \ - "You begin to rend apart the final barriers to ultimate power.") - sleep(40) - if(!D) - return - to_chat(D, "Yes!") - sleep(10) - if(!D) - return - to_chat(D, "YES!!") - sleep(10) - if(!D) - return - to_chat(D, "YE--") - sleep(1) - if(!D) - return - to_chat(world, "\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"") - SEND_SOUND(world, sound('sound/hallucinations/veryfar_noise.ogg')) - give_appropriate_spells() - D.convert_to_archdevil() - if(istype(D.loc, /obj/effect/dummy/slaughter/)) - D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted. - var/area/A = get_area(owner.current) - if(A) - notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK) - sleep(50) - if(!SSticker.mode.devil_ascended) - SSshuttle.emergency.request(null, set_coefficient = 0.3) - SSticker.mode.devil_ascended++ - form = ARCH_DEVIL - -/datum/antagonist/devil/proc/remove_spells() - for(var/X in owner.spell_list) - var/obj/effect/proc_holder/spell/S = X - if(is_type_in_typecache(S, devil_spells)) - owner.RemoveSpell(S) - -/datum/antagonist/devil/proc/give_summon_contract() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null)) - if(obligation == OBLIGATION_FIDDLE) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null)) - else if(obligation == OBLIGATION_DANCEOFF) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null)) - -/datum/antagonist/devil/proc/give_appropriate_spells() - remove_spells() - give_summon_contract() - if(SOULVALUE >= ARCH_THRESHOLD && ascendable) - give_arch_spells() - else if(SOULVALUE >= TRUE_THRESHOLD) - give_true_spells() - else if(SOULVALUE >= BLOOD_THRESHOLD) - give_blood_spells() - else if(SOULVALUE >= 0) - give_base_spells() - -/datum/antagonist/devil/proc/give_base_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null)) - -/datum/antagonist/devil/proc/give_blood_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) - -/datum/antagonist/devil/proc/give_true_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) - -/datum/antagonist/devil/proc/give_arch_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null)) - -/datum/antagonist/devil/proc/beginResurrectionCheck(mob/living/body) - if(SOULVALUE>0) - to_chat(owner.current, "Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body.") - sleep(DEVILRESURRECTTIME) - if (!body || body.stat == DEAD) - if(SOULVALUE>0) - if(check_banishment(body)) - to_chat(owner.current, "Unfortunately, the mortals have finished a ritual that prevents your resurrection.") - return -1 - else - to_chat(owner.current, "WE LIVE AGAIN!") - return hellish_resurrection(body) - else - to_chat(owner.current, "Unfortunately, the power that stemmed from your contracts has been extinguished. You no longer have enough power to resurrect.") - return -1 - else - to_chat(owner.current, " You seem to have resurrected without your hellish powers.") - else - to_chat(owner.current, "Your hellish powers are too weak to resurrect yourself.") - -/datum/antagonist/devil/proc/check_banishment(mob/living/body) - switch(banish) - if(BANISH_WATER) - if(iscarbon(body)) - var/mob/living/carbon/H = body - return H.reagents.has_reagent("holy water") - return 0 - if(BANISH_COFFIN) - return (body && istype(body.loc, /obj/structure/closet/coffin)) - if(BANISH_FORMALDYHIDE) - if(iscarbon(body)) - var/mob/living/carbon/H = body - return H.reagents.has_reagent("formaldehyde") - return 0 - if(BANISH_RUNES) - if(body) - for(var/obj/effect/decal/cleanable/crayon/R in range(0,body)) - if (R.name == "rune") - return 1 - return 0 - if(BANISH_CANDLES) - if(body) - var/count = 0 - for(var/obj/item/candle/C in range(1,body)) - count += C.lit - if(count>=4) - return 1 - return 0 - if(BANISH_DESTRUCTION) - if(body) - return 0 - return 1 - if(BANISH_FUNERAL_GARB) - if(ishuman(body)) - var/mob/living/carbon/human/H = body - if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/burial)) - return 1 - return 0 - else - for(var/obj/item/clothing/under/burial/B in range(0,body)) - if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something. - return 1 - return 0 - -/datum/antagonist/devil/proc/hellish_resurrection(mob/living/body) - message_admins("[owner.name] (true name is: [truename]) is resurrecting using hellish energy.") - if(SOULVALUE < ARCH_THRESHOLD || !ascendable) // once ascended, arch devils do not go down in power by any means. - reviveNumber += LOSS_PER_DEATH - update_hud() - if(body) - body.revive(TRUE, TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart. - if(istype(body.loc, /obj/effect/dummy/slaughter/)) - body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted. - if(istype(body, /mob/living/carbon/true_devil)) - var/mob/living/carbon/true_devil/D = body - if(D.oldform) - D.oldform.revive(1,0) // Heal the old body too, so the devil doesn't resurrect, then immediately regress into a dead body. - if(body.stat == DEAD) - create_new_body() - else - create_new_body() - check_regression() - -/datum/antagonist/devil/proc/create_new_body() - if(GLOB.blobstart.len > 0) - var/turf/targetturf = get_turf(pick(GLOB.blobstart)) - var/mob/currentMob = owner.current - if(!currentMob) - currentMob = owner.get_ghost() - if(!currentMob) - message_admins("[owner.name]'s devil resurrection failed due to client logoff. Aborting.") - return -1 - if(currentMob.mind != owner) - message_admins("[owner.name]'s devil resurrection failed due to becoming a new mob. Aborting.") - return -1 - currentMob.change_mob_type( /mob/living/carbon/human, targetturf, null, 1) - var/mob/living/carbon/human/H = owner.current - H.equip_to_slot_or_del(new /obj/item/clothing/under/lawyer/black(H), slot_w_uniform) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes) - H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), slot_hands) - H.equip_to_slot_or_del(new /obj/item/pen(H), slot_l_store) - if(SOULVALUE >= BLOOD_THRESHOLD) - H.set_species(/datum/species/lizard, 1) - H.underwear = "Nude" - H.undershirt = "Nude" - H.socks = "Nude" - H.dna.features["mcolor"] = "511" - H.regenerate_icons() - if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough. - var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf) - A.faction |= "hell" - H.forceMove(A) - A.oldform = H - owner.transfer_to(A, TRUE) - A.set_name() - if(SOULVALUE >= ARCH_THRESHOLD && ascendable) - A.convert_to_archdevil() - else - throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection") - - -/datum/antagonist/devil/proc/update_hud() - if(iscarbon(owner.current)) - var/mob/living/C = owner.current - if(C.hud_used && C.hud_used.devilsouldisplay) - C.hud_used.devilsouldisplay.update_counter(SOULVALUE) - -/datum/antagonist/devil/greet() - to_chat(owner.current, "You remember your link to the infernal. You are [truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp.") - to_chat(owner.current, "However, your infernal form is not without weaknesses.") - to_chat(owner.current, "You may not use violence to coerce someone into selling their soul.") - to_chat(owner.current, "You may not directly and knowingly physically harm a devil, other than yourself.") - to_chat(owner.current, GLOB.lawlorify[LAW][bane]) - to_chat(owner.current, GLOB.lawlorify[LAW][ban]) - to_chat(owner.current, GLOB.lawlorify[LAW][obligation]) - to_chat(owner.current, GLOB.lawlorify[LAW][banish]) - to_chat(owner.current, "Remember, the crew can research your weaknesses if they find out your devil name.
") - .=..() - -/datum/antagonist/devil/on_gain() - truename = randomDevilName() - ban = randomdevilban() - bane = randomdevilbane() - obligation = randomdevilobligation() - banish = randomdevilbanish() - GLOB.allDevils[lowertext(truename)] = src - - antag_memory += "Your devilic true name is [truename]
[GLOB.lawlorify[LAW][ban]]
You may not use violence to coerce someone into selling their soul.
You may not directly and knowingly physically harm a devil, other than yourself.
[GLOB.lawlorify[LAW][bane]]
[GLOB.lawlorify[LAW][obligation]]
[GLOB.lawlorify[LAW][banish]]
" - if(issilicon(owner.current)) - var/mob/living/silicon/robot_devil = owner.current - var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.") - robot_devil.set_law_sixsixsix(laws) - sleep(10) - if(owner.assigned_role == "Clown" && ishuman(owner.current)) - var/mob/living/carbon/human/S = owner.current - to_chat(S, "Your infernal nature has allowed you to overcome your clownishness.") - S.dna.remove_mutation(CLOWNMUT) - .=..() - -/datum/antagonist/devil/on_removal() - to_chat(owner.current, "Your infernal link has been severed! You are no longer a devil!") - .=..() - -/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override) - give_appropriate_spells() - owner.current.grant_all_languages(TRUE) - update_hud() - .=..() - -/datum/antagonist/devil/remove_innate_effects(mob/living/mob_override) - for(var/X in owner.spell_list) - var/obj/effect/proc_holder/spell/S = X - if(is_type_in_typecache(S, devil_spells)) - owner.RemoveSpell(S) - .=..() - -/datum/antagonist/devil/proc/printdevilinfo() - var/list/parts = list() - parts += "The devil's true name is: [truename]" - parts += "The devil's bans were:" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]" - return parts.Join("
") - -/datum/antagonist/devil/roundend_report() - var/list/parts = list() - parts += printplayer(owner) - parts += printdevilinfo() - parts += printobjectives(owner) - return parts.Join("
") - -/datum/antagonist/devil/roundend_report_footer() - //sintouched go here for now as a hack , TODO proper antag datum for these - var/list/parts = list() - if(SSticker.mode.sintouched.len) - parts += "The sintouched were:" - var/list/sintouchedUnique = uniqueList(SSticker.mode.sintouched) - for(var/S in sintouchedUnique) - var/datum/mind/sintouched_mind = S - parts += printplayer(sintouched_mind) - parts += printobjectives(sintouched_mind) - return parts.Join("
") - -//A simple super light weight datum for the codex gigas. -/datum/fakeDevil - var/truename - var/bane - var/obligation - var/ban - var/banish - var/ascendable - -/datum/fakeDevil/New(name = randomDevilName()) - truename = name - bane = randomdevilbane() - obligation = randomdevilobligation() - ban = randomdevilban() - banish = randomdevilbanish() - ascendable = prob(25) diff --git a/code/datums/antagonists/internal_affairs.dm b/code/datums/antagonists/internal_affairs.dm deleted file mode 100644 index 9077b84dcd..0000000000 --- a/code/datums/antagonists/internal_affairs.dm +++ /dev/null @@ -1,302 +0,0 @@ -#define PINPOINTER_MINIMUM_RANGE 15 -#define PINPOINTER_EXTRA_RANDOM_RANGE 10 -#define PINPOINTER_PING_TIME 40 -#define PROB_ACTUAL_TRAITOR 20 -#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent" - -/datum/antagonist/traitor/internal_affairs - name = "Internal Affairs Agent" - human_datum = /datum/antagonist/traitor/human/internal_affairs - ai_datum = /datum/antagonist/traitor/AI/internal_affairs - antagpanel_category = "IAA" - -/datum/antagonist/traitor/AI/internal_affairs - name = "Internal Affairs Agent" - employer = "Nanotrasen" - special_role = "internal affairs agent" - antagpanel_category = "IAA" - var/syndicate = FALSE - var/last_man_standing = FALSE - var/list/datum/mind/targets_stolen - - -/datum/antagonist/traitor/human/internal_affairs - name = "Internal Affairs Agent" - employer = "Nanotrasen" - special_role = "internal affairs agent" - antagpanel_category = "IAA" - var/syndicate = FALSE - var/last_man_standing = FALSE - var/list/datum/mind/targets_stolen - - -/datum/antagonist/traitor/human/internal_affairs/proc/give_pinpointer() - if(owner && owner.current) - owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer) - -/datum/antagonist/traitor/human/internal_affairs/apply_innate_effects() - .=..() //in case the base is used in future - if(owner && owner.current) - give_pinpointer(owner.current) - -/datum/antagonist/traitor/human/internal_affairs/remove_innate_effects() - .=..() - if(owner && owner.current) - owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer) - -/datum/antagonist/traitor/human/internal_affairs/on_gain() - START_PROCESSING(SSprocessing, src) - .=..() -/datum/antagonist/traitor/human/internal_affairs/on_removal() - STOP_PROCESSING(SSprocessing,src) - .=..() -/datum/antagonist/traitor/human/internal_affairs/process() - iaa_process() - -/datum/antagonist/traitor/AI/internal_affairs/on_gain() - START_PROCESSING(SSprocessing, src) - .=..() -/datum/antagonist/traitor/AI/internal_affairs/on_removal() - STOP_PROCESSING(SSprocessing,src) - .=..() -/datum/antagonist/traitor/AI/internal_affairs/process() - iaa_process() - -/datum/status_effect/agent_pinpointer - id = "agent_pinpointer" - duration = -1 - tick_interval = PINPOINTER_PING_TIME - alert_type = /obj/screen/alert/status_effect/agent_pinpointer - var/minimum_range = PINPOINTER_MINIMUM_RANGE - var/mob/scan_target = null - -/obj/screen/alert/status_effect/agent_pinpointer - name = "Internal Affairs Integrated Pinpointer" - desc = "Even stealthier than a normal implant." - icon = 'icons/obj/device.dmi' - icon_state = "pinon" - -/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction - if(!scan_target) - linked_alert.icon_state = "pinonnull" - return - var/turf/here = get_turf(owner) - var/turf/there = get_turf(scan_target) - if(here.z != there.z) - linked_alert.icon_state = "pinonnull" - return - if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE)) - linked_alert.icon_state = "pinondirect" - else - linked_alert.setDir(get_dir(here, there)) - switch(get_dist(here, there)) - if(1 to 8) - linked_alert.icon_state = "pinonclose" - if(9 to 16) - linked_alert.icon_state = "pinonmedium" - if(16 to INFINITY) - linked_alert.icon_state = "pinonfar" - -/datum/status_effect/agent_pinpointer/proc/scan_for_target() - scan_target = null - if(owner) - if(owner.mind) - if(owner.mind.objectives) - for(var/datum/objective/objective_ in owner.mind.objectives) - if(!is_internal_objective(objective_)) - continue - var/datum/objective/assassinate/internal/objective = objective_ - var/mob/current = objective.target.current - if(current&¤t.stat!=DEAD) - scan_target = current - break - -/datum/status_effect/agent_pinpointer/tick() - if(!owner) - qdel(src) - return - scan_for_target() - point_to_target() - - -/proc/is_internal_objective(datum/objective/O) - return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal)) - -/datum/antagonist/traitor/proc/replace_escape_objective() - if(!owner||!owner.objectives) - return - for (var/objective_ in owner.objectives) - if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive))) - continue - remove_objective(objective_) - - var/datum/objective/martyr/martyr_objective = new - martyr_objective.owner = owner - add_objective(martyr_objective) - -/datum/antagonist/traitor/proc/reinstate_escape_objective() - if(!owner||!owner.objectives) - return - for (var/objective_ in owner.objectives) - if(!istype(objective_, /datum/objective/martyr)) - continue - remove_objective(objective_) - -/datum/antagonist/traitor/human/internal_affairs/reinstate_escape_objective() - ..() - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) - -/datum/antagonist/traitor/AI/internal_affairs/reinstate_escape_objective() - ..() - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) - -/datum/antagonist/traitor/proc/steal_targets(datum/mind/victim) - var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA - - if(!owner.current||owner.current.stat==DEAD) - return - to_chat(owner.current, " Target eliminated: [victim.name]") - for(var/objective_ in victim.objectives) - if(istype(objective_, /datum/objective/assassinate/internal)) - var/datum/objective/assassinate/internal/objective = objective_ - if(objective.target==owner) - continue - else if(this.targets_stolen.Find(objective.target) == 0) - var/datum/objective/assassinate/internal/new_objective = new - new_objective.owner = owner - new_objective.target = objective.target - new_objective.update_explanation_text() - add_objective(new_objective) - this.targets_stolen += objective.target - var/status_text = objective.check_completion() ? "neutralised" : "active" - to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") - else if(istype(objective_, /datum/objective/destroy/internal)) - var/datum/objective/destroy/internal/objective = objective_ - var/datum/objective/destroy/internal/new_objective = new - if(objective.target==owner) - continue - else if(this.targets_stolen.Find(objective.target) == 0) - new_objective.owner = owner - new_objective.target = objective.target - new_objective.update_explanation_text() - add_objective(new_objective) - this.targets_stolen += objective.target - var/status_text = objective.check_completion() ? "neutralised" : "active" - to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") - this.last_man_standing = TRUE - for(var/objective_ in owner.objectives) - if(!is_internal_objective(objective_)) - continue - var/datum/objective/assassinate/internal/objective = objective_ - if(!objective.check_completion()) - this.last_man_standing = FALSE - return - if(this.last_man_standing) - if(this.syndicate) - to_chat(owner.current," All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. ") - else - to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.") - replace_escape_objective(owner) - -/datum/antagonist/traitor/proc/iaa_process() - var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA - if(owner&&owner.current&&owner.current.stat!=DEAD) - for(var/objective_ in owner.objectives) - if(!is_internal_objective(objective_)) - continue - var/datum/objective/assassinate/internal/objective = objective_ - if(!objective.target) - continue - if(objective.check_completion()) - if(objective.stolen) - continue - else - steal_targets(objective.target) - objective.stolen = TRUE - else - if(objective.stolen) - var/fail_msg = "Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! " - if(this.last_man_standing) - if(this.syndicate) - fail_msg += " You no longer have permission to die. " - else - fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated." - reinstate_escape_objective(owner) - this.last_man_standing = FALSE - to_chat(owner.current, fail_msg) - objective.stolen = FALSE - -/datum/antagonist/traitor/proc/forge_iaa_objectives() - var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA - if(SSticker.mode.target_list.len && SSticker.mode.target_list[owner]) // Is a double agent - - // Assassinate - var/datum/mind/target_mind = SSticker.mode.target_list[owner] - if(issilicon(target_mind.current)) - var/datum/objective/destroy/internal/destroy_objective = new - destroy_objective.owner = owner - destroy_objective.target = target_mind - destroy_objective.update_explanation_text() - else - var/datum/objective/assassinate/internal/kill_objective = new - kill_objective.owner = owner - kill_objective.target = target_mind - kill_objective.update_explanation_text() - add_objective(kill_objective) - - //Optional traitor objective - if(prob(PROB_ACTUAL_TRAITOR)) - employer = "The Syndicate" - owner.special_role = TRAITOR_AGENT_ROLE - special_role = TRAITOR_AGENT_ROLE - this.syndicate = TRUE - forge_single_objective() - - else - ..() // Give them standard objectives. - return - -/datum/antagonist/traitor/human/internal_affairs/forge_traitor_objectives() - forge_iaa_objectives() - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) - -/datum/antagonist/traitor/AI/internal_affairs/forge_traitor_objectives() - forge_iaa_objectives() - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) - -/datum/antagonist/traitor/proc/greet_iaa() - var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA - var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") - - to_chat(owner.current, "You are the [special_role].") - if(this.syndicate) - to_chat(owner.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.") - to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") - to_chat(owner.current, " You have been provided with a standard uplink to accomplish your task. ") - else - to_chat(owner.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.") - to_chat(owner.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.") - to_chat(owner.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.") - - to_chat(owner.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") - owner.announce_objectives() - -/datum/antagonist/traitor/AI/internal_affairs/greet() - greet_iaa() - -/datum/antagonist/traitor/human/internal_affairs/greet() - greet_iaa() - - -#undef PROB_ACTUAL_TRAITOR -#undef PINPOINTER_EXTRA_RANDOM_RANGE -#undef PINPOINTER_MINIMUM_RANGE -#undef PINPOINTER_PING_TIME diff --git a/code/datums/antagonists/monkey.dm b/code/datums/antagonists/monkey.dm deleted file mode 100644 index 25e80f6afb..0000000000 --- a/code/datums/antagonists/monkey.dm +++ /dev/null @@ -1,214 +0,0 @@ -#define MONKEYS_ESCAPED 1 -#define MONKEYS_LIVED 2 -#define MONKEYS_DIED 3 -#define DISEASE_LIVED 4 - -/datum/antagonist/monkey - name = "Monkey" - job_rank = ROLE_MONKEY - roundend_category = "monkeys" - antagpanel_category = "Monkey" - var/datum/team/monkey/monkey_team - var/monkey_only = TRUE - -/datum/antagonist/monkey/can_be_owned(datum/mind/new_owner) - return ..() && (!monkey_only || ismonkey(new_owner.current)) - -/datum/antagonist/monkey/get_team() - return monkey_team - -/datum/antagonist/monkey/on_gain() - . = ..() - SSticker.mode.ape_infectees += owner - owner.special_role = "Infected Monkey" - - var/datum/disease/D = new /datum/disease/transformation/jungle_fever/monkeymode - if(!owner.current.HasDisease(D)) - owner.current.ForceContractDisease(D) - else - QDEL_NULL(D) - -/datum/antagonist/monkey/greet() - to_chat(owner, "You are a monkey now!") - to_chat(owner, "Bite humans to infect them, follow the orders of the monkey leaders, and help fellow monkeys!") - to_chat(owner, "Ensure at least one infected monkey escapes on the Emergency Shuttle!") - to_chat(owner, "As an intelligent monkey, you know how to use technology and how to ventcrawl while wearing things.") - to_chat(owner, "You can use :k to talk to fellow monkeys!") - SEND_SOUND(owner.current, sound('sound/ambience/antag/monkey.ogg')) - -/datum/antagonist/monkey/on_removal() - owner.special_role = null - SSticker.mode.ape_infectees -= owner - - var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.viruses - if(D) - D.remove_virus() - qdel(D) - - . = ..() - -/datum/antagonist/monkey/create_team(datum/team/monkey/new_team) - if(!new_team) - for(var/datum/antagonist/monkey/H in GLOB.antagonists) - if(!H.owner) - continue - if(H.monkey_team) - monkey_team = H.monkey_team - return - monkey_team = new /datum/team/monkey - monkey_team.update_objectives() - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - monkey_team = new_team - -/datum/antagonist/monkey/proc/forge_objectives() - objectives |= monkey_team.objectives - owner.objectives |= objectives - -/datum/antagonist/monkey/admin_remove(mob/admin) - var/mob/living/carbon/monkey/M = owner.current - if(istype(M)) - switch(alert(admin, "Humanize?", "Humanize", "Yes", "No")) - if("Yes") - if(admin == M) - admin = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) - else - M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) - if("No") - //nothing - else - return - . = ..() - -/datum/antagonist/monkey/leader - name = "Monkey Leader" - monkey_only = FALSE - -/datum/antagonist/monkey/leader/admin_add(datum/mind/new_owner,mob/admin) - var/mob/living/carbon/human/H = new_owner.current - if(istype(H)) - switch(alert(admin, "Monkeyize?", "Monkeyize", "Yes", "No")) - if("Yes") - if(admin == H) - admin = H.monkeyize() - else - H.monkeyize() - if("No") - //nothing - else - return - new_owner.add_antag_datum(src) - log_admin("[key_name(admin)] made [key_name(new_owner.current)] a monkey leader!") - message_admins("[key_name_admin(admin)] made [key_name_admin(new_owner.current)] a monkey leader!") - -/datum/antagonist/monkey/leader/on_gain() - . = ..() - var/obj/item/organ/heart/freedom/F = new - F.Insert(owner.current, drop_if_replaced = FALSE) - SSticker.mode.ape_leaders += owner - owner.special_role = "Monkey Leader" - -/datum/antagonist/monkey/leader/on_removal() - SSticker.mode.ape_leaders -= owner - var/obj/item/organ/heart/H = new - H.Insert(owner.current, drop_if_replaced = FALSE) //replace freedom heart with normal heart - - . = ..() - -/datum/antagonist/monkey/leader/greet() - to_chat(owner, "You are the Jungle Fever patient zero!!") - to_chat(owner, "You have been planted onto this station by the Animal Rights Consortium.") - to_chat(owner, "Soon the disease will transform you into an ape. Afterwards, you will be able spread the infection to others with a bite.") - to_chat(owner, "While your infection strain is undetectable by scanners, any other infectees will show up on medical equipment.") - to_chat(owner, "Your mission will be deemed a success if any of the live infected monkeys reach CentCom.") - to_chat(owner, "As an initial infectee, you will be considered a 'leader' by your fellow monkeys.") - to_chat(owner, "You can use :k to talk to fellow monkeys!") - SEND_SOUND(owner.current, sound('sound/ambience/antag/monkey.ogg')) - -/datum/objective/monkey - explanation_text = "Ensure that infected monkeys escape on the emergency shuttle!" - martyr_compatible = TRUE - var/monkeys_to_win = 1 - var/escaped_monkeys = 0 - -/datum/objective/monkey/check_completion() - var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list) - if (M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase())) - escaped_monkeys++ - if(escaped_monkeys >= monkeys_to_win) - return TRUE - return FALSE - -/datum/team/monkey - name = "Monkeys" - -/datum/team/monkey/proc/update_objectives() - objectives = list() - var/datum/objective/monkey/O = new() - O.team = src - objectives += O - -/datum/team/monkey/proc/infected_monkeys_alive() - var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list) - if(M.HasDisease(D)) - return TRUE - return FALSE - -/datum/team/monkey/proc/infected_monkeys_escaped() - var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list) - if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase())) - return TRUE - return FALSE - -/datum/team/monkey/proc/infected_humans_escaped() - var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/human/M in GLOB.alive_mob_list) - if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase())) - return TRUE - return FALSE - -/datum/team/monkey/proc/infected_humans_alive() - var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/human/M in GLOB.alive_mob_list) - if(M.HasDisease(D)) - return TRUE - return FALSE - -/datum/team/monkey/proc/get_result() - if(infected_monkeys_escaped()) - return MONKEYS_ESCAPED - if(infected_monkeys_alive()) - return MONKEYS_LIVED - if(infected_humans_alive() || infected_humans_escaped()) - return DISEASE_LIVED - return MONKEYS_DIED - -/datum/team/monkey/roundend_report() - var/list/parts = list() - switch(get_result()) - if(MONKEYS_ESCAPED) - parts += "Monkey Major Victory!" - parts += "Central Command and [station_name()] were taken over by the monkeys! Ook ook!" - if(MONKEYS_LIVED) - parts += "Monkey Minor Victory!" - parts += "[station_name()] was taken over by the monkeys! Ook ook!" - if(DISEASE_LIVED) - parts += "Monkey Minor Defeat!" - parts += "All the monkeys died, but the disease lives on! The future is uncertain." - if(MONKEYS_DIED) - parts += "Monkey Major Defeat!" - parts += "All the monkeys died, and Jungle Fever was wiped out!" - var/list/leaders = get_antagonists(/datum/antagonist/monkey/leader, TRUE) - var/list/monkeys = get_antagonists(/datum/antagonist/monkey, TRUE) - - if(LAZYLEN(leaders)) - parts += "The monkey leaders were:" - parts += printplayerlist(SSticker.mode.ape_leaders) - if(LAZYLEN(monkeys)) - parts += "The monkeys were:" - parts += printplayerlist(SSticker.mode.ape_infectees) - return "
[parts.Join("
")]
" diff --git a/code/datums/antagonists/ninja.dm b/code/datums/antagonists/ninja.dm deleted file mode 100644 index e8a1c140ea..0000000000 --- a/code/datums/antagonists/ninja.dm +++ /dev/null @@ -1,155 +0,0 @@ -/datum/antagonist/ninja - name = "Ninja" - antagpanel_category = "Ninja" - job_rank = ROLE_NINJA - var/helping_station = FALSE - var/give_objectives = TRUE - var/give_equipment = TRUE - - -/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_ninja_icons_added(M) - -/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_ninja_icons_removed(M) - -/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current) - return H.equipOutfit(/datum/outfit/ninja) - -/datum/antagonist/ninja/proc/addMemories() - antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!
" - antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!
" - antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.
" - -/datum/antagonist/ninja/proc/addObjectives(quantity = 6) - var/list/possible_targets = list() - for(var/datum/mind/M in SSticker.minds) - if(M.current && M.current.stat != DEAD) - if(ishuman(M.current)) - if(M.special_role) - possible_targets[M] = 0 //bad-guy - else if(M.assigned_role in GLOB.command_positions) - possible_targets[M] = 1 //good-guy - - var/list/possible_objectives = list(1,2,3,4) - - while(objectives.len < quantity) - switch(pick_n_take(possible_objectives)) - if(1) //research - var/datum/objective/download/O = new /datum/objective/download() - O.owner = owner - O.gen_amount_goal() - objectives += O - - if(2) //steal - var/datum/objective/steal/special/O = new /datum/objective/steal/special() - O.owner = owner - objectives += O - - if(3) //protect/kill - if(!possible_targets.len) continue - var/index = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[index] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(index,index+1) - - if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = owner - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - objectives += O - else //protect - var/datum/objective/protect/O = new /datum/objective/protect() - O.owner = owner - O.target = M - O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - objectives += O - if(4) //debrain/capture - if(!possible_targets.len) continue - var/selected = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[selected] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(selected,selected+1) - - if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/debrain/O = new /datum/objective/debrain() - O.owner = owner - O.target = M - O.explanation_text = "Steal the brain of [M.current.real_name]." - objectives += O - else //capture - var/datum/objective/capture/O = new /datum/objective/capture() - O.owner = owner - O.gen_amount_goal() - objectives += O - else - break - var/datum/objective/O = new /datum/objective/survive() - O.owner = owner - owner.objectives |= objectives - - -/proc/remove_ninja(mob/living/L) - if(!L || !L.mind) - return FALSE - var/datum/antagonist/datum = L.mind.has_antag_datum(/datum/antagonist/ninja) - datum.on_removal() - return TRUE - -/proc/is_ninja(mob/living/M) - return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja) - - -/datum/antagonist/ninja/greet() - SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg')) - to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") - to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") - to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") - return - -/datum/antagonist/ninja/on_gain() - if(give_objectives) - addObjectives() - addMemories() - if(give_equipment) - equip_space_ninja(owner.current) - . = ..() - -/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin) - var/adj - switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives")) - if("Random") - helping_station = pick(TRUE,FALSE) - adj = "" - if("Syndicate") - helping_station = FALSE - adj = "syndie" - if("Nanotrasen") - helping_station = TRUE - adj = "friendly" - if("No objectives") - give_objectives = FALSE - adj = "objectiveless" - else - return - new_owner.assigned_role = ROLE_NINJA - new_owner.special_role = ROLE_NINJA - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].") - log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].") - -/datum/antagonist/ninja/antag_listing_name() - return ..() + "(Ninja)" - -/datum/antagonist/ninja/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja) - var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA] - ninjahud.join_hud(ninja) - set_antag_hud(ninja, "ninja") - -/datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja) - var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA] - ninjahud.leave_hud(ninja) - set_antag_hud(ninja, null) \ No newline at end of file diff --git a/code/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm deleted file mode 100644 index 1ec2e77f64..0000000000 --- a/code/datums/antagonists/nukeop.dm +++ /dev/null @@ -1,379 +0,0 @@ -#define NUKE_RESULT_FLUKE 0 -#define NUKE_RESULT_NUKE_WIN 1 -#define NUKE_RESULT_CREW_WIN 2 -#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 -#define NUKE_RESULT_DISK_LOST 4 -#define NUKE_RESULT_DISK_STOLEN 5 -#define NUKE_RESULT_NOSURVIVORS 6 -#define NUKE_RESULT_WRONG_STATION 7 -#define NUKE_RESULT_WRONG_STATION_DEAD 8 - -/datum/antagonist/nukeop - name = "Nuclear Operative" - roundend_category = "syndicate operatives" //just in case - antagpanel_category = "NukeOp" - job_rank = ROLE_OPERATIVE - var/datum/team/nuclear/nuke_team - var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. - var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. - var/nukeop_outfit = /datum/outfit/syndicate - -/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(M) - set_antag_hud(M, "synd") - -/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(M) - set_antag_hud(M, null) - -/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_synd_icons_added(M) - -/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_synd_icons_removed(M) - -/datum/antagonist/nukeop/proc/equip_op() - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/H = owner.current - - H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - H.equipOutfit(nukeop_outfit) - return TRUE - -/datum/antagonist/nukeop/greet() - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) - to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") - owner.announce_objectives() - return - -/datum/antagonist/nukeop/on_gain() - give_alias() - forge_objectives() - . = ..() - equip_op() - memorize_code() - if(send_to_spawnpoint) - move_to_spawnpoint() - -/datum/antagonist/nukeop/get_team() - return nuke_team - -/datum/antagonist/nukeop/proc/assign_nuke() - if(nuke_team && !nuke_team.tracked_nuke) - nuke_team.memorized_code = random_nukecode() - var/obj/machinery/nuclearbomb/syndicate/nuke = locate() in GLOB.nuke_list - if(nuke) - nuke_team.tracked_nuke = nuke - if(nuke.r_code == "ADMIN") - nuke.r_code = nuke_team.memorized_code - else //Already set by admins/something else? - nuke_team.memorized_code = nuke.r_code - else - stack_trace("Syndicate nuke not found during nuke team creation.") - nuke_team.memorized_code = null - -/datum/antagonist/nukeop/proc/give_alias() - if(nuke_team && nuke_team.syndicate_name) - var/number = 1 - number = nuke_team.members.Find(owner) - owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" - -/datum/antagonist/nukeop/proc/memorize_code() - if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) - antag_memory += "[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]
" - to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") - else - to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") - -/datum/antagonist/nukeop/proc/forge_objectives() - if(nuke_team) - owner.objectives |= nuke_team.objectives - -/datum/antagonist/nukeop/proc/move_to_spawnpoint() - var/team_number = 1 - if(nuke_team) - team_number = nuke_team.members.Find(owner) - owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) - -/datum/antagonist/nukeop/leader/move_to_spawnpoint() - owner.current.forceMove(pick(GLOB.nukeop_leader_start)) - -/datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team) - if(!new_team) - if(!always_new_team) - for(var/datum/antagonist/nukeop/N in GLOB.antagonists) - if(!N.owner) - continue - if(N.nuke_team) - nuke_team = N.nuke_team - return - nuke_team = new /datum/team/nuclear - nuke_team.update_objectives() - assign_nuke() //This is bit ugly - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - nuke_team = new_team - -/datum/antagonist/nukeop/admin_add(datum/mind/new_owner,mob/admin) - new_owner.assigned_role = ROLE_SYNDICATE - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has nuke op'ed [new_owner.current].") - log_admin("[key_name(admin)] has nuke op'ed [new_owner.current].") - -/datum/antagonist/nukeop/get_admin_commands() - . = ..() - .["Send to base"] = CALLBACK(src,.proc/admin_send_to_base) - .["Tell code"] = CALLBACK(src,.proc/admin_tell_code) - -/datum/antagonist/nukeop/proc/admin_send_to_base(mob/admin) - owner.current.forceMove(pick(GLOB.nukeop_start)) - -/datum/antagonist/nukeop/proc/admin_tell_code(mob/admin) - var/code - for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines) - if (length(bombue.r_code) <= 5 && bombue.r_code != initial(bombue.r_code)) - code = bombue.r_code - break - if (code) - antag_memory += "Syndicate Nuclear Bomb Code: [code]
" - to_chat(owner.current, "The nuclear authorization code is: [code]") - else - to_chat(admin, "No valid nuke found!") - -/datum/antagonist/nukeop/leader - name = "Nuclear Operative Leader" - nukeop_outfit = /datum/outfit/syndicate/leader - always_new_team = TRUE - var/title - -/datum/antagonist/nukeop/leader/memorize_code() - ..() - if(nuke_team && nuke_team.memorized_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = owner.current - if(!istype(H)) - P.forceMove(get_turf(H)) - else - H.put_in_hands(P, TRUE) - H.update_icons() - -/datum/antagonist/nukeop/leader/give_alias() - title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - if(nuke_team && nuke_team.syndicate_name) - owner.current.real_name = "[nuke_team.syndicate_name] [title]" - else - owner.current.real_name = "Syndicate [title]" - -/datum/antagonist/nukeop/leader/greet() - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) - to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - owner.announce_objectives() - addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) - - -/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() - if(!nuke_team) - return - nuke_team.rename_team(ask_name()) - -/datum/team/nuclear/proc/rename_team(new_name) - syndicate_name = new_name - name = "[syndicate_name] Team" - for(var/I in members) - var/datum/mind/synd_mind = I - var/mob/living/carbon/human/H = synd_mind.current - if(!istype(H)) - continue - var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) - H.fully_replace_character_name(H.real_name,chosen_name) - -/datum/antagonist/nukeop/leader/proc/ask_name() - var/randomname = pick(GLOB.last_names) - var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) - if (!newname) - newname = randomname - else - newname = reject_bad_name(newname) - if(!newname) - newname = randomname - - return capitalize(newname) - -/datum/antagonist/nukeop/lone - name = "Lone Operative" - always_new_team = TRUE - send_to_spawnpoint = FALSE //Handled by event - nukeop_outfit = /datum/outfit/syndicate/full - -/datum/antagonist/nukeop/lone/assign_nuke() - if(nuke_team && !nuke_team.tracked_nuke) - nuke_team.memorized_code = random_nukecode() - var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list - if(nuke) - nuke_team.tracked_nuke = nuke - if(nuke.r_code == "ADMIN") - nuke.r_code = nuke_team.memorized_code - else //Already set by admins/something else? - nuke_team.memorized_code = nuke.r_code - else - stack_trace("Station self destruct ot found during lone op team creation.") - nuke_team.memorized_code = null - -/datum/antagonist/nukeop/reinforcement - send_to_spawnpoint = FALSE - nukeop_outfit = /datum/outfit/syndicate/no_crystals - -/datum/team/nuclear - var/syndicate_name - var/obj/machinery/nuclearbomb/tracked_nuke - var/core_objective = /datum/objective/nuclear - var/memorized_code - -/datum/team/nuclear/New() - ..() - syndicate_name = syndicate_name() - -/datum/team/nuclear/proc/update_objectives() - if(core_objective) - var/datum/objective/O = new core_objective - O.team = src - objectives += O - -/datum/team/nuclear/proc/disk_rescued() - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - return FALSE - return TRUE - -/datum/team/nuclear/proc/operatives_dead() - for(var/I in members) - var/datum/mind/operative_mind = I - if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) - return FALSE - return TRUE - -/datum/team/nuclear/proc/syndies_escaped() - var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") - return S && (is_centcom_level(S.z) || is_transit_level(S.z)) - -/datum/team/nuclear/proc/get_result() - var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME - var/disk_rescued = disk_rescued() - var/syndies_didnt_escape = !syndies_escaped() - var/station_was_nuked = SSticker.mode.station_was_nuked - var/nuke_off_station = SSticker.mode.nuke_off_station - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - return NUKE_RESULT_FLUKE - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - return NUKE_RESULT_NUKE_WIN - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - return NUKE_RESULT_NOSURVIVORS - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - return NUKE_RESULT_WRONG_STATION - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - return NUKE_RESULT_WRONG_STATION_DEAD - else if ((disk_rescued || evacuation) && operatives_dead()) - return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD - else if (disk_rescued) - return NUKE_RESULT_CREW_WIN - else if (!disk_rescued && operatives_dead()) - return NUKE_RESULT_DISK_LOST - else if (!disk_rescued && evacuation) - return NUKE_RESULT_DISK_STOLEN - else - return //Undefined result - -/datum/team/nuclear/roundend_report() - var/list/parts = list() - parts += "[syndicate_name] Operatives:" - - switch(get_result()) - if(NUKE_RESULT_FLUKE) - parts += "Humiliating Syndicate Defeat" - parts += "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!" - if(NUKE_RESULT_NUKE_WIN) - parts += "Syndicate Major Victory!" - parts += "[syndicate_name] operatives have destroyed [station_name()]!" - if(NUKE_RESULT_NOSURVIVORS) - parts += "Total Annihilation" - parts += "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!" - if(NUKE_RESULT_WRONG_STATION) - parts += "Crew Minor Victory" - parts += "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!" - if(NUKE_RESULT_WRONG_STATION_DEAD) - parts += "[syndicate_name] operatives have earned Darwin Award!" - parts += "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!" - if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) - parts += "Crew Major Victory!" - parts += "The Research Staff has saved the disk and killed the [syndicate_name] Operatives" - if(NUKE_RESULT_CREW_WIN) - parts += "Crew Major Victory" - parts += "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!" - if(NUKE_RESULT_DISK_LOST) - parts += "Neutral Victory!" - parts += "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!" - if(NUKE_RESULT_DISK_STOLEN) - parts += "Syndicate Minor Victory!" - parts += "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!" - else - parts += "Neutral Victory" - parts += "Mission aborted!" - - var/text = "
The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/I in members) - var/datum/mind/syndicate = I - var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[syndicate.key] - if(H) - TC_uses += H.total_spent - purchases += H.generate_render(show_key = FALSE) - text += printplayerlist(members) - text += "
" - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - - parts += text - - return "
[parts.Join("
")]
" - -/datum/team/nuclear/antag_listing_name() - if(syndicate_name) - return "[syndicate_name] Syndicates" - else - return "Syndicates" - -/datum/team/nuclear/antag_listing_entry() - var/disk_report = "Nuclear Disk(s)
" - disk_report += "" - for(var/obj/item/disk/nuclear/N in GLOB.poi_list) - disk_report += "" - disk_report += "
[N.name], " - var/atom/disk_loc = N.loc - while(!isturf(disk_loc)) - if(ismob(disk_loc)) - var/mob/M = disk_loc - disk_report += "carried by [M.real_name] " - if(isobj(disk_loc)) - var/obj/O = disk_loc - disk_report += "in \a [O.name] " - disk_loc = disk_loc.loc - disk_report += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])FLW
" - var/common_part = ..() - return common_part + disk_report - -/datum/team/nuclear/is_gamemode_hero() - return SSticker.mode.name == "nuclear emergency" \ No newline at end of file diff --git a/code/datums/antagonists/pirate.dm b/code/datums/antagonists/pirate.dm deleted file mode 100644 index cdd871ff35..0000000000 --- a/code/datums/antagonists/pirate.dm +++ /dev/null @@ -1,132 +0,0 @@ -/datum/antagonist/pirate - name = "Space Pirate" - job_rank = ROLE_TRAITOR - roundend_category = "space pirates" - antagpanel_category = "Pirate" - var/datum/team/pirate/crew - -/datum/antagonist/pirate/greet() - to_chat(owner, "You are a Space Pirate!") - to_chat(owner, "The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.") - owner.announce_objectives() - -/datum/antagonist/pirate/get_team() - return crew - -/datum/antagonist/pirate/create_team(datum/team/pirate/new_team) - if(!new_team) - for(var/datum/antagonist/pirate/P in GLOB.antagonists) - if(!P.owner) - continue - if(P.crew) - crew = P.crew - return - if(!new_team) - crew = new /datum/team/pirate - crew.forge_objectives() - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - crew = new_team - -/datum/antagonist/pirate/on_gain() - if(crew) - owner.objectives |= crew.objectives - . = ..() - -/datum/antagonist/pirate/on_removal() - if(crew) - owner.objectives -= crew.objectives - . = ..() - -/datum/team/pirate - name = "Pirate crew" - -/datum/team/pirate/proc/forge_objectives() - var/datum/objective/loot/getbooty = new() - getbooty.team = src - getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas - getbooty.update_initial_value() - getbooty.update_explanation_text() - objectives += getbooty - for(var/datum/mind/M in members) - M.objectives |= objectives - - -GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( - /obj/structure/reagent_dispensers/beerkeg, - /mob/living/simple_animal/parrot, - /obj/item/stack/sheet/mineral/gold, - /obj/item/stack/sheet/mineral/diamond, - /obj/item/stack/spacecash, - /obj/item/melee/sabre,))) - -/datum/objective/loot - var/area/storage_area //Place where we we will look for the loot. - explanation_text = "Acquire valuable loot and store it in designated area." - var/target_value = 50000 - var/initial_value = 0 //Things in the vault at spawn time do not count - -/datum/objective/loot/update_explanation_text() - if(storage_area) - explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name]." - -/datum/objective/loot/proc/loot_listing() - //Lists notable loot. - if(!storage_area) - return "Nothing" - var/list/loot_table = list() - for(var/atom/movable/AM in storage_area.GetAllContents()) - if(is_type_in_typecache(AM,GLOB.pirate_loot_cache)) - var/lootname = AM.name - var/count = 1 - if(istype(AM,/obj/item/stack)) //Ugh. - var/obj/item/stack/S = AM - lootname = S.singular_name - count = S.amount - if(!loot_table[lootname]) - loot_table[lootname] = count - else - loot_table[lootname] += count - var/list/loot_texts = list() - for(var/key in loot_table) - var/amount = loot_table[key] - loot_texts += "[amount] [key][amount > 1 ? "s":""]" - return loot_texts.Join(", ") - -/datum/objective/loot/proc/get_loot_value() - if(!storage_area) - return 0 - var/value = 0 - for(var/turf/T in storage_area.contents) - value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE) - return value - initial_value - -/datum/objective/loot/proc/update_initial_value() - initial_value = get_loot_value() - -/datum/objective/loot/check_completion() - return ..() || get_loot_value() >= target_value - -/datum/team/pirate/roundend_report() - var/list/parts = list() - - parts += "Space Pirates were:" - - var/all_dead = TRUE - for(var/datum/mind/M in members) - if(considered_alive(M)) - all_dead = FALSE - parts += printplayerlist(members) - - parts += "Loot stolen: " - var/datum/objective/loot/L = locate() in objectives - parts += L.loot_listing() - parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits" - - if(L.check_completion() && !all_dead) - parts += "The pirate crew was successful!" - else - parts += "The pirate crew has failed." - - return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm deleted file mode 100644 index 5ac3bfe2aa..0000000000 --- a/code/datums/antagonists/revolution.dm +++ /dev/null @@ -1,368 +0,0 @@ -//How often to check for promotion possibility -#define HEAD_UPDATE_PERIOD 300 - -/datum/antagonist/rev - name = "Revolutionary" - roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen - antagpanel_category = "Revolution" - job_rank = ROLE_REV - var/hud_type = "rev" - var/datum/team/revolution/rev_team - -/datum/antagonist/rev/can_be_owned(datum/mind/new_owner) - . = ..() - if(.) - if(new_owner.assigned_role in GLOB.command_positions) - return FALSE - if(new_owner.unconvertable) - return FALSE - if(new_owner.current && new_owner.current.isloyal()) - return FALSE - -/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_rev_icons_added(M) - -/datum/antagonist/rev/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_rev_icons_removed(M) - -/datum/antagonist/rev/proc/equip_rev() - return - -/datum/antagonist/rev/on_gain() - . = ..() - create_objectives() - equip_rev() - owner.current.log_message("Has been converted to the revolution!", INDIVIDUAL_ATTACK_LOG) - -/datum/antagonist/rev/on_removal() - remove_objectives() - . = ..() - -/datum/antagonist/rev/greet() - to_chat(owner, "You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") - owner.announce_objectives() - -/datum/antagonist/rev/create_team(datum/team/revolution/new_team) - if(!new_team) - //For now only one revolution at a time - for(var/datum/antagonist/rev/head/H in GLOB.antagonists) - if(!H.owner) - continue - if(H.rev_team) - rev_team = H.rev_team - return - rev_team = new /datum/team/revolution - rev_team.update_objectives() - rev_team.update_heads() - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - rev_team = new_team - -/datum/antagonist/rev/get_team() - return rev_team - -/datum/antagonist/rev/proc/create_objectives() - owner.objectives |= rev_team.objectives - -/datum/antagonist/rev/proc/remove_objectives() - owner.objectives -= rev_team.objectives - -//Bump up to head_rev -/datum/antagonist/rev/proc/promote() - var/old_team = rev_team - var/datum/mind/old_owner = owner - silent = TRUE - owner.remove_antag_datum(/datum/antagonist/rev) - var/datum/antagonist/rev/head/new_revhead = new() - new_revhead.silent = TRUE - old_owner.add_antag_datum(new_revhead,old_team) - new_revhead.silent = FALSE - to_chat(old_owner, "You have proved your devotion to revolution! You are a head revolutionary now!") - -/datum/antagonist/rev/get_admin_commands() - . = ..() - .["Promote"] = CALLBACK(src,.proc/admin_promote) - -/datum/antagonist/rev/proc/admin_promote(mob/admin) - var/datum/mind/O = owner - promote() - message_admins("[key_name_admin(admin)] has head-rev'ed [O].") - log_admin("[key_name(admin)] has head-rev'ed [O].") - -/datum/antagonist/rev/head/admin_add(datum/mind/new_owner,mob/admin) - give_flash = TRUE - give_hud = TRUE - remove_clumsy = TRUE - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has head-rev'ed [new_owner.current].") - log_admin("[key_name(admin)] has head-rev'ed [new_owner.current].") - to_chat(new_owner.current, "You are a member of the revolutionaries' leadership now!") - -/datum/antagonist/rev/head/get_admin_commands() - . = ..() - . -= "Promote" - .["Take flash"] = CALLBACK(src,.proc/admin_take_flash) - .["Give flash"] = CALLBACK(src,.proc/admin_give_flash) - .["Repair flash"] = CALLBACK(src,.proc/admin_repair_flash) - .["Demote"] = CALLBACK(src,.proc/admin_demote) - -/datum/antagonist/rev/head/proc/admin_take_flash(mob/admin) - var/list/L = owner.current.get_contents() - var/obj/item/device/assembly/flash/flash = locate() in L - if (!flash) - to_chat(admin, "Deleting flash failed!") - return - qdel(flash) - -/datum/antagonist/rev/head/proc/admin_give_flash(mob/admin) - //This is probably overkill but making these impact state annoys me - var/old_give_flash = give_flash - var/old_give_hud = give_hud - var/old_remove_clumsy = remove_clumsy - give_flash = TRUE - give_hud = FALSE - remove_clumsy = FALSE - equip_rev() - give_flash = old_give_flash - give_hud = old_give_hud - remove_clumsy = old_remove_clumsy - -/datum/antagonist/rev/head/proc/admin_repair_flash(mob/admin) - var/list/L = owner.current.get_contents() - var/obj/item/device/assembly/flash/flash = locate() in L - if (!flash) - to_chat(admin, "Repairing flash failed!") - else - flash.crit_fail = 0 - flash.update_icon() - -/datum/antagonist/rev/head/proc/admin_demote(datum/mind/target,mob/user) - message_admins("[key_name_admin(user)] has demoted [owner.current] from head revolutionary.") - log_admin("[key_name(user)] has demoted [owner.current] from head revolutionary.") - demote() - -/datum/antagonist/rev/head - name = "Head Revolutionary" - hud_type = "rev_head" - var/remove_clumsy = FALSE - var/give_flash = FALSE - var/give_hud = TRUE - -/datum/antagonist/rev/head/antag_listing_name() - return ..() + "(Leader)" - -/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M) - var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV] - revhud.join_hud(M) - set_antag_hud(M,hud_type) - -/datum/antagonist/rev/proc/update_rev_icons_removed(mob/living/M) - var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV] - revhud.leave_hud(M) - set_antag_hud(M, null) - -/datum/antagonist/rev/proc/can_be_converted(mob/living/candidate) - if(!candidate.mind) - return FALSE - if(!can_be_owned(candidate.mind)) - return FALSE - var/mob/living/carbon/C = candidate //Check to see if the potential rev is implanted - if(!istype(C)) //Can't convert simple animals - return FALSE - return TRUE - -/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE) - if(!can_be_converted(rev_mind.current)) - return FALSE - if(stun) - if(iscarbon(rev_mind.current)) - var/mob/living/carbon/carbon_mob = rev_mind.current - carbon_mob.silent = max(carbon_mob.silent, 5) - carbon_mob.flash_act(1, 1) - rev_mind.current.Stun(100) - rev_mind.add_antag_datum(/datum/antagonist/rev,rev_team) - rev_mind.special_role = ROLE_REV - return TRUE - -/datum/antagonist/rev/head/proc/demote() - var/datum/mind/old_owner = owner - var/old_team = rev_team - silent = TRUE - owner.remove_antag_datum(/datum/antagonist/rev/head) - var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev() - new_rev.silent = TRUE - old_owner.add_antag_datum(new_rev,old_team) - new_rev.silent = FALSE - to_chat(old_owner, "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!") - -/datum/antagonist/rev/farewell() - if(ishuman(owner.current)) - owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", null, null, null, owner.current) - to_chat(owner, "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...") - else if(issilicon(owner.current)) - owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", null, null, null, owner.current) - to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.") - -/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter) - log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!") - if(borged) - message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]") - owner.special_role = null - if(iscarbon(owner.current)) - var/mob/living/carbon/C = owner.current - C.Unconscious(100) - owner.remove_antag_datum(type) - -/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter) - if(!borged) - return - . = ..() - -/datum/antagonist/rev/head/equip_rev() - var/mob/living/carbon/human/H = owner.current - if(!istype(H)) - return - - if(remove_clumsy && owner.assigned_role == "Clown") - to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - H.dna.remove_mutation(CLOWNMUT) - - if(give_flash) - var/obj/item/device/assembly/flash/T = new(H) - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - to_chat(H, "The Syndicate were unfortunately unable to get you a flash.") - else - to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.") - - if(give_hud) - var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H) - S.Insert(H, special = FALSE, drop_if_replaced = FALSE) - to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") - -/datum/team/revolution - name = "Revolution" - var/max_headrevs = 3 - -/datum/team/revolution/proc/update_objectives(initial = FALSE) - var/untracked_heads = SSjob.get_all_heads() - for(var/datum/objective/mutiny/O in objectives) - untracked_heads -= O.target - for(var/datum/mind/M in untracked_heads) - var/datum/objective/mutiny/new_target = new() - new_target.team = src - new_target.target = M - new_target.update_explanation_text() - objectives += new_target - for(var/datum/mind/M in members) - M.objectives |= objectives - - addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) - -/datum/team/revolution/proc/head_revolutionaries() - . = list() - for(var/datum/mind/M in members) - if(M.has_antag_datum(/datum/antagonist/rev/head)) - . += M - -/datum/team/revolution/proc/update_heads() - if(SSticker.HasRoundStarted()) - var/list/datum/mind/head_revolutionaries = head_revolutionaries() - var/list/datum/mind/heads = SSjob.get_all_heads() - var/list/sec = SSjob.get_all_sec() - - if(head_revolutionaries.len < max_headrevs && head_revolutionaries.len < round(heads.len - ((8 - sec.len) / 3))) - var/list/datum/mind/non_heads = members - head_revolutionaries - var/list/datum/mind/promotable = list() - for(var/datum/mind/khrushchev in non_heads) - if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD) - if(ROLE_REV in khrushchev.current.client.prefs.be_special) - promotable += khrushchev - if(promotable.len) - var/datum/mind/new_leader = pick(promotable) - var/datum/antagonist/rev/rev = new_leader.has_antag_datum(/datum/antagonist/rev) - rev.promote() - - addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) - - -/datum/team/revolution/roundend_report() - if(!members.len) - return - - var/list/result = list() - - result += "
" - - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" - - - var/list/targets = list() - var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) - var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) - if(headrevs.len) - var/list/headrev_part = list() - headrev_part += "The head revolutionaries were:" - headrev_part += printplayerlist(headrevs,TRUE) - result += headrev_part.Join("
") - - if(revs.len) - var/list/rev_part = list() - rev_part += "The revolutionaries were:" - rev_part += printplayerlist(revs,TRUE) - result += rev_part.Join("
") - - var/list/heads = SSjob.get_all_heads() - if(heads.len) - var/head_text = "The heads of staff were:" - head_text += "
    " - for(var/datum/mind/head in heads) - var/target = (head in targets) - head_text += "
  • " - if(target) - head_text += "Target" - head_text += "[printplayer(head, 1)]
  • " - head_text += "

" - result += head_text - - result += "
" - - return result.Join() - -/datum/team/revolution/antag_listing_entry() - var/common_part = ..() - var/heads_report = "Heads of Staff
" - heads_report += "" - for(var/datum/mind/N in SSjob.get_living_heads()) - var/mob/M = N.current - if(M) - heads_report += "" - heads_report += "" - heads_report += "" - var/turf/mob_loc = get_turf(M) - heads_report += "" - else - heads_report += "" - heads_report += "" - heads_report += "
[M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]PMFLW[mob_loc.loc]
[N.name]([N.key])Head body destroyed!PM
" - return common_part + heads_report - -/datum/team/revolution/is_gamemode_hero() - return SSticker.mode.name == "revolution" \ No newline at end of file diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm deleted file mode 100644 index 8aba74f70a..0000000000 --- a/code/datums/antagonists/wizard.dm +++ /dev/null @@ -1,339 +0,0 @@ -#define APPRENTICE_DESTRUCTION "destruction" -#define APPRENTICE_BLUESPACE "bluespace" -#define APPRENTICE_ROBELESS "robeless" -#define APPRENTICE_HEALING "healing" - -/datum/antagonist/wizard - name = "Space Wizard" - roundend_category = "wizards/witches" - antagpanel_category = "Wizard" - job_rank = ROLE_WIZARD - var/give_objectives = TRUE - var/strip = TRUE //strip before equipping - var/allow_rename = TRUE - var/hud_version = "wizard" - var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices - var/move_to_lair = TRUE - var/outfit_type = /datum/outfit/wizard - var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ - -/datum/antagonist/wizard/on_gain() - register() - if(give_objectives) - create_objectives() - equip_wizard() - if(move_to_lair) - send_to_lair() - . = ..() - if(allow_rename) - rename_wizard() - -/datum/antagonist/wizard/proc/register() - SSticker.mode.wizards |= owner - -/datum/antagonist/wizard/proc/unregister() - SSticker.mode.wizards -= src - -/datum/antagonist/wizard/create_team(datum/team/wizard/new_team) - if(!new_team) - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - wiz_team = new_team - -/datum/antagonist/wizard/get_team() - return wiz_team - -/datum/team/wizard - name = "wizard team" - var/datum/antagonist/wizard/master_wizard - -/datum/antagonist/wizard/proc/create_wiz_team() - wiz_team = new(owner) - wiz_team.name = "[owner.current.real_name] team" - wiz_team.master_wizard = src - update_wiz_icons_added(owner.current) - -/datum/antagonist/wizard/proc/send_to_lair() - if(!owner || !owner.current) - return - if(!GLOB.wizardstart.len) - SSjob.SendToLateJoin(owner.current) - to_chat(owner, "HOT INSERTION, GO GO GO") - owner.current.forceMove(pick(GLOB.wizardstart)) - -/datum/antagonist/wizard/proc/create_objectives() - switch(rand(1,100)) - if(1 to 30) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - objectives += kill_objective - - if (!(locate(/datum/objective/escape) in owner.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - objectives += escape_objective - - if(31 to 60) - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - objectives += steal_objective - - if (!(locate(/datum/objective/escape) in owner.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - objectives += escape_objective - - if(61 to 85) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - objectives += kill_objective - - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - objectives += steal_objective - - if (!(locate(/datum/objective/survive) in owner.objectives)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - objectives += survive_objective - - else - if (!(locate(/datum/objective/hijack) in owner.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = owner - objectives += hijack_objective - - for(var/datum/objective/O in objectives) - owner.objectives += O - -/datum/antagonist/wizard/on_removal() - unregister() - for(var/objective in objectives) - owner.objectives -= objective - owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff - return ..() - -/datum/antagonist/wizard/proc/equip_wizard() - if(!owner) - return - var/mob/living/carbon/human/H = owner.current - if(!istype(H)) - return - if(strip) - H.delete_equipment() - //Wizards are human by default. Use the mirror if you want something else. - H.set_species(/datum/species/human) - if(H.age < wiz_age) - H.age = wiz_age - H.equipOutfit(outfit_type) - -/datum/antagonist/wizard/greet() - to_chat(owner, "You are the Space Wizard!") - to_chat(owner, "The Space Wizards Federation has given you the following tasks:") - owner.announce_objectives() - to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") - to_chat(owner, "The spellbook is bound to you, and others cannot use it.") - to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.") - to_chat(owner,"Remember: do not forget to prepare your spells.") - -/datum/antagonist/wizard/farewell() - to_chat(owner, "You have been brainwashed! You are no longer a wizard!") - -/datum/antagonist/wizard/proc/rename_wizard() - set waitfor = FALSE - - var/wizard_name_first = pick(GLOB.wizard_first) - var/wizard_name_second = pick(GLOB.wizard_second) - var/randomname = "[wizard_name_first] [wizard_name_second]" - var/mob/living/wiz_mob = owner.current - var/newname = copytext(sanitize(input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - wiz_mob.fully_replace_character_name(wiz_mob.real_name, newname) - -/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_wiz_icons_added(M, wiz_team ? TRUE : FALSE) //Don't bother showing the icon if you're solo wizard - M.faction |= ROLE_WIZARD - -/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_wiz_icons_removed(M) - M.faction -= ROLE_WIZARD - - -/datum/antagonist/wizard/get_admin_commands() - . = ..() - .["Send to Lair"] = CALLBACK(src,.proc/admin_send_to_lair) - -/datum/antagonist/wizard/proc/admin_send_to_lair(mob/admin) - owner.current.forceMove(pick(GLOB.wizardstart)) - -/datum/antagonist/wizard/apprentice - name = "Wizard Apprentice" - hud_version = "apprentice" - var/datum/mind/master - var/school = APPRENTICE_DESTRUCTION - outfit_type = /datum/outfit/wizard/apprentice - wiz_age = APPRENTICE_AGE_MIN - -/datum/antagonist/wizard/apprentice/greet() - to_chat(owner, "You are [master.current.real_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.") - owner.announce_objectives() - -/datum/antagonist/wizard/apprentice/register() - SSticker.mode.apprentices |= owner - -/datum/antagonist/wizard/apprentice/unregister() - SSticker.mode.apprentices -= owner - -/datum/antagonist/wizard/apprentice/equip_wizard() - . = ..() - if(!owner) - return - var/mob/living/carbon/human/H = owner.current - if(!istype(H)) - return - switch(school) - if(APPRENTICE_DESTRUCTION) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") - if(APPRENTICE_BLUESPACE) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.") - if(APPRENTICE_HEALING) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) - H.put_in_hands(new /obj/item/gun/magic/staff/healing(H)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") - if(APPRENTICE_ROBELESS) - owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") - -/datum/antagonist/wizard/apprentice/create_objectives() - var/datum/objective/protect/new_objective = new /datum/objective/protect - new_objective.owner = owner - new_objective.target = master - new_objective.explanation_text = "Protect [master.current.real_name], the wizard." - owner.objectives += new_objective - objectives += new_objective - -//Random event wizard -/datum/antagonist/wizard/apprentice/imposter - name = "Wizard Imposter" - allow_rename = FALSE - move_to_lair = FALSE - -/datum/antagonist/wizard/apprentice/imposter/greet() - to_chat(owner, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!") - owner.announce_objectives() - -/datum/antagonist/wizard/apprentice/imposter/equip_wizard() - var/mob/living/carbon/human/master_mob = master.current - var/mob/living/carbon/human/H = owner.current - if(!istype(master_mob) || !istype(H)) - return - if(master_mob.ears) - H.equip_to_slot_or_del(new master_mob.ears.type, slot_ears) - if(master_mob.w_uniform) - H.equip_to_slot_or_del(new master_mob.w_uniform.type, slot_w_uniform) - if(master_mob.shoes) - H.equip_to_slot_or_del(new master_mob.shoes.type, slot_shoes) - if(master_mob.wear_suit) - H.equip_to_slot_or_del(new master_mob.wear_suit.type, slot_wear_suit) - if(master_mob.head) - H.equip_to_slot_or_del(new master_mob.head.type, slot_head) - if(master_mob.back) - H.equip_to_slot_or_del(new master_mob.back.type, slot_back) - - //Operation: Fuck off and scare people - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - -/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz,join = TRUE) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.join_hud(wiz) - set_antag_hud(wiz, hud_version) - -/datum/antagonist/wizard/proc/update_wiz_icons_removed(mob/living/wiz) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.leave_hud(wiz) - set_antag_hud(wiz, null) - - -/datum/antagonist/wizard/academy - name = "Academy Teacher" - outfit_type = /datum/outfit/wizard/academy - -/datum/antagonist/wizard/academy/equip_wizard() - . = ..() - - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile) - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball) - - var/mob/living/M = owner.current - if(!istype(M)) - return - - var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M) - Implant.implant(M) - -/datum/antagonist/wizard/academy/create_objectives() - var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders") - new_objective.owner = owner - owner.objectives += new_objective - objectives += new_objective - -//Solo wizard report -/datum/antagonist/wizard/roundend_report() - var/list/parts = list() - - parts += printplayer(owner) - - var/count = 1 - var/wizardwin = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - parts += "Objective #[count]: [objective.explanation_text] Success!" - else - parts += "Objective #[count]: [objective.explanation_text] Fail." - wizardwin = 0 - count++ - - if(wizardwin) - parts += "The wizard was successful!" - else - parts += "The wizard has failed!" - - if(owner.spell_list.len>0) - parts += "[owner.name] used the following spells: " - var/list/spell_names = list() - for(var/obj/effect/proc_holder/spell/S in owner.spell_list) - spell_names += S.name - parts += spell_names.Join(", ") - - return parts.Join("
") - -//Wizard with apprentices report -/datum/team/wizard/roundend_report() - var/list/parts = list() - - parts += "Wizards/witches of [master_wizard.owner.name] team were:" - parts += master_wizard.roundend_report() - parts += " " - parts += "[master_wizard.owner.name] apprentices were:" - parts += printplayerlist(members - master_wizard.owner) - - return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/votablemap.dm b/code/datums/votablemap.dm deleted file mode 100644 index c1c0c7d818..0000000000 --- a/code/datums/votablemap.dm +++ /dev/null @@ -1,10 +0,0 @@ -/datum/votablemap - var/name = "" - var/friendlyname = "" - var/minusers = 0 - var/maxusers = 0 - var/voteweight = 1 - -/datum/votablemap/New(name) - src.name = name - src.friendlyname = name \ No newline at end of file diff --git a/code/game/gamemodes/antag_spawner_cit.dm b/code/game/gamemodes/antag_spawner_cit.dm deleted file mode 100644 index 4cdc096072..0000000000 --- a/code/game/gamemodes/antag_spawner_cit.dm +++ /dev/null @@ -1,57 +0,0 @@ -////////////Syndicate Cortical Borer -obj/item/antag_spawner/syndi_borer - name = "syndicate brain-slug container" - desc = "Releases a modified cortical borer to assist the user." - icon = 'icons/obj/device.dmi' //Temporary? Doesn't really look like a container for xenofauna... but IDK what else could work. - icon_state = "locator" - var/polling = FALSE - -obj/item/antag_spawner/syndi_borer/spawn_antag(client/C, turf/T, mob/owner) - var/mob/living/simple_animal/borer/syndi_borer/B = new /mob/living/simple_animal/borer/syndi_borer(T) - - B.key = C.key - if (owner) - B.owner = owner - B.faction = B.faction | owner.faction.Copy() - - B.mind.assigned_role = B.name - B.mind.special_role = B.name - var/datum/objective/syndi_borer/new_objective - new_objective = new /datum/objective/syndi_borer - new_objective.owner = B.mind - new_objective.target = owner.mind - new_objective.explanation_text = "You are a modified cortical borer. You obey [owner.real_name] and must assist them in completing their objectives." - B.mind.objectives += new_objective - - to_chat(B, "You are awake at last! Seek out whoever released you and aid them as best you can!") - if(new_objective) - to_chat(B, "Objective #[1]: [new_objective.explanation_text]") - -/obj/item/antag_spawner/syndi_borer/proc/check_usability(mob/user) - if(used) - to_chat(user, "[src] appears to be empty!") - return 0 - if(polling == TRUE) - to_chat(user, "[src] is busy activating!") - return 0 - return 1 - -/obj/item/antag_spawner/syndi_borer/attack_self(mob/user) - if(!(check_usability(user))) - return - polling = TRUE - var/list/borer_candidates = pollCandidatesForMob("Do you want to play as a syndicate cortical borer?", ROLE_BORER, null, ROLE_BORER, 150, src) - if(borer_candidates.len) - polling = FALSE - if(!(check_usability(user))) - return - used = 1 - var/mob/dead/observer/theghost = pick(borer_candidates) - spawn_antag(theghost.client, get_turf(src), user) - var/datum/effect_system/spark_spread/S = new /datum/effect_system/spark_spread - S.set_up(4, 1, src) - S.start() - qdel(src) - else - polling = FALSE - to_chat(user, "Unable to connect to release specimen. Please wait and try again later or use the container on your uplink to get your points refunded.") \ No newline at end of file diff --git a/code/game/gamemodes/cit_objectives.dm b/code/game/gamemodes/cit_objectives.dm deleted file mode 100644 index fbcfc675e3..0000000000 --- a/code/game/gamemodes/cit_objectives.dm +++ /dev/null @@ -1,106 +0,0 @@ -#define MIN_LATE_TARGET_TIME 600 //lower bound of re-rolled timer, 1 min -#define MAX_LATE_TARGET_TIME 6000 //upper bound of re-rolled timer, 10 min -#define LATE_TARGET_HIT_CHANCE 70 //How often would the find_target succeed, otherwise it re-rolls later and tries again. -//Hit chance is here to avoid people checking github and then hovering around new arrivals within the max minute range every round. - -/datum/objective/assassinate/late - martyr_compatible = FALSE - - -/datum/objective/assassinate/late/find_target() - var/list/possible_targets = list() - for(var/mob/M in GLOB.latejoiners) - var/datum/mind/possible_target = M.mind - if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && is_unique_objective(possible_target)) - possible_targets += possible_target - if(possible_targets.len > 0 && prob(LATE_TARGET_HIT_CHANCE)) - target = pick(possible_targets) - martyr_compatible = TRUE //Might never matter, but I guess if an admin gives another random objective, this should now be compatible - update_explanation_text() - - message_admins("[target] has been selected as the assassination target of [owner].") - log_game("[target] has been selected as the assassination target of [owner].") - - to_chat(owner, "You hear a crackling noise in your ears, as a one-way syndicate message plays:") - to_chat(owner, "You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].") - return target - else - update_explanation_text() - addtimer(CALLBACK(src, .proc/find_target),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME)) - return null - -/datum/objective/assassinate/late/find_target_by_role(role, role_type=0, invert=0) - var/list/possible_targets = list() - for(var/mob/M in GLOB.latejoiners) - var/datum/mind/possible_target = M.mind - if((possible_target != owner) && ishuman(possible_target.current)) - var/is_role = 0 - if(role_type) - if(possible_target.special_role == role) - is_role++ - else - if(possible_target.assigned_role == role) - is_role++ - - if(invert) - if(is_role) - continue - possible_targets += possible_target - //break - else if(is_role) - possible_targets += possible_target - //break - if(possible_targets && prob(LATE_TARGET_HIT_CHANCE)) - target = pick(possible_targets) - update_explanation_text() - - message_admins("[target] has been selected as the assassination target of [owner].") - log_game("[target] has been selected as the assassination target of [owner].") - - to_chat(owner, "You hear a crackling noise in your ears, as a one-way syndicate message plays:") - to_chat(owner, "You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].") - else - update_explanation_text() - addtimer(CALLBACK(src, .proc/find_target_by_role, role, role_type, invert),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME)) - - - -/datum/objective/assassinate/late/check_completion() - if(target && target.current) //If target WAS assigned - if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite - return TRUE - return FALSE - else //If no target was ever given - if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current)) - return FALSE - if(!is_special_character(owner.current)) - return FALSE - return TRUE - -/datum/objective/assassinate/late/update_explanation_text() - //..() - if(target && target.current) - explanation_text = "Assassinate [target.name], the [!target_role_type ? target.assigned_role : target.special_role]." - else - explanation_text = "Stay alive until your target arrives on the station, you will be notified when the target has been identified." - - - -//BORER STUFF -//Because borers didn't use to have objectives -/datum/objective/normal_borer //Default objective, should technically never be used unmodified but CAN work unmodified. - explanation_text = "You must escape with at least one borer with host on the shuttle." - target_amount = 1 - martyr_compatible = 0 - -/datum/objective/normal_borer/check_completion() - var/total_borer_hosts = 0 - for(var/mob/living/carbon/C in GLOB.mob_list) - var/mob/living/simple_animal/borer/D = C.has_brain_worms() - var/turf/location = get_turf(C) - if(is_centcom_level(location.z) && D && D.stat != DEAD) - total_borer_hosts++ - if(target_amount <= total_borer_hosts) - return TRUE - else - return FALSE diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm deleted file mode 100644 index dd66edcfb1..0000000000 --- a/code/game/gamemodes/cult/blood_magic.dm +++ /dev/null @@ -1,769 +0,0 @@ -/datum/action/innate/cult/blood_magic //Blood magic handles the creation of blood spells (formerly talismans) - name = "Prepare Blood Magic" - button_icon_state = "carve" - desc = "Prepare blood magic by carving runes into your flesh. This rite is most effective with an empowering rune" - var/list/spells = list() - var/channeling = FALSE - -/datum/action/innate/cult/blood_magic/Grant() - ..() - button.screen_loc = "6:-29,4:-2" - button.moved = "6:-29,4:-2" - button.locked = TRUE - -/datum/action/innate/cult/blood_magic/Remove() - for(var/X in spells) - qdel(X) - ..() - -/datum/action/innate/cult/blood_magic/IsAvailable() - if(!iscultist(owner)) - return FALSE - return ..() - -/datum/action/innate/cult/blood_magic/proc/Positioning() - for(var/datum/action/innate/cult/blood_spell/B in spells) - var/pos = -29+spells.Find(B)*31 - B.button.screen_loc = "6:[pos],4:-2" - B.button.moved = B.button.screen_loc - B.button.locked = TRUE - -/datum/action/innate/cult/blood_magic/Activate() - var/rune = FALSE - var/limit = RUNELESS_MAX_BLOODCHARGE - for(var/obj/effect/rune/empower/R in range(1, owner)) - rune = TRUE - break - if(rune) - limit = MAX_BLOODCHARGE - if(spells.len >= limit) - if(rune) - to_chat(owner, "Your body has reached its limit, you cannot store more than [MAX_BLOODCHARGE] spells at once. Pick a spell to nullify.") - else - to_chat(owner, "Your body has reached its limit, you cannot have more than [RUNELESS_MAX_BLOODCHARGE] spells at once without an empowering rune! Pick a spell to nullify.") - var/nullify_spell = input(owner, "Choose a spell to remove.", "Current Spells") as null|anything in spells - if(nullify_spell) - qdel(nullify_spell) - return - var/entered_spell_name - var/datum/action/innate/cult/blood_spell/BS - var/list/possible_spells = list() - for(var/I in subtypesof(/datum/action/innate/cult/blood_spell)) - var/datum/action/innate/cult/blood_spell/J = I - var/cult_name = initial(J.name) - possible_spells[cult_name] = J - possible_spells += "(REMOVE SPELL)" - entered_spell_name = input(owner, "Pick a blood spell to prepare...", "Spell Choices") as null|anything in possible_spells - if(entered_spell_name == "(REMOVE SPELL)") - var/nullify_spell = input(owner, "Choose a spell to remove.", "Current Spells") as null|anything in spells - if(nullify_spell) - qdel(nullify_spell) - return - BS = possible_spells[entered_spell_name] - if(QDELETED(src) || owner.incapacitated() || !BS) - return - to_chat(owner,"You begin to carve unnatural symbols into your flesh!") - SEND_SOUND(owner, sound('sound/weapons/slice.ogg',0,1,10)) - if(!channeling) - channeling = TRUE - else - to_chat(owner, "You are already invoking blood magic!") - return - if(do_after(owner, 100 - rune*65, target = owner)) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - H.bleed(30 - rune*25) - var/datum/action/innate/cult/blood_spell/new_spell = new BS(owner) - new_spell.Grant(owner, src) - spells += new_spell - Positioning() - to_chat(owner, "Your wounds glows with power, you have prepared a [new_spell.name] invocation!") - channeling = FALSE - -/datum/action/innate/cult/blood_spell //The next generation of talismans - name = "Blood Magic" - button_icon_state = "telerune" - desc = "Fear the Old Blood." - var/charges = 1 - var/magic_path = null - var/obj/item/melee/blood_magic/hand_magic - var/datum/action/innate/cult/blood_magic/all_magic - var/base_desc //To allow for updating tooltips - var/invocation - var/health_cost = 0 - -/datum/action/innate/cult/blood_spell/Grant(mob/living/owner, datum/action/innate/cult/blood_magic/BM) - if(health_cost) - desc += "
Deals [health_cost] damage to your arm per use." - base_desc = desc - desc += "
Has [charges] use\s remaining." - all_magic = BM - ..() - -/datum/action/innate/cult/blood_spell/Remove() - if(all_magic) - all_magic.spells -= src - if(hand_magic) - qdel(hand_magic) - hand_magic = null - ..() - -/datum/action/innate/cult/blood_spell/IsAvailable() - if(!iscultist(owner) || owner.incapacitated() || !charges) - return FALSE - return ..() - -/datum/action/innate/cult/blood_spell/Activate() - if(magic_path) //If this spell flows from the hand - if(!hand_magic) - hand_magic = new magic_path(owner, src) - if(!owner.put_in_hands(hand_magic)) - qdel(hand_magic) - hand_magic = null - to_chat(owner, "You have no empty hand for invoking blood magic!") - return - to_chat(owner, "Your old wounds glow again as you invoke the [name].") - return - if(hand_magic) - qdel(hand_magic) - hand_magic = null - to_chat(owner, "You snuff out the spell with your hand, saving its power for another time.") - - -//Cult Blood Spells -/datum/action/innate/cult/blood_spell/stun - name = "Stun" - desc = "A potent spell that will stun and mute victims upon contact." - button_icon_state = "hand" - magic_path = "/obj/item/melee/blood_magic/stun" - health_cost = 10 - -/datum/action/innate/cult/blood_spell/teleport - name = "Teleport" - desc = "A useful spell that teleport cultists to a chosen destination on contact." - button_icon_state = "tele" - magic_path = "/obj/item/melee/blood_magic/teleport" - health_cost = 7 - -/datum/action/innate/cult/blood_spell/emp - name = "Electromagnetic Pulse" - desc = "A large spell that immediately disables all electronics in the area." - button_icon_state = "emp" - health_cost = 10 - invocation = "Ta'gh fara'qha fel d'amar det!" - -/datum/action/innate/cult/blood_spell/emp/Activate() - owner.visible_message("[owner]'s hand flashes a bright blue!", \ - "You speak the cursed words, emitting an EMP blast from your hand.") - empulse(owner, 3, 6) - owner.whisper(invocation, language = /datum/language/common) - charges-- - if(charges<=0) - qdel(src) - -/datum/action/innate/cult/blood_spell/shackles - name = "Shadow Shackles" - desc = "A stealthy spell that will handcuff and temporarily silence your victim." - button_icon_state = "cuff" - charges = 4 - magic_path = "/obj/item/melee/blood_magic/shackles" - -/datum/action/innate/cult/blood_spell/construction - name = "Twisted Construction" - desc = "A sinister spell used to convert:
Plasteel into runed metal
25 metal into a construct shell
Cyborgs directly into constructs
Cyborg shells into construct shells
Airlocks into runed airlocks (harm intent)" - button_icon_state = "transmute" - magic_path = "/obj/item/melee/blood_magic/construction" - -/datum/action/innate/cult/blood_spell/equipment - name = "Summon Equipment" - desc = "A crucial spell that enables you to summon either a ritual dagger or combat gear including armored robes, the nar'sien bola, and an eldritch longsword." - button_icon_state = "equip" - magic_path = "/obj/item/melee/blood_magic/armor" - -/datum/action/innate/cult/blood_spell/equipment/Activate() - var/choice = alert(owner,"Choose your equipment type",,"Combat Equipment","Ritual Dagger","Cancel") - if(choice == "Ritual Dagger") - var/turf/T = get_turf(owner) - owner.visible_message("[owner]'s hand glows red for a moment.", \ - "Red light begins to shimmer and take form within your hand!") - var/obj/O = new /obj/item/melee/cultblade/dagger(T) - if(owner.put_in_hands(O)) - to_chat(owner, "A ritual dagger appears in your hand!") - else - owner.visible_message("A ritual dagger appears at [owner]'s feet!", \ - "A ritual dagger materializes at your feet.") - SEND_SOUND(owner, sound('sound/effects/magic.ogg',0,1,25)) - charges-- - desc = base_desc - desc += "
Has [charges] use\s remaining." - if(charges<=0) - qdel(src) - else if(choice == "Combat Equipment") - ..() - -/datum/action/innate/cult/blood_spell/horror - name = "Hallucinations" - desc = "A ranged yet stealthy spell that will break the mind of the victim with nightmarish hallucinations." - button_icon_state = "horror" - var/obj/effect/proc_holder/horror/PH - charges = 4 - -/datum/action/innate/cult/blood_spell/horror/New() - PH = new() - PH.attached_action = src - ..() - -/datum/action/innate/cult/blood_spell/horror/Destroy() - var/obj/effect/proc_holder/horror/destroy = PH - . = ..() - if(destroy && !QDELETED(destroy)) - QDEL_NULL(destroy) - -/datum/action/innate/cult/blood_spell/horror/Activate() - PH.toggle(owner) //the important bit - return TRUE - -/obj/effect/proc_holder/horror - active = FALSE - ranged_mousepointer = 'icons/effects/cult_target.dmi' - var/datum/action/innate/cult/blood_spell/attached_action - -/obj/effect/proc_holder/horror/Destroy() - var/datum/action/innate/cult/blood_spell/AA = attached_action - . = ..() - if(AA && !QDELETED(AA)) - QDEL_NULL(AA) - -/obj/effect/proc_holder/horror/proc/toggle(mob/user) - if(active) - remove_ranged_ability("You dispel the magic...") - else - add_ranged_ability(user, "You prepare to horrify a target...") - -/obj/effect/proc_holder/horror/InterceptClickOn(mob/living/caller, params, atom/target) - if(..()) - return - if(ranged_ability_user.incapacitated() || !iscultist(caller)) - remove_ranged_ability() - return - var/turf/T = get_turf(ranged_ability_user) - if(!isturf(T)) - return FALSE - if(target in view(7, get_turf(ranged_ability_user))) - if(!ishuman(target) || iscultist(target)) - return - var/mob/living/carbon/human/H = target - H.hallucination = max(H.hallucination, 240) - SEND_SOUND(ranged_ability_user, sound('sound/effects/ghost.ogg',0,1,50)) - var/image/C = image('icons/effects/cult_effects.dmi',H,"bloodsparkles", ABOVE_MOB_LAYER) - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/cult, "cult_apoc", C, FALSE) - addtimer(CALLBACK(H,/atom/.proc/remove_alt_appearance,"cult_apoc",TRUE), 2400, TIMER_OVERRIDE|TIMER_UNIQUE) - to_chat(ranged_ability_user,"[H] has been cursed with living nightmares!") - attached_action.charges-- - attached_action.desc = attached_action.base_desc - attached_action.desc += "
Has [attached_action.charges] use\s remaining." - attached_action.UpdateButtonIcon() - if(attached_action.charges <= 0) - remove_mousepointer(ranged_ability_user.client) - remove_ranged_ability("You have exhausted the spell's power!") - qdel(src) - -/datum/action/innate/cult/blood_spell/veiling - name = "Conceal Presence" - desc = "A multi-function spell that alternates between hiding and revealing nearby cult runes, structures, turf, and airlocks." - invocation = "Kla'atu barada nikt'o!" - button_icon_state = "gone" - charges = 10 - var/revealing = FALSE //if it reveals or not - -/datum/action/innate/cult/blood_spell/veiling/Activate() - if(!revealing) - owner.visible_message("Thin grey dust falls from [owner]'s hand!", \ - "You invoke the veiling spell, hiding nearby runes.") - charges-- - SEND_SOUND(owner, sound('sound/magic/smoke.ogg',0,1,25)) - owner.whisper(invocation, language = /datum/language/common) - for(var/obj/effect/rune/R in range(5,owner)) - R.conceal() - for(var/obj/structure/destructible/cult/S in range(5,owner)) - S.conceal() - for(var/turf/open/floor/engine/cult/T in range(5,owner)) - T.realappearance.alpha = 0 - for(var/obj/machinery/door/airlock/cult/AL in range(5, owner)) - AL.conceal() - revealing = TRUE - name = "Reveal Runes" - button_icon_state = "back" - else - owner.visible_message("A flash of light shines from [owner]'s hand!", \ - "You invoke the counterspell, revealing nearby runes.") - charges-- - owner.whisper(invocation, language = /datum/language/common) - SEND_SOUND(owner, sound('sound/magic/enter_blood.ogg',0,1,25)) - for(var/obj/effect/rune/R in range(7,owner)) //More range in case you weren't standing in exactly the same spot - R.reveal() - for(var/obj/structure/destructible/cult/S in range(6,owner)) - S.reveal() - for(var/turf/open/floor/engine/cult/T in range(6,owner)) - T.realappearance.alpha = initial(T.realappearance.alpha) - for(var/obj/machinery/door/airlock/cult/AL in range(6, owner)) - AL.reveal() - revealing = FALSE - name = "Conceal Runes" - button_icon_state = "gone" - if(charges<= 0) - qdel(src) - desc = base_desc - desc += "
Has [charges] use\s remaining." - UpdateButtonIcon() - -/datum/action/innate/cult/blood_spell/manipulation - name = "Blood Rites" - desc = "A complex spell that allows you to gather blood and use it for healing or other powerful spells." - invocation = "Fel'th Dol Ab'orod!" - button_icon_state = "manip" - charges = 5 - magic_path = "/obj/item/melee/blood_magic/manipulator" - - -// The "magic hand" items -/obj/item/melee/blood_magic - name = "\improper magical aura" - desc = "Sinister looking aura that distorts the flow of reality around it." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "disintegrate" - item_state = null - flags_1 = ABSTRACT_1 | NODROP_1 | DROPDEL_1 - w_class = WEIGHT_CLASS_HUGE - throwforce = 0 - throw_range = 0 - throw_speed = 0 - var/invocation - var/uses = 1 - var/health_cost = 0 //The amount of health taken from the user when invoking the spell - var/datum/action/innate/cult/blood_spell/source - -/obj/item/melee/blood_magic/New(loc, spell) - source = spell - uses = source.charges - health_cost = source.health_cost - ..() - -/obj/item/melee/blood_magic/Destroy() - if(!QDELETED(source)) - if(uses <= 0) - source.hand_magic = null - qdel(source) - source = null - else - source.hand_magic = null - source.charges = uses - source.desc = source.base_desc - source.desc += "
Has [uses] use\s remaining." - source.UpdateButtonIcon() - ..() - -/obj/item/melee/blood_magic/attack_self(mob/living/user) - afterattack(user, user, TRUE) - -/obj/item/melee/blood_magic/attack(mob/living/M, mob/living/carbon/user) - if(!iscarbon(user) || !iscultist(user)) - uses = 0 - qdel(src) - return - add_logs(user, M, "used a cult spell on", source.name, "") - M.lastattacker = user.real_name - M.lastattackerckey = user.ckey - -/obj/item/melee/blood_magic/afterattack(atom/target, mob/living/carbon/user, proximity) - if(invocation) - user.whisper(invocation, language = /datum/language/common) - if(health_cost) - if(user.active_hand_index == 1) - user.apply_damage(health_cost, BRUTE, "l_arm") - else - user.apply_damage(health_cost, BRUTE, "r_arm") - if(uses <= 0) - qdel(src) - else if(source) - source.desc = source.base_desc - source.desc += "
Has [uses] use\s remaining." - source.UpdateButtonIcon() - -//Stun -/obj/item/melee/blood_magic/stun - color = "#ff0000" // red - invocation = "Fuu ma'jin!" - -/obj/item/melee/blood_magic/stun/afterattack(atom/target, mob/living/carbon/user, proximity) - if(!isliving(target) || !proximity) - return - var/mob/living/L = target - if(iscultist(target)) - return - if(iscultist(user)) - user.visible_message("[user] holds up their hand, which explodes in a flash of red light!", \ - "You stun [L] with the spell!") - var/obj/item/nullrod/N = locate() in L - if(N) - target.visible_message("[L]'s holy weapon absorbs the light!", \ - "Your holy weapon absorbs the blinding light!") - else - L.Knockdown(180) - L.flash_act(1,1) - if(issilicon(target)) - var/mob/living/silicon/S = L - S.emp_act(EMP_HEAVY) - else if(iscarbon(target)) - var/mob/living/carbon/C = L - C.silent += 6 - C.stuttering += 15 - C.cultslurring += 15 - C.Jitter(15) - if(is_servant_of_ratvar(L)) - L.adjustBruteLoss(15) - uses-- - ..() - -//Teleportation -/obj/item/melee/blood_magic/teleport - color = RUNE_COLOR_TELEPORT - desc = "A potent spell that teleport cultists on contact." - invocation = "Sas'so c'arta forbici!" - -/obj/item/melee/blood_magic/teleport/afterattack(atom/target, mob/living/carbon/user, proximity) - if(!iscultist(target) || !proximity) - to_chat(user, "You can only teleport adjacent cultists with this spell!") - return - if(iscultist(user)) - var/list/potential_runes = list() - var/list/teleportnames = list() - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T - - if(!potential_runes.len) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport talisman failed - no other teleport runes") - return - - var/turf/T = get_turf(src) - if(is_away_level(T.z)) - to_chat(user, "You are not in the right dimension!") - log_game("Teleport spell failed - user in away mission") - return - - var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked - var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) - return - var/turf/dest = get_turf(actual_selected_rune) - if(is_blocked_turf(dest, TRUE)) - to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") - return - uses-- - user.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ - "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") - var/mob/living/L = target - L.forceMove(dest) - dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") - ..() - -//Shackles -/obj/item/melee/blood_magic/shackles - name = "Shadow Shackles" - desc = "Allows you to bind a victim and temporarily silence them." - invocation = "In'totum Lig'abis!" - color = "#000000" // black - -/obj/item/melee/blood_magic/shackles/afterattack(atom/target, mob/living/carbon/user, proximity) - if(iscultist(user) && iscarbon(target) && proximity) - var/mob/living/carbon/C = target - if(C.get_num_arms() >= 2 || C.get_arm_ignore()) - CuffAttack(C, user) - else - user.visible_message("This victim doesn't have enough arms to complete the restraint!") - return - ..() - -/obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user) - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - C.visible_message("[user] begins restraining [C] with dark magic!", \ - "[user] begins shaping a dark magic around your wrists!") - if(do_mob(user, C, 30)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/restraints/handcuffs/energy/cult/used(C) - C.update_handcuffed() - C.silent += 5 - to_chat(user, "You shackle [C].") - add_logs(user, C, "shackled") - uses-- - else - to_chat(user, "[C] is already bound.") - else - to_chat(user, "You fail to shackle [C].") - else - to_chat(user, "[C] is already bound.") - - -/obj/item/restraints/handcuffs/energy/cult //For the shackling spell - name = "shadow shackles" - desc = "Shackles that bind the wrists with sinister magic." - trashtype = /obj/item/restraints/handcuffs/energy/used - flags_1 = DROPDEL_1 - -/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!") - . = ..() - - -//Construction: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal -/obj/item/melee/blood_magic/construction - name = "Twisted Construction" - desc = "Corrupts metal and plasteel into more sinister forms." - invocation = "Ethra p'ni dedol!" - color = "#000000" // black - -/obj/item/melee/blood_magic/construction/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(proximity_flag && iscultist(user)) - var/turf/T = get_turf(target) - if(istype(target, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/candidate = target - if(candidate.use(50)) - uses-- - to_chat(user, "A dark cloud eminates from your hand and swirls around the metal, twisting it into a construct shell!") - new /obj/structure/constructshell(T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - else - to_chat(user, "You need 50 metal to produce a construct shell!") - else if(istype(target, /obj/item/stack/sheet/plasteel)) - var/obj/item/stack/sheet/plasteel/candidate = target - var/quantity = min(candidate.amount, uses) - uses -= quantity - new /obj/item/stack/sheet/runed_metal(T,quantity) - candidate.use(quantity) - to_chat(user, "A dark cloud eminates from you hand and swirls around the plasteel, transforming it into runed metal!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - else if(istype(target,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/candidate = target - if(candidate.mmi) - user.visible_message("A dark cloud eminates from [user]'s hand and swirls around [candidate]!") - playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) - var/prev_color = candidate.color - candidate.color = "black" - if(do_after(user, 90, target = candidate)) - candidate.emp_act(EMP_HEAVY) - var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") - user.visible_message("The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!") - switch(construct_class) - if("Juggernaut") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T) - if("Wraith") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) - if("Artificer") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - uses-- - candidate.mmi = null - qdel(candidate) - else - candidate.color = prev_color - else - uses-- - to_chat(user, "A dark cloud eminates from you hand and swirls around [candidate] - twisting it into a construct shell!") - new /obj/structure/constructshell(T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - else if(istype(target,/obj/machinery/door/airlock)) - target.narsie_act() - uses-- - user.visible_message("Black ribbons suddenly eminate from [user]'s hand and cling to the airlock - twisting and corrupting it!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - else - to_chat(user, "The spell will not work on [target]!") - ..() - -//Armor: Gives the target a basic cultist combat loadout -/obj/item/melee/blood_magic/armor - name = "Sinister Armaments" - desc = "A spell that will equip the target with cultist equipment if there is a slot to equip it to." - color = "#33cc33" // green - -/obj/item/melee/blood_magic/armor/afterattack(atom/target, mob/living/carbon/user, proximity) - if(iscarbon(target) && proximity) - uses-- - var/mob/living/carbon/C = target - C.visible_message("Otherworldly armor suddenly appears on [C]!") - C.equip_to_slot_or_del(new /obj/item/clothing/under/color/black,slot_w_uniform) - C.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) - C.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) - C.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes) - C.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), slot_back) - if(C == user) - qdel(src) //Clears the hands - C.put_in_hands(new /obj/item/melee/cultblade(user)) - C.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user)) - ..() - -/obj/item/melee/blood_magic/manipulator - name = "Blood Rite" - desc = "A spell that will absorb blood from anything you touch.
Touching cultists and constructs can heal them.
Clicking the hand will potentially let you focus the spell into something stronger." - color = "#7D1717" - -/obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity) - if(proximity) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(NOBLOOD in H.dna.species.species_traits) - to_chat(user,"Blood rites do not work on species with no blood!") - return - if(iscultist(H)) - if(H.stat == DEAD) - to_chat(user,"Only a revive rune can bring back the dead!") - return - if(H.blood_volume < BLOOD_VOLUME_SAFE) - var/restore_blood = BLOOD_VOLUME_SAFE - H.blood_volume - if(uses*2 < restore_blood) - H.blood_volume += uses*2 - to_chat(user,"You use the last of your blood rites to restore what blood you could!") - uses = 0 - return ..() - else - H.blood_volume = BLOOD_VOLUME_SAFE - uses -= round(restore_blood/2) - to_chat(user,"Your blood rites have restored [H == user ? "your" : "their"] blood to safe levels!") - var/overall_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss() - if(overall_damage == 0) - to_chat(user,"That cultist doesn't require healing!") - else - var/ratio = uses/overall_damage - if(H == user) - to_chat(user,"Your blood healing is far less efficient when used on yourself!") - ratio *= 0.35 // Healing is half as effective if you can't perform a full heal - uses -= round(overall_damage) // Healing is 65% more "expensive" even if you can still perform the full heal - if(ratio>1) - ratio = 1 - uses -= round(overall_damage) - H.visible_message("[H] is fully healed by [H==user ? "their":"[H]'s"]'s blood magic!") - else - H.visible_message("[H] is partially healed by [H==user ? "their":"[H]'s"] blood magic.") - uses = 0 - ratio *= -1 - H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((overall_damage*ratio) * (H.getToxLoss() / overall_damage), 0) - H.adjustFireLoss((overall_damage*ratio) * (H.getFireLoss() / overall_damage), 0) - H.adjustBruteLoss((overall_damage*ratio) * (H.getBruteLoss() / overall_damage), 0) - H.updatehealth() - playsound(get_turf(H), 'sound/magic/staff_healing.ogg', 25) - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - user.Beam(H,icon_state="sendbeam",time=15) - else - if(H.stat == DEAD) - to_chat(user,"Their blood has stopped flowing, you'll have to find another way to extract it.") - return - if(H.cultslurring) - to_chat(user,"Their blood has been tainted by an even stronger form of blood magic, it's no use to us like this!") - return - if(H.blood_volume > BLOOD_VOLUME_SAFE) - H.blood_volume -= 100 - uses += 50 - user.Beam(H,icon_state="drainbeam",time=10) - playsound(get_turf(H), 'sound/magic/enter_blood.ogg', 50) - H.visible_message("[user] has drained some of [H]'s blood!") - to_chat(user,"Your blood rite gains 50 charges from draining [H]'s blood.") - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - else - to_chat(user,"They're missing too much blood - you cannot drain them further!") - return - if(isconstruct(target)) - var/mob/living/simple_animal/M = target - var/missing = M.maxHealth - M.health - if(missing) - if(uses > missing) - M.adjustHealth(-missing) - M.visible_message("[M] is fully-healed by [user]'s blood magic!") - uses -= missing - else - M.adjustHealth(-uses) - M.visible_message("[M] is healed by [user]'sblood magic!") - uses = 0 - playsound(get_turf(M), 'sound/magic/staff_healing.ogg', 25) - user.Beam(M,icon_state="sendbeam",time=10) - if(istype(target, /obj/effect/decal/cleanable/blood)) - blood_draw(target, user) - ..() - -/obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user) - var/temp = 0 - var/turf/T = get_turf(target) - if(T) - for(var/obj/effect/decal/cleanable/blood/B in view(T, 2)) - if(B.blood_state == "blood") - if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam - temp += 30 - else - temp += max((B.bloodiness**2)/800,1) - new /obj/effect/temp_visual/cult/turf/floor(get_turf(B)) - qdel(B) - for(var/obj/effect/decal/cleanable/trail_holder/TH in view(T, 2)) - qdel(TH) - var/obj/item/clothing/shoes/shoecheck = user.shoes - if(shoecheck && shoecheck.bloody_shoes["blood"]) - temp += shoecheck.bloody_shoes["blood"]/20 - shoecheck.bloody_shoes["blood"] = 0 - if(temp) - user.Beam(T,icon_state="drainbeam",time=15) - new /obj/effect/temp_visual/cult/sparks(get_turf(user)) - playsound(T, 'sound/magic/enter_blood.ogg', 50) - to_chat(user, "Your blood rite has gained [round(temp)] charge\s from blood sources around you!") - uses += round(temp) - -/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user) - if(iscultist(user)) - var/list/options = list("Blood Spear (200)", "Blood Bolt Barrage (400)", "Blood Beam (600)") - var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options - if(!choice) - to_chat(user, "You decide against conducting a greater blood rite.") - return - switch(choice) - if("Blood Spear (200)") - if(uses < 200) - to_chat(user, "You need 200 charges to perform this rite.") - else - uses -= 200 - var/turf/T = get_turf(user) - qdel(src) - var/datum/action/innate/cult/spear/S = new(user) - var/obj/item/twohanded/cult_spear/rite = new(T) - S.Grant(user, rite) - rite.spear_act = S - if(user.put_in_hands(rite)) - to_chat(user, "A [rite.name] appears in your hand!") - else - user.visible_message("A [rite.name] appears at [user]'s feet!", \ - "A [rite.name] materializes at your feet.") - if("Blood Bolt Barrage (400)") - if(uses < 400) - to_chat(user, "You need 400 charges to perform this rite.") - else - var/obj/rite = new /obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage/blood() - uses -= 400 - qdel(src) - if(user.put_in_hands(rite)) - to_chat(user, "Your hands glow with power!") - else - to_chat(user, "You need a free hand for this rite!") - qdel(rite) - if("Blood Beam (600)") - if(uses < 600) - to_chat(user, "You need 600 charges to perform this rite.") - else - var/obj/rite = new /obj/item/blood_beam() - uses -= 600 - qdel(src) - if(user.put_in_hands(rite)) - to_chat(user, "Your hands glow with POWER OVERWHELMING!!!") - else - to_chat(user, "You need a free hand for this rite!") - qdel(rite) diff --git a/code/citadel/dogborgstuff.dm b/code/game/objects/items/devices/dogborg_sleeper.dm similarity index 57% rename from code/citadel/dogborgstuff.dm rename to code/game/objects/items/devices/dogborg_sleeper.dm index fcefdcc3e3..217786f142 100644 --- a/code/citadel/dogborgstuff.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -1,306 +1,4 @@ -/obj/item/dogborg/jaws/big - name = "combat jaws" - icon = 'icons/mob/dogborg.dmi' - icon_state = "jaws" - desc = "The jaws of the law." - flags_1 = CONDUCT_1 - force = 12 - throwforce = 0 - hitsound = 'sound/weapons/bite.ogg' - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - w_class = 3 - sharpness = IS_SHARP - -/obj/item/dogborg/jaws/small - name = "puppy jaws" - icon = 'icons/mob/dogborg.dmi' - icon_state = "smalljaws" - desc = "The jaws of a small dog." - flags_1 = CONDUCT_1 - force = 6 - throwforce = 0 - hitsound = 'sound/weapons/bite.ogg' - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - w_class = 3 - sharpness = IS_SHARP - -/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) - ..() - user.do_attack_animation(A, ATTACK_EFFECT_BITE) - -/obj/item/dogborg/jaws/small/attack_self(mob/user) - var/mob/living/silicon/robot.R = user - if(R.emagged) - name = "combat jaws" - icon = 'icons/mob/dogborg.dmi' - icon_state = "jaws" - desc = "The jaws of the law." - flags_1 = CONDUCT_1 - force = 12 - throwforce = 0 - hitsound = 'sound/weapons/bite.ogg' - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - w_class = 3 - sharpness = IS_SHARP - else - name = "puppy jaws" - icon = 'icons/mob/dogborg.dmi' - icon_state = "smalljaws" - desc = "The jaws of a small dog." - flags_1 = CONDUCT_1 - force = 5 - throwforce = 0 - hitsound = 'sound/weapons/bite.ogg' - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - w_class = 3 - sharpness = IS_SHARP - update_icon() - - -//Cuffs - -/obj/item/restraints/handcuffs/cable/zipties/cyborg/dog/attack(mob/living/carbon/C, mob/user) - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 60, 1, -2) - C.visible_message("[user] is trying to put zipties on [C]!", \ - "[user] is trying to put zipties on [C]!") - if(do_mob(user, C, 60)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C) - C.update_inv_handcuffed(0) - to_chat(user,"You handcuff [C].") - playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) - add_logs(user, C, "handcuffed") - else - to_chat(user,"You fail to handcuff [C]!") - - -//Boop - -/obj/item/device/analyzer/nose - name = "boop module" - icon = 'icons/mob/dogborg.dmi' - icon_state = "nose" - desc = "The BOOP module" - flags_1 = CONDUCT_1 - force = 0 - throwforce = 0 - attack_verb = list("nuzzled", "nosed", "booped") - w_class = 1 - -/obj/item/device/analyzer/nose/attack_self(mob/user) - user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") - - var/turf/location = user.loc - if(!istype(location)) - return - - var/datum/gas_mixture/environment = location.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - to_chat(user, "Results:") - if(abs(pressure - ONE_ATMOSPHERE) < 10) - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - else - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - if(total_moles) - var/list/env_gases = environment.gases - - environment.assert_gases(arglist(GLOB.hardcoded_gases)) - var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles - var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles - var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles - var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles - environment.garbage_collect() - - if(abs(n2_concentration - N2STANDARD) < 20) - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - else - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - - if(abs(o2_concentration - O2STANDARD) < 2) - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - else - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - - if(co2_concentration > 0.01) - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - else - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - - if(plasma_concentration > 0.005) - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - else - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - - - for(var/id in env_gases) - if(id in GLOB.hardcoded_gases) - continue - var/gas_concentration = env_gases[id][MOLES]/total_moles - to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %") - to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") - -/obj/item/device/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens - . = ..() - -//Delivery - -/obj/item/storage/bag/borgdelivery - name = "fetching storage" - desc = "Fetch the thing!" - icon = 'icons/mob/dogborg.dmi' - icon_state = "dbag" - //Can hold one big item at a time. Drops contents on unequip.(see inventory.dm) - w_class = 5 - max_w_class = 2 - max_combined_w_class = 2 - storage_slots = 1 - collection_mode = 0 - can_hold = list() // any - cant_hold = list(/obj/item/disk/nuclear) - - -//Tongue stuff - -/obj/item/soap/tongue - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon = 'icons/mob/dogborg.dmi' - icon_state = "synthtongue" - hitsound = 'sound/effects/attackblob.ogg' - cleanspeed = 80 - -/obj/item/soap/tongue/scrubpup - cleanspeed = 25 //slightly faster than a mop. - -/obj/item/soap/tongue/New() - ..() - flags_1 |= NOBLUDGEON_1 //No more attack messages - -/obj/item/trash/rkibble - name = "robo kibble" - desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." - icon = 'icons/mob/dogborg.dmi' - icon_state= "kibble" - -/obj/item/soap/tongue/attack_self(mob/user) - var/mob/living/silicon/robot.R = user - if(R.emagged) - name = "hacked tongue of doom" - desc = "Your tongue has been upgraded successfully. Congratulations." - icon = 'icons/mob/dogborg.dmi' - icon_state = "syndietongue" - cleanspeed = 10 //(nerf'd)tator soap stat - else - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon = 'icons/mob/dogborg.dmi' - icon_state = "synthtongue" - cleanspeed = initial(cleanspeed) - update_icon() - -/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) - var/mob/living/silicon/robot.R = user - if(!proximity || !check_allowed_items(target)) - return - if(R.client && (target in R.client.screen)) - to_chat(R, "You need to take that [target.name] off before cleaning it!") - else if(is_cleanable(target)) - R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't eat them. - to_chat(R, "You finish licking off \the [target.name].") - qdel(target) - R.cell.give(50) - else if(isobj(target)) //hoo boy. danger zone man - if(istype(target,/obj/item/trash)) - R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - qdel(target) - R.cell.give(250) - return - if(istype(target,/obj/item/stock_parts/cell)) - R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") - if(do_after(R, 50, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - var/obj/item/stock_parts/cell.C = target - R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf - qdel(target) - return - var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT - if(!I.anchored && R.emagged) - R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") - if(do_after(R, 100, target = I)) //Nerf dat time yo - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. Even emags don't make you magically eat things at range. - return //If they moved away, you can't eat them. - visible_message("[R] chews up \the [target.name] and cleans off the debris!") - to_chat(R, "You finish off \the [target.name].") - qdel(I) - R.cell.give(500) - return - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't clean them. - to_chat(R,"You clean \the [target.name].") - var/obj/effect/decal/cleanable/C = locate() in target - qdel(C) - SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - else if(ishuman(target)) - if(R.emagged) - var/mob/living/L = target - if(R.cell.charge <= 666) - return - L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! - L.Knockdown(80) - L.apply_effect(STUTTER, 4) - L.visible_message("[R] has shocked [L] with its tongue!", \ - "[R] has shocked you with its tongue! You can feel the betrayal.") - playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - R.cell.use(666) - else - R.visible_message("\the [R] affectionally licks \the [target]'s face!", "You affectionally lick \the [target]'s face!") - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - return - else if(istype(target, /obj/structure/window)) - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't clean them. - to_chat(R, "You clean \the [target.name].") - target.color = initial(target.color) - else - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't clean them. - to_chat(R, "You clean \the [target.name].") - var/obj/effect/decal/cleanable/C = locate() in target - qdel(C) - SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - return - - - -//Defibs - -/obj/item/twohanded/shockpaddles/cyborg/hound - name = "defibrillator paws" - desc = "MediHound specific shock paws." - icon = 'icons/mob/dogborg.dmi' - icon_state = "defibpaddles0" - item_state = "defibpaddles0" - -//Sleeper +// Dogborg Sleeper units /obj/item/device/dogborg/sleeper name = "hound sleeper" @@ -363,7 +61,7 @@ return if(!(target.client && target.client.prefs && target.client.prefs.toggles && (target.client.prefs.toggles & MEDIHOUND_SLEEPER))) to_chat(user, "This person is incompatible with our equipment.") - return + return if(target.buckled) to_chat(user, "The user is buckled and can not be put into your [src.name].") return @@ -799,101 +497,4 @@ user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside.", "Your garbage compactor groans lightly as [trashman] slips inside.") playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) return - return - - -// Pounce stuff for K-9 - -/obj/item/dogborg/pounce - name = "pounce" - icon = 'icons/mob/dogborg.dmi' - icon_state = "pounce" - desc = "Leap at your target to momentarily stun them." - force = 0 - throwforce = 0 - -/obj/item/dogborg/pounce/New() - ..() - flags_1 |= NOBLUDGEON_1 - -/mob/living/silicon/robot - var/leaping = 0 - var/pounce_cooldown = 0 - var/pounce_cooldown_time = 50 //Nearly doubled, u happy? - var/pounce_spoolup = 3 - var/leap_at - var/disabler - var/laser - var/sleeper_g - var/sleeper_r - -#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. - -/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) - var/mob/living/silicon/robot/R = user - if(R && !R.pounce_cooldown) - R.pounce_cooldown = !R.pounce_cooldown - to_chat(R, "Your targeting systems lock on to [A]...") - addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) - spawn(R.pounce_cooldown_time) - R.pounce_cooldown = !R.pounce_cooldown - else if(R && R.pounce_cooldown) - to_chat(R, "Your leg actuators are still recharging!") - -/mob/living/silicon/robot/proc/leap_at(atom/A) - if(leaping || stat || buckled || lying) - return - - if(!has_gravity(src) || !has_gravity(A)) - to_chat(src,"It is unsafe to leap without gravity!") - //It's also extremely buggy visually, so it's balance+bugfix - return - - if(cell.charge <= 500) - to_chat(src,"Insufficent reserves for jump actuators!") - return - - else - leaping = 1 - weather_immunities += "lava" - pixel_y = 10 - update_icons() - throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) - cell.use(500) //Doubled the energy consumption - weather_immunities -= "lava" - -/mob/living/silicon/robot/throw_impact(atom/A) - - if(!leaping) - return ..() - - if(A) - if(isliving(A)) - var/mob/living/L = A - var/blocked = 0 - if(ishuman(A)) - var/mob/living/carbon/human/H = A - if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) - blocked = 1 - if(!blocked) - L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - L.Knockdown(45) - playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) - sleep(2)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) - else - Knockdown(45, 1, 1) - - pounce_cooldown = !pounce_cooldown - spawn(pounce_cooldown_time) //3s by default - pounce_cooldown = !pounce_cooldown - else if(A.density && !A.CanPass(src)) - visible_message("[src] smashes into [A]!", "You smash into [A]!") - playsound(src, 'sound/items/trayhit1.ogg', 50, 1) - Knockdown(45, 1, 1) - - if(leaping) - leaping = 0 - pixel_y = initial(pixel_y) - update_icons() - update_canmove() + return \ No newline at end of file diff --git a/code/game/skincmd.dm b/code/game/skincmd.dm deleted file mode 100644 index ad2f97f55a..0000000000 --- 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(mob/user, name as text, obj/O) - 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/modules/atmospherics/machinery/other/zvent.dm b/code/modules/atmospherics/machinery/other/zvent.dm deleted file mode 100644 index d12c6196ec..0000000000 --- a/code/modules/atmospherics/machinery/other/zvent.dm +++ /dev/null @@ -1,36 +0,0 @@ -/obj/machinery/zvent - name = "interfloor air transfer system" - - icon = 'icons/obj/atmospherics/components/unary_devices.dmi' - icon_state = "vent_map" - density = FALSE - anchored=1 - desc = "This may be needed some day." - - var/on = FALSE - var/volume_rate = 800 - -/obj/machinery/zvent/New() - ..() - SSair.atmos_machinery += src - -/obj/machinery/zvent/Destroy() - SSair.atmos_machinery -= src - return ..() - -/obj/machinery/zvent/process_atmos() - - //all this object does, is make its turf share air with the ones above and below it, if they have a vent too. - if(isturf(loc)) //if we're not on a valid turf, forget it - for (var/new_z in list(-1,1)) //change this list if a fancier system of z-levels gets implemented - var/turf/open/zturf_conn = locate(x,y,z+new_z) - if (istype(zturf_conn)) - var/obj/machinery/zvent/zvent_conn= locate(/obj/machinery/zvent) in zturf_conn - if (istype(zvent_conn)) - //both floors have simulated turfs, share() - var/turf/open/myturf = loc - var/datum/gas_mixture/conn_air = zturf_conn.air //TODO: pop culture reference - var/datum/gas_mixture/my_air = myturf.air - if (istype(conn_air) && istype(my_air)) - my_air.share(conn_air) - air_update_turf() diff --git a/code/modules/client/verbs/sethotkeys.dm b/code/modules/client/verbs/sethotkeys.dm deleted file mode 100644 index ee14787011..0000000000 --- a/code/modules/client/verbs/sethotkeys.dm +++ /dev/null @@ -1,25 +0,0 @@ -/client/verb/sethotkeys(from_pref = 0 as num) - set name = "Set Hotkeys" - set hidden = TRUE - set waitfor = FALSE - set desc = "Used to set mob-specific hotkeys or load hoykey mode from preferences" - - var/hotkey_default = "default" - var/hotkey_macro = "hotkeys" - var/current_setting - - var/list/default_macros = list("default", "robot-default") - - if(from_pref) - current_setting = (prefs.hotkeys ? hotkey_macro : hotkey_default) - else - current_setting = winget(src, "mainwindow", "macro") - - if(mob) - hotkey_macro = mob.macro_hotkeys - hotkey_default = mob.macro_default - - if(current_setting in default_macros) - winset(src, null, "mainwindow.macro=[hotkey_default] input.focus=true input.background-color=#d3b5b5") - else - winset(src, null, "mainwindow.macro=[hotkey_macro] mapwindow.map.focus=true input.background-color=#e0e0e0") diff --git a/code/modules/events/solar_flare.dm b/code/modules/events/solar_flare.dm deleted file mode 100644 index 5f64570c7d..0000000000 --- a/code/modules/events/solar_flare.dm +++ /dev/null @@ -1,17 +0,0 @@ -/datum/round_event_control/solar_flare - name = "Solar Flare" - typepath = /datum/round_event/solar_flare - max_occurrences = 1 - -/datum/round_event/solar_flare - -/datum/round_event/solar_flare/setup() - startWhen = 3 - endWhen = startWhen + 1 - announceWhen = 1 - -/datum/round_event/solar_flare/announce() - priority_announce("Incoming solar flare detected near the station. Expect power outages in all exposed areas for a short duration.", "Anomaly Alert", 'sound/effects/alert.ogg') - -/datum/round_event/solar_flare/start() - SSweather.run_weather("solar flare",1) diff --git a/code/modules/holodeck/computer_funcs.dm b/code/modules/holodeck/computer_funcs.dm deleted file mode 100644 index 65741eafea..0000000000 --- a/code/modules/holodeck/computer_funcs.dm +++ /dev/null @@ -1,111 +0,0 @@ -/obj/machinery/computer/holodeck/attack_hand(var/mob/user as mob) - user.set_machine(src) - - var/dat = "

Current Loaded Programs

" - dat += "Power Off
" - for(var/area/A in program_cache) - dat += "[A.name]
" - if(emagged && emag_programs.len) - dat += "SUPERVISOR ACCESS - SAFETY PROTOCOLS DISABLED - CAUTION: EMITTER ANOMALY
" - for(var/area/A in emag_programs) - dat += "[A.name]
" - - var/datum/browser/popup = new(user, "computer", name, 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/holodeck/attack_ai(var/mob/user as mob) - var/dat = "

Current Loaded Programs

" - - dat += "Power Off
" - for(var/area/A in program_cache) - dat += "[A.name]
" - - if(emag_programs.len) - dat += "
" - if(emagged) - dat += "Safety protocol: Offline Engage
" - for(var/area/A in emag_programs) - dat += "[A.name]
" - else - dat += "Safety protocol: Online Disengage
" - - var/datum/browser/popup = new(user, "computer", name, 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - - -/obj/machinery/computer/holodeck/proc/load_program(var/area/A, var/force = 0, var/delay = 0) - if(stat) - A = offline_program - force = 1 - delay = 0 - if(program == A) - return - if(world.time < (last_change + 25 + (damaged?500:0)) && !force) - if(delay) - sleep(25) - else - if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve - return - if(get_dist(usr,src) <= 3) - to_chat(usr, "ERROR. Recalibrating projection apparatus.") - return - - last_change = world.time - active = (A != offline_program) - use_power = active ? ACTIVE_POWER_USE : IDLE_POWER_USE - - for(var/obj/effect/holodeck_effect/HE in effects) - HE.deactivate(src) - - for(var/item in spawned) - derez(item, forced=force) - - program = A - // note nerfing does not yet work on guns, should - // should also remove/limit/filter reagents? - // this is an exercise left to others I'm afraid. -Sayu - spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged) - for(var/obj/machinery/M in spawned) - M.flags_1 |= NODECONSTRUCT_1 - for(var/obj/structure/S in spawned) - S.flags_1 |= NODECONSTRUCT_1 - effects = list() - - spawn(30) - var/list/added = list() - for(var/obj/effect/holodeck_effect/HE in spawned) - effects += HE - spawned -= HE - var/atom/x = HE.activate(src) - if(istype(x) || islist(x)) - spawned += x // holocarp are not forever - added += x - for(var/obj/machinery/M in added) - M.flags_1 |= NODECONSTRUCT_1 - for(var/obj/structure/S in added) - S.flags_1 |= NODECONSTRUCT_1 - -/obj/machinery/computer/holodeck/proc/derez(var/obj/obj, var/silent = 1, var/forced = 0) - // Emagging a machine creates an anomaly in the derez systems. - if(obj && src.emagged && !src.stat && !forced) - if((ismob(obj) || istype(obj.loc,/mob)) && prob(50)) - spawn(50) .(obj,silent) // may last a disturbingly long time - return - spawned.Remove(obj) - - if(!obj) - return - var/turf/T = get_turf(obj) - for(var/atom/movable/AM in obj.contents) // these should be derezed if they were generated - AM.loc = T - if(ismob(AM)) - silent = FALSE // otherwise make sure they are dropped - - if(!silent) - visible_message("The [obj.name] fades away!") - qdel(obj) diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index a4d234ded7..39a0bba701 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -98,7 +98,7 @@ proc/get_top_level_mob(var/mob/S) return FALSE user.log_message(message, INDIVIDUAL_EMOTE_LOG) - message = "[user] " + message + message = "[user] " + "[message]" for(var/mob/M in GLOB.dead_mob_list) if(!M.client || isnewplayer(M)) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 019508778b..2fc41e1638 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -129,7 +129,7 @@ display_name = "Basic Bluespace Theory" description = "Basic studies into the mysterious alternate dimension known as bluespace." prereq_ids = list("base") - design_ids = list("beacon", "xenobioconsole") + design_ids = list("beacon") //CIT CHANGE removed xenobioconsole from here. research_cost = 2500 export_price = 5000 @@ -148,7 +148,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning", "roastingstick") + design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning", "roastingstick", "xenobioconsole") //CIT CHANGE added xenobioconsole here research_cost = 5000 export_price = 5000 diff --git a/code/citadel/icons/areas.dmi b/modular_citadel/code/game/area/areas.dmi similarity index 100% rename from code/citadel/icons/areas.dmi rename to modular_citadel/code/game/area/areas.dmi diff --git a/code/citadel/cit_areas.dm b/modular_citadel/code/game/area/cit_areas.dm similarity index 70% rename from code/citadel/cit_areas.dm rename to modular_citadel/code/game/area/cit_areas.dm index 42879b7408..ae36ed6df5 100644 --- a/code/citadel/cit_areas.dm +++ b/modular_citadel/code/game/area/cit_areas.dm @@ -1,6 +1,6 @@ /area/maintenance/bar name = "Maintenance Bar" - icon = 'code/citadel/icons/areas.dmi' + icon = 'modular_citadel/code/game/area/areas.dmi' icon_state = "maintbar" /area/maintenance/bar/cafe @@ -14,5 +14,5 @@ /area/crew_quarters/cryopod name = "Cryogenics" - icon = 'code/citadel/icons/areas.dmi' + icon = 'modular_citadel/code/game/area/areas.dmi' icon_state = "cryo" \ No newline at end of file diff --git a/code/citadel/cit_displaycases.dm b/modular_citadel/code/game/machinery/displaycases.dm similarity index 100% rename from code/citadel/cit_displaycases.dm rename to modular_citadel/code/game/machinery/displaycases.dm diff --git a/code/citadel/plasmacases.dm b/modular_citadel/code/game/machinery/plasmacases.dm similarity index 100% rename from code/citadel/plasmacases.dm rename to modular_citadel/code/game/machinery/plasmacases.dm diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm index 130c93d854..6905efd88d 100644 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -1,3 +1,106 @@ /obj/machinery/vending/security contraband = list(/obj/item/clothing/glasses/sunglasses = 2, /obj/item/storage/fancy/donut_box = 2, /obj/item/device/ssword_kit = 1) - premium = list(/obj/item/coin/antagtoken = 1, /obj/item/device/ssword_kit = 1) \ No newline at end of file + premium = list(/obj/item/coin/antagtoken = 1, /obj/item/device/ssword_kit = 1) + +#define STANDARD_CHARGE 1 +#define CONTRABAND_CHARGE 2 +#define COIN_CHARGE 3 + +/obj/machinery/vending/kink + name = "KinkMate" + desc = "A vending machine for all your unmentionable desires." + icon = 'icons/obj/citvending.dmi' + icon_state = "kink" + product_slogans = "Kinky!;Sexy!;Check me out, big boy!" + vend_reply = "Have fun, you shameless pervert!" + products = list( + /obj/item/clothing/under/maid = 5, + /obj/item/clothing/under/stripper_pink = 5, + /obj/item/clothing/under/stripper_green = 5, + /obj/item/dildo/custom = 5 + ) + contraband = list(/obj/item/restraints/handcuffs/fake/kinky = 5, + /obj/item/clothing/neck/petcollar = 5, + /obj/item/clothing/under/mankini = 1, + /obj/item/dildo/flared/huge = 1 + ) + premium = list(/obj/item/device/electropack/shockcollar = 1) + refill_canister = /obj/item/vending_refill/kink +/* +/obj/machinery/vending/nazivend + name = "Nazivend" + desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\"" + icon = 'icons/obj/citvending.dmi' + icon_state = "nazi" + vend_reply = "SIEG HEIL!" + product_slogans = "Das Vierte Reich wird zuruckkehren!;ENTFERNEN JUDEN!;Billiger als die Juden jemals geben!;Rader auf dem adminbus geht rund und rund.;Warten Sie, warum wir wieder hassen Juden?- *BZZT*" + products = list( + /obj/item/clothing/head/stalhelm = 20, + /obj/item/clothing/head/panzer = 20, + /obj/item/clothing/suit/soldiercoat = 20, + // /obj/item/clothing/under/soldieruniform = 20, + /obj/item/clothing/shoes/jackboots = 20 + ) + contraband = list( + /obj/item/clothing/head/naziofficer = 10, + // /obj/item/clothing/suit/officercoat = 10, + // /obj/item/clothing/under/officeruniform = 10, + /obj/item/clothing/suit/space/hardsuit/nazi = 3, + /obj/item/gun/energy/plasma/MP40k = 4 + ) + premium = list() + + refill_canister = /obj/item/vending_refill/nazi +*/ +/obj/machinery/vending/sovietvend + name = "KomradeVendtink" + desc = "Rodina-mat' zovyot!" + icon = 'icons/obj/citvending.dmi' + icon_state = "soviet" + vend_reply = "The fascist and capitalist svin'ya shall fall, komrade!" + product_slogans = "Quality worth waiting in line for!; Get Hammer and Sickled!; Sosvietsky soyuz above all!; With capitalist pigsky, you would have paid a fortunetink! ; Craftink in Motherland herself!" + products = list( + /obj/item/clothing/under/soviet = 20, + /obj/item/clothing/head/ushanka = 20, + /obj/item/clothing/shoes/jackboots = 20, + /obj/item/clothing/head/squatter_hat = 20, + /obj/item/clothing/under/squatter_outfit = 20, + /obj/item/clothing/under/russobluecamooutfit = 20, + /obj/item/clothing/head/russobluecamohat = 20 + ) + contraband = list( + /obj/item/clothing/under/syndicate/tacticool = 4, + /obj/item/clothing/mask/balaclava = 4, + /obj/item/clothing/suit/russofurcoat = 4, + /obj/item/clothing/head/russofurhat = 4, + /obj/item/clothing/suit/space/hardsuit/soviet = 3, + /obj/item/gun/energy/laser/LaserAK = 4 + ) + premium = list() + + refill_canister = /obj/item/vending_refill/soviet + + +#undef STANDARD_CHARGE +#undef CONTRABAND_CHARGE +#undef COIN_CHARGE + + +/obj/item/vending_refill/kink + machine_name = "KinkMate" + icon = 'modular_citadel/icons/vending_restock.dmi' + icon_state = "refill_kink" + charges = list(8, 5, 0)// of 20 standard, 12 contraband, 0 premium + init_charges = list(8, 5, 0) + +/obj/item/vending_refill/nazi + machine_name = "nazivend" + icon_state = "refill_nazi" + charges = list(33, 13, 0) + init_charges = list(33, 13, 0) + +/obj/item/vending_refill/soviet + machine_name = "sovietvend" + icon_state = "refill_soviet" + charges = list(47, 7, 0) + init_charges = list(47, 7, 0) diff --git a/code/citadel/cit_spawners.dm b/modular_citadel/code/game/objects/effects/spawner/spawners.dm similarity index 100% rename from code/citadel/cit_spawners.dm rename to modular_citadel/code/game/objects/effects/spawner/spawners.dm diff --git a/code/citadel/cit_genemods.dm b/modular_citadel/code/game/objects/items/devices/genemods.dm similarity index 100% rename from code/citadel/cit_genemods.dm rename to modular_citadel/code/game/objects/items/devices/genemods.dm diff --git a/code/citadel/cit_crewobjectives.dm b/modular_citadel/code/modules/antagonists/cit_crewobjectives.dm similarity index 100% rename from code/citadel/cit_crewobjectives.dm rename to modular_citadel/code/modules/antagonists/cit_crewobjectives.dm diff --git a/code/citadel/cit_miscreants.dm b/modular_citadel/code/modules/antagonists/cit_miscreants.dm similarity index 100% rename from code/citadel/cit_miscreants.dm rename to modular_citadel/code/modules/antagonists/cit_miscreants.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_cargo.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_cargo.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_cargo.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_cargo.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_civilian.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_civilian.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_civilian.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_command.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_command.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_command.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_command.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_engineering.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_engineering.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_engineering.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_engineering.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_medical.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_medical.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_medical.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_medical.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_science.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_science.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_science.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_science.dm diff --git a/code/citadel/crew_objectives/cit_crewobjectives_security.dm b/modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_security.dm similarity index 100% rename from code/citadel/crew_objectives/cit_crewobjectives_security.dm rename to modular_citadel/code/modules/antagonists/crew_objectives/cit_crewobjectives_security.dm diff --git a/code/citadel/cit_arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm similarity index 99% rename from code/citadel/cit_arousal.dm rename to modular_citadel/code/modules/arousal/arousal.dm index 077824fe9e..584acc6eb6 100644 --- a/code/citadel/cit_arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -142,7 +142,7 @@ /obj/screen/arousal name = "arousal" icon_state = "arousal0" - icon = 'code/citadel/icons/hud.dmi' + icon = 'modular_citadel/icons/obj/genitals/hud.dmi' screen_loc = ui_arousal /obj/screen/arousal/Click() diff --git a/code/citadel/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm similarity index 96% rename from code/citadel/organs/breasts.dm rename to modular_citadel/code/modules/arousal/organs/breasts.dm index 901c546212..ea44c6d671 100644 --- a/code/citadel/organs/breasts.dm +++ b/modular_citadel/code/modules/arousal/organs/breasts.dm @@ -2,7 +2,7 @@ name = "breasts" desc = "Female milk producing organs." icon_state = "breasts" - icon = 'code/citadel/icons/breasts.dmi' + icon = 'modular_citadel/icons/obj/genitals/breasts.dmi' zone = "chest" slot = "breasts" w_class = 3 diff --git a/code/citadel/organs/eggsack.dm b/modular_citadel/code/modules/arousal/organs/eggsack.dm similarity index 87% rename from code/citadel/organs/eggsack.dm rename to modular_citadel/code/modules/arousal/organs/eggsack.dm index 1486310d61..27104cd36a 100644 --- a/code/citadel/organs/eggsack.dm +++ b/modular_citadel/code/modules/arousal/organs/eggsack.dm @@ -2,7 +2,7 @@ name = "Egg sack" desc = "An egg producing reproductive organ." icon_state = "egg_sack" - icon = 'code/citadel/icons/ovipositor.dmi' + icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi' zone = "groin" slot = "testicles" color = null //don't use the /genital color since it already is colored diff --git a/code/citadel/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm similarity index 100% rename from code/citadel/organs/genitals.dm rename to modular_citadel/code/modules/arousal/organs/genitals.dm diff --git a/code/citadel/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm similarity index 83% rename from code/citadel/organs/genitals_sprite_accessories.dm rename to modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm index 710bab787c..7c02b1c3a5 100644 --- a/code/citadel/organs/genitals_sprite_accessories.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm @@ -4,7 +4,7 @@ //DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM /datum/sprite_accessory/penis - icon = 'code/citadel/icons/penis_onmob.dmi' + icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi' icon_state = null name = "penis" //the preview name of the accessory gender_specific = 0 //Might be needed somewhere down the list. @@ -35,21 +35,21 @@ // Taur cocks go here // //////////////////////// /datum/sprite_accessory/penis/taur_flared - icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width + icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width icon_state = "flared" name = "Taur, Flared" center = TRUE //Center the image 'cause 2-tile wide. dimension_x = 64 /datum/sprite_accessory/penis/taur_knotted - icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width + icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width icon_state = "knotted" name = "Taur, Knotted" center = TRUE //Center the image 'cause 2-tile wide. dimension_x = 64 /datum/sprite_accessory/penis/taur_tapered - icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width + icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width icon_state = "tapered" name = "Taur, Tapered" center = TRUE //Center the image 'cause 2-tile wide. @@ -60,7 +60,7 @@ //Vaginas /datum/sprite_accessory/vagina - icon = 'code/citadel/icons/vagina_onmob.dmi' + icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi' icon_state = null name = "vagina" gender_specific = 0 @@ -90,7 +90,7 @@ //BREASTS BE HERE /datum/sprite_accessory/breasts - icon = 'code/citadel/icons/breasts_onmob.dmi' + icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi' icon_state = null name = "breasts" gender_specific = 0 @@ -104,7 +104,7 @@ //OVIPOSITORS BE HERE /datum/sprite_accessory/ovipositor - icon = 'code/citadel/icons/penis_onmob.dmi' + icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi' icon_state = null name = "Ovipositor" //the preview name of the accessory gender_specific = 0 //Might be needed somewhere down the list. diff --git a/code/citadel/organs/ovipositor.dm b/modular_citadel/code/modules/arousal/organs/ovipositor.dm similarity index 88% rename from code/citadel/organs/ovipositor.dm rename to modular_citadel/code/modules/arousal/organs/ovipositor.dm index 3d684ee387..76bf60d93c 100644 --- a/code/citadel/organs/ovipositor.dm +++ b/modular_citadel/code/modules/arousal/organs/ovipositor.dm @@ -2,7 +2,7 @@ name = "Ovipositor" desc = "An egg laying reproductive organ." icon_state = "ovi_knotted_2" - icon = 'code/citadel/icons/ovipositor.dmi' + icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi' zone = "groin" slot = "penis" w_class = 3 diff --git a/code/citadel/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm similarity index 97% rename from code/citadel/organs/penis.dm rename to modular_citadel/code/modules/arousal/organs/penis.dm index 509ed72ef4..ae58aabf51 100644 --- a/code/citadel/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -2,7 +2,7 @@ name = "penis" desc = "A male reproductive organ." icon_state = "penis" - icon = 'code/citadel/icons/penis.dmi' + icon = 'modular_citadel/icons/obj/genitals/penis.dmi' zone = "groin" slot = "penis" w_class = 3 diff --git a/code/citadel/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm similarity index 96% rename from code/citadel/organs/testicles.dm rename to modular_citadel/code/modules/arousal/organs/testicles.dm index bb3ade6048..815d8034e7 100644 --- a/code/citadel/organs/testicles.dm +++ b/modular_citadel/code/modules/arousal/organs/testicles.dm @@ -2,7 +2,7 @@ name = "testicles" desc = "A male reproductive organ." icon_state = "testicles" - icon = 'code/citadel/icons/penis.dmi' + icon = 'modular_citadel/icons/obj/genitals/penis.dmi' zone = "groin" slot = "testicles" w_class = 3 diff --git a/code/citadel/organs/vagina.dm b/modular_citadel/code/modules/arousal/organs/vagina.dm similarity index 97% rename from code/citadel/organs/vagina.dm rename to modular_citadel/code/modules/arousal/organs/vagina.dm index 1f19dc7e64..4d9eedb1cf 100644 --- a/code/citadel/organs/vagina.dm +++ b/modular_citadel/code/modules/arousal/organs/vagina.dm @@ -1,7 +1,7 @@ /obj/item/organ/genital/vagina name = "vagina" desc = "A female reproductive organ." - icon = 'code/citadel/icons/vagina.dmi' + icon = 'modular_citadel/icons/obj/genitals/vagina.dmi' icon_state = "vagina" zone = "groin" slot = "vagina" diff --git a/code/citadel/organs/womb.dm b/modular_citadel/code/modules/arousal/organs/womb.dm similarity index 94% rename from code/citadel/organs/womb.dm rename to modular_citadel/code/modules/arousal/organs/womb.dm index 433f005623..c59d74e629 100644 --- a/code/citadel/organs/womb.dm +++ b/modular_citadel/code/modules/arousal/organs/womb.dm @@ -1,7 +1,7 @@ /obj/item/organ/genital/womb name = "womb" desc = "A female reproductive organ." - icon = 'code/citadel/icons/vagina.dmi' + icon = 'modular_citadel/icons/obj/genitals/vagina.dmi' icon_state = "womb" zone = "groin" slot = "womb" diff --git a/code/citadel/toys/dildos.dm b/modular_citadel/code/modules/arousal/toys/dildos.dm similarity index 98% rename from code/citadel/toys/dildos.dm rename to modular_citadel/code/modules/arousal/toys/dildos.dm index d216ed86ba..45f4f5a64a 100644 --- a/code/citadel/toys/dildos.dm +++ b/modular_citadel/code/modules/arousal/toys/dildos.dm @@ -4,7 +4,7 @@ obj/item/dildo name = "dildo" desc = "Floppy!" - icon = 'code/citadel/icons/dildo.dmi' + icon = 'modular_citadel/icons/obj/genitals/dildo.dmi' damtype = BRUTE force = 0 throwforce = 0 diff --git a/modular_citadel/code/modules/clothing/suits/suits.dm b/modular_citadel/code/modules/clothing/suits/suits.dm new file mode 100644 index 0000000000..776da896bd --- /dev/null +++ b/modular_citadel/code/modules/clothing/suits/suits.dm @@ -0,0 +1,13 @@ +/*///////////////////////////////////////////////////////////////////////////////// +/////// /////// +/////// Cit's exclusive suits, armor, etc. go here /////// +/////// /////// +*////////////////////////////////////////////////////////////////////////////////// + + +/obj/item/clothing/suit/armor/hos/trenchcoat/cloak + name = "armored trenchcloak" + desc = "A trenchcoat enchanced with a special lightweight kevlar. This one appears to be designed to be draped over one's shoulders rather than worn normally.." + alternate_worn_icon = 'icons/mob/citadel/suit.dmi' + icon_state = "hostrench" + item_state = "hostrench" \ No newline at end of file diff --git a/modular_citadel/code/modules/clothing/under.dm b/modular_citadel/code/modules/clothing/under.dm deleted file mode 100644 index bf77704122..0000000000 --- a/modular_citadel/code/modules/clothing/under.dm +++ /dev/null @@ -1,7 +0,0 @@ -/obj/item/clothing/under/syndicate/cosmetic - name = "tactitool turtleneck" - desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." - icon_state = "tactifool" - item_state = "bl_suit" - item_color = "tactifool" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) \ No newline at end of file diff --git a/modular_citadel/code/modules/clothing/under/syndicate.dm b/modular_citadel/code/modules/clothing/under/syndicate.dm deleted file mode 100644 index 5364d4a0fb..0000000000 --- a/modular_citadel/code/modules/clothing/under/syndicate.dm +++ /dev/null @@ -1,2 +0,0 @@ -/obj/item/clothing/under/syndicate/tacticool - has_sensor = TRUE diff --git a/modular_citadel/code/modules/clothing/under/turtlenecks.dm b/modular_citadel/code/modules/clothing/under/turtlenecks.dm index 47432d87f7..2f40a08dc3 100644 --- a/modular_citadel/code/modules/clothing/under/turtlenecks.dm +++ b/modular_citadel/code/modules/clothing/under/turtlenecks.dm @@ -19,4 +19,59 @@ /obj/structure/closet/secure_closet/CMO/PopulateContents() //This is placed here because it's a very specific addition for a very specific niche ..() - new /obj/item/clothing/under/rank/chief_medical_officer/turtleneck(src) \ No newline at end of file + new /obj/item/clothing/under/rank/chief_medical_officer/turtleneck(src) + +/obj/item/clothing/under/syndicate/cosmetic + name = "tactitool turtleneck" + desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." + icon_state = "tactifool" + item_state = "bl_suit" + item_color = "tactifool" + has_sensor = TRUE + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + +/obj/item/clothing/under/syndicate/tacticool + has_sensor = TRUE + +// Sweaters are good enough for this category too. + +/obj/item/clothing/under/bb_sweater + name = "cream sweater" + desc = "Why trade style for comfort? Now you can go commando down south and still be cozy up north." + icon_state = "bb_turtle" + item_state = "w_suit" + item_color = "bb_turtle" + body_parts_covered = CHEST|ARMS + can_adjust = 1 + icon = 'icons/obj/clothing/turtlenecks.dmi' + icon_override = 'icons/mob/citadel/uniforms.dmi' + +/obj/item/clothing/under/bb_sweater/black + name = "black sweater" + icon_state = "bb_turtleblk" + item_state = "bl_suit" + item_color = "bb_turtleblk" + +/obj/item/clothing/under/bb_sweater/purple + name = "purple sweater" + icon_state = "bb_turtlepur" + item_state = "p_suit" + item_color = "bb_turtlepur" + +/obj/item/clothing/under/bb_sweater/green + name = "green sweater" + icon_state = "bb_turtlegrn" + item_state = "g_suit" + item_color = "bb_turtlegrn" + +/obj/item/clothing/under/bb_sweater/red + name = "red sweater" + icon_state = "bb_turtlered" + item_state = "r_suit" + item_color = "bb_turtlered" + +/obj/item/clothing/under/bb_sweater/blue + name = "blue sweater" + icon_state = "bb_turtleblu" + item_state = "b_suit" + item_color = "bb_turtleblu" diff --git a/code/citadel/cit_clothes.dm b/modular_citadel/code/modules/clothing/under/under.dm similarity index 72% rename from code/citadel/cit_clothes.dm rename to modular_citadel/code/modules/clothing/under/under.dm index dd83c6b769..042273ac6a 100644 --- a/code/citadel/cit_clothes.dm +++ b/modular_citadel/code/modules/clothing/under/under.dm @@ -21,11 +21,4 @@ icon_state = "hosskirt" icon_override = 'icons/mob/citadel/uniforms.dmi' item_state = "gy_suit" - item_color = "hosskirt" - -/obj/item/clothing/suit/armor/hos/trenchcoat/cloak - name = "armored trenchcloak" - desc = "A trenchcoat enchanced with a special lightweight kevlar. This one appears to be designed to be draped over one's shoulders rather than worn normally.." - alternate_worn_icon = 'icons/mob/citadel/suit.dmi' - icon_state = "hostrench" - item_state = "hostrench" \ No newline at end of file + item_color = "hosskirt" \ No newline at end of file diff --git a/code/citadel/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm similarity index 100% rename from code/citadel/custom_loadout/custom_items.dm rename to modular_citadel/code/modules/custom_loadout/custom_items.dm diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/modular_citadel/code/modules/custom_loadout/load_to_mob.dm similarity index 100% rename from code/citadel/custom_loadout/load_to_mob.dm rename to modular_citadel/code/modules/custom_loadout/load_to_mob.dm diff --git a/code/citadel/custom_loadout/read_from_file.dm b/modular_citadel/code/modules/custom_loadout/read_from_file.dm similarity index 100% rename from code/citadel/custom_loadout/read_from_file.dm rename to modular_citadel/code/modules/custom_loadout/read_from_file.dm diff --git a/code/citadel/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm similarity index 100% rename from code/citadel/cit_emotes.dm rename to modular_citadel/code/modules/mob/cit_emotes.dm diff --git a/code/citadel/dogborgs.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg archive.dm similarity index 100% rename from code/citadel/dogborgs.dm rename to modular_citadel/code/modules/mob/living/silicon/robot/dogborg archive.dm diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm new file mode 100644 index 0000000000..dceaf9d1c5 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -0,0 +1,401 @@ +/* +DOG BORG EQUIPMENT HERE +SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! +*/ + +/obj/item/dogborg/jaws/big + name = "combat jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "jaws" + desc = "The jaws of the law." + flags_1 = CONDUCT_1 + force = 12 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + w_class = 3 + sharpness = IS_SHARP + +/obj/item/dogborg/jaws/small + name = "puppy jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "smalljaws" + desc = "The jaws of a small dog." + flags_1 = CONDUCT_1 + force = 6 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + w_class = 3 + sharpness = IS_SHARP + +/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) + ..() + user.do_attack_animation(A, ATTACK_EFFECT_BITE) + +/obj/item/dogborg/jaws/small/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.emagged) + name = "combat jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "jaws" + desc = "The jaws of the law." + flags_1 = CONDUCT_1 + force = 12 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + w_class = 3 + sharpness = IS_SHARP + else + name = "puppy jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "smalljaws" + desc = "The jaws of a small dog." + flags_1 = CONDUCT_1 + force = 5 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + w_class = 3 + sharpness = IS_SHARP + update_icon() + + +//Cuffs + +/obj/item/restraints/handcuffs/cable/zipties/cyborg/dog/attack(mob/living/carbon/C, mob/user) + if(!C.handcuffed) + playsound(loc, 'sound/weapons/cablecuff.ogg', 60, 1, -2) + C.visible_message("[user] is trying to put zipties on [C]!", \ + "[user] is trying to put zipties on [C]!") + if(do_mob(user, C, 60)) + if(!C.handcuffed) + C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C) + C.update_inv_handcuffed(0) + to_chat(user,"You handcuff [C].") + playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) + add_logs(user, C, "handcuffed") + else + to_chat(user,"You fail to handcuff [C]!") + + +//Boop + +/obj/item/device/analyzer/nose + name = "boop module" + icon = 'icons/mob/dogborg.dmi' + icon_state = "nose" + desc = "The BOOP module" + flags_1 = CONDUCT_1 + force = 0 + throwforce = 0 + attack_verb = list("nuzzled", "nosed", "booped") + w_class = 1 + +/obj/item/device/analyzer/nose/attack_self(mob/user) + user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") + + var/turf/location = user.loc + if(!istype(location)) + return + + var/datum/gas_mixture/environment = location.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + to_chat(user, "Results:") + if(abs(pressure - ONE_ATMOSPHERE) < 10) + to_chat(user, "Pressure: [round(pressure,0.1)] kPa") + else + to_chat(user, "Pressure: [round(pressure,0.1)] kPa") + if(total_moles) + var/list/env_gases = environment.gases + + environment.assert_gases(arglist(GLOB.hardcoded_gases)) + var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles + var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles + var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles + var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles + environment.garbage_collect() + + if(abs(n2_concentration - N2STANDARD) < 20) + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") + else + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") + + if(abs(o2_concentration - O2STANDARD) < 2) + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") + else + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") + + if(co2_concentration > 0.01) + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") + else + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") + + if(plasma_concentration > 0.005) + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") + else + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") + + + for(var/id in env_gases) + if(id in GLOB.hardcoded_gases) + continue + var/gas_concentration = env_gases[id][MOLES]/total_moles + to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %") + to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") + +/obj/item/device/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens + . = ..() + +//Delivery + +/obj/item/storage/bag/borgdelivery + name = "fetching storage" + desc = "Fetch the thing!" + icon = 'icons/mob/dogborg.dmi' + icon_state = "dbag" + //Can hold one big item at a time. Drops contents on unequip.(see inventory.dm) + w_class = 5 + max_w_class = 2 + max_combined_w_class = 2 + storage_slots = 1 + collection_mode = 0 + can_hold = list() // any + cant_hold = list(/obj/item/disk/nuclear) + + +//Tongue stuff + +/obj/item/soap/tongue + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + hitsound = 'sound/effects/attackblob.ogg' + cleanspeed = 80 + +/obj/item/soap/tongue/scrubpup + cleanspeed = 25 //slightly faster than a mop. + +/obj/item/soap/tongue/New() + ..() + flags_1 |= NOBLUDGEON_1 //No more attack messages + +/obj/item/trash/rkibble + name = "robo kibble" + desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." + icon = 'icons/mob/dogborg.dmi' + icon_state= "kibble" + +/obj/item/soap/tongue/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.emagged) + name = "hacked tongue of doom" + desc = "Your tongue has been upgraded successfully. Congratulations." + icon = 'icons/mob/dogborg.dmi' + icon_state = "syndietongue" + cleanspeed = 10 //(nerf'd)tator soap stat + else + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + cleanspeed = initial(cleanspeed) + update_icon() + +/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) + var/mob/living/silicon/robot.R = user + if(!proximity || !check_allowed_items(target)) + return + if(R.client && (target in R.client.screen)) + to_chat(R, "You need to take that [target.name] off before cleaning it!") + else if(is_cleanable(target)) + R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't eat them. + to_chat(R, "You finish licking off \the [target.name].") + qdel(target) + R.cell.give(50) + else if(isobj(target)) //hoo boy. danger zone man + if(istype(target,/obj/item/trash)) + R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't eat them. + to_chat(R, "You finish off \the [target.name].") + qdel(target) + R.cell.give(250) + return + if(istype(target,/obj/item/stock_parts/cell)) + R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") + if(do_after(R, 50, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't eat them. + to_chat(R, "You finish off \the [target.name].") + var/obj/item/stock_parts/cell.C = target + R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf + qdel(target) + return + var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT + if(!I.anchored && R.emagged) + R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") + if(do_after(R, 100, target = I)) //Nerf dat time yo + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. Even emags don't make you magically eat things at range. + return //If they moved away, you can't eat them. + visible_message("[R] chews up \the [target.name] and cleans off the debris!") + to_chat(R, "You finish off \the [target.name].") + qdel(I) + R.cell.give(500) + return + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't clean them. + to_chat(R,"You clean \the [target.name].") + var/obj/effect/decal/cleanable/C = locate() in target + qdel(C) + SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) + else if(ishuman(target)) + if(R.emagged) + var/mob/living/L = target + if(R.cell.charge <= 666) + return + L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! + L.Knockdown(80) + L.apply_effect(STUTTER, 4) + L.visible_message("[R] has shocked [L] with its tongue!", \ + "[R] has shocked you with its tongue! You can feel the betrayal.") + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + R.cell.use(666) + else + R.visible_message("\the [R] affectionally licks \the [target]'s face!", "You affectionally lick \the [target]'s face!") + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + return + else if(istype(target, /obj/structure/window)) + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't clean them. + to_chat(R, "You clean \the [target.name].") + target.color = initial(target.color) + else + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't clean them. + to_chat(R, "You clean \the [target.name].") + var/obj/effect/decal/cleanable/C = locate() in target + qdel(C) + SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) + return + + +//Defibs + +/obj/item/twohanded/shockpaddles/cyborg/hound + name = "Paws of Life" + desc = "MediHound specific shock paws." + icon = 'icons/mob/dogborg.dmi' + icon_state = "defibpaddles0" + item_state = "defibpaddles0" + +// Pounce stuff for K-9 + +/obj/item/dogborg/pounce + name = "pounce" + icon = 'icons/mob/dogborg.dmi' + icon_state = "pounce" + desc = "Leap at your target to momentarily stun them." + force = 0 + throwforce = 0 + +/obj/item/dogborg/pounce/New() + ..() + flags_1 |= NOBLUDGEON_1 + +/mob/living/silicon/robot + var/leaping = 0 + var/pounce_cooldown = 0 + var/pounce_cooldown_time = 50 //Nearly doubled, u happy? + var/pounce_spoolup = 3 + var/leap_at + var/disabler + var/laser + var/sleeper_g + var/sleeper_r + +#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. + +/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) + var/mob/living/silicon/robot/R = user + if(R && !R.pounce_cooldown) + R.pounce_cooldown = !R.pounce_cooldown + to_chat(R, "Your targeting systems lock on to [A]...") + addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) + spawn(R.pounce_cooldown_time) + R.pounce_cooldown = !R.pounce_cooldown + else if(R && R.pounce_cooldown) + to_chat(R, "Your leg actuators are still recharging!") + +/mob/living/silicon/robot/proc/leap_at(atom/A) + if(leaping || stat || buckled || lying) + return + + if(!has_gravity(src) || !has_gravity(A)) + to_chat(src,"It is unsafe to leap without gravity!") + //It's also extremely buggy visually, so it's balance+bugfix + return + + if(cell.charge <= 500) + to_chat(src,"Insufficent reserves for jump actuators!") + return + + else + leaping = 1 + weather_immunities += "lava" + pixel_y = 10 + update_icons() + throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) + cell.use(500) //Doubled the energy consumption + weather_immunities -= "lava" + +/mob/living/silicon/robot/throw_impact(atom/A) + + if(!leaping) + return ..() + + if(A) + if(isliving(A)) + var/mob/living/L = A + var/blocked = 0 + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) + blocked = 1 + if(!blocked) + L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") + L.Knockdown(45) + playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) + sleep(2)//Runtime prevention (infinite bump() calls on hulks) + step_towards(src,L) + else + Knockdown(45, 1, 1) + + pounce_cooldown = !pounce_cooldown + spawn(pounce_cooldown_time) //3s by default + pounce_cooldown = !pounce_cooldown + else if(A.density && !A.CanPass(src)) + visible_message("[src] smashes into [A]!", "You smash into [A]!") + playsound(src, 'sound/items/trayhit1.ogg', 50, 1) + Knockdown(45, 1, 1) + + if(leaping) + leaping = 0 + pixel_y = initial(pixel_y) + update_icons() + update_canmove() diff --git a/code/citadel/pokemon.dm b/modular_citadel/code/modules/mob/living/simple_animal/pokemon.dm similarity index 100% rename from code/citadel/pokemon.dm rename to modular_citadel/code/modules/mob/living/simple_animal/pokemon.dm diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm new file mode 100644 index 0000000000..28dfeb89d6 --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/flechette.dm @@ -0,0 +1,117 @@ +//////Flechette Launcher////// + +///projectiles/// + +/obj/item/projectile/bullet/cflechetteap //shreds armor + name = "flechette (armor piercing)" + damage = 8 + armour_penetration = 80 + +/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding + name = "flechette (serrated)" + damage = 15 + dismemberment = 10 + armour_penetration = -80 + +/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE) + if((blocked != 100) && iscarbon(target)) + var/mob/living/carbon/C = target + C.bleed(10) + return ..() + +///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)/// + +/obj/item/ammo_casing/caseless/flechetteap + name = "flechette (armor piercing)" + desc = "A flechette made with a tungsten alloy." + projectile_type = /obj/item/projectile/bullet/cflechetteap + caliber = "flechette" + throwforce = 1 + throw_speed = 3 + +/obj/item/ammo_casing/caseless/flechettes + name = "flechette (serrated)" + desc = "A serrated flechette made of a special alloy intended to deform drastically upon penetration of human flesh." + projectile_type = /obj/item/projectile/bullet/cflechettes + caliber = "flechette" + throwforce = 2 + throw_speed = 3 + embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 40, "embedded_fall_chance" = 10) + +///magazine/// + +/obj/item/ammo_box/magazine/flechette + name = "flechette magazine (armor piercing)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "flechettemag" + ammo_type = /obj/item/ammo_casing/caseless/flechetteap + caliber = "flechette" + max_ammo = 40 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/flechette/s + name = "flechette magazine (serrated)" + ammo_type = /obj/item/ammo_casing/caseless/flechettes + +///the gun itself/// + +/obj/item/gun/ballistic/automatic/flechette + name = "\improper CX Flechette Launcher" + desc = "A flechette launching machine pistol with an unconventional bullpup frame." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "flechettegun" + item_state = "gun" + w_class = WEIGHT_CLASS_NORMAL + slot_flags = 0 + /obj/item/device/firing_pin/implant/pindicate + mag_type = /obj/item/ammo_box/magazine/flechette/ + fire_sound = 'sound/weapons/gunshot_smg.ogg' + can_suppress = 0 + burst_size = 5 + fire_delay = 1 + casing_ejector = 0 + spread = 10 + recoil = 0.05 + +/obj/item/gun/ballistic/automatic/flechette/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("flechettegun-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +///unique variant/// + +/obj/item/projectile/bullet/cflechetteshredder + name = "flechette (shredder)" + damage = 5 + dismemberment = 40 + +/obj/item/ammo_casing/caseless/flechetteshredder + name = "flechette (shredder)" + desc = "A serrated flechette made of a special alloy that forms a monofilament edge." + projectile_type = /obj/item/projectile/bullet/cflechettes + +/obj/item/ammo_box/magazine/flechette/shredder + name = "flechette magazine (shredder)" + icon_state = "shreddermag" + ammo_type = /obj/item/ammo_casing/caseless/flechetteshredder + +/obj/item/gun/ballistic/automatic/flechette/shredder + name = "\improper CX Shredder" + desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes." + w_class = WEIGHT_CLASS_SMALL + mag_type = /obj/item/ammo_box/magazine/flechette/shredder + spread = 15 + recoil = 0.1 + +/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("shreddergun-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/handguns.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/handguns.dm new file mode 100644 index 0000000000..487d5111fc --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/handguns.dm @@ -0,0 +1,424 @@ +////////////Anti Tank Pistol//////////// + +/obj/item/gun/ballistic/automatic/pistol/antitank + name = "Anti Tank Pistol" + desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate your wrist." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "atp" + item_state = "pistol" + recoil = 4 + mag_type = /obj/item/ammo_box/magazine/sniper_rounds + fire_delay = 50 + burst_size = 1 + can_suppress = 0 + w_class = WEIGHT_CLASS_NORMAL + actions_types = list() + fire_sound = 'sound/weapons/blastcannon.ogg' + spread = 20 //damn thing has no rifling. + +/obj/item/gun/ballistic/automatic/pistol/antitank/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("atp-mag") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +/obj/item/gun/ballistic/automatic/pistol/antitank/syndicate + name = "Syndicate Anti Tank Pistol" + desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing." + pin = /obj/item/device/firing_pin/implant/pindicate + +/* made redundant by reskinnable stetchkins +//////Stealth Pistol////// + +/obj/item/gun/ballistic/automatic/pistol/stealth + name = "stealth pistol" + desc = "A unique bullpup pistol with a compact frame. Has an integrated surpressor." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "stealthpistol" + w_class = WEIGHT_CLASS_SMALL + mag_type = /obj/item/ammo_box/magazine/m10mm + can_suppress = 0 + fire_sound = 'sound/weapons/gunshot_silenced.ogg' + suppressed = 1 + burst_size = 1 + +/obj/item/gun/ballistic/automatic/pistol/stealth/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("stealthpistol-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +*/ + +///foam stealth pistol/// + +/obj/item/gun/ballistic/automatic/toy/pistol/stealth + name = "foam force stealth pistol" + desc = "A small, easily concealable toy bullpup handgun. Ages 8 and up." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "foamsp" + w_class = WEIGHT_CLASS_SMALL + mag_type = /obj/item/ammo_box/magazine/toy/pistol + can_suppress = FALSE + fire_sound = 'sound/weapons/gunshot_silenced.ogg' + suppressed = TRUE + burst_size = 1 + fire_delay = 0 + spread = 20 + actions_types = list() + +/obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("foamsp-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +//////10mm soporific bullets////// + +obj/item/projectile/bullet/c10mm/soporific + name ="10mm soporific bullet" + armour_penetration = 0 + nodamage = TRUE + dismemberment = 0 + knockdown = 0 + +/obj/item/projectile/bullet/c10mm/soporific/on_hit(atom/target, blocked = FALSE) + if((blocked != 100) && isliving(target)) + var/mob/living/L = target + L.blur_eyes(6) + if(L.getStaminaLoss() >= 60) + L.Sleeping(300) + else + L.adjustStaminaLoss(25) + return 1 + +/obj/item/ammo_casing/c10mm/soporific + name = ".10mm soporific bullet casing" + desc = "A 10mm soporific bullet casing." + projectile_type = /obj/item/projectile/bullet/c10mm/soporific + +/obj/item/ammo_box/magazine/m10mm/soporific + name = "pistol magazine (10mm soporific)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "9x19pS" + desc = "A gun magazine. Loaded with rounds which inject the target with a variety of illegal substances to induce sleep in the target." + ammo_type = /obj/item/ammo_casing/c10mm/soporific + +/obj/item/ammo_box/c10mm/soporific + name = "ammo box (10mm soporific)" + ammo_type = /obj/item/ammo_casing/c10mm/soporific + max_ammo = 24 + +//////modular pistol////// (reskinnable stetchkins) + +/obj/item/gun/ballistic/automatic/pistol/modular + name = "modular pistol" + desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "cde" + can_unsuppress = TRUE + obj_flags = UNIQUE_RENAME + unique_reskin = list("Default" = "cde", + "NT-99" = "n99", + "Stealth" = "stealthpistol", + "HKVP-78" = "vp78", + "Luger" = "p08b", + "Mk.58" = "secguncomp", + "PX4 Storm" = "px4" + ) + +/obj/item/gun/ballistic/automatic/pistol/modular/update_icon() + ..() + if(current_skin) + icon_state = "[unique_reskin[current_skin]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + else + icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + if(magazine && suppressed) + cut_overlays() + add_overlay("[unique_reskin[current_skin]]-magazine-sup") //Yes, this means the default iconstate can't have a magazine overlay + else if (magazine) + cut_overlays() + add_overlay("[unique_reskin[current_skin]]-magazine") + else + cut_overlays() + +/////////RAYGUN MEMES///////// + +/obj/item/projectile/beam/lasertag/ray //the projectile, compatible with regular laser tag armor + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "ray" + name = "ray bolt" + eyeblur = 0 + +/obj/item/ammo_casing/energy/laser/raytag + projectile_type = /obj/item/projectile/beam/lasertag/ray + select_name = "raytag" + fire_sound = 'sound/weapons/raygun.ogg' + +/obj/item/gun/energy/laser/practice/raygun + name = "toy ray gun" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "raygun" + desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems." + ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag) + selfcharge = TRUE + +/*///////////////////////////////////////////////////////////////////////////////////////////// + The Recolourable Gun +*////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/item/gun/ballistic/automatic/pistol/p37 + name = "\improper CX Mk.37P" + desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. \ + This model is coated with a special polychromic material. \ + Has a small warning on the receiver that boldly states 'WARNING: WILL DETONATE UPON UNAUTHORIZED USE'. \ + Uses 9mm bullets loaded into proprietary magazines." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "p37" + w_class = WEIGHT_CLASS_NORMAL + spawnwithmagazine = FALSE + mag_type = /obj/item/ammo_box/magazine/m9mm/p37 + can_suppress = FALSE + pin = /obj/item/device/firing_pin/dna/dredd //goes boom if whoever isn't DNA locked to it tries to use it + actions_types = list(/datum/action/item_action/pick_color) + + var/frame_color = "#808080" //RGB + var/receiver_color = "#808080" + var/body_color = "#0098FF" + var/barrel_color = "#808080" + var/tip_color = "#808080" + var/arm_color = "#808080" + var/grip_color = "#00FFCB" //Does not actually colour the grip, just the lights surrounding it + var/energy_color = "#00FFCB" + +///Defining all the colourable bits and displaying them/// + +/obj/item/gun/ballistic/automatic/pistol/p37/update_icon() + var/mutable_appearance/frame_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_frame") + var/mutable_appearance/receiver_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_receiver") + var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_body") + var/mutable_appearance/barrel_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_barrel") + var/mutable_appearance/tip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_tip") + var/mutable_appearance/grip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_grip") + var/mutable_appearance/energy_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_light") + var/mutable_appearance/arm_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm") + var/mutable_appearance/arm_overlay_e = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm-e") + + if(frame_color) + frame_overlay.color = frame_color + if(receiver_color) + receiver_overlay.color = receiver_color + if(body_color) + body_overlay.color = body_color + if(barrel_color) + barrel_overlay.color = barrel_color + if(tip_color) + tip_overlay.color = tip_color + if(grip_color) + grip_overlay.color = grip_color + if(energy_color) + energy_overlay.color = energy_color + if(arm_color) + arm_overlay.color = arm_color + if(arm_color) + arm_overlay_e.color = arm_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(frame_overlay) + add_overlay(receiver_overlay) + add_overlay(body_overlay) + add_overlay(barrel_overlay) + add_overlay(tip_overlay) + add_overlay(grip_overlay) + add_overlay(energy_overlay) + + if(magazine) //does not need a cut_overlays proc call here because it's already called further up + add_overlay("p37_mag") + + if(chambered) + cut_overlay(arm_overlay_e) + add_overlay(arm_overlay) + else + cut_overlay(arm_overlay) + add_overlay(arm_overlay_e) + +///letting you actually recolor things/// + +/obj/item/gun/ballistic/automatic/pistol/p37/ui_action_click(mob/user, var/datum/action/A) + if(istype(A, /datum/action/item_action/pick_color)) + + var/choice = input(user,"Mk.37P polychrome options", "Gun Recolor") in list("Frame Color","Receiver Color","Body Color", + "Barrel Color", "Barrel Tip Color", "Grip Light Color", + "Light Color", "Arm Color", "*CANCEL*") + + switch(choice) + + if("Frame Color") + var/frame_color_input = input(usr,"","Choose Frame Color",frame_color) as color|null + if(frame_color_input) + frame_color = sanitize_hexcolor(frame_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Receiver Color") + var/receiver_color_input = input(usr,"","Choose Receiver Color",receiver_color) as color|null + if(receiver_color_input) + receiver_color = sanitize_hexcolor(receiver_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Body Color") + var/body_color_input = input(usr,"","Choose Body Color",body_color) as color|null + if(body_color_input) + body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Barrel Color") + var/barrel_color_input = input(usr,"","Choose Barrel Color",barrel_color) as color|null + if(barrel_color_input) + barrel_color = sanitize_hexcolor(barrel_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Barrel Tip Color") + var/tip_color_input = input(usr,"","Choose Barrel Tip Color",tip_color) as color|null + if(tip_color_input) + tip_color = sanitize_hexcolor(tip_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Grip Light Color") + var/grip_color_input = input(usr,"","Choose Grip Light Color",grip_color) as color|null + if(grip_color_input) + grip_color = sanitize_hexcolor(grip_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Light Color") + var/energy_color_input = input(usr,"","Choose Light Color",energy_color) as color|null + if(energy_color_input) + energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + + if("Arm Color") + var/arm_color_input = input(usr,"","Choose Arm Color",arm_color) as color|null + if(arm_color_input) + arm_color = sanitize_hexcolor(arm_color_input, desired_format=6, include_crunch=1) + update_icon() + A.UpdateButtonIcon() + + else + ..() + +///boolets/// + +/obj/item/projectile/bullet/c9mm/frangible + name = "9mm frangible bullet" + damage = 15 + stamina = 0 + speed = 1.0 + range = 20 + armour_penetration = -25 + +/obj/item/projectile/bullet/c9mm/rubber + name = "9mm rubber bullet" + damage = 5 + stamina = 30 + speed = 1.2 + range = 14 + knockdown = 0 + +/obj/item/ammo_casing/c9mm/frangible + name = "9mm frangible bullet casing" + desc = "A 9mm frangible bullet casing." + projectile_type = /obj/item/projectile/bullet/c9mm/frangible + +/obj/item/ammo_casing/c9mm/rubber + name = "9mm rubber bullet casing" + desc = "A 9mm rubber bullet casing." + projectile_type = /obj/item/projectile/bullet/c9mm/rubber + +/obj/item/ammo_box/magazine/m9mm/p37 + name = "\improper P37 magazine (9mm frangible)" + desc = "A gun magazine. Loaded with plastic composite rounds which fragment upon impact to minimize collateral damage." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "11mm" //topkek + ammo_type = /obj/item/ammo_casing/c9mm/frangible + caliber = "9mm" + max_ammo = 11 + multiple_sprites = 1 + +/obj/item/ammo_box/magazine/m9mm/p37/fmj + name = "\improper P37 magazine (9mm)" + ammo_type = /obj/item/ammo_casing/c9mm + desc = "A gun magazine. Loaded with conventional full metal jacket rounds." + +/obj/item/ammo_box/magazine/m9mm/p37/rubber + name = "\improper P37 magazine (9mm Non-Lethal Rubbershot)" + ammo_type = /obj/item/ammo_casing/c9mm/rubber + desc = "A gun magazine. Loaded with less-than-lethal rubber bullets." + +/obj/item/ammo_box/c9mm/frangible + name = "ammo box (9mm frangible)" + ammo_type = /obj/item/ammo_casing/c9mm/frangible + +/obj/item/ammo_box/c9mm/rubber + name = "ammo box (9mm non-lethal rubbershot)" + ammo_type = /obj/item/ammo_casing/c9mm/rubber + +/datum/design/c9mmfrag + name = "Box of 9mm Frangible Bullets" + id = "9mm_frag" + build_type = AUTOLATHE + materials = list(MAT_METAL = 25000) + build_path = /obj/item/ammo_box/c9mm/frangible + category = list("hacked", "Security") + +/datum/design/c9mmrubber + name = "Box of 9mm Rubber Bullets" + id = "9mm_rubber" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/ammo_box/c9mm/rubber + category = list("initial", "Security") + + +///Security Variant/// + +/obj/item/gun/ballistic/automatic/pistol/p37/sec + name = "\improper CX Mk.37S" + desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. Uses 9mm bullets loaded into proprietary magazines." + spawnwithmagazine = FALSE + pin = /obj/item/device/firing_pin/implant/mindshield + actions_types = list() //so you can't recolor it + + frame_color = "#808080" //RGB + receiver_color = "#808080" + body_color = "#282828" + barrel_color = "#808080" + tip_color = "#808080" + arm_color = "#800000" + grip_color = "#FFFF00" //Does not actually colour the grip, just the lights surrounding it + energy_color = "#FFFF00" + +///Foam Variant because WE NEED MEMES/// + +/obj/item/gun/ballistic/automatic/pistol/p37/foam + name = "\improper Foam Force Mk.37F" + desc = "A licensed foam-firing reproduction of a handgun with a toggle-locking mechanism manufactured by CX Armories. This model is coated with a special polychromic material. Uses standard foam pistol magazines." + icon_state = "p37_foam" + pin = /obj/item/device/firing_pin + spawnwithmagazine = TRUE + obj_flags = 0 + casing_ejector = FALSE + mag_type = /obj/item/ammo_box/magazine/toy/pistol + can_suppress = FALSE + actions_types = list(/datum/action/item_action/pick_color) + +/obj/item/ammo_box/magazine/toy/pistol //forcing this might be a bad idea, but it'll fix the foam gun infinite material exploit + materials = list(MAT_METAL = 200) diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm new file mode 100644 index 0000000000..cd4ec113de --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm @@ -0,0 +1,466 @@ +///////XCOM X9 AR/////// + +/obj/item/gun/ballistic/automatic/x9 //will be adminspawn only so ERT or something can use them + name = "\improper X9 Assault Rifle" + desc = "A rather old design of a cheap, reliable assault rifle made for combat against unknown enemies. Uses 5.56mm ammo." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "x9" + item_state = "arg" + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG + fire_sound = 'sound/weapons/gunshot_smg.ogg' + can_suppress = 0 + burst_size = 6 //in line with XCOMEU stats. This can fire 5 bursts from a full magazine. + fire_delay = 1 + spread = 30 //should be 40 for XCOM memes, but since its adminspawn only, might as well make it useable + recoil = 1 + +///toy memes/// + +/obj/item/ammo_box/magazine/toy/x9 + name = "foam force X9 magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toy9magazine" + max_ammo = 30 + multiple_sprites = 2 + materials = list(MAT_METAL = 200) + +/obj/item/gun/ballistic/automatic/x9/toy + name = "\improper Foam Force X9" + desc = "An old but reliable assault rifle made for combat against unknown enemies. Appears to be hastily converted. Ages 8 and up." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toy9" + can_suppress = 0 + obj_flags = 0 + mag_type = /obj/item/ammo_box/magazine/toy/x9 + casing_ejector = 0 + spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY + +////////XCOM2 Magpistol///////// + +//////projectiles////// + +/obj/item/projectile/bullet/mags + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile" + damage = 15 + armour_penetration = 10 + light_range = 2 + speed = 0.6 + range = 25 + light_color = LIGHT_COLOR_RED + +/obj/item/projectile/bullet/nlmags //non-lethal boolets + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-nl" + damage = 0 + knockdown = 0 + stamina = 25 + armour_penetration = -10 + light_range = 2 + speed = 0.7 + range = 25 + light_color = LIGHT_COLOR_BLUE + + +/////actual ammo///// + +/obj/item/ammo_casing/caseless/amags + desc = "A ferromagnetic slug intended to be launched out of a compatible weapon." + caliber = "mags" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/mags + +/obj/item/ammo_casing/caseless/anlmags + desc = "A specialized ferromagnetic slug designed with a less-than-lethal payload." + caliber = "mags" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/nlmags + +//////magazines///// + +/obj/item/ammo_box/magazine/mmag/small + name = "magpistol magazine (non-lethal disabler)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "nlmagmag" + ammo_type = /obj/item/ammo_casing/caseless/anlmags + caliber = "mags" + max_ammo = 15 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/mmag/small/lethal + name = "magpistol magazine (lethal)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "smallmagmag" + ammo_type = /obj/item/ammo_casing/caseless/amags + +//////the gun itself////// + +/obj/item/gun/ballistic/automatic/pistol/mag + name = "magpistol" + desc = "A handgun utilizing maglev technologies to propel a ferromagnetic slug to extreme velocities." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magpistol" + force = 10 + fire_sound = 'sound/weapons/magpistol.ogg' + mag_type = /obj/item/ammo_box/magazine/mmag/small + can_suppress = 0 + casing_ejector = 0 + fire_delay = 2 + recoil = 0.2 + +/obj/item/gun/ballistic/automatic/pistol/mag/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("magpistol-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +///research memes/// + +/obj/item/gun/ballistic/automatic/pistol/mag/nopin + pin = null + spawnwithmagazine = FALSE + +/datum/design/magpistol + name = "Magpistol" + desc = "A weapon which fires ferromagnetic slugs." + id = "magpisol" + build_type = PROTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) + build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magpistol + name = "Magpistol Magazine" + desc = "A 14 round magazine for the Magpistol." + id = "mag_magpistol" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_SILVER = 500) + build_path = /obj/item/ammo_box/magazine/mmag/small/lethal + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magpistol/nl + name = "Magpistol Magazine (Non-Lethal)" + desc = "A 14 round non-lethal magazine for the Magpistol." + id = "mag_magpistol_nl" + materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) + build_path = /obj/item/ammo_box/magazine/mmag/small + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +//////toy memes///// + +/obj/item/projectile/bullet/reusable/foam_dart/mag + name = "magfoam dart" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-toy" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + light_range = 2 + light_color = LIGHT_COLOR_YELLOW + +/obj/item/ammo_casing/caseless/foam_dart/mag + name = "magfoam dart" + desc = "A foam dart with fun light-up projectiles powered by magnets!" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/mag + +/obj/item/ammo_box/magazine/internal/shot/toy/mag + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + max_ammo = 14 + +/obj/item/gun/ballistic/shotgun/toy/mag + name = "foam force magpistol" + desc = "A fancy toy sold alongside light-up foam force darts. Ages 8 and up." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toymag" + item_state = "gun" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/mag + fire_sound = 'sound/weapons/magpistol.ogg' + slot_flags = SLOT_BELT + w_class = WEIGHT_CLASS_SMALL + +/obj/item/ammo_box/foambox/mag + name = "ammo box (Magnetic Foam Darts)" + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foambox" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + max_ammo = 42 + +//////Magrifle////// + +///projectiles/// + +/obj/item/projectile/bullet/magrifle + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-large" + damage = 20 + armour_penetration = 25 + light_range = 3 + speed = 0.7 + range = 35 + light_color = LIGHT_COLOR_RED + +/obj/item/projectile/bullet/nlmagrifle //non-lethal boolets + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-large-nl" + damage = 0 + knockdown = 0 + stamina = 25 + armour_penetration = -10 + light_range = 3 + speed = 0.65 + range = 35 + light_color = LIGHT_COLOR_BLUE + +///ammo casings/// + +/obj/item/ammo_casing/caseless/amagm + desc = "A large ferromagnetic slug intended to be launched out of a compatible weapon." + caliber = "magm" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/magrifle + +/obj/item/ammo_casing/caseless/anlmagm + desc = "A large, specialized ferromagnetic slug designed with a less-than-lethal payload." + caliber = "magm" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/nlmagrifle + +///magazines/// + +/obj/item/ammo_box/magazine/mmag/ + name = "magrifle magazine (non-lethal disabler)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mediummagmag" + ammo_type = /obj/item/ammo_casing/caseless/anlmagm + caliber = "magm" + max_ammo = 24 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/mmag/lethal + name = "magrifle magazine (lethal)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mediummagmag" + ammo_type = /obj/item/ammo_casing/caseless/amagm + max_ammo = 24 + +///the gun itself/// + +/obj/item/gun/ballistic/automatic/magrifle + name = "\improper Magnetic Rifle" + desc = "A simple upscalling of the technologies used in the magpistol, the magrifle is capable of firing slightly larger slugs in bursts. Compatible with the magpistol's slugs." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magrifle" + item_state = "arg" + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/mmag + fire_sound = 'sound/weapons/magrifle.ogg' + can_suppress = 0 + burst_size = 3 + fire_delay = 2 + spread = 5 + recoil = 0.15 + casing_ejector = 0 + +///research/// + +/obj/item/gun/ballistic/automatic/magrifle/nopin + pin = null + spawnwithmagazine = FALSE + +/datum/design/magrifle + name = "Magrifle" + desc = "An upscaled Magpistol in rifle form." + id = "magrifle" + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000) + build_path = /obj/item/gun/ballistic/automatic/magrifle/nopin + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magrifle + name = "Magrifle Magazine (Lethal)" + desc = "A 24-round magazine for the Magrifle." + id = "mag_magrifle" + build_type = PROTOLATHE + materials = list(MAT_METAL = 8000, MAT_SILVER = 1000) + build_path = /obj/item/ammo_box/magazine/mmag/lethal + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magrifle/nl + name = "Magrifle Magazine (Non-Lethal)" + desc = "A 24- round non-lethal magazine for the Magrifle." + id = "mag_magrifle_nl" + materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) + build_path = /obj/item/ammo_box/magazine/mmag + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +///foamagrifle/// + +/obj/item/ammo_box/magazine/toy/foamag + name = "foam force magrifle magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "foamagmag" + max_ammo = 24 + multiple_sprites = 2 + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + materials = list(MAT_METAL = 200) + +/obj/item/gun/ballistic/automatic/magrifle/toy + name = "foamag rifle" + desc = "A foam launching magnetic rifle. Ages 8 and up." + icon_state = "foamagrifle" + obj_flags = 0 + mag_type = /obj/item/ammo_box/magazine/toy/foamag + casing_ejector = FALSE + spread = 60 + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY + +/* +// TECHWEBS IMPLEMENTATION +*/ + +/datum/techweb_node/magnetic_weapons + id = "magnetic_weapons" + display_name = "Magnetic Weapons" + description = "Weapons using magnetic technology" + prereq_ids = list("weaponry", "adv_weaponry", "emp_adv") + design_ids = list("magrifle", "magpisol", "mag_magrifle", "mag_magrifle_nl", "mag_magpistol", "mag_magpistol_nl") + research_cost = 2500 + export_price = 5000 + + +//////Hyper-Burst Rifle////// + +///projectiles/// + +/obj/item/projectile/bullet/mags/hyper + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile" + damage = 10 + armour_penetration = 10 + stamina = 10 + forcedodge = TRUE + range = 6 + light_range = 1 + light_color = LIGHT_COLOR_RED + +/obj/item/projectile/bullet/mags/hyper/inferno + icon_state = "magjectile-large" + stamina = 0 + forcedodge = FALSE + range = 25 + light_range = 4 + +/obj/item/projectile/bullet/mags/hyper/inferno/on_hit(atom/target, blocked = FALSE) + ..() + explosion(target, -1, 1, 2, 4, 5) + return 1 + +///ammo casings/// + +/obj/item/ammo_casing/caseless/ahyper + desc = "A large block of speciallized ferromagnetic material designed to be fired out of the experimental Hyper-Burst Rifle." + caliber = "hypermag" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "hyper-casing-live" + projectile_type = /obj/item/projectile/bullet/mags/hyper + pellets = 12 + variance = 40 + +/obj/item/ammo_casing/caseless/ahyper/inferno + projectile_type = /obj/item/projectile/bullet/mags/hyper/inferno + pellets = 1 + variance = 0 + +///magazines/// + +/obj/item/ammo_box/magazine/mhyper + name = "hyper-burst rifle magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "hypermag-4" + ammo_type = /obj/item/ammo_casing/caseless/ahyper + caliber = "hypermag" + desc = "A magazine for the Hyper-Burst Rifle. Loaded with a special slug that fragments into 12 smaller shards which can absolutely puncture anything, but has rather short effective range." + max_ammo = 4 + +/obj/item/ammo_box/magazine/mhyper/update_icon() + ..() + icon_state = "hypermag-[ammo_count() ? "4" : "0"]" + +/obj/item/ammo_box/magazine/mhyper/inferno + name = "hyper-burst rifle magazine (inferno)" + ammo_type = /obj/item/ammo_casing/caseless/ahyper/inferno + desc = "A magazine for the Hyper-Burst Rifle. Loaded with a special slug that violently reacts with whatever surface it strikes, generating a massive amount of heat and light." + +///gun itself/// + +/obj/item/gun/ballistic/automatic/hyperburst + name = "\improper Hyper-Burst Rifle" + desc = "An extremely beefed up version of a stolen Nanotrasen weapon prototype, this 'rifle' is more like a cannon, with an extremely large bore barrel capable of generating several smaller magnetic 'barrels' to simultaneously launch multiple projectiles at once." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "hyperburst" + item_state = "arg" + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/mhyper + fire_sound = 'sound/weapons/magburst.ogg' + can_suppress = 0 + burst_size = 1 + fire_delay = 40 + recoil = 2 + casing_ejector = 0 + weapon_weight = WEAPON_HEAVY + +/obj/item/gun/ballistic/automatic/hyperburst/update_icon() + ..() + icon_state = "hyperburst[magazine ? "-[get_ammo()]" : ""][chambered ? "" : "-e"]" + +///toy memes/// + +/obj/item/projectile/beam/lasertag/mag //the projectile, compatible with regular laser tag armor + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-toy" + name = "lasertag magbolt" + forcedodge = TRUE //for penetration memes + range = 5 //so it isn't super annoying + light_range = 2 + light_color = LIGHT_COLOR_YELLOW + eyeblur = 0 + +/obj/item/ammo_casing/energy/laser/magtag + projectile_type = /obj/item/projectile/beam/lasertag/mag + select_name = "magtag" + pellets = 3 + variance = 30 + e_cost = 1000 + fire_sound = 'sound/weapons/magburst.ogg' + +/obj/item/gun/energy/laser/practice/hyperburst + name = "toy hyper-burst launcher" + desc = "A toy laser with a unique beam shaping lens that projects harmless bolts capable of going through objects. Compatible with existing laser tag systems." + ammo_type = list(/obj/item/ammo_casing/energy/laser/magtag) + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toyburst" + clumsy_check = FALSE + obj_flags = 0 + fire_delay = 40 + weapon_weight = WEAPON_HEAVY + selfcharge = TRUE + charge_delay = 2 + recoil = 2 + cell_type = /obj/item/stock_parts/cell/toymagburst + +/obj/item/stock_parts/cell/toymagburst + name = "toy mag burst rifle power supply" + maxcharge = 4000 \ No newline at end of file diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm new file mode 100644 index 0000000000..a9824c7d33 --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/rifles.dm @@ -0,0 +1,234 @@ + +///////XCOM X9 AR/////// + +/obj/item/gun/ballistic/automatic/x9 //will be adminspawn only so ERT or something can use them + name = "\improper X9 Assault Rifle" + desc = "A rather old design of a cheap, reliable assault rifle made for combat against unknown enemies. Uses 5.56mm ammo." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "x9" + item_state = "arg" + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG + fire_sound = 'sound/weapons/gunshot_smg.ogg' + can_suppress = 0 + burst_size = 6 //in line with XCOMEU stats. This can fire 5 bursts from a full magazine. + fire_delay = 1 + spread = 30 //should be 40 for XCOM memes, but since its adminspawn only, might as well make it useable + recoil = 1 + +///toy memes/// + +/obj/item/ammo_box/magazine/toy/x9 + name = "foam force X9 magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toy9magazine" + max_ammo = 30 + multiple_sprites = 2 + materials = list(MAT_METAL = 200) + +/obj/item/gun/ballistic/automatic/x9/toy + name = "\improper Foam Force X9" + desc = "An old but reliable assault rifle made for combat against unknown enemies. Appears to be hastily converted. Ages 8 and up." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toy9" + can_suppress = 0 + obj_flags = 0 + mag_type = /obj/item/ammo_box/magazine/toy/x9 + casing_ejector = 0 + spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY + + +//////Flechette Launcher////// + +///projectiles/// + +/obj/item/projectile/bullet/cflechetteap //shreds armor + name = "flechette (armor piercing)" + damage = 8 + armour_penetration = 80 + +/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding + name = "flechette (serrated)" + damage = 15 + dismemberment = 10 + armour_penetration = -80 + +/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE) + if((blocked != 100) && iscarbon(target)) + var/mob/living/carbon/C = target + C.bleed(10) + return ..() + +///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)/// + +/obj/item/ammo_casing/caseless/flechetteap + name = "flechette (armor piercing)" + desc = "A flechette made with a tungsten alloy." + projectile_type = /obj/item/projectile/bullet/cflechetteap + caliber = "flechette" + throwforce = 1 + throw_speed = 3 + +/obj/item/ammo_casing/caseless/flechettes + name = "flechette (serrated)" + desc = "A serrated flechette made of a special alloy intended to deform drastically upon penetration of human flesh." + projectile_type = /obj/item/projectile/bullet/cflechettes + caliber = "flechette" + throwforce = 2 + throw_speed = 3 + embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 40, "embedded_fall_chance" = 10) + +///magazine/// + +/obj/item/ammo_box/magazine/flechette + name = "flechette magazine (armor piercing)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "flechettemag" + ammo_type = /obj/item/ammo_casing/caseless/flechetteap + caliber = "flechette" + max_ammo = 40 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/flechette/s + name = "flechette magazine (serrated)" + ammo_type = /obj/item/ammo_casing/caseless/flechettes + +///the gun itself/// + +/obj/item/gun/ballistic/automatic/flechette + name = "\improper CX Flechette Launcher" + desc = "A flechette launching machine pistol with an unconventional bullpup frame." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "flechettegun" + item_state = "gun" + w_class = WEIGHT_CLASS_NORMAL + slot_flags = 0 + /obj/item/device/firing_pin/implant/pindicate + mag_type = /obj/item/ammo_box/magazine/flechette/ + fire_sound = 'sound/weapons/gunshot_smg.ogg' + can_suppress = 0 + burst_size = 5 + fire_delay = 1 + casing_ejector = 0 + spread = 10 + recoil = 0.05 + +/obj/item/gun/ballistic/automatic/flechette/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("flechettegun-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +///unique variant/// + +/obj/item/projectile/bullet/cflechetteshredder + name = "flechette (shredder)" + damage = 5 + dismemberment = 40 + +/obj/item/ammo_casing/caseless/flechetteshredder + name = "flechette (shredder)" + desc = "A serrated flechette made of a special alloy that forms a monofilament edge." + projectile_type = /obj/item/projectile/bullet/cflechettes + +/obj/item/ammo_box/magazine/flechette/shredder + name = "flechette magazine (shredder)" + icon_state = "shreddermag" + ammo_type = /obj/item/ammo_casing/caseless/flechetteshredder + +/obj/item/gun/ballistic/automatic/flechette/shredder + name = "\improper CX Shredder" + desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes." + w_class = WEIGHT_CLASS_SMALL + mag_type = /obj/item/ammo_box/magazine/flechette/shredder + spread = 15 + recoil = 0.1 + +/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("shreddergun-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +/*///////////////////////////////////////////////////////////// +//////////////////////// Zero's Meme ////////////////////////// +*////////////////////////////////////////////////////////////// +/obj/item/ammo_box/magazine/toy/AM4B + name = "foam force AM4-B magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "AM4MAG-60" + max_ammo = 60 + multiple_sprites = 0 + materials = list(MAT_METAL = 200) + +/obj/item/gun/ballistic/automatic/AM4B + name = "AM4-B" + desc = "A Relic from a bygone age. Nobody quite knows why it's here. Has a polychromic coating." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "AM4" + item_state = "arg" + mag_type = /obj/item/ammo_box/magazine/toy/AM4B + can_suppress = 0 + item_flags = NEEDS_PERMIT + casing_ejector = 0 + spread = 30 //Assault Rifleeeeeee + w_class = WEIGHT_CLASS_NORMAL + burst_size = 4 //Shh. + fire_delay = 1 + var/body_color = "#3333aa" + +/obj/item/gun/ballistic/automatic/AM4B/update_icon() + ..() + var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "AM4-Body") + if(body_color) + body_overlay.color = body_color + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + add_overlay(body_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() +/obj/item/gun/ballistic/automatic/AM4B/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + if(alert("Are you sure you want to recolor your gun?", "Confirm Repaint", "Yes", "No") == "Yes") + var/body_color_input = input(usr,"","Choose Shroud Color",body_color) as color|null + if(body_color_input) + body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) + update_icon() +/obj/item/gun/ballistic/automatic/AM4B/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +/obj/item/ammo_box/magazine/toy/AM4C + name = "foam force AM4-C magazine" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "AM4MAG-32" + max_ammo = 32 + multiple_sprites = 0 + materials = list(MAT_METAL = 200) + +/obj/item/gun/ballistic/automatic/AM4C + name = "AM4-C" + desc = "A Relic from a bygone age. This one seems newer, yet less effective." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "AM4C" + item_state = "arg" + mag_type = /obj/item/ammo_box/magazine/toy/AM4C + can_suppress = 0 + item_flags = NEEDS_PERMIT + casing_ejector = 0 + spread = 45 //Assault Rifleeeeeee + w_class = WEIGHT_CLASS_NORMAL + burst_size = 4 //Shh. + fire_delay = 1 diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm new file mode 100644 index 0000000000..5b42f9686a --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm @@ -0,0 +1,90 @@ +/////////////spinfusor stuff//////////////// + +/obj/item/projectile/bullet/spinfusor + name ="spinfusor disk" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state= "spinner" + damage = 30 + dismemberment = 25 + +/obj/item/projectile/bullet/spinfusor/on_hit(atom/target, blocked = FALSE) //explosion to emulate the spinfusor's AOE + ..() + explosion(target, -1, -1, 2, 0, -1) + return 1 + +/obj/item/ammo_casing/caseless/spinfusor + name = "spinfusor disk" + desc = "A magnetic disk designed specifically for the Stormhammer magnetic cannon. Warning: extremely volatile!" + projectile_type = /obj/item/projectile/bullet/spinfusor + caliber = "spinfusor" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "disk" + throwforce = 15 //still deadly when thrown + throw_speed = 3 + +/obj/item/ammo_casing/caseless/spinfusor/throw_impact(atom/target) //disks detonate when thrown + if(!..()) // not caught in mid-air + visible_message("[src] detonates!") + playsound(src.loc, "sparks", 50, 1) + explosion(target, -1, -1, 1, 1, -1) + qdel(src) + return 1 + +/obj/item/ammo_box/magazine/internal/spinfusor + name = "spinfusor internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/spinfusor + caliber = "spinfusor" + max_ammo = 1 + +/obj/item/gun/ballistic/automatic/spinfusor + name = "Stormhammer Magnetic Cannon" + desc = "An innovative weapon utilizing mag-lev technology to spin up a magnetic fusor and launch it at extreme velocities." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "spinfusor" + item_state = "spinfusor" + mag_type = /obj/item/ammo_box/magazine/internal/spinfusor + fire_sound = 'sound/weapons/rocketlaunch.ogg' + w_class = WEIGHT_CLASS_BULKY + can_suppress = 0 + burst_size = 1 + fire_delay = 40 + select = 0 + actions_types = list() + casing_ejector = 0 + +/obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params) + var/num_loaded = magazine.attackby(A, user, params, 1) + if(num_loaded) + to_chat(user, "You load [num_loaded] disk\s into \the [src].") + update_icon() + chamber_round() + +/obj/item/gun/ballistic/automatic/spinfusor/attack_self(mob/living/user) + return //caseless rounds are too glitchy to unload properly. Best to make it so that you cannot remove disks from the spinfusor + +/obj/item/gun/ballistic/automatic/spinfusor/update_icon() + ..() + icon_state = "spinfusor[magazine ? "-[get_ammo(1)]" : ""]" + +/obj/item/ammo_box/aspinfusor + name = "ammo box (spinfusor disks)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "spinfusorbox" + ammo_type = /obj/item/ammo_casing/caseless/spinfusor + max_ammo = 8 + +/datum/supply_pack/security/armory/spinfusor + name = "Stormhammer Spinfusor Crate" + cost = 14000 + contains = list(/obj/item/gun/ballistic/automatic/spinfusor, + /obj/item/gun/ballistic/automatic/spinfusor) + crate_name = "spinfusor crate" + +/datum/supply_pack/security/armory/spinfusorammo + name = "Spinfusor Disk Crate" + cost = 7000 + contains = list(/obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor) + crate_name = "spinfusor disk crate" \ No newline at end of file diff --git a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm index e054e65ac5..fb488fcca4 100644 --- a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm @@ -1,7 +1,56 @@ /obj/item/gun/energy/e_gun + name = "blaster carbine" + desc = "A high powered particle blaster carbine with varitable setting for stunning or lethal applications." icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi' lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi' righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi' ammo_x_offset = 2 flight_x_offset = 17 - flight_y_offset = 11 \ No newline at end of file + flight_y_offset = 11 + + +/*///////////////////////////////////////////////////////////////////////////////////////////// + The Recolourable Energy Gun +*////////////////////////////////////////////////////////////////////////////////////////////// + +obj/item/gun/energy/e_gun/cx + name = "\improper CX Model D Energy Gun" + desc = "An overpriced hybrid energy gun with two settings: disable, and kill. Manufactured by CX Armories. Has a polychromic coating." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "cxe" + lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi' + righthand_file = 'icons/mob/citadel/guns_righthand.dmi' + ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) + flight_x_offset = 15 + flight_y_offset = 10 + var/body_color = "#252528" + +obj/item/gun/energy/e_gun/cx/update_icon() + ..() + var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "cxegun_body") + if(body_color) + body_overlay.color = body_color + add_overlay(body_overlay) + + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +obj/item/gun/energy/e_gun/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + if(alert("Are you sure you want to repaint your gun?", "Confirm Repaint", "Yes", "No") == "Yes") + var/body_color_input = input(usr,"","Choose Body Color",body_color) as color|null + if(body_color_input) + body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1) + update_icon() + +obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(isinhands) + var/mutable_appearance/body_inhand = mutable_appearance(icon_file, "cxe_body") + body_inhand.color = body_color + . += body_inhand diff --git a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm index 316c976f6a..25ae98e72a 100644 --- a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm +++ b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm @@ -1,4 +1,6 @@ /obj/item/gun/energy/laser + name = "blaster rifle" + desc = "a high energy particle blaster, efficient and deadly." icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi' ammo_x_offset = 1 shaded_charge = 1 @@ -14,4 +16,31 @@ /obj/item/gun/energy/laser/redtag lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' \ No newline at end of file + righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' + +/obj/item/gun/energy/laser/carbine + name = "VGS blaster carbine" + desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal blaster carbine." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "lasernew" + item_state = "laser" + force = 10 + throwforce = 10 + ammo_type = list(/obj/item/ammo_casing/energy/lasergun) + cell_type = /obj/item/stock_parts/cell/lascarbine + +/obj/item/gun/energy/laser/carbine/nopin + pin = null + +/obj/item/stock_parts/cell/lascarbine + name = "laser carbine power supply" + maxcharge = 2500 + +/datum/design/lasercarbine + name = "VGS Blaster Carbine" + desc = "Beefed up version of a normal blaster carbine." + id = "lasercarbine" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000) + build_path = /obj/item/gun/energy/laser/carbine/nopin + category = list("Weapons") \ No newline at end of file diff --git a/code/citadel/cit_kegs.dm b/modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm similarity index 93% rename from code/citadel/cit_kegs.dm rename to modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm index d7e4ac03b9..d40dba8a3f 100644 --- a/code/citadel/cit_kegs.dm +++ b/modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm @@ -1,7 +1,7 @@ /obj/structure/reagent_dispensers/keg name = "keg" desc = "A keg." - icon = 'code/citadel/icons/objects.dmi' + icon = 'modular_citadel/icons/obj/objects.dmi' icon_state = "keg" reagent_id = "water" diff --git a/code/citadel/hypospraymkii.dm b/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm similarity index 95% rename from code/citadel/hypospraymkii.dm rename to modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm index 587a980cd5..e89068c95f 100644 --- a/code/citadel/hypospraymkii.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm @@ -4,7 +4,7 @@ //A vial-loaded hypospray. Cartridge-based! /obj/item/reagent_containers/hypospray/mkii name = "hypospray mk.II" - icon = 'icons/obj/citadel/hypospray.dmi' + icon = 'modular_citadel/icons/obj/hypospraymkii.dmi' icon_state = "hypo2" var/list/allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/small) desc = "A new development from DeForest Medical, this new hypospray takes 30-unit vials as the drug supply for easy swapping." @@ -111,6 +111,15 @@ to_chat(user, "[target] is full.") return + if(ishuman(L)) + var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected)) + if(!affecting) + to_chat(user, "The limb is missing!") + return + if(affecting.status != BODYPART_ORGANIC) + to_chat(user, "Medicine won't work on a robotic limb!") + return + var/contained = reagents.log_list() add_logs(user, L, "attemped to inject", src, addition="which had [contained]") //Always log attemped injections for admins diff --git a/code/citadel/hypovial.dm b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm similarity index 78% rename from code/citadel/hypovial.dm rename to modular_citadel/code/modules/reagents/reagent container/hypovial.dm index 61c61ed6c3..e3e82e22a7 100644 --- a/code/citadel/hypovial.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm @@ -1,20 +1,28 @@ /obj/item/reagent_containers/glass/bottle/vial name = "hypospray vial" desc = "This is a vial suitable for loading into mk II hyposprays." - icon = 'icons/obj/citadel/vial.dmi' + icon = 'modular_citadel/icons/obj/vial.dmi' icon_state = "hypovial" - w_class = WEIGHT_CLASS_SMALL //Why would it be the same size as a beaker? - container_type = OPENCONTAINER spillable = FALSE - resistance_flags = ACID_PROOF var/comes_with = list() //Easy way of doing this. volume = 10 + obj_flags = UNIQUE_RENAME + unique_reskin = list("Hypospray vial" = "hypovial", + "Red hypospray vial" = "hypovial-b", + "Blue hypospray vial" = "hypovial-d", + "Green hypospray vial" = "hypovial-a", + "Orange hypospray vial" = "hypovial-k", + "Purple hypospray vial" = "hypovial-p", + "Black hypospray vial" = "hypovial-t" + ) /obj/item/reagent_containers/glass/bottle/vial/Initialize() . = ..() if(!icon_state) icon_state = "hypovial" update_icon() + for(var/R in comes_with) + reagents.add_reagent(R,comes_with[R]) /obj/item/reagent_containers/glass/bottle/vial/on_reagent_change() update_icon() @@ -22,7 +30,7 @@ /obj/item/reagent_containers/glass/bottle/vial/update_icon() cut_overlays() if(reagents.total_volume) - var/mutable_appearance/filling = mutable_appearance('icons/obj/citadel/vial.dmi', "[icon_state]10") + var/mutable_appearance/filling = mutable_appearance('modular_citadel/icons/obj/vial.dmi', "[icon_state]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) @@ -48,11 +56,14 @@ desc = "This is a vial suitable for loading into the Chief Medical Officer's Hypospray mk II." icon_state = "hypoviallarge" volume = 60 - -/obj/item/reagent_containers/glass/bottle/vial/New() - ..() - for(var/R in comes_with) - reagents.add_reagent(R,comes_with[R]) + unique_reskin = list("Large hypospray vial" = "hypoviallarge", + "Red hypospray vial" = "hypoviallarge-b", + "Blue hypospray vial" = "hypoviallarge-d", + "Green hypospray vial" = "hypoviallarge-a", + "Orange hypospray vial" = "hypoviallarge-k", + "Purple hypospray vial" = "hypoviallarge-p", + "Black hypospray vial" = "hypoviallarge-t" + ) /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/bicaridine name = "vial (bicaridine)" diff --git a/code/citadel/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm similarity index 98% rename from code/citadel/cit_reagents.dm rename to modular_citadel/code/modules/reagents/reagents/cit_reagents.dm index df4af10faa..01c5e005a3 100644 --- a/code/citadel/cit_reagents.dm +++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm @@ -29,7 +29,7 @@ gender = PLURAL density = 0 layer = ABOVE_NORMAL_TURF_LAYER - icon = 'code/citadel/icons/effects.dmi' + icon = 'modular_citadel/icons/obj/genitals/effects.dmi' icon_state = "semen1" random_icon_states = list("semen1", "semen2", "semen3", "semen4") @@ -59,7 +59,7 @@ gender = PLURAL density = 0 layer = ABOVE_NORMAL_TURF_LAYER - icon = 'code/citadel/icons/effects.dmi' + icon = 'modular_citadel/icons/obj/genitals/effects.dmi' icon_state = "fem1" random_icon_states = list("fem1", "fem2", "fem3", "fem4") blood_state = null @@ -260,7 +260,7 @@ /obj/item/reagent_containers/food/drinks/bottle/sake name = "Traditional Sake" desc = "Sweet as can be, and burns like foxfire going down." - icon = 'code/citadel/icons/drinks.dmi' + icon = 'modular_citadel/icons/obj/drinks.dmi' icon_state = "sakebottle" list_reagents = list("sake" = 100) diff --git a/code/modules/vore/eating/belly_dat_vr.dm b/modular_citadel/code/modules/vore/eating/belly_dat_vr.dm similarity index 100% rename from code/modules/vore/eating/belly_dat_vr.dm rename to modular_citadel/code/modules/vore/eating/belly_dat_vr.dm diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm similarity index 100% rename from code/modules/vore/eating/belly_obj_vr.dm rename to modular_citadel/code/modules/vore/eating/belly_obj_vr.dm diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm similarity index 100% rename from code/modules/vore/eating/bellymodes_vr.dm rename to modular_citadel/code/modules/vore/eating/bellymodes_vr.dm diff --git a/code/modules/vore/eating/digest_act_vr.dm b/modular_citadel/code/modules/vore/eating/digest_act_vr.dm similarity index 100% rename from code/modules/vore/eating/digest_act_vr.dm rename to modular_citadel/code/modules/vore/eating/digest_act_vr.dm diff --git a/code/modules/vore/eating/living_vr.dm b/modular_citadel/code/modules/vore/eating/living_vr.dm similarity index 100% rename from code/modules/vore/eating/living_vr.dm rename to modular_citadel/code/modules/vore/eating/living_vr.dm diff --git a/code/modules/vore/eating/simple_animal_vr.dm b/modular_citadel/code/modules/vore/eating/simple_animal_vr.dm similarity index 100% rename from code/modules/vore/eating/simple_animal_vr.dm rename to modular_citadel/code/modules/vore/eating/simple_animal_vr.dm diff --git a/code/modules/vore/eating/vore_vr.dm b/modular_citadel/code/modules/vore/eating/vore_vr.dm similarity index 100% rename from code/modules/vore/eating/vore_vr.dm rename to modular_citadel/code/modules/vore/eating/vore_vr.dm diff --git a/code/modules/vore/eating/voreitems.dm b/modular_citadel/code/modules/vore/eating/voreitems.dm similarity index 100% rename from code/modules/vore/eating/voreitems.dm rename to modular_citadel/code/modules/vore/eating/voreitems.dm diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm similarity index 100% rename from code/modules/vore/eating/vorepanel_vr.dm rename to modular_citadel/code/modules/vore/eating/vorepanel_vr.dm diff --git a/code/modules/vore/hook-defs_vr.dm b/modular_citadel/code/modules/vore/hook-defs_vr.dm similarity index 100% rename from code/modules/vore/hook-defs_vr.dm rename to modular_citadel/code/modules/vore/hook-defs_vr.dm diff --git a/code/modules/vore/persistence.dm b/modular_citadel/code/modules/vore/persistence.dm similarity index 100% rename from code/modules/vore/persistence.dm rename to modular_citadel/code/modules/vore/persistence.dm diff --git a/code/modules/vore/resizing/grav_pull_vr.dm b/modular_citadel/code/modules/vore/resizing/grav_pull_vr.dm similarity index 100% rename from code/modules/vore/resizing/grav_pull_vr.dm rename to modular_citadel/code/modules/vore/resizing/grav_pull_vr.dm diff --git a/code/modules/vore/resizing/holder_micro_vr.dm b/modular_citadel/code/modules/vore/resizing/holder_micro_vr.dm similarity index 100% rename from code/modules/vore/resizing/holder_micro_vr.dm rename to modular_citadel/code/modules/vore/resizing/holder_micro_vr.dm diff --git a/code/modules/vore/resizing/resize_vr.dm b/modular_citadel/code/modules/vore/resizing/resize_vr.dm similarity index 100% rename from code/modules/vore/resizing/resize_vr.dm rename to modular_citadel/code/modules/vore/resizing/resize_vr.dm diff --git a/code/modules/vore/resizing/sizechemicals.dm b/modular_citadel/code/modules/vore/resizing/sizechemicals.dm similarity index 98% rename from code/modules/vore/resizing/sizechemicals.dm rename to modular_citadel/code/modules/vore/resizing/sizechemicals.dm index 78b4bd71ca..1164bf65d6 100644 --- a/code/modules/vore/resizing/sizechemicals.dm +++ b/modular_citadel/code/modules/vore/resizing/sizechemicals.dm @@ -110,6 +110,6 @@ for(var/atom/movable/A in B.internal_contents) if(prob(55)) playsound(M, 'sound/effects/splat.ogg', 50, 1) - B.release_specific_contents(A) + B.release_vore_contents(A) ..() . = 1 \ No newline at end of file diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/modular_citadel/code/modules/vore/resizing/sizegun_vr.dm similarity index 100% rename from code/modules/vore/resizing/sizegun_vr.dm rename to modular_citadel/code/modules/vore/resizing/sizegun_vr.dm diff --git a/code/modules/vore/trycatch_vr.dm b/modular_citadel/code/modules/vore/trycatch_vr.dm similarity index 100% rename from code/modules/vore/trycatch_vr.dm rename to modular_citadel/code/modules/vore/trycatch_vr.dm diff --git a/code/citadel/icons/misc.dmi b/modular_citadel/icons/misc/misc.dmi similarity index 100% rename from code/citadel/icons/misc.dmi rename to modular_citadel/icons/misc/misc.dmi diff --git a/code/citadel/icons/robot_transformations.dmi b/modular_citadel/icons/mob/legacy robo transforms.dmi similarity index 100% rename from code/citadel/icons/robot_transformations.dmi rename to modular_citadel/icons/mob/legacy robo transforms.dmi diff --git a/code/citadel/icons/mobs.dmi b/modular_citadel/icons/mob/mobs.dmi similarity index 100% rename from code/citadel/icons/mobs.dmi rename to modular_citadel/icons/mob/mobs.dmi diff --git a/code/citadel/icons/drinks.dmi b/modular_citadel/icons/obj/drinks.dmi similarity index 100% rename from code/citadel/icons/drinks.dmi rename to modular_citadel/icons/obj/drinks.dmi diff --git a/code/citadel/icons/breasts.dmi b/modular_citadel/icons/obj/genitals/breasts.dmi similarity index 100% rename from code/citadel/icons/breasts.dmi rename to modular_citadel/icons/obj/genitals/breasts.dmi diff --git a/code/citadel/icons/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi similarity index 100% rename from code/citadel/icons/breasts_onmob.dmi rename to modular_citadel/icons/obj/genitals/breasts_onmob.dmi diff --git a/code/citadel/icons/dildo.dmi b/modular_citadel/icons/obj/genitals/dildo.dmi similarity index 100% rename from code/citadel/icons/dildo.dmi rename to modular_citadel/icons/obj/genitals/dildo.dmi diff --git a/code/citadel/icons/effects.dmi b/modular_citadel/icons/obj/genitals/effects.dmi similarity index 100% rename from code/citadel/icons/effects.dmi rename to modular_citadel/icons/obj/genitals/effects.dmi diff --git a/code/citadel/icons/hud.dmi b/modular_citadel/icons/obj/genitals/hud.dmi similarity index 100% rename from code/citadel/icons/hud.dmi rename to modular_citadel/icons/obj/genitals/hud.dmi diff --git a/code/citadel/icons/onahole.dmi b/modular_citadel/icons/obj/genitals/onahole.dmi similarity index 100% rename from code/citadel/icons/onahole.dmi rename to modular_citadel/icons/obj/genitals/onahole.dmi diff --git a/code/citadel/icons/ovipositor.dmi b/modular_citadel/icons/obj/genitals/ovipositor.dmi similarity index 100% rename from code/citadel/icons/ovipositor.dmi rename to modular_citadel/icons/obj/genitals/ovipositor.dmi diff --git a/code/citadel/icons/penis.dmi b/modular_citadel/icons/obj/genitals/penis.dmi similarity index 100% rename from code/citadel/icons/penis.dmi rename to modular_citadel/icons/obj/genitals/penis.dmi diff --git a/code/citadel/icons/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi similarity index 100% rename from code/citadel/icons/penis_onmob.dmi rename to modular_citadel/icons/obj/genitals/penis_onmob.dmi diff --git a/code/citadel/icons/taur_penis_onmob.dmi b/modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi similarity index 100% rename from code/citadel/icons/taur_penis_onmob.dmi rename to modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi diff --git a/code/citadel/icons/vagina.dmi b/modular_citadel/icons/obj/genitals/vagina.dmi similarity index 100% rename from code/citadel/icons/vagina.dmi rename to modular_citadel/icons/obj/genitals/vagina.dmi diff --git a/code/citadel/icons/vagina_onmob.dmi b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi similarity index 100% rename from code/citadel/icons/vagina_onmob.dmi rename to modular_citadel/icons/obj/genitals/vagina_onmob.dmi diff --git a/modular_citadel/icons/obj/hypospraymkii.dmi b/modular_citadel/icons/obj/hypospraymkii.dmi new file mode 100644 index 0000000000..f5e89227c7 Binary files /dev/null and b/modular_citadel/icons/obj/hypospraymkii.dmi differ diff --git a/code/citadel/icons/objects.dmi b/modular_citadel/icons/obj/objects.dmi similarity index 100% rename from code/citadel/icons/objects.dmi rename to modular_citadel/icons/obj/objects.dmi diff --git a/code/citadel/icons/structures.dmi b/modular_citadel/icons/obj/structures.dmi similarity index 100% rename from code/citadel/icons/structures.dmi rename to modular_citadel/icons/obj/structures.dmi diff --git a/modular_citadel/icons/obj/vial.dmi b/modular_citadel/icons/obj/vial.dmi new file mode 100644 index 0000000000..694cc1741b Binary files /dev/null and b/modular_citadel/icons/obj/vial.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 0f159bed10..b1787c6712 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -92,6 +92,7 @@ #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\wall_dents.dm" #include "code\__DEFINES\wires.dm" +#include "code\__HELPERS\_cit_helpers.dm" #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" @@ -182,44 +183,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" -#include "code\citadel\_cit_helpers.dm" -#include "code\citadel\cit_areas.dm" -#include "code\citadel\cit_arousal.dm" -#include "code\citadel\cit_clothes.dm" -#include "code\citadel\cit_crewobjectives.dm" -#include "code\citadel\cit_displaycases.dm" -#include "code\citadel\cit_emotes.dm" -#include "code\citadel\cit_guns.dm" -#include "code\citadel\cit_kegs.dm" -#include "code\citadel\cit_miscreants.dm" -#include "code\citadel\cit_reagents.dm" -#include "code\citadel\cit_spawners.dm" -#include "code\citadel\cit_uniforms.dm" -#include "code\citadel\cit_vendors.dm" -#include "code\citadel\dogborgstuff.dm" -#include "code\citadel\hypospraymkii.dm" -#include "code\citadel\hypovial.dm" -#include "code\citadel\plasmacases.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_cargo.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_civilian.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_command.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_engineering.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_medical.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_science.dm" -#include "code\citadel\crew_objectives\cit_crewobjectives_security.dm" -#include "code\citadel\custom_loadout\custom_items.dm" -#include "code\citadel\custom_loadout\load_to_mob.dm" -#include "code\citadel\custom_loadout\read_from_file.dm" -#include "code\citadel\organs\breasts.dm" -#include "code\citadel\organs\eggsack.dm" -#include "code\citadel\organs\genitals.dm" -#include "code\citadel\organs\genitals_sprite_accessories.dm" -#include "code\citadel\organs\ovipositor.dm" -#include "code\citadel\organs\penis.dm" -#include "code\citadel\organs\testicles.dm" -#include "code\citadel\organs\vagina.dm" -#include "code\citadel\organs\womb.dm" -#include "code\citadel\toys\dildos.dm" #include "code\controllers\admin.dm" #include "code\controllers\configuration_citadel.dm" #include "code\controllers\controller.dm" @@ -807,6 +770,7 @@ #include "code\game\objects\items\devices\aicard.dm" #include "code\game\objects\items\devices\camera_bug.dm" #include "code\game\objects\items\devices\chameleonproj.dm" +#include "code\game\objects\items\devices\dogborg_sleeper.dm" #include "code\game\objects\items\devices\doorCharge.dm" #include "code\game\objects\items\devices\electroadaptive_pseudocircuit.dm" #include "code\game\objects\items\devices\flashlight.dm" @@ -2588,18 +2552,6 @@ #include "code\modules\vehicles\speedbike.dm" #include "code\modules\vehicles\vehicle_actions.dm" #include "code\modules\vehicles\vehicle_key.dm" -#include "code\modules\vore\hook-defs_vr.dm" -#include "code\modules\vore\persistence.dm" -#include "code\modules\vore\trycatch_vr.dm" -#include "code\modules\vore\eating\belly_dat_vr.dm" -#include "code\modules\vore\eating\belly_obj_vr.dm" -#include "code\modules\vore\eating\bellymodes_vr.dm" -#include "code\modules\vore\eating\digest_act_vr.dm" -#include "code\modules\vore\eating\living_vr.dm" -#include "code\modules\vore\eating\simple_animal_vr.dm" -#include "code\modules\vore\eating\vore_vr.dm" -#include "code\modules\vore\eating\voreitems.dm" -#include "code\modules\vore\eating\vorepanel_vr.dm" #include "code\modules\VR\vr_human.dm" #include "code\modules\VR\vr_sleeper.dm" #include "code\modules\zombie\items.dm" @@ -2627,15 +2579,18 @@ #include "modular_citadel\code\datums\mutations\hulk.dm" #include "modular_citadel\code\datums\wires\airlock.dm" #include "modular_citadel\code\datums\wires\autoylathe.dm" +#include "modular_citadel\code\game\area\cit_areas.dm" #include "modular_citadel\code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm" #include "modular_citadel\code\game\gamemodes\revolution\revolution.dm" #include "modular_citadel\code\game\machinery\cryopod.dm" +#include "modular_citadel\code\game\machinery\displaycases.dm" #include "modular_citadel\code\game\machinery\Sleeper.dm" #include "modular_citadel\code\game\machinery\toylathe.dm" #include "modular_citadel\code\game\machinery\vending.dm" #include "modular_citadel\code\game\machinery\computer\card.dm" #include "modular_citadel\code\game\objects\ids.dm" #include "modular_citadel\code\game\objects\tools.dm" +#include "modular_citadel\code\game\objects\effects\spawner\spawners.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\projectiles\impact.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\projectiles\muzzle.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\projectiles\tracer.dm" @@ -2658,6 +2613,26 @@ #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" #include "modular_citadel\code\modules\admin\topic.dm" +#include "modular_citadel\code\modules\antagonists\cit_crewobjectives.dm" +#include "modular_citadel\code\modules\antagonists\cit_miscreants.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_cargo.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_civilian.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_command.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_engineering.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_medical.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_science.dm" +#include "modular_citadel\code\modules\antagonists\crew_objectives\cit_crewobjectives_security.dm" +#include "modular_citadel\code\modules\arousal\arousal.dm" +#include "modular_citadel\code\modules\arousal\organs\breasts.dm" +#include "modular_citadel\code\modules\arousal\organs\eggsack.dm" +#include "modular_citadel\code\modules\arousal\organs\genitals.dm" +#include "modular_citadel\code\modules\arousal\organs\genitals_sprite_accessories.dm" +#include "modular_citadel\code\modules\arousal\organs\ovipositor.dm" +#include "modular_citadel\code\modules\arousal\organs\penis.dm" +#include "modular_citadel\code\modules\arousal\organs\testicles.dm" +#include "modular_citadel\code\modules\arousal\organs\vagina.dm" +#include "modular_citadel\code\modules\arousal\organs\womb.dm" +#include "modular_citadel\code\modules\arousal\toys\dildos.dm" #include "modular_citadel\code\modules\cargo\console.dm" #include "modular_citadel\code\modules\cargo\packs.dm" #include "modular_citadel\code\modules\client\client_defines.dm" @@ -2681,12 +2656,15 @@ #include "modular_citadel\code\modules\client\loadout\suit.dm" #include "modular_citadel\code\modules\client\loadout\uniform.dm" #include "modular_citadel\code\modules\client\verbs\who.dm" -#include "modular_citadel\code\modules\clothing\under.dm" #include "modular_citadel\code\modules\clothing\spacesuits\flightsuit.dm" +#include "modular_citadel\code\modules\clothing\suits\suits.dm" #include "modular_citadel\code\modules\clothing\under\polychromic_clothes.dm" -#include "modular_citadel\code\modules\clothing\under\syndicate.dm" #include "modular_citadel\code\modules\clothing\under\turtlenecks.dm" +#include "modular_citadel\code\modules\clothing\under\under.dm" #include "modular_citadel\code\modules\crafting\recipes.dm" +#include "modular_citadel\code\modules\custom_loadout\custom_items.dm" +#include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm" +#include "modular_citadel\code\modules\custom_loadout\read_from_file.dm" #include "modular_citadel\code\modules\events\blob.dm" #include "modular_citadel\code\modules\jobs\jobs.dm" #include "modular_citadel\code\modules\jobs\job_types\captain.dm" @@ -2701,9 +2679,11 @@ #include "modular_citadel\code\modules\mentor\mentorpm.dm" #include "modular_citadel\code\modules\mentor\mentorsay.dm" #include "modular_citadel\code\modules\mining\mine_items.dm" +#include "modular_citadel\code\modules\mob\cit_emotes.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\life.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\species_types\jellypeople.dm" +#include "modular_citadel\code\modules\mob\living\silicon\robot\dogborg_equipment.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\robot.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm" #include "modular_citadel\code\modules\mob\living\simple_animal\banana_spider.dm" @@ -2711,13 +2691,34 @@ #include "modular_citadel\code\modules\power\lighting.dm" #include "modular_citadel\code\modules\projectiles\guns\pumpenergy.dm" #include "modular_citadel\code\modules\projectiles\guns\toys.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\flechette.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\handguns.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\magweapon.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\revolver.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\rifles.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\spinfusor.dm" #include "modular_citadel\code\modules\projectiles\guns\energy\energy_gun.dm" #include "modular_citadel\code\modules\projectiles\guns\energy\laser.dm" +#include "modular_citadel\code\modules\reagents\reagent container\cit_kegs.dm" +#include "modular_citadel\code\modules\reagents\reagent container\hypospraymkii.dm" +#include "modular_citadel\code\modules\reagents\reagent container\hypovial.dm" +#include "modular_citadel\code\modules\reagents\reagents\cit_reagents.dm" #include "modular_citadel\code\modules\research\designs\autoylathe_designs.dm" #include "modular_citadel\code\modules\research\designs\machine_designs.dm" #include "modular_citadel\code\modules\research\techweb\_techweb.dm" #include "modular_citadel\code\modules\research\techweb\all_nodes.dm" #include "modular_citadel\code\modules\uplink\uplink_items.dm" +#include "modular_citadel\code\modules\vore\hook-defs_vr.dm" +#include "modular_citadel\code\modules\vore\persistence.dm" +#include "modular_citadel\code\modules\vore\trycatch_vr.dm" +#include "modular_citadel\code\modules\vore\eating\belly_dat_vr.dm" +#include "modular_citadel\code\modules\vore\eating\belly_obj_vr.dm" +#include "modular_citadel\code\modules\vore\eating\bellymodes_vr.dm" +#include "modular_citadel\code\modules\vore\eating\digest_act_vr.dm" +#include "modular_citadel\code\modules\vore\eating\living_vr.dm" +#include "modular_citadel\code\modules\vore\eating\simple_animal_vr.dm" +#include "modular_citadel\code\modules\vore\eating\vore_vr.dm" +#include "modular_citadel\code\modules\vore\eating\voreitems.dm" +#include "modular_citadel\code\modules\vore\eating\vorepanel_vr.dm" #include "modular_citadel\interface\skin.dmf" // END_INCLUDE diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index ffe61666b9..256b53c106 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file