diff --git a/_maps/map_files/BigRed_v2/BigRed_v2.dmm b/_maps/map_files/BigRed_v2/BigRed_v2.dmm index 366e83ebcf5..01e45e98a8f 100644 --- a/_maps/map_files/BigRed_v2/BigRed_v2.dmm +++ b/_maps/map_files/BigRed_v2/BigRed_v2.dmm @@ -2726,10 +2726,6 @@ /obj/machinery/light, /turf/open/floor/tile/darkish, /area/bigredv2/caves/lambda_lab) -"axF" = ( -/obj/structure/barricade/wooden, -/turf/open/floor/plating/ground/mars/random/sand, -/area/bigredv2/outside/n) "axP" = ( /obj/structure/bed/chair{ dir = 4 @@ -37102,7 +37098,7 @@ gzM gzM gzM gzM -axF +aqO aqO gzM gQv diff --git a/_maps/map_files/Magmoor_Digsite_IV/Magmoor_Digsite_IV.dmm b/_maps/map_files/Magmoor_Digsite_IV/Magmoor_Digsite_IV.dmm index d50b6863838..47b112a72ba 100644 --- a/_maps/map_files/Magmoor_Digsite_IV/Magmoor_Digsite_IV.dmm +++ b/_maps/map_files/Magmoor_Digsite_IV/Magmoor_Digsite_IV.dmm @@ -14226,8 +14226,8 @@ /area/magmoor/compound) "koF" = ( /obj/item/toy/plush/rouny, -/turf/open/lavaland/basalt/cave/autosmooth, -/area/magmoor/cave/south) +/turf/closed/mineral/smooth, +/area/magmoor/cave/rock) "kpw" = ( /obj/structure/rock/basalt/pile, /turf/open/floor/plating/ground/mars/random/dirt, @@ -32962,7 +32962,7 @@ /turf/open/floor/mainship/mono, /area/magmoor/engi) "xWF" = ( -/turf/open/liquid/lava/autosmoothing, +/turf/open/floor/plating/ground/mars/random/dirt, /area/magmoor/cave/south) "xWG" = ( /obj/effect/ai_node, @@ -55248,8 +55248,8 @@ ylo ylo ylo ylo -ylo -ylo +rxl +rxl rxl rxl rxl @@ -55481,9 +55481,9 @@ ylo ylo ylo ylo -ylo -ylo -ylo +rxl +rxl +rxl rxl rxl rxl @@ -55714,10 +55714,10 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl rxl rxl rxl @@ -55946,11 +55946,11 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -56179,6 +56179,232 @@ ylo ylo ylo ylo +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +iLH +iLH +"} +(99,1,1) = {" +iLH +iLH +rxl +rxl +rxl +kcd +kcd +kcd +kxx +awr +kcd +kcd +jkR +jkR +lxN +lxN +lxN +lxN +jkR +jkR +kcd +kcd +kcd +kcd +kxx +kcd +kcd +rxl +rxl +rxl +rxl +rxl +rxl +kcd +kcd +kcd +kcd +kcd +kcd +kcd +kcd +kcd +kxx +kcd +kcd +kcd +kcd +kcd +kcd +vRc +vRc +ymj +ymj +ymj +ymj +vUC +vUC +ymj +rxl +rxl +rxl +rxl +rxl +gKh +gKh +bsu +mNI +mNI +gKh +gKh +urG +gKh +gKh +bsu +gKh +gKh +bsu +gKh +gKh +gKh +xAr +pCC +ymj +ymj +ymj +ymj +ymj +ymj +ymj +ymj +ymj +xfT +xfT +jVm +uOU +qHR +qHR +qHR +qHR +iXj +xqg +dSo +dSo +kJY +noB +jjU +vcM +rBq +tlb +kdG +rge +wEH +bgM +nSX +hiG +hiG +iDm +rKd +dtj +hiG +hiG +hiG +hiG +hiG +hiG +pDq +syD +rSf +hiG +hiG +hiG +kKp +beu +lGN +xmr +rjq +hIT +aje +aau +mSb +imu +mSb +aau +aje +hIT +pKb +fIr +jRr +xmr +hIT +gRT +eeU +mpw +gRT +ddm +uJz +gRT +mpw +eeU +gRT +eeU +mpw +gRT +ddm +uJz +gRT +mpw +eeU +gRT +eeU +mpw +gRT +ddm +uJz +gRT +mpw +eeU +gRT +iCe +dum +dum +pDq +dum +dum +dum +qkn +eTo +pUx +ylo +ylo +ylo +ylo +ylo +ylo +ylo ylo ylo ylo @@ -56206,232 +56432,6 @@ rxl rxl rxl rxl -iLH -iLH -"} -(99,1,1) = {" -iLH -iLH -rxl -rxl -rxl -kcd -kcd -kcd -kxx -awr -kcd -kcd -jkR -jkR -lxN -lxN -lxN -lxN -jkR -jkR -kcd -kcd -kcd -kcd -kxx -kcd -kcd -rxl -rxl -rxl -rxl -rxl -rxl -kcd -kcd -kcd -kcd -kcd -kcd -kcd -kcd -kcd -kxx -kcd -kcd -kcd -kcd -kcd -kcd -vRc -vRc -ymj -ymj -ymj -ymj -vUC -vUC -ymj -rxl -rxl -rxl -rxl -rxl -gKh -gKh -bsu -mNI -mNI -gKh -gKh -urG -gKh -gKh -bsu -gKh -gKh -bsu -gKh -gKh -gKh -xAr -pCC -ymj -ymj -ymj -ymj -ymj -ymj -ymj -ymj -ymj -xfT -xfT -jVm -uOU -qHR -qHR -qHR -qHR -iXj -xqg -dSo -dSo -kJY -noB -jjU -vcM -rBq -tlb -kdG -rge -wEH -bgM -nSX -hiG -hiG -iDm -rKd -dtj -hiG -hiG -hiG -hiG -hiG -hiG -pDq -syD -rSf -hiG -hiG -hiG -kKp -beu -lGN -xmr -rjq -hIT -aje -aau -mSb -imu -mSb -aau -aje -hIT -pKb -fIr -jRr -xmr -hIT -gRT -eeU -mpw -gRT -ddm -uJz -gRT -mpw -eeU -gRT -eeU -mpw -gRT -ddm -uJz -gRT -mpw -eeU -gRT -eeU -mpw -gRT -ddm -uJz -gRT -mpw -eeU -gRT -iCe -dum -dum -pDq -dum -dum -dum -qkn -eTo -pUx -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl -rxl rxl rxl rxl @@ -56643,14 +56643,14 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -56876,15 +56876,15 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -57108,16 +57108,16 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -57340,18 +57340,18 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -57573,28 +57573,28 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -57806,30 +57806,30 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl koF rxl rxl @@ -58040,31 +58040,31 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -58274,16 +58274,6 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo rxl rxl rxl @@ -58293,12 +58283,22 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -58507,15 +58507,6 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo rxl rxl rxl @@ -58527,12 +58518,21 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -58741,14 +58741,6 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo rxl rxl rxl @@ -58762,11 +58754,19 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl iLH @@ -58974,13 +58974,6 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo -ylo -ylo rxl rxl rxl @@ -58996,10 +58989,17 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl iLH @@ -59208,11 +59208,6 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo -ylo rxl rxl rxl @@ -59229,10 +59224,15 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl +rxl rxl rxl iLH @@ -59442,10 +59442,10 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl rxl rxl rxl @@ -59675,10 +59675,10 @@ ylo ylo ylo ylo -ylo -ylo -ylo -ylo +rxl +rxl +rxl +rxl rxl rxl rxl @@ -59909,9 +59909,9 @@ ylo ylo ylo ylo -ylo -ylo -ylo +rxl +rxl +rxl rxl rxl rxl @@ -60142,8 +60142,8 @@ ylo ylo ylo ylo -ylo -ylo +rxl +rxl rxl rxl rxl @@ -60375,8 +60375,8 @@ ylo ylo ylo ylo -ylo -ylo +rxl +rxl rxl rxl rxl @@ -60608,7 +60608,7 @@ ylo ylo ylo ylo -ylo +rxl rxl rxl rxl @@ -60841,7 +60841,7 @@ ylo ylo ylo ylo -ylo +rxl rxl rxl rxl @@ -64554,7 +64554,7 @@ xwh xwh xwh xUd -xwh +xUd xUd jRL jRL @@ -64787,8 +64787,8 @@ xUd xUd xUd xUd -xwh -xUd +jRL +jRL jRL jRL jRL @@ -65019,9 +65019,9 @@ xUd jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL jRL jRL @@ -65252,10 +65252,10 @@ jRL jRL jRL jRL -xUd -xwh -xUd -xUd +jRL +jRL +jRL +jRL jRL jRL jRL @@ -65485,10 +65485,10 @@ jRL jRL jRL jRL -xUd -xwh -xwh -xUd +jRL +jRL +jRL +jRL jRL jRL jRL @@ -65718,10 +65718,10 @@ jRL jRL jRL jRL -xUd -xUd -xwh -xUd +jRL +jRL +jRL +jRL jRL jRL jRL @@ -65952,9 +65952,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL jRL jRL @@ -66185,9 +66185,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL jRL rxl @@ -66418,9 +66418,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL jRL rxl @@ -66651,9 +66651,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL rxl rxl @@ -66884,9 +66884,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL rxl rxl @@ -67117,9 +67117,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL rxl rxl @@ -67350,9 +67350,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL rxl rxl @@ -67583,9 +67583,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL jRL rxl rxl @@ -67816,9 +67816,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL rxl rxl rxl @@ -68049,9 +68049,9 @@ jRL jRL jRL jRL -xUd -xwh -xUd +jRL +jRL +jRL rxl rxl rxl @@ -68282,9 +68282,9 @@ jRL jRL jRL jRL -xUd -xwh -xwh +jRL +jRL +jRL xWF rxl rxl @@ -68515,9 +68515,9 @@ jRL jRL jRL jRL -xUd -xUd -xUd +jRL +jRL +jRL xWF rxl rxl @@ -68750,9 +68750,7 @@ jRL jRL jRL jRL -xUd -xWF -xWF +jRL xWF rxl rxl @@ -68788,6 +68786,8 @@ rxl rxl rxl rxl +rxl +rxl iLH iLH "} @@ -68983,10 +68983,10 @@ jRL jRL jRL jRL -xUd +jRL +rxl rxl rxl -xWF rxl rxl rxl @@ -69219,8 +69219,8 @@ jRL rxl rxl rxl -xWF -xWF +rxl +rxl rxl rxl rxl @@ -69453,8 +69453,8 @@ rxl rxl rxl rxl -xWF -xWF +rxl +rxl rxl rxl rxl @@ -69687,8 +69687,8 @@ rxl rxl rxl rxl -xWF -xWF +rxl +rxl rxl rxl rxl @@ -69921,11 +69921,11 @@ rxl rxl rxl rxl -xWF -xWF -xWF -xWF -xWF +rxl +rxl +rxl +rxl +rxl rxl rxl rxl @@ -70158,8 +70158,8 @@ rxl rxl rxl rxl -xWF -xWF +rxl +rxl rxl rxl rxl @@ -70392,8 +70392,8 @@ rxl rxl rxl rxl -xWF -xWF +rxl +rxl rxl rxl rxl diff --git a/_maps/map_files/Orion_Military_Outpost/orionoutpost.dmm b/_maps/map_files/Orion_Military_Outpost/orionoutpost.dmm index 23a764f5f9d..d55f2d0936f 100644 --- a/_maps/map_files/Orion_Military_Outpost/orionoutpost.dmm +++ b/_maps/map_files/Orion_Military_Outpost/orionoutpost.dmm @@ -8570,10 +8570,6 @@ "RQ" = ( /turf/closed/mineral/smooth/indestructible, /area/orion_outpost/ground/outpostw) -"RS" = ( -/obj/structure/barricade/metal, -/turf/open/floor/plating/ground/mars/random/cave/darker, -/area/orion_outpost/surface/landing_pad2_external) "RT" = ( /obj/structure/window{ dir = 4 @@ -12867,7 +12863,7 @@ ft jF gU eW -RS +hz Df lW lW diff --git a/_maps/map_files/Talos/TGS_Talos.dmm b/_maps/map_files/Talos/TGS_Talos.dmm index 5a16988c3b8..f0adc348b91 100644 --- a/_maps/map_files/Talos/TGS_Talos.dmm +++ b/_maps/map_files/Talos/TGS_Talos.dmm @@ -4092,7 +4092,7 @@ /turf/open/floor/plating/plating_catwalk/dark, /area/mainship/living/pilotbunks) "cmc" = ( -/obj/machinery/telecomms/processor/preset_four, +/obj/machinery/telecomms/processor/preset/four, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "cmn" = ( @@ -20434,7 +20434,7 @@ /turf/closed/wall/mainship/outer/talos, /area/mainship/hull/port_hull) "mkk" = ( -/obj/machinery/telecomms/bus/preset_two, +/obj/machinery/telecomms/bus/preset/two, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "mku" = ( @@ -20731,7 +20731,7 @@ /turf/open/floor/plating, /area/mainship/hull/starboard_hull) "msD" = ( -/obj/machinery/telecomms/receiver/preset_left, +/obj/machinery/telecomms/receiver/preset/left, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "msE" = ( @@ -20762,7 +20762,7 @@ }, /area/mainship/living/basketball) "msU" = ( -/obj/machinery/telecomms/broadcaster/preset_left, +/obj/machinery/telecomms/broadcaster/preset/left, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "msZ" = ( @@ -21523,6 +21523,10 @@ /obj/machinery/light/mainship, /turf/open/floor/mainship/red/full, /area/mainship/shipboard/brig) +"mMJ" = ( +/obj/machinery/telecomms/receiver/preset/right, +/turf/open/floor/mainship/silver/full, +/area/mainship/command/telecomms) "mMT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 9 @@ -21571,7 +21575,7 @@ /turf/open/floor/wood, /area/mainship/squads/alpha) "mNr" = ( -/obj/machinery/telecomms/bus/preset_one, +/obj/machinery/telecomms/bus/preset/one, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "mOb" = ( @@ -22556,7 +22560,7 @@ /turf/open/floor/prison/plate, /area/mainship/command/self_destruct) "nrw" = ( -/obj/machinery/telecomms/bus/preset_three, +/obj/machinery/telecomms/bus/preset/three, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "nrJ" = ( @@ -23549,7 +23553,7 @@ /turf/open/floor/plating, /area/mainship/hull/upper_hull) "nRT" = ( -/obj/machinery/telecomms/bus/preset_four, +/obj/machinery/telecomms/bus/preset/four, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "nRU" = ( @@ -30279,10 +30283,6 @@ /obj/effect/spawner/random/engineering/computercircuit, /turf/open/floor/plating, /area/mainship/hull/starboard_hull) -"rPT" = ( -/obj/machinery/telecomms/receiver/preset_right, -/turf/open/floor/mainship/silver/full, -/area/mainship/command/telecomms) "rPU" = ( /obj/effect/turf_decal/siding/dark{ dir = 4 @@ -31499,7 +31499,7 @@ /turf/open/floor/mainship/metal/green, /area/mainship/medical/lounge) "sBS" = ( -/obj/machinery/telecomms/broadcaster/preset_right, +/obj/machinery/telecomms/broadcaster/preset/right, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "sCb" = ( @@ -34026,7 +34026,7 @@ /turf/open/floor/wood, /area/mainship/medical/upper_medical) "ugO" = ( -/obj/machinery/telecomms/processor/preset_one, +/obj/machinery/telecomms/processor/preset/one, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "uho" = ( @@ -35752,7 +35752,7 @@ /turf/closed/wall/mainship/talos, /area/mainship/hull/upper_hull) "viz" = ( -/obj/machinery/telecomms/processor/preset_three, +/obj/machinery/telecomms/processor/preset/three, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "viB" = ( @@ -37320,7 +37320,7 @@ /turf/open/floor/mainship/metal, /area/mainship/hallways/aft_hallway) "wgv" = ( -/obj/machinery/telecomms/processor/preset_two, +/obj/machinery/telecomms/processor/preset/two, /turf/open/floor/mainship/silver/full, /area/mainship/command/telecomms) "wgY" = ( @@ -69477,7 +69477,7 @@ vfY vfY ver vfY -rPT +mMJ xPw eRE snt diff --git a/_maps/map_files/Whiskey_Outpost/Whiskey_Outpost_v2.dmm b/_maps/map_files/Whiskey_Outpost/Whiskey_Outpost_v2.dmm index 7fad30fbd7d..61a9f0a2cbc 100644 --- a/_maps/map_files/Whiskey_Outpost/Whiskey_Outpost_v2.dmm +++ b/_maps/map_files/Whiskey_Outpost/Whiskey_Outpost_v2.dmm @@ -7044,10 +7044,6 @@ /obj/structure/barricade/plasteel, /turf/open/floor/plating/warning, /area/whiskey_outpost/outside/west) -"Rb" = ( -/obj/structure/barricade/metal, -/turf/open/floor/plating/warning, -/area/whiskey_outpost/outside/west) "Rc" = ( /obj/structure/flora/tree/jungle, /turf/open/ground/jungle, @@ -15132,7 +15128,7 @@ Hr hm hm Xh -Rb +QX Hm Qu In diff --git a/_maps/map_files/deltastation/deltastation.dmm b/_maps/map_files/deltastation/deltastation.dmm index 87f8c6806f6..220a27c6e29 100644 --- a/_maps/map_files/deltastation/deltastation.dmm +++ b/_maps/map_files/deltastation/deltastation.dmm @@ -4980,10 +4980,6 @@ }, /turf/open/floor/plating, /area/deltastation/maintenance/port/fore) -"baV" = ( -/obj/machinery/telecomms/receiver/preset_left, -/turf/open/floor/gcircuit, -/area/deltastation/tcommsat/server) "baY" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -6357,10 +6353,6 @@ /obj/effect/spawner/random/engineering/cable, /turf/open/floor/iron, /area/deltastation/command/heads_quarters/rd) -"bpC" = ( -/obj/machinery/telecomms/broadcaster/preset_right, -/turf/open/floor/bcircuit, -/area/deltastation/tcommsat/server) "bpI" = ( /obj/machinery/light{ dir = 8 @@ -29969,6 +29961,10 @@ /obj/machinery/miner/damaged, /turf/open/floor/plating/ground/mars/random/cave, /area/deltastation/engineering/storage/tech) +"fZT" = ( +/obj/machinery/telecomms/receiver/preset/left, +/turf/open/floor/gcircuit, +/area/deltastation/tcommsat/server) "gac" = ( /obj/effect/turf_decal/tile/transparent/neutral{ dir = 4 @@ -45980,6 +45976,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/deltastation/commons/toilet/restrooms) +"jrg" = ( +/obj/machinery/telecomms/broadcaster/preset/left, +/turf/open/floor/bcircuit, +/area/deltastation/tcommsat/server) "jrk" = ( /obj/effect/turf_decal/warning_stripes/linethick{ dir = 4 @@ -69355,10 +69355,6 @@ }, /turf/open/floor/iron, /area/deltastation/maintenance/department/science) -"ojN" = ( -/obj/machinery/telecomms/broadcaster/preset_left, -/turf/open/floor/bcircuit, -/area/deltastation/tcommsat/server) "ojW" = ( /obj/effect/landmark/xeno_resin_door, /turf/open/floor/plating, @@ -74284,6 +74280,10 @@ /obj/effect/spawner/random/misc/structure/chair_or_metal/west, /turf/open/floor/iron/white, /area/deltastation/science/research) +"pjX" = ( +/obj/machinery/telecomms/broadcaster/preset/right, +/turf/open/floor/bcircuit, +/area/deltastation/tcommsat/server) "pjZ" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ @@ -74998,10 +74998,6 @@ }, /turf/open/floor/glass/reinforced, /area/deltastation/maintenance/space_hut/observatory) -"prv" = ( -/obj/machinery/telecomms/receiver/preset_right, -/turf/open/floor/gcircuit, -/area/deltastation/tcommsat/server) "prR" = ( /obj/structure/table/reinforced, /obj/effect/spawner/random/misc/paperbin{ @@ -158152,7 +158148,7 @@ rpV vRI wHO vgI -ojN +jrg pCQ fun wGX @@ -158662,7 +158658,7 @@ ndM jLv vIe ykl -prv +fZT tNq pCQ mBm @@ -159690,7 +159686,7 @@ cAr jLv vIe ykl -baV +fZT tNq pCQ sHW @@ -160208,7 +160204,7 @@ rpV cjF kpV xKi -bpC +pjX vgI ixu beT diff --git a/_maps/map_files/gelida_iv/gelida_iv.dmm b/_maps/map_files/gelida_iv/gelida_iv.dmm index 174b8972b28..9cd3151c30d 100644 --- a/_maps/map_files/gelida_iv/gelida_iv.dmm +++ b/_maps/map_files/gelida_iv/gelida_iv.dmm @@ -27045,12 +27045,6 @@ /obj/structure/prop/mainship/gelida/rails, /turf/open/floor/prison, /area/gelida/indoors/c_block/mining) -"shH" = ( -/obj/structure/barricade/metal{ - dir = 4 - }, -/turf/open/floor/plating/ground/snow/layer0, -/area/gelida/outdoors/colony_streets/south_west_street) "shI" = ( /obj/item/clothing/mask/facehugger/dead{ desc = "It has some sort of a tube at the end of its tail. What the hell is this thing?"; @@ -31417,12 +31411,6 @@ dir = 1 }, /area/gelida/outdoors/colony_streets/east_central_street) -"vka" = ( -/obj/structure/barricade/metal{ - dir = 1 - }, -/turf/open/floor/plating/ground/snow/layer0, -/area/gelida/outdoors/colony_streets/south_east_street) "vke" = ( /obj/effect/spawner/random/misc/structure/chair_or_metal, /obj/structure/cable, @@ -45360,7 +45348,7 @@ ngP ndb ngP iCC -shH +iCC xNz xNz ljQ @@ -66001,7 +65989,7 @@ eWY eWY eWY mDs -vka +sHp txG txG txG diff --git a/_maps/modularmaps/big_red/bigredcaveswvar2.dmm b/_maps/modularmaps/big_red/bigredcaveswvar2.dmm index 79416dd2517..76a1cfd4017 100644 --- a/_maps/modularmaps/big_red/bigredcaveswvar2.dmm +++ b/_maps/modularmaps/big_red/bigredcaveswvar2.dmm @@ -63,9 +63,6 @@ /obj/effect/landmark/lv624/fog_blocker, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"D" = ( -/turf/open/floor/plating/ground/mars/random/cave/rock, -/area/bigredv2/caves/southwest) "F" = ( /obj/effect/landmark/weed_node, /obj/effect/ai_node, @@ -90,15 +87,6 @@ /obj/effect/landmark/weed_node, /turf/open/floor/plating/ground/mars/random/cave/rock, /area/bigredv2/caves/southwest) -"R" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) -"S" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) -"W" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "Y" = ( /obj/effect/landmark/xeno_silo_spawn, /turf/open/floor/plating/ground/mars/random/cave, @@ -486,8 +474,8 @@ j j j j -R -S +N +N j j j @@ -510,8 +498,8 @@ l l "} (10,1,1) = {" -S -S +N +N j j j @@ -527,12 +515,12 @@ j j j j -S -S +N +N g -S -S -S +N +N +N j j j @@ -556,8 +544,8 @@ l "} (11,1,1) = {" g -S -S +N +N j j j @@ -571,14 +559,14 @@ j j j j -S -S -S -S -S -S -S -S +N +N +N +N +N +N +N +N j j j @@ -600,11 +588,11 @@ l l "} (12,1,1) = {" -S -S -S -D -D +N +N +N +b +b j j j @@ -616,14 +604,14 @@ j j j j -S -S +N +N j j -S -S -S -S +N +N +N +N j j j @@ -645,11 +633,11 @@ l l "} (13,1,1) = {" -S -D +N +b d -S -D +N +b j j j @@ -661,14 +649,14 @@ j j j g -S -S +N +N j j j j -S -S +N +N g j j @@ -690,11 +678,11 @@ l l "} (14,1,1) = {" -S -S -D -S -D +N +N +b +N +b j j j @@ -705,16 +693,16 @@ j j j j -S -S -S -S +N +N +N +N j j j -S -S -S +N +N +N j j j @@ -735,11 +723,11 @@ l l "} (15,1,1) = {" -S -S -S -S -D +N +N +N +N +b j j j @@ -750,16 +738,16 @@ j j j j -S -S -S -S +N +N +N +N g j j j -S -S +N +N j j j @@ -780,10 +768,10 @@ l l "} (16,1,1) = {" -S -S +N +N m -S +N d j j @@ -795,16 +783,16 @@ j j j j -S +N g -S -S -S -S +N +N +N +N j j -S -W +N +N j j j @@ -825,10 +813,10 @@ l l "} (17,1,1) = {" -S +N g -S -S +N +N g d j @@ -836,20 +824,20 @@ j j j j -D -D -D -S -S -S -S -S +b +b +b +N +N +N +N +N k -S -S -S -S -S +N +N +N +N +N j j j @@ -870,31 +858,31 @@ l l "} (18,1,1) = {" -S -S -S -S -S -D +N +N +N +N +N +b j j j j j -D -S -S -S -S -S -S -S -S +b +N +N +N +N +N +N +N +N g -S -S +N +N m -S +N j j j @@ -915,32 +903,32 @@ l l "} (19,1,1) = {" -S +N g M g -S -S -D -S +N +N +b +N j j j -S +N M -S -S -S -S -S -S -S -S +N +N +N +N +N +N +N +N g -S -D -S -S +N +b +N +N j j j @@ -961,32 +949,32 @@ l "} (20,1,1) = {" j -S -S -S -S -S -S -S -S +N +N +N +N +N +N +N +N j -S -S -S -S -S -S -S -S -S -S -S -S -S -D -S -S -S +N +N +N +N +N +N +N +N +N +N +N +N +N +b +N +N +N j j j @@ -1008,30 +996,30 @@ l j j j -S -S -S -S -S -S -S -S -S -S -S -S +N +N +N +N +N +N +N +N +N +N +N +N g -S -S -S -S -S -S -D -S -S +N +N +N +N +N +N +b +N +N g -S +N j j j @@ -1053,30 +1041,30 @@ l j j j -S -S +N +N M -S -S -S -S -S -S +N +N +N +N +N +N M -S -S +N +N M -D +b j b -S -S -S -D +N +N +N +b j j -S -S +N +N j j j @@ -1098,19 +1086,19 @@ l j j j -S -S -S -S -S -S -S -S -S -S -S -S -D +N +N +N +N +N +N +N +N +N +N +N +N +b j j j @@ -1120,9 +1108,9 @@ j j j j -S -S -S +N +N +N j j j @@ -1143,19 +1131,19 @@ l j j j -S -S +N +N g -S -S -D -S -S -D -S +N +N +b +N +N +b +N g -S -D +N +b j j j @@ -1165,9 +1153,9 @@ j j j N -S -S -S +N +N +N j j j @@ -1188,18 +1176,18 @@ l j j j -D -S -S -S +b +N +N +N g -S -S +N +N Q -S -S -S -S +N +N +N +N j j j @@ -1209,10 +1197,10 @@ j j j j -S +N F -S -S +N +N j j j @@ -1235,16 +1223,16 @@ j j j M -S -S -S -S -S -S +N +N +N +N +N +N g -D -S -S +b +N +N t t t @@ -1255,9 +1243,9 @@ t t t t -S +N M -S +N j j j @@ -1278,18 +1266,18 @@ l j j j -S +N g M -S -S -S -S -S -S +N +N +N +N +N +N M -S -S +N +N t j j @@ -1300,10 +1288,10 @@ j j j t -S -S +N +N g -S +N j j j @@ -1322,33 +1310,33 @@ l (28,1,1) = {" j j -S -S -S -S -S -S -S -S -S -S +N +N +N +N +N +N +N +N +N +N g -S -D +N +b t j j j -S +N g v j j t j -S -S -S +N +N +N j j j @@ -1367,33 +1355,33 @@ l (29,1,1) = {" j j -S -S -S -S -S +N +N +N +N +N g -S -S -S -S -S +N +N +N +N +N g -S +N t j j -S -S -S +N +N +N Y -S +N j t j -S +N g -S +N j j j @@ -1412,34 +1400,34 @@ l (30,1,1) = {" j j -S +N g -S -S -S -S +N +N +N +N g -D +b j -D +b M -S +N F c j j -S +N g -S -S +N +N g j t j -S +N g -S -S +N +N j j j @@ -1456,35 +1444,35 @@ l "} (31,1,1) = {" j -S -S -S -S -S -S -S -S -D +N +N +N +N +N +N +N +N +b j j -D +b M g c q j M -S -S -S -S +N +N +N +N j t j d -S -S -S +N +N +N j j j @@ -1501,35 +1489,35 @@ l "} (32,1,1) = {" j -S +N M -S -S +N +N M j -S -S -D +N +N +b j j j -S -S +N +N c q M -S -S -S -S +N +N +N +N j j t j -D +b d g -S +N j j j @@ -1546,36 +1534,36 @@ l "} (33,1,1) = {" j -S -S -S +N +N +N j j j -D -D +b +b j j j j -S -S +N +N c x -S +N g -S -D +N +b g j j t j j -D +b M -S -S +N +N j j j @@ -1591,9 +1579,9 @@ l "} (34,1,1) = {" j -S -S -S +N +N +N j j j @@ -1604,7 +1592,7 @@ j j j j -S +N c q w @@ -1618,10 +1606,10 @@ t j j j -S -S -S -S +N +N +N +N j j j @@ -1636,8 +1624,8 @@ l "} (35,1,1) = {" j -S -S +N +N j j j @@ -1648,8 +1636,8 @@ j j j j -S -S +N +N c c c @@ -1663,9 +1651,9 @@ t j j j -S -S -S +N +N +N j j j @@ -1681,8 +1669,8 @@ l "} (36,1,1) = {" j -S -S +N +N j j j @@ -1693,14 +1681,14 @@ j j j j -D +b F -S -S +N +N g F -S -D +N +b j j j @@ -1708,9 +1696,9 @@ j j j j -S +N g -S +N j j j @@ -1725,9 +1713,9 @@ l l "} (37,1,1) = {" -S -S -S +N +N +N j j j @@ -1741,11 +1729,11 @@ j j j j -S +N h -S +N M -S +N d j j @@ -1753,9 +1741,9 @@ j j j j -S +N k -S +N j j j @@ -1770,9 +1758,9 @@ l l "} (38,1,1) = {" -S -S -S +N +N +N j j j @@ -1786,21 +1774,21 @@ j j j j -S -S -S -S -S -D +N +N +N +N +N +b j j j j -D +b Q -S +N g -S +N j j j @@ -1815,9 +1803,9 @@ l l "} (39,1,1) = {" -S -S -S +N +N +N j j j @@ -1831,20 +1819,20 @@ j j j j -D -S -S -S -S -D +b +N +N +N +N +b j j j j -D -D -S -S +b +b +N +N j j j @@ -1860,9 +1848,9 @@ l l "} (40,1,1) = {" -S +N g -S +N j j j @@ -1881,15 +1869,15 @@ j j g g -S -D -D +N +b +b j j j j -S -S +N +N j j j @@ -1924,16 +1912,16 @@ j j j j -S -S -S -S -D +N +N +N +N +b j j j j -S +N g j j diff --git a/_maps/modularmaps/big_red/bigredcaveswvar3.dmm b/_maps/modularmaps/big_red/bigredcaveswvar3.dmm index dece87cdc04..538c1e45272 100644 --- a/_maps/modularmaps/big_red/bigredcaveswvar3.dmm +++ b/_maps/modularmaps/big_red/bigredcaveswvar3.dmm @@ -15,9 +15,6 @@ /obj/effect/landmark/weed_node, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"l" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "p" = ( /obj/effect/ai_node, /turf/open/floor/plating/ground/mars/random/cave/rock, @@ -45,12 +42,6 @@ /obj/effect/landmark/weed_node, /turf/open/floor/plating/ground/mars/random/cave/rock, /area/bigredv2/caves/southwest) -"B" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) -"C" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "E" = ( /obj/effect/landmark/xeno_resin_wall, /turf/open/floor/plating/ground/mars/random/cave/rock, @@ -96,9 +87,6 @@ /obj/effect/landmark/lv624/fog_blocker/xeno_spawn, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"Y" = ( -/turf/open/floor/plating/ground/mars/random/cave/rock, -/area/bigredv2/caves/southwest) (1,1,1) = {" K @@ -315,8 +303,8 @@ Q Q Q Q -l -l +c +c t i Q @@ -359,11 +347,11 @@ Q Q Q Q -l -l -l +c +c +c S -l +c c d Q @@ -375,11 +363,11 @@ Q Q Q Q -l -l -l -l -l +c +c +c +c +c Q Q Q @@ -398,17 +386,17 @@ Q Q Q Q -C +c V -l +c E Q -l +c i -l -l -l -l +c +c +c +c i d Q @@ -418,42 +406,42 @@ K (8,1,1) = {" Q Q -l -l -l +c +c +c i -Y -l -l -l -l +u +c +c +c +c Q Q Q Q Q Q -l -l -l -l -Y -l -l -l -l -l -l +c +c +c +c +u +c +c +c +c +c +c V -l +c E -l -l -l -l -l -l -l +c +c +c +c +c +c +c L d Q @@ -462,43 +450,43 @@ K "} (9,1,1) = {" Q -l -Y -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l -l +c +u +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c +c i -l +c V -l +c E -l +c i -l -l -l +c +c +c i -l +c Q d Q @@ -506,44 +494,44 @@ Q K "} (10,1,1) = {" -l -l +c +c t -l +c i i -l -l +c +c i -l +c i t -l -l -l -l -l +c +c +c +c +c t -l -l -l -l +c +c +c +c t -l -l -l -l +c +c +c +c t V -l +c U -Y -l +u +c t i -l +c t -l +c Q d Q @@ -552,42 +540,42 @@ K "} (11,1,1) = {" i -l -l -l -l -l +c +c +c +c +c i -l -Y -l -l -l -l -Y -Y -l -l -l -l -Y -l -l -l +c +u +c +c +c +c +u +u +c +c +c +c +u +c +c +c i -l -l -l -l +c +c +c +c V -l +c U -Y +u i -l -l -l -l +c +c +c +c Q Q d @@ -596,40 +584,40 @@ Q K "} (12,1,1) = {" -l -l -l -l -l -l -l -l -l -l -Q -Q -Q -l -l -l -Y -l -l -l -l -l -l -l -l -l -l -l +c +c +c +c +c +c +c +c +c +c +Q +Q +Q +c +c +c +u +c +c +c +c +c +c +c +c +c +c +c V -l +c q -l -l -B +c +c +c Q Q Q @@ -641,8 +629,8 @@ Q K "} (13,1,1) = {" -l -Y +c +u p Q Q @@ -655,22 +643,22 @@ Q Q Q Q -l -l -l +c +c +c t -l -l -l -l +c +c +c +c i -l -l -l +c +c +c i -l +c V -l +c q f q @@ -686,9 +674,9 @@ Q K "} (14,1,1) = {" -l -l -Y +c +c +u Q Q Q @@ -704,23 +692,23 @@ Q Q Q Q -l -l -l -l -l -l -l -l -l -l +c +c +c +c +c +c +c +c +c +c V -l -l -l -l -l -Y +c +c +c +c +c +u Q Q Q @@ -731,11 +719,11 @@ Q K "} (15,1,1) = {" -l -l -l -Y -Y +c +c +c +u +u Q Q Q @@ -751,14 +739,14 @@ Q Q Q Q -l -l -l -l -l -l +c +c +c +c +c +c i -l +c V V V @@ -776,11 +764,11 @@ Q K "} (16,1,1) = {" -l -l +c +c M -l -Y +c +u Q Q Q @@ -796,21 +784,21 @@ Q Q Q Q -l -l +c +c t i -l -l -l +c +c +c t -l -l -l -l +c +c +c +c t -l -l +c +c Q Q Q @@ -821,11 +809,11 @@ Q K "} (17,1,1) = {" -l +c i -l -l -Y +c +c +u Q Q Q @@ -841,20 +829,20 @@ Q Q Q Q -l -l -l -l -l -l +c +c +c +c +c +c r -l -l -l -l -l -l -l +c +c +c +c +c +c +c u Q Q @@ -866,11 +854,11 @@ Q K "} (18,1,1) = {" -l -l -l -l -Y +c +c +c +c +u Q Q Q @@ -885,20 +873,20 @@ Q Q Q Q -l -l -l -l -l -l -l -l -i -l -l -M -l -l +c +c +c +c +c +c +c +c +i +c +c +M +c +c Q Q Q @@ -911,10 +899,10 @@ Q K "} (19,1,1) = {" -l +c i t -l +c p Q Q @@ -928,22 +916,22 @@ Q Q Q Q -l -l -Y -l -l +c +c +u +c +c i -l -l -l -l -l +c +c +c +c +c i -l -Y -l -l +c +u +c +c Q Q Q @@ -957,11 +945,11 @@ K "} (20,1,1) = {" Q -l -l -l +c +c +c i -Y +u Q Q Q @@ -971,25 +959,25 @@ Q Q Q Q -l -l -l +c +c +c i -l -l -l -l -l -l +c +c +c +c +c +c A -l -l -l -l -Y -l -l -l +c +c +c +c +u +c +c +c Q Q Q @@ -1004,37 +992,37 @@ K Q Q Q -l -l -Y +c +c +u Q Q Q Q Q -Y -l -l -l -l -l -Y -l -l -l -l +u +c +c +c +c +c +u +c +c +c +c i -l -l -l -l -l -l -Y -l -l +c +c +c +c +c +c +u +c +c I -l +c Q Q Q @@ -1050,38 +1038,38 @@ Q Q Q i -l -l -Y -l +c +c +u +c Q Q Q -l +c t -l -l +c +c i -l -l -l -l -l -l +c +c +c +c +c +c t -Y +u Q -Y -l -l -l -Y +u +c +c +c +u Q Q -l +c t i -l +c t Q Q @@ -1094,19 +1082,19 @@ K Q Q Q -l -l -l -l -l -l +c +c +c +c +c +c Q -l -l -l -l -l -Y +c +c +c +c +c +u Q Q Q @@ -1116,17 +1104,17 @@ Q Q Q Q -l -l +c +c t Q Q Q Q Q -l -l -l +c +c +c i Q Q @@ -1139,19 +1127,19 @@ K Q Q Q -l -l +c +c i -l -l -Y -l -l -Y -l +c +c +u +c +c +u +c i -l -Y +c +u Q Q Q @@ -1160,21 +1148,21 @@ Q Q Q Q -l -l -l -l +c +c +c +c Q Q Q Q Q -l -Y -l -l -l -l +c +u +c +c +c +c Q Q Q @@ -1184,18 +1172,18 @@ K Q Q Q -Y -l -l -l +u +c +c +c i -l -l +c +c A -l -l -l -l +c +c +c +c Q Q Q @@ -1205,22 +1193,22 @@ Q Q Q Q -l +c I -l -l +c +c Q Q Q Q Q Q -l -l -l -l -l -l +c +c +c +c +c +c Q Q K @@ -1231,16 +1219,16 @@ Q Q Q t -l -l -l -l -l -l +c +c +c +c +c +c i -Y -l -l +u +c +c Q Q Q @@ -1251,9 +1239,9 @@ Q Q Q Q -l +c t -l +c Q Q Q @@ -1261,11 +1249,11 @@ Q Q Q Q -l -l -l +c +c +c A -l +c Q Q K @@ -1274,18 +1262,18 @@ K Q Q Q -l +c i t -l -l -l -l -l -l +c +c +c +c +c +c t -l -l +c +c Q Q Q @@ -1296,21 +1284,21 @@ Q Q Q Q -l -l +c +c i -l +c Q Q Q Q Q Q -l -l -l -l -l +c +c +c +c +c Q Q K @@ -1318,19 +1306,19 @@ K (28,1,1) = {" Q Q -l -l -l -l -l -l -l -l -l -l +c +c +c +c +c +c +c +c +c +c i -l -Y +c +u Q Q Q @@ -1342,20 +1330,20 @@ Q Q Q Q -l -l -l +c +c +c Q Q Q Q Q Q -l +c A -l +c i -l +c Q Q K @@ -1363,19 +1351,19 @@ K (29,1,1) = {" Q Q -l -l -l -l -l +c +c +c +c +c i -l -l -l -l -l +c +c +c +c +c i -l +c Q Q Q @@ -1387,20 +1375,20 @@ Q Q Q Q -l +c i -l +c Q Q Q Q Q Q -l -l -l -l -l +c +c +c +c +c Q Q K @@ -1408,20 +1396,20 @@ K (30,1,1) = {" Q Q -l +c i -l -l -l -l +c +c +c +c i -Y +u Q -Y +u t -l -l -l +c +c +c Q Q Q @@ -1432,19 +1420,19 @@ Q Q Q Q -l +c i -l -l +c +c Q Q Q t i -l +c t -l -l +c +c Q Q Q @@ -1452,22 +1440,22 @@ K "} (31,1,1) = {" Q -l -l -l -l -l -l -l -l -Y +c +c +c +c +c +c +c +c +u Q Q -Y +u t i -l -l +c +c Q Q Q @@ -1478,15 +1466,15 @@ Q Q Q p -l -l -l -l -l -l -l -l -l +c +c +c +c +c +c +c +c +c Q Q Q @@ -1497,24 +1485,24 @@ K "} (32,1,1) = {" Q -l +c t -l -l +c +c t Q -l -l -Y +c +c +u Q Q Q -l +c t -l -l +c +c t -l +c Q Q Q @@ -1522,14 +1510,14 @@ Q Q Q Q -Y +u p i -l -l +c +c i -l -l +c +c Q Q Q @@ -1542,38 +1530,38 @@ K "} (33,1,1) = {" Q -l -l -l +c +c +c Q Q Q -Y -Y +u +u Q Q Q Q -l -l -l +c +c +c i -l +c i -l -Y +c +u Q Q Q Q Q Q -Y +u t -l -l -l -l +c +c +c +c t Q K @@ -1587,9 +1575,9 @@ K "} (34,1,1) = {" Q -l -l -l +c +c +c Q Q Q @@ -1600,25 +1588,25 @@ Q Q Q Q -l -l -l -l -l -l -l -Y +c +c +c +c +c +c +c +u Q Q Q Q Q Q -l +c i -l -l -l +c +c +c Q Q K @@ -1632,8 +1620,8 @@ K "} (35,1,1) = {" Q -l -l +c +c Q Q Q @@ -1644,14 +1632,14 @@ Q Q Q Q -l -l -l -l -l -l -l -Y +c +c +c +c +c +c +c +u Q Q Q @@ -1659,9 +1647,9 @@ Q Q Q Q -l -l -l +c +c +c Q Q Q @@ -1677,8 +1665,8 @@ K "} (36,1,1) = {" Q -l -l +c +c Q Q Q @@ -1689,14 +1677,14 @@ Q Q Q Q -Y +u t -l -l +c +c t i -l -Y +c +u Q Q Q @@ -1704,9 +1692,9 @@ Q Q Q Q -l +c i -l +c Q Q Q @@ -1721,9 +1709,9 @@ K K "} (37,1,1) = {" -l -l -l +c +c +c Q Q Q @@ -1737,11 +1725,11 @@ Q Q Q Q -l +c F -l -l -l +c +c +c p Q Q @@ -1749,9 +1737,9 @@ Q Q Q Q -l +c r -l +c Q Q Q @@ -1766,9 +1754,9 @@ K K "} (38,1,1) = {" -l -l -l +c +c +c Q Q Q @@ -1782,21 +1770,21 @@ Q Q Q Q -l -l -l -l -l -Y +c +c +c +c +c +u Q Q Q Q -Y +u A -l +c i -l +c Q Q Q @@ -1811,9 +1799,9 @@ K K "} (39,1,1) = {" -l -l -l +c +c +c Q Q Q @@ -1827,20 +1815,20 @@ Q Q Q Q -Y -l -l -l -l -Y +u +c +c +c +c +u Q Q Q Q -Y -Y -l -l +u +u +c +c Q Q Q @@ -1856,9 +1844,9 @@ K K "} (40,1,1) = {" -l +c i -l +c Q Q Q @@ -1877,15 +1865,15 @@ Q Q i i -l -Y -Y +c +u +u Q Q Q Q t -l +c Q Q Q @@ -1920,16 +1908,16 @@ Q Q Q Q -l -l -l -l -Y +c +c +c +c +u Q Q Q Q -l +c i Q Q diff --git a/_maps/modularmaps/big_red/bigredcaveswvar4.dmm b/_maps/modularmaps/big_red/bigredcaveswvar4.dmm index 0992917c1ad..bb988d350f1 100644 --- a/_maps/modularmaps/big_red/bigredcaveswvar4.dmm +++ b/_maps/modularmaps/big_red/bigredcaveswvar4.dmm @@ -18,9 +18,6 @@ "af" = ( /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"ag" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "ah" = ( /obj/effect/ai_node, /turf/open/floor/plating/ground/mars/random/cave/rock, @@ -71,17 +68,11 @@ /obj/effect/landmark/lv624/fog_blocker/xeno_spawn, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"aB" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "aF" = ( /obj/effect/landmark/weed_node, /obj/effect/landmark/xeno_resin_wall, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"aG" = ( -/turf/open/floor/plating/ground/mars/random/cave/rock, -/area/bigredv2/caves/southwest) "aH" = ( /turf/closed/mineral/smooth/bigred, /area/bigredv2/caves/rock) @@ -98,9 +89,6 @@ /obj/effect/landmark/weed_node, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"aR" = ( -/turf/open/floor/plating/ground/mars/random/cave/rock, -/area/bigredv2/caves/southwest) "aT" = ( /obj/effect/landmark/lv624/fog_blocker/xeno_spawn, /turf/closed/mineral/smooth/bigred, @@ -358,11 +346,11 @@ aH aT aH aH -aB -aR -aR +af +ae +ae hG -aR +ae ae aH aH @@ -385,11 +373,11 @@ aH aH aH aH -aB -aB -aB -aB -aB +af +af +af +af +af aH aH aH @@ -397,19 +385,19 @@ aH aH aH aj -ag -aB -aB +af +af +af az -aB +af ar -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +ae aH aH aH @@ -428,33 +416,33 @@ au (8,1,1) = {" aH aH -aB -aB -aB +af +af +af aQ -aB -aB -aB -aB -aB +af +af +af +af +af aH aH aH -aR -aB -aB -aB -aB +ae +af +af +af +af aJ -aB +af ar -aB -aB +af +af aQ -aB +af aQ -aB -aR +af +ae aH aH aH @@ -472,33 +460,33 @@ au "} (9,1,1) = {" aH -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af az -aB +af ar -aB -aB -aB +af +af +af ak -aB -aB +af +af aj aH aH @@ -516,36 +504,36 @@ au au "} (10,1,1) = {" -aB -aB +af +af am -aB +af aQ aQ -aB -aB +af +af aQ -aB +af aQ am -aB -aB -aB +af +af +af am -aB -aB -aB +af +af +af az -aB +af ar -aB -aB +af +af aQ am -aB +af aQ -aB -aR +af +ae aH aH aH @@ -562,35 +550,35 @@ au "} (11,1,1) = {" aQ -aB -aB -aB -aB -aB +af +af +af +af +af aQ -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af +af +af aQ az -aB +af aF -aB -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +af +ae aH aH aH @@ -606,38 +594,38 @@ au au "} (12,1,1) = {" -aB -aB -aB -aB -aB -aB -aB -aB -aH -aH -aH -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +aH +aH +aH +af +af +af +af +af +af +af +af az -aB +af ar -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af +af aH aH aH @@ -651,8 +639,8 @@ au au "} (13,1,1) = {" -aB -aB +af +af aH aH aH @@ -662,16 +650,16 @@ aH aH aH aH -aB -aB -aB -aB +af +af +af +af aQ -aB -aB -aB +af +af +af az -aB +af ar ar ar @@ -696,7 +684,7 @@ au au "} (14,1,1) = {" -aB +af aH aH aH @@ -707,26 +695,26 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af az -aB -aB -aB -aB -aB -aB -aB -aR -aB -aB -aB +af +af +af +af +af +af +af +ae +af +af +af aH aH aH @@ -752,25 +740,25 @@ aH aH aH aH -aR -aB -aB -aB -aB -aB -aB -aB +ae +af +af +af +af +af +af +af aJ -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af +af aQ aH aH @@ -798,25 +786,25 @@ aH aH aH aH -aB -aB -aB +af +af +af am aQ -aB -aB +af +af az am -aB -aB -aB -aB +af +af +af +af am -aB -aB +af +af aQ -aB -aB +af +af aH aH aH @@ -843,13 +831,13 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af an az az @@ -888,23 +876,23 @@ aH aH aH aH -aB -aB +af +af aQ -aB -aB -aB -aB -aB +af +af +af +af +af aQ -aB -aB +af +af ai -aB -aB -aB -aB -aB +af +af +af +af +af af aH aH @@ -933,22 +921,22 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af aQ -aB -aR +af +ae aQ -aB -aB -aB +af +af +af aH aH aH @@ -976,23 +964,23 @@ aH aH aH aH -aB -aR -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aR -aB -aB -aB +af +ae +af +af +af +af +af +af +af +af +af +af +af +ae +af +af +af aH aH aH @@ -1020,24 +1008,24 @@ aH aH aH aH -aB -aB -aR -aB -aB -aB +af +af +ae +af +af +af aQ -aB -aB -aB +af +af +af aQ -aB -aB -aR -aB -aB +af +af +ae +af +af aQ -aB +af aH aH aH @@ -1065,24 +1053,24 @@ aH aH aH aH -aB -aB -aB +af +af +af am -aB -aB +af +af am -aR +ae aH -aR -aB -aB -aB -aG +ae +af +af +af +ae aH aH -aB -aB +af +af aH aH aH @@ -1109,14 +1097,14 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +af +ae aH aH aH @@ -1126,9 +1114,9 @@ aH aH aH aH -aB -aB -aB +af +af +af aH aH aH @@ -1152,16 +1140,16 @@ aH aH aH aQ -aB -aB -aR -aB -aB -aR -aB +af +af +ae +af +af +ae +af aQ -aB -aR +af +ae aH aH aH @@ -1170,10 +1158,10 @@ aH aH aH aH -aB -aB -aB -aB +af +af +af +af aH aH aH @@ -1196,16 +1184,16 @@ aH aH aH aH -aB -aB +af +af aQ -aB -aB +af +af aj -aB -aB -aB -aB +af +af +af +af aH aH aH @@ -1215,10 +1203,10 @@ aH aH aH aH -aB +af ab -aB -aB +af +af aH aH aH @@ -1241,16 +1229,16 @@ aH aH aH am -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af aQ -aR -aB -aB +ae +af +af aH aH aH @@ -1261,9 +1249,9 @@ aH aH aH aH -aB +af am -aB +af aH aH aH @@ -1284,18 +1272,18 @@ au aH aH aH -aB +af aQ am -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af am -aB -aB +af +af aH aH aH @@ -1306,10 +1294,10 @@ aH aH aH aH -aB -aB +af +af aQ -aB +af aH aH aH @@ -1328,19 +1316,19 @@ au (28,1,1) = {" aH aH -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB +af +af +af +af +af +af +af +af +af +af aQ -aB -aR +af +ae aH aH aH @@ -1352,9 +1340,9 @@ aH aH aH aH -aB -aB -aB +af +af +af aH aH aH @@ -1373,19 +1361,19 @@ au (29,1,1) = {" aH aH -aB -aB -aB -aB -aB +af +af +af +af +af aQ -aB -aB -aB -aB -aB +af +af +af +af +af aQ -aB +af aH aH aH @@ -1397,9 +1385,9 @@ aH aH aH aH -aB +af aQ -aB +af aH aH aH @@ -1418,20 +1406,20 @@ au (30,1,1) = {" aH aH -aB +af aQ -aB -aB -aB -aB +af +af +af +af aQ -aR +ae aH -aR +ae am -aB -aB -aB +af +af +af aH aH aH @@ -1442,10 +1430,10 @@ aH aH aH aH -aB +af aQ -aB -aB +af +af aH aH aH @@ -1462,22 +1450,22 @@ au "} (31,1,1) = {" aH -aB -aB -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +af +af +ae aH aH -aR +ae am aQ -aB -aB +af +af aH aH aH @@ -1488,9 +1476,9 @@ aH aH aH ah -aB -aB -aB +af +af +af aH aH aH @@ -1507,24 +1495,24 @@ au "} (32,1,1) = {" aH -aB +af am -aB -aB +af +af am aH -aB -aB -aR +af +af +ae aH aH aH -aB +af am -aB -aB +af +af am -aB +af aH aH aH @@ -1532,10 +1520,10 @@ aH aH aH aH -aR +ae ah aQ -aB +af aH aH aH @@ -1552,36 +1540,36 @@ au "} (33,1,1) = {" aH -aB -aB -aB +af +af +af aH aH aH -aR -aR +ae +ae aH aH aH aH -aB -aB -aB +af +af +af aQ -aB +af aQ -aB -aR +af +ae aH aH aH aH aH aH -aR +ae am -aB -aB +af +af aH aH aH @@ -1597,9 +1585,9 @@ au "} (34,1,1) = {" aH -aB -aB -aB +af +af +af aH aH aH @@ -1610,24 +1598,24 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +af +ae aH aH aH aH aH aH -aB -aB -aB -aB +af +af +af +af aH aH aH @@ -1642,8 +1630,8 @@ au "} (35,1,1) = {" aH -aB -aB +af +af aH aH aH @@ -1654,14 +1642,14 @@ aH aH aH aH -aB -aB -aB -aB -aB -aB -aB -aR +af +af +af +af +af +af +af +ae aH aH aH @@ -1669,9 +1657,9 @@ aH aH aH aH -aB -aB -aB +af +af +af aH aH aH @@ -1687,8 +1675,8 @@ au "} (36,1,1) = {" aH -aB -aB +af +af aH aH aH @@ -1699,14 +1687,14 @@ aH aH aH aH -aR -aB -aB -aB -aB +ae +af +af +af +af aQ -aB -aR +af +ae aH aH aH @@ -1714,9 +1702,9 @@ aH aH aH aH -aB +af aQ -aB +af aH aH aH @@ -1731,9 +1719,9 @@ au au "} (37,1,1) = {" -aB -aB -aB +af +af +af aH aH aH @@ -1747,11 +1735,11 @@ aH aH aH aH -aB +af as -aB -aB -aB +af +af +af ah aH aH @@ -1759,9 +1747,9 @@ aH aH aH aH -aB +af ac -aB +af aH aH aH @@ -1776,9 +1764,9 @@ au au "} (38,1,1) = {" -aB -aB -aB +af +af +af aH aH aH @@ -1792,21 +1780,21 @@ aH aH aH aH -aB -aB -aB -aB -aB -aR +af +af +af +af +af +ae aH aH aH aH -aR +ae aj -aB +af aQ -aB +af aH aH aH @@ -1821,9 +1809,9 @@ au au "} (39,1,1) = {" -aB -aB -aB +af +af +af aH aH aH @@ -1837,20 +1825,20 @@ aH aH aH aH -aR -aB -aB -aB -aB -aR +ae +af +af +af +af +ae aH aH aH aH -aR -aR -aB -aB +ae +ae +af +af aH aH aH @@ -1866,9 +1854,9 @@ au au "} (40,1,1) = {" -aB +af aQ -aB +af aH aH aH @@ -1887,15 +1875,15 @@ aH aH aQ aQ -aB -aR -aR +af +ae +ae aH aH aH aH -aB -aB +af +af aH aH aH @@ -1930,16 +1918,16 @@ aH aH aH aH -aB -aB -aB -aB -aR +af +af +af +af +ae aH aH aH aH -aB +af aQ aH aH diff --git a/_maps/modularmaps/big_red/bigredcaveswvar5.dmm b/_maps/modularmaps/big_red/bigredcaveswvar5.dmm index 2c3adf839cd..7adeb11a551 100644 --- a/_maps/modularmaps/big_red/bigredcaveswvar5.dmm +++ b/_maps/modularmaps/big_red/bigredcaveswvar5.dmm @@ -50,9 +50,6 @@ /obj/effect/landmark/lv624/fog_blocker/xeno_spawn, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"A" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "F" = ( /obj/effect/landmark/xeno_silo_spawn, /turf/open/floor/plating/ground/mars/random/cave, @@ -74,23 +71,14 @@ /obj/effect/landmark/xeno_tunnel_spawn, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/southwest) -"L" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "P" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/mineral/smooth/bigred, /area/bigredv2/caves/rock) -"T" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "U" = ( /obj/effect/ai_node, /turf/open/floor/plating/ground/mars/random/cave/rock, /area/bigredv2/caves/southwest) -"V" = ( -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/southwest) "W" = ( /obj/effect/ai_node, /turf/open/floor/plating/ground/mars/random/cave, @@ -300,10 +288,10 @@ f f f j -T -T -T -T +j +j +j +j f f f @@ -339,17 +327,17 @@ I f f f -T +j w w w w w -T +j h -T -T -T +j +j +j f f f @@ -371,30 +359,30 @@ f f f f -T -T +j +j W -T -T +j +j f f f f I -T +j p l -T -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j +j F -T +j f f f @@ -414,33 +402,33 @@ n (8,1,1) = {" f f -T +j h -T +j h -T -T +j +j h -T -T +j +j f f g U -T +j l -T -T +j +j h -T +j h W -T -T -T -T +j +j +j +j W -T +j f f f @@ -458,34 +446,34 @@ n "} (9,1,1) = {" f -T -T -T -T -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j +j +j +j +j g -T -T +j +j l -T -T -T -T -T -T +j +j +j +j +j +j h -T -T -T -T -A +j +j +j +j +j f f f @@ -502,19 +490,19 @@ n n "} (10,1,1) = {" -T -T +j +j W -T +j h h W -T +j h -T +j h W -T +j y W f @@ -522,15 +510,15 @@ f f f f -T -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j +j f f f @@ -548,20 +536,20 @@ n "} (11,1,1) = {" h -T -T -T -T -T +j +j +j +j +j h -T -T -T -T -T -T +j +j +j +j +j +j g -T +j f f f @@ -569,13 +557,13 @@ f f f f -V +j K w -T -T +j +j h -T +j f f f @@ -592,22 +580,22 @@ n n "} (12,1,1) = {" -T -T -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j +j +j f f f g -T -T +j +j f f f @@ -616,11 +604,11 @@ f f f f -T -T -T -T -T +j +j +j +j +j f f f @@ -637,7 +625,7 @@ n n "} (13,1,1) = {" -T +j w U f @@ -651,9 +639,9 @@ f f f g -T +j h -T +j f f f @@ -661,11 +649,11 @@ f f f f -T -T -T -T -T +j +j +j +j +j f f f @@ -682,8 +670,8 @@ n n "} (14,1,1) = {" -T -T +j +j w f f @@ -696,19 +684,19 @@ f f f g -T -T -T -T -T +j +j +j +j +j f f f f f f -T -T +j +j w f f @@ -728,8 +716,8 @@ n "} (15,1,1) = {" h -T -T +j +j w w f @@ -742,19 +730,19 @@ f f x W -T -T -T -T +j +j +j +j h f f f f f -T -T -T +j +j +j f f f @@ -772,10 +760,10 @@ n n "} (16,1,1) = {" -T -T +j +j t -T +j w f f @@ -786,12 +774,12 @@ f f f I -T +j W h -T -T -T +j +j +j W f f @@ -817,10 +805,10 @@ n n "} (17,1,1) = {" -T +j h -T -T +j +j w f f @@ -831,19 +819,19 @@ f f f I -T -T -T -T -T +j +j +j +j +j u -T +j W -T -T -L -T -T +j +j +j +j +j U f f @@ -862,10 +850,10 @@ n n "} (18,1,1) = {" -T -T -T -T +j +j +j +j w f f @@ -876,18 +864,18 @@ f f f I -T -T -T +j +j +j h -T -T +j +j h -T -T +j +j t -T -T +j +j W f f @@ -907,10 +895,10 @@ n n "} (19,1,1) = {" -T +j h W -T +j U f f @@ -953,9 +941,9 @@ n "} (20,1,1) = {" f -T -T -T +j +j +j h w f @@ -968,17 +956,17 @@ f f f f -T -T -T -T +j +j +j +j h -T -T +j +j w -T -T -T +j +j +j f f f @@ -1000,8 +988,8 @@ n f f f -T -T +j +j w f f @@ -1014,16 +1002,16 @@ f f f f -T -T -T -T -T +j +j +j +j +j w -T -T +j +j h -T +j f f f @@ -1046,10 +1034,10 @@ f f f h -T -T +j +j w -T +j f f f @@ -1062,13 +1050,13 @@ f f f f -T -T +j +j w f f -T -T +j +j f f f @@ -1090,12 +1078,12 @@ n f f f -T -T -T -T -T -T +j +j +j +j +j +j f f f @@ -1112,9 +1100,9 @@ f f f f -T -T -T +j +j +j f f f @@ -1135,14 +1123,14 @@ n f f f -T -T +j +j h -T -T +j +j w -T -T +j +j f f f @@ -1156,10 +1144,10 @@ f f f f -T -T -T -T +j +j +j +j f f f @@ -1181,14 +1169,14 @@ f f f w -T -T -T +j +j +j h -T -T +j +j p -T +j f f f @@ -1201,10 +1189,10 @@ f f f f -T +j J -T -T +j +j f f f @@ -1227,12 +1215,12 @@ f f f W -T -T -T -T -T -T +j +j +j +j +j +j h w f @@ -1247,9 +1235,9 @@ f f f f -T +j W -T +j f f f @@ -1270,17 +1258,17 @@ n f f f -T +j h W -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j f f f @@ -1292,10 +1280,10 @@ f f f f -T -T +j +j h -T +j f f f @@ -1314,18 +1302,18 @@ n (28,1,1) = {" f f -T -T -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j +j +j h -T +j w f f @@ -1338,9 +1326,9 @@ f f f f -T -T -T +j +j +j f f f @@ -1359,19 +1347,19 @@ n (29,1,1) = {" f f -T -T -T -T -T +j +j +j +j +j h -T -T -T -T -T +j +j +j +j +j h -T +j f f f @@ -1383,9 +1371,9 @@ f f f f -T +j h -T +j f f f @@ -1404,20 +1392,20 @@ n (30,1,1) = {" f f -T +j h -T -T -T -T +j +j +j +j h w f w W -T -T -T +j +j +j f f f @@ -1428,10 +1416,10 @@ f f f f -T +j h -T -T +j +j f f f @@ -1448,22 +1436,22 @@ n "} (31,1,1) = {" f -T -T -T -T -T -T -T -T +j +j +j +j +j +j +j +j w f f w W h -T -T +j +j f f f @@ -1474,9 +1462,9 @@ f f f U -T -T -T +j +j +j f f f @@ -1493,24 +1481,24 @@ n "} (32,1,1) = {" f -T +j W -T -T +j +j W f -T -T +j +j w f f f -T +j W -T -T +j +j W -T +j f f f @@ -1521,7 +1509,7 @@ f w U h -T +j f f f @@ -1538,9 +1526,9 @@ n "} (33,1,1) = {" f -T -T -T +j +j +j f f f @@ -1550,13 +1538,13 @@ f f f f -T -T -T +j +j +j h -T +j h -T +j w f f @@ -1566,8 +1554,8 @@ f f w W -T -T +j +j f f f @@ -1583,9 +1571,9 @@ n "} (34,1,1) = {" f -T -T -T +j +j +j f f f @@ -1596,13 +1584,13 @@ f f f f -T -T -T -T -T -T -T +j +j +j +j +j +j +j w f f @@ -1610,10 +1598,10 @@ f f f f -T -T +j +j h -T +j f f f @@ -1628,8 +1616,8 @@ n "} (35,1,1) = {" f -T -T +j +j f f f @@ -1640,13 +1628,13 @@ f f f f -T +j h -T -T -T -T -T +j +j +j +j +j w f f @@ -1655,9 +1643,9 @@ f f f f -T -T -T +j +j +j f f f @@ -1673,8 +1661,8 @@ n "} (36,1,1) = {" f -T -T +j +j f f f @@ -1686,12 +1674,12 @@ f f f w -T -T -T -T +j +j +j +j h -T +j w f f @@ -1700,9 +1688,9 @@ f f f f -T +j h -T +j f f f @@ -1717,9 +1705,9 @@ n n "} (37,1,1) = {" -T -T -T +j +j +j f f f @@ -1733,11 +1721,11 @@ f f f f -T +j d -T -T -T +j +j +j U f f @@ -1745,9 +1733,9 @@ f f f f -T +j u -T +j f f f @@ -1762,9 +1750,9 @@ n n "} (38,1,1) = {" -T -T -T +j +j +j f f f @@ -1778,11 +1766,11 @@ f f f f -T -T -T -T -T +j +j +j +j +j w f f @@ -1790,9 +1778,9 @@ f f w p -T +j h -T +j f f f @@ -1807,9 +1795,9 @@ n n "} (39,1,1) = {" -T -T -T +j +j +j f f f @@ -1824,10 +1812,10 @@ f f f w -T -T -T -T +j +j +j +j w f f @@ -1835,8 +1823,8 @@ f f w w -T -T +j +j f f f @@ -1852,9 +1840,9 @@ n n "} (40,1,1) = {" -T +j h -T +j f f f @@ -1873,15 +1861,15 @@ f f h h -T +j w w f f f f -T -T +j +j f f f @@ -1916,16 +1904,16 @@ f f f f -T -T -T -T +j +j +j +j w f f f f -T +j h f f diff --git a/_maps/modularmaps/big_red/bigredengineeringvar2.dmm b/_maps/modularmaps/big_red/bigredengineeringvar2.dmm index 64198449fba..d7cc7a1fb18 100644 --- a/_maps/modularmaps/big_red/bigredengineeringvar2.dmm +++ b/_maps/modularmaps/big_red/bigredengineeringvar2.dmm @@ -887,9 +887,6 @@ "VL" = ( /turf/closed/wall/r_wall, /area/bigredv2/caves/rock) -"Wo" = ( -/turf/open/floor, -/area/bigredv2/outside/engineering) "WD" = ( /obj/machinery/light{ dir = 1 @@ -983,9 +980,9 @@ GH Pt Ds uk -Wo +ib kJ -Wo +ib jo GH Cj @@ -1011,9 +1008,9 @@ oK Zt Pt tK -Wo +ib JW -Wo +ib Vv kq GH @@ -1065,8 +1062,8 @@ su (5,1,1) = {" Pt ge -Wo -Wo +ib +ib Pt EH wt @@ -1098,9 +1095,9 @@ pZ LM Pt Ds -Wo +ib Jv -Wo +ib gF gF GH @@ -1150,17 +1147,17 @@ LF LF "} (8,1,1) = {" -Wo +ib iu Pt xn bb Oa -Wo -Wo -Wo -Wo -Wo +ib +ib +ib +ib +ib GH LF LF @@ -1179,17 +1176,17 @@ su LF "} (9,1,1) = {" -Wo +ib rP wt -Wo -Wo +ib +ib en tR -Wo +ib tR -Wo -Wo +ib +ib GH LF LF @@ -1208,7 +1205,7 @@ CS su "} (10,1,1) = {" -Wo +ib iu wt Vv @@ -1216,8 +1213,8 @@ sd en VC DH -Wo -Wo +ib +ib DH GH LF @@ -1243,11 +1240,11 @@ hE hb JU Vs -Wo -Wo -Wo +ib +ib +ib dv -Wo +ib GH LF LF @@ -1324,7 +1321,7 @@ su qm "} (14,1,1) = {" -Wo +ib wW Pt Oa @@ -1332,7 +1329,7 @@ DH Pt UB wW -Wo +ib DH yB GH @@ -1353,13 +1350,13 @@ su su "} (15,1,1) = {" -Wo +ib zj wt Ie qO Pt -Wo +ib Qv Jv Ow @@ -1448,8 +1445,8 @@ Jv Pt ib At -Wo -Wo +ib +ib hV GH LF @@ -1500,15 +1497,15 @@ su (20,1,1) = {" SP wt -Wo +ib Ds Jv -Wo -Wo +ib +ib Sv Vv Jv -Wo +ib GH LF Gh @@ -1537,7 +1534,7 @@ fr Jv dv Jv -Wo +ib GH LF ox @@ -1556,16 +1553,16 @@ Bn su "} (22,1,1) = {" -Wo +ib wt -Wo +ib Oa nC jG CN DO -Wo -Wo +ib +ib Vv GH LF @@ -1592,9 +1589,9 @@ Of KV tt bN -Wo -Wo -Wo +ib +ib +ib OF GH LF @@ -1616,15 +1613,15 @@ su (24,1,1) = {" Jv Px -Wo +ib Of eh eh eh Jv Jv -Wo -Wo +ib +ib GH LF LF @@ -1681,8 +1678,8 @@ Dx ON Fq Jv -Wo -Wo +ib +ib GH VL VL @@ -1710,8 +1707,8 @@ GH OK en AQ -Wo -Wo +ib +ib GH GH GH @@ -1766,11 +1763,11 @@ xH xH GH Yq -Wo +ib VI bq Jv -Wo +ib Vv tv GH @@ -1800,7 +1797,7 @@ GH GH GH GH -Wo +ib sg GH wm diff --git a/_maps/modularmaps/big_red/bigredengineeringvar4.dmm b/_maps/modularmaps/big_red/bigredengineeringvar4.dmm index 8853d0c3f26..6d133c55249 100644 --- a/_maps/modularmaps/big_red/bigredengineeringvar4.dmm +++ b/_maps/modularmaps/big_red/bigredengineeringvar4.dmm @@ -697,9 +697,6 @@ /obj/item/tool/lighter/random, /turf/open/floor, /area/bigredv2/outside/engineering) -"OK" = ( -/turf/open/floor, -/area/bigredv2/outside/engineering) "OZ" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/green/hidden{ @@ -979,9 +976,9 @@ vP Qe EF wG -OK +GK yH -OK +GK fh vP PW @@ -1007,9 +1004,9 @@ Ul De Qe cD -OK +GK Be -OK +GK Ek SH vP @@ -1061,8 +1058,8 @@ RB (5,1,1) = {" Qe xD -OK -OK +GK +GK Qe NI Mw @@ -1094,9 +1091,9 @@ dz ko Qe EF -OK +GK jg -OK +GK qy qy vP @@ -1146,17 +1143,17 @@ ZD ZD "} (8,1,1) = {" -OK +GK Rp Qe Qv CC PH -OK -OK -OK -OK -OK +GK +GK +GK +GK +GK vP ZD ZD @@ -1175,17 +1172,17 @@ RB ZD "} (9,1,1) = {" -OK +GK Ej Mw -OK -OK +GK +GK OZ JS -OK +GK JS -OK -OK +GK +GK vP ZD ZD @@ -1204,7 +1201,7 @@ Yb RB "} (10,1,1) = {" -OK +GK Rp Mw Ek @@ -1212,8 +1209,8 @@ RR OZ ta eH -OK -OK +GK +GK eH vP ZD @@ -1239,11 +1236,11 @@ Cu aZ Hz pq -OK -OK -OK +GK +GK +GK nu -OK +GK vP ZD ZD @@ -1320,7 +1317,7 @@ RB zc "} (14,1,1) = {" -OK +GK DP Qe PH @@ -1328,7 +1325,7 @@ eH Qe Zj DP -OK +GK eH LP vP @@ -1349,13 +1346,13 @@ RB RB "} (15,1,1) = {" -OK +GK xo Mw ky KR Qe -OK +GK vN jg bO @@ -1444,8 +1441,8 @@ jg Qe GK Pw -OK -OK +GK +GK rL vP ZD @@ -1496,15 +1493,15 @@ RB (20,1,1) = {" jb Mw -OK +GK EF jg -OK -OK +GK +GK TA Ek jg -OK +GK vP ZD fd @@ -1533,7 +1530,7 @@ pX jg nu jg -OK +GK vP ZD Au @@ -1552,16 +1549,16 @@ vs RB "} (22,1,1) = {" -OK +GK Mw -OK +GK PH Mx Xz Kz Ns -OK -OK +GK +GK Ek vP ZD @@ -1588,9 +1585,9 @@ km HC Pd OA -OK -OK -OK +GK +GK +GK AW vP ZD @@ -1612,15 +1609,15 @@ RB (24,1,1) = {" jg ax -OK +GK km yb yb yb jg jg -OK -OK +GK +GK vP ZD ZD @@ -1677,8 +1674,8 @@ BS SZ Db jg -OK -OK +GK +GK vP bf bf @@ -1706,8 +1703,8 @@ vP rN OZ Wy -OK -OK +GK +GK vP vP vP @@ -1762,11 +1759,11 @@ xM xM vP IN -OK +GK pV cI jg -OK +GK Ek YW vP @@ -1796,7 +1793,7 @@ vP vP vP vP -OK +GK tr vP qS diff --git a/_maps/modularmaps/big_red/bigredsouthetavar1.dmm b/_maps/modularmaps/big_red/bigredsouthetavar1.dmm index 9a3ab45ee00..0cfc6ea0b9d 100644 --- a/_maps/modularmaps/big_red/bigredsouthetavar1.dmm +++ b/_maps/modularmaps/big_red/bigredsouthetavar1.dmm @@ -1,7 +1,4 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/closed/wall/indestructible/mineral, -/area/space) "ab" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/tile/dark/red2/corner, @@ -55,10 +52,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"aj" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/mineral/bigred, -/area/bigredv2/caves/rock) "ak" = ( /obj/effect/landmark/weed_node, /obj/effect/ai_node, @@ -88,15 +81,6 @@ /obj/effect/landmark/weed_node, /turf/open/floor/tile/dark/red2/corner, /area/bigredv2/caves/south) -"aq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/sandedge{ - dir = 4 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) "ar" = ( /obj/effect/landmark/weed_node, /turf/open/floor/tile/dark/yellow2/corner, @@ -104,29 +88,11 @@ "as" = ( /turf/closed/wall/r_wall, /area/bigredv2/caves/south) -"at" = ( -/turf/closed/mineral/bigred, -/area/bigredv2/caves/rock) -"au" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) "av" = ( /turf/open/floor/tile/dark/red2/corner{ dir = 8 }, /area/bigredv2/caves/south) -"aw" = ( -/obj/machinery/door/airlock/multi_tile/mainship/generic{ - dir = 2 - }, -/obj/effect/turf_decal/sandedge{ - dir = 8 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) "ax" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/rack, @@ -144,20 +110,10 @@ "aA" = ( /turf/closed/mineral/smooth/bigred, /area/bigredv2/caves/rock) -"aB" = ( -/obj/machinery/light, -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) "aC" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/wall/r_wall, /area/bigredv2/outside/nanotrasen_lab/inside) -"aD" = ( -/obj/effect/landmark/corpsespawner/colonist, -/obj/effect/decal/cleanable/blood/oil, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) "aE" = ( /obj/effect/landmark/corpsespawner/colonist, /obj/effect/decal/cleanable/blood/oil, @@ -184,10 +140,6 @@ /obj/effect/decal/cleanable/dirt, /turf/closed/wall/r_wall/unmeltable, /area/bigredv2/caves/south) -"aJ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) "aK" = ( /turf/open/floor/tile/dark/yellow2/corner, /area/bigredv2/caves/south) @@ -199,11 +151,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"aM" = ( -/obj/effect/landmark/corpsespawner/colonist, -/obj/effect/decal/cleanable/blood/oil, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) "aN" = ( /obj/effect/ai_node, /turf/open/floor/plating/ground/mars/random/cave, @@ -221,44 +168,13 @@ /obj/item/storage/holster/belt/pistol, /turf/open/floor/tile/dark/red2/corner, /area/bigredv2/caves/south) -"aQ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/closed/wall/r_wall/unmeltable, -/area/bigredv2/caves/south) "aR" = ( /turf/closed/mineral/smooth/bigred/indestructible, /area/space) -"aS" = ( -/obj/effect/landmark/weed_node, -/obj/effect/ai_node, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) "aT" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/wall/r_wall, /area/bigredv2/caves/south) -"aU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/multi_tile/mainship/generic{ - dir = 2 - }, -/obj/effect/turf_decal/sandedge{ - dir = 4 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"aV" = ( -/obj/effect/decal/cleanable/dirt, -/turf/closed/wall/r_wall, -/area/bigredv2/caves/south) -"aW" = ( -/obj/effect/ai_node, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) "aX" = ( /obj/effect/landmark/weed_node, /turf/open/floor/tile/dark/red2/corner{ @@ -271,48 +187,6 @@ }, /turf/open/floor/plating/ground/mars/random/cave, /area/bigredv2/caves/south) -"aZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/rack, -/obj/item/storage/holster/belt/pistol/m4a3/full, -/obj/item/storage/holster/belt/pistol/m4a3/officer, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) -"dW" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"fq" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/wall/r_wall, -/area/bigredv2/outside/nanotrasen_lab/inside) -"zG" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/caves/south) -"DZ" = ( -/obj/machinery/door/airlock/multi_tile/mainship/generic, -/obj/effect/ai_node, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/outside/nanotrasen_lab/inside) -"Ji" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/wall/r_wall, -/area/bigredv2/caves/south) -"PS" = ( -/obj/effect/turf_decal/sandedge{ - dir = 8 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"SE" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/caves/south) "YJ" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/mineral/smooth/bigred, @@ -324,7 +198,7 @@ YJ as al ad -aU +ah al aI aA @@ -344,7 +218,7 @@ aR "} (3,1,1) = {" ay -Ji +aT as aP af @@ -355,8 +229,8 @@ aA aR "} (4,1,1) = {" -DZ -SE +ae +az aK av ak @@ -368,12 +242,12 @@ aR "} (5,1,1) = {" ao -SE -zG +az +ar ab ab ab -aZ +ax aI aA aR @@ -407,7 +281,7 @@ ay YJ as av -dW +aX av av aG @@ -419,8 +293,8 @@ ay YJ as as -PS -aw +aL +ai as aG aA @@ -446,7 +320,7 @@ am am am am -aM +aE aA aR "} @@ -456,8 +330,8 @@ YJ aA am aN -au -au +ag +ag am aA aR @@ -494,7 +368,7 @@ aA aA am am -au +ag aA aR "} @@ -504,7 +378,7 @@ YJ aA aA aA -au +ag am am aA @@ -576,14 +450,14 @@ YJ aA aA am -au +ag am aA aA aR "} (23,1,1) = {" -fq +aC YJ aA aA diff --git a/_maps/modularmaps/big_red/bigredsouthetavar4.dmm b/_maps/modularmaps/big_red/bigredsouthetavar4.dmm index d362b765162..6a17ecc1dde 100644 --- a/_maps/modularmaps/big_red/bigredsouthetavar4.dmm +++ b/_maps/modularmaps/big_red/bigredsouthetavar4.dmm @@ -1,7 +1,4 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/closed/wall/indestructible/mineral, -/area/space) "ab" = ( /turf/open/floor/tile/dark/red2/corner{ dir = 8 @@ -21,9 +18,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"af" = ( -/turf/closed/mineral/bigred, -/area/bigredv2/caves/rock) "ag" = ( /obj/effect/landmark/weed_node, /obj/effect/ai_node, @@ -79,25 +73,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"ap" = ( -/obj/machinery/door/airlock/multi_tile/mainship/generic{ - dir = 2 - }, -/obj/effect/turf_decal/sandedge{ - dir = 8 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"aq" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/mineral/bigred, -/area/bigredv2/caves/rock) -"ar" = ( -/obj/effect/decal/cleanable/dirt, -/turf/closed/wall/r_wall, -/area/bigredv2/caves/south) "as" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/wall/r_wall, @@ -142,10 +117,6 @@ /obj/effect/decal/cleanable/blood/oil, /turf/open/floor/tile/dark/red2/corner, /area/bigredv2/caves/south) -"aC" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) "aD" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/sandedge{ @@ -164,16 +135,6 @@ "aF" = ( /turf/open/floor/tile/dark/red2/corner, /area/bigredv2/caves/south) -"aG" = ( -/obj/effect/landmark/corpsespawner/colonist, -/obj/effect/decal/cleanable/blood/oil, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) -"aH" = ( -/obj/effect/landmark/corpsespawner/colonist, -/obj/effect/decal/cleanable/blood/oil, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) "aI" = ( /turf/closed/mineral/smooth/bigred, /area/bigredv2/caves/rock) @@ -195,15 +156,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"aN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/sandedge{ - dir = 4 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) "aO" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/open/floor/plating/ground/mars/random/cave, @@ -220,25 +172,6 @@ "aR" = ( /turf/closed/wall/r_wall, /area/bigredv2/outside/nanotrasen_lab/inside) -"aS" = ( -/obj/effect/ai_node, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) -"aT" = ( -/obj/effect/decal/cleanable/dirt, -/turf/closed/wall/r_wall/unmeltable, -/area/bigredv2/caves/south) -"aU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/rack, -/obj/item/storage/holster/belt/pistol/m4a3/full, -/obj/item/storage/holster/belt/pistol/m4a3/officer, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) -"aV" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) "aW" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/multi_tile/mainship/generic{ @@ -251,23 +184,6 @@ dir = 8 }, /area/bigredv2/caves/south) -"aX" = ( -/obj/machinery/light, -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/red2/corner, -/area/bigredv2/caves/south) -"aY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/multi_tile/mainship/generic{ - dir = 2 - }, -/obj/effect/turf_decal/sandedge{ - dir = 4 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) "aZ" = ( /obj/structure/table, /obj/machinery/computer/security, @@ -275,64 +191,18 @@ dir = 8 }, /area/bigredv2/caves/south) -"iV" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"oN" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/wall/r_wall, -/area/bigredv2/caves/south) -"rE" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/caves/south) -"xc" = ( -/obj/machinery/door/airlock/multi_tile/mainship/generic, -/obj/effect/ai_node, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/outside/nanotrasen_lab/inside) -"xQ" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/open/floor/plating/ground/mars/random/cave, -/area/bigredv2/caves/south) "JO" = ( /obj/effect/landmark/lv624/fog_blocker, /turf/closed/mineral/smooth/bigred, /area/bigredv2/caves/rock) -"Rf" = ( -/obj/effect/landmark/lv624/fog_blocker, -/turf/closed/wall/r_wall, -/area/bigredv2/outside/nanotrasen_lab/inside) -"TA" = ( -/obj/effect/landmark/weed_node, -/obj/effect/ai_node, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) -"TK" = ( -/obj/effect/landmark/weed_node, -/turf/open/floor/tile/dark/yellow2/corner, -/area/bigredv2/caves/south) -"Xm" = ( -/obj/effect/turf_decal/sandedge{ - dir = 8 - }, -/turf/open/floor/tile/dark/red2/corner{ - dir = 8 - }, -/area/bigredv2/caves/south) (1,1,1) = {" aR JO ay aj -aN -aY +aD +aW aj av aI @@ -352,22 +222,22 @@ ah "} (3,1,1) = {" aR -oN +as ay aQ aF -aH +aB au av aI ah "} (4,1,1) = {" -xc -rE +at +an aK ab -TA +ag ab ay av @@ -376,11 +246,11 @@ ah "} (5,1,1) = {" aL -rE -TK -aC -aC -aC +an +ak +ad +ad +ad ax av aI @@ -415,7 +285,7 @@ aR JO ay ab -iV +am ab ab az @@ -427,8 +297,8 @@ aR JO ay ay -Xm -ap +al +ao ay az aI @@ -464,8 +334,8 @@ JO aI aA ac -aV -aV +aJ +aJ aA aI ah @@ -496,23 +366,23 @@ ah "} (15,1,1) = {" aR -xQ +aO aA aA aA aA aA -aV +aJ aI ah "} (16,1,1) = {" aR -xQ +aO aA aA aA -aV +aJ aA aA aI @@ -520,7 +390,7 @@ ah "} (17,1,1) = {" aR -xQ +aO aA aA aA @@ -568,7 +438,7 @@ ah "} (21,1,1) = {" aR -xQ +aO aA aA aA @@ -580,18 +450,18 @@ ah "} (22,1,1) = {" aR -xQ +aO aA aA aA -aV +aJ aA aI aI ah "} (23,1,1) = {" -Rf +aP JO aI aI diff --git a/_maps/modularmaps/oscaroutpost/oscarnorthvar1.dmm b/_maps/modularmaps/oscaroutpost/oscarnorthvar1.dmm index 495d6465d1e..c8ba370addc 100644 --- a/_maps/modularmaps/oscaroutpost/oscarnorthvar1.dmm +++ b/_maps/modularmaps/oscaroutpost/oscarnorthvar1.dmm @@ -4325,14 +4325,6 @@ dir = 4 }, /area/oscar_outpost/outside/northeast) -"Yr" = ( -/obj/structure/barricade/sandbags{ - dir = 8; - name = "trench lining"; - pixel_y = 1 - }, -/turf/open/floor/plating/ground/dirt2, -/area/oscar_outpost/outside/northeast) "Yu" = ( /turf/open/floor/plating/ground/dirtgrassborder/corner{ dir = 4 @@ -26887,7 +26879,7 @@ CE CE YZ sV -Yr +Rb Rb Rb Rb diff --git a/_maps/modularmaps/oscaroutpost/oscarnorthvar2.dmm b/_maps/modularmaps/oscaroutpost/oscarnorthvar2.dmm index c399f3a1349..12462f31569 100644 --- a/_maps/modularmaps/oscaroutpost/oscarnorthvar2.dmm +++ b/_maps/modularmaps/oscaroutpost/oscarnorthvar2.dmm @@ -4789,14 +4789,6 @@ /obj/structure/fence, /turf/open/ground/grass, /area/oscar_outpost/outside/northwest) -"Tj" = ( -/obj/structure/barricade/sandbags{ - dir = 4; - name = "trench lining"; - pixel_y = 1 - }, -/turf/open/floor/plating/ground/dirt2, -/area/oscar_outpost/outside/northwest) "Tn" = ( /turf/open/floor/plating/ground/dirtgrassborder/corner{ dir = 4 @@ -5387,14 +5379,6 @@ }, /turf/open/floor/plating/ground/dirt2, /area/oscar_outpost/outside/northeast) -"Yr" = ( -/obj/structure/barricade/sandbags{ - dir = 8; - name = "trench lining"; - pixel_y = 1 - }, -/turf/open/floor/plating/ground/dirt2, -/area/oscar_outpost/outside/northeast) "Yu" = ( /obj/structure/platform/rockcliff{ dir = 1 @@ -6378,7 +6362,7 @@ MU wR eC Oe -Tj +qC Rx eC eC @@ -6506,23 +6490,23 @@ Pv Pv Pv Tv -Tj -Tj -Tj +qC +qC +qC hz hz -Tj -Tj -Tj -Tj +qC +qC +qC +qC xu XP eC mP xu -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -6826,9 +6810,9 @@ eC eC eC ZD -Tj qC -Tj +qC +qC Rx eC eC @@ -6989,9 +6973,9 @@ qH Uw eC Oe -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -7590,15 +7574,15 @@ ym Fn Fn Fn -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj +qC +qC +qC +qC +qC +qC +qC +qC +qC xu XP eC @@ -7613,9 +7597,9 @@ eC eC eC Oe -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -7628,7 +7612,7 @@ eC eC eC Oe -Tj +qC Rx eC eC @@ -8220,7 +8204,7 @@ eC eC eC RA -Tj +qC xu XP IQ @@ -8237,9 +8221,9 @@ Uw eC eC Oe -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -8693,7 +8677,7 @@ MU MU pp Oe -Tj +qC Rx Ly Ym @@ -8861,9 +8845,9 @@ eC eC Hz Oe -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -9484,8 +9468,8 @@ wK wK wK wK -Tj -Tj +qC +qC Qz XP eC @@ -9605,7 +9589,7 @@ vX os eC Oe -Tj +qC Rx eC Ly @@ -10541,8 +10525,8 @@ eC eC eC Oe -Tj -Tj +qC +qC RA qN qN @@ -10881,7 +10865,7 @@ wK wK xu xu -Tj +qC Rx eC eC @@ -11010,7 +10994,7 @@ eC eC Oe ll -Tj +qC mP XP IQ @@ -11026,7 +11010,7 @@ eC eC eC vg -Tj +qC Rx eC eC @@ -11345,7 +11329,7 @@ eC eC eC Oe -Tj +qC xu XP eC @@ -11962,10 +11946,10 @@ eC eC mP xu -Tj -Tj -Tj -Tj +qC +qC +qC +qC xu XP eC @@ -12406,13 +12390,13 @@ eC eC mP xu -Tj +qC Rx IQ MU MU Oe -Tj +qC Rx eC eC @@ -12578,9 +12562,9 @@ eC eC mP xu -Tj -Tj -Tj +qC +qC +qC Rx eC eC @@ -13016,15 +13000,15 @@ Pv Li gl Tv -Tj -Tj -Tj +qC +qC +qC hz hz -Tj -Tj -Tj -Tj +qC +qC +qC +qC zf eC eC @@ -13051,7 +13035,7 @@ eC eC mP xu -Tj +qC Rx eC eC @@ -13194,9 +13178,9 @@ eC eC mP xu -Tj -Tj -Tj +qC +qC +qC Rx eC tN @@ -13515,7 +13499,7 @@ eC eC eC Oe -Tj +qC xu XP eC @@ -13810,9 +13794,9 @@ eC eC mP xu -Tj -Tj -Tj +qC +qC +qC Rx eC eC @@ -14288,7 +14272,7 @@ wR eC eC vg -Tj +qC Rx eC mP @@ -14410,24 +14394,24 @@ ym Fn Fn Fn -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj -Tj +qC +qC +qC +qC +qC +qC +qC +qC +qC +qC +qC xu xu -Tj -Tj -Tj -Tj -Tj +qC +qC +qC +qC +qC xu XP eC @@ -14739,9 +14723,9 @@ eC eC eC Oe -Tj -Tj -Tj +qC +qC +qC xu XP eC @@ -15066,7 +15050,7 @@ eC eC mP xu -Tj +qC Rx eC ut @@ -15363,8 +15347,8 @@ eC eC eC Oe -Tj -Tj +qC +qC xG xu XP @@ -15530,7 +15514,7 @@ ao Tt eC Oe -Tj +qC xu XP eC @@ -15822,7 +15806,7 @@ eC eC eC Oe -Tj +qC Rx eC eC @@ -15987,9 +15971,9 @@ eC eC eC Oe -Tj -Tj -Tj +qC +qC +qC xu XP Hz @@ -16610,12 +16594,12 @@ wK wK wK wK -Tj -Tj -Tj -Tj -Tj -Tj +qC +qC +qC +qC +qC +qC xu XP eC @@ -16758,7 +16742,7 @@ eC eC eC vg -Tj +qC Rx eC eC @@ -28051,7 +28035,7 @@ Pv Pv YZ FC -Yr +Az Az Az Kk diff --git a/_maps/shuttles/tgs_bigbury.dmm b/_maps/shuttles/tgs_bigbury.dmm index 0acbce2693b..2933690aedd 100644 --- a/_maps/shuttles/tgs_bigbury.dmm +++ b/_maps/shuttles/tgs_bigbury.dmm @@ -442,7 +442,7 @@ /turf/open/floor/mainship, /area/shuttle/canterbury/cic) "bN" = ( -/obj/machinery/telecomms/relay/preset/telecomms, +/obj/machinery/telecomms/allinone/needs_power, /turf/open/floor/mainship/blue{ dir = 4 }, diff --git a/_maps/shuttles/tgs_canterbury.dmm b/_maps/shuttles/tgs_canterbury.dmm index f7c784c435b..6938ea9f984 100644 --- a/_maps/shuttles/tgs_canterbury.dmm +++ b/_maps/shuttles/tgs_canterbury.dmm @@ -91,10 +91,10 @@ }, /area/shuttle/canterbury/cic) "aq" = ( -/obj/machinery/telecomms/relay/preset/telecomms, /obj/machinery/air_alarm{ dir = 1 }, +/obj/machinery/telecomms/allinone/needs_power, /turf/open/floor/mainship/blue, /area/shuttle/canterbury/cic) "ar" = ( diff --git a/code/__DEFINES/action.dm b/code/__DEFINES/action.dm index 52b21e90cd8..aea454c92bd 100644 --- a/code/__DEFINES/action.dm +++ b/code/__DEFINES/action.dm @@ -30,6 +30,8 @@ #define VREF_MUTABLE_SAVAGE_COOLDOWN "VREF_SAVAGE_COOLDOWN" // extra define for jab charges #define VREF_MUTABLE_JAB "VREF_JAB" +// create spiderling charges +#define VREF_MUTABLE_SPIDERLING_CHARGES "VREF_SPIDERLING_CHARGES" /// Actions that toggle on click/trigger diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm index a93178fd987..8b3b7851f95 100644 --- a/code/__DEFINES/actions.dm +++ b/code/__DEFINES/actions.dm @@ -13,6 +13,7 @@ #define ABILITY_IGNORE_DEAD_TARGET (1 << 13) // bypass checks of a dead target #define ABILITY_IGNORE_SELECTED_ABILITY (1 << 14) // bypass the check of the selected ability #define ABILITY_DO_AFTER_ATTACK (1 << 15) //Let the xeno attack the object and perform the ability. +#define ABILITY_USE_BURROWED (1 << 16) // ignore being burrowed #define ABILITY_TURF_TARGET (1 << 0) // ability targets turfs #define ABILITY_MOB_TARGET (1 << 1) // ability targets mobs diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index d7986661308..ca8bfd87804 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -28,6 +28,9 @@ #define COMSIG_GLOB_SHIP_SELF_DESTRUCT_ACTIVATED "!ship_self_destruct_activated" +///Gamemode has successfully loaded +#define COMSIG_GLOB_GAMEMODE_LOADED "!gamemode_loaded" + /// from /obj/machinery/setAnchored(): (machine, anchoredstate) #define COMSIG_GLOB_MACHINERY_ANCHORED_CHANGE "!machinery_anchored_change" @@ -349,7 +352,6 @@ #define COMSIG_ITEM_TOGGLE_ACTION "item_toggle_action" //from base of obj/item/ui_interact(): (/mob/user) #define COMSIG_ITEM_TOGGLE_ACTIVE "item_toggle_active" //from base of /obj/item/toggle_active(): (new_state) -#define COMSIG_ITEM_EXCLUSIVE_TOGGLE "item_exclusive_toggle" #define COMSIG_ITEM_MIDDLECLICKON "item_middleclickon" //from base of mob/living/carbon/human/MiddleClickOn(): (/atom, /mob) #define COMSIG_ITEM_SHIFTCLICKON "item_shiftclickon" //from base of mob/living/carbon/human/ShiftClickOn(): (/atom, /mob) @@ -413,6 +415,8 @@ #define COMSIG_MOB_GUN_AUTOFIRED "mob_gun_autofired" #define COMSIG_MOB_GUN_COOLDOWN "mob_gun_cooldown" +#define COMSIG_MAGAZINE_DROP "magazine_drop" + #define COMSIG_XENO_FIRE "xeno_fire" #define COMSIG_XENO_STOP_FIRE "xeno_stop_fire" #define COMSIG_XENO_AUTOFIREDELAY_MODIFIED "xeno_firedelay_modified" @@ -716,6 +720,7 @@ #define COMSIG_MECHABILITY_SKYFALL "mechability_skyfall" #define COMSIG_MECHABILITY_STRIKE "mechability_strike" +#define COMSIG_ACTION_EXCLUSIVE_TOGGLE "action_exclusive_toggle" // xeno abilities for keybindings #define COMSIG_XENOABILITY_REST "xenoability_rest" @@ -891,6 +896,19 @@ #define COMSIG_XENOABILITY_SEISMIC_FRACTURE "xenoability_seismic_fracture" #define COMSIG_XENOABILITY_PRIMAL_WRATH "xenoability_primal_wrath" +#define COMSIG_XENOABILITY_BURROW "xenoability_burrow" +#define COMSIG_XENOABILITY_LEASH_BALL "xenoability_leash_ball" +#define COMSIG_XENOABILITY_CREATE_SPIDERLING "xenoability_create_spiderling" +#define COMSIG_XENOABILITY_ATTACH_SPIDERLINGS "xenoability_attach_spiderlings" +#define COMSIG_XENOABILITY_WEB_SPIT "xenoability_web_spit" +#define COMSIG_XENOABILITY_CREATE_HUGGER "xenoability_create_hugger" +#define COMSIG_XENOABILITY_UNLEASH_SPIDERLINGS "xenoability_unleash_spiderlings" +#define COMSIG_XENOABILITY_RECALL_SPIDERLINGS "xenoability_recall_spiderlings" + +//spiderling +#define COMSIG_SPIDERLING_CHANGE_ORDER "spiderlingchangeorder" +#define COMSIG_SPIDERLING_CHANGE_ALL_ORDER "spiderlingglobalorder" + //sectoid abilities #define COMSIG_ABILITY_MINDMELD "ability_mindmeld" #define COMSIG_ABILITY_MINDFRAY "ability_mindfray" @@ -938,6 +956,14 @@ #define COMSIG_KB_RETREATORDER "keybind_retreatorder" #define COMSIG_KB_VEHICLEHONK "keybind_vehiclehonk" +//Item toggle keybinds +#define COMSIG_ITEM_TOGGLE_JETPACK "item_toggle_jetpack" +#define COMSIG_ITEM_TOGGLE_BLINKDRIVE "item_toggle_blinkdrive" + +//Weapon related ability keybinds +#define COMSIG_WEAPONABILITY_AXESWEEP "weaponability_axesweep" +#define COMSIG_WEAPONABILITY_SWORDLUNGE "weaponability_swordlunge" + // human modules signals for keybindings #define COMSIG_KB_VALI_CONFIGURE "keybinding_vali_configure" #define COMSIG_KB_VALI_HEAL "keybinding_vali_heal" diff --git a/code/__DEFINES/greyscale_guns.dm b/code/__DEFINES/greyscale_guns.dm index a6396f9350c..fcfeb35e883 100644 --- a/code/__DEFINES/greyscale_guns.dm +++ b/code/__DEFINES/greyscale_guns.dm @@ -6,12 +6,6 @@ #define AMMO_BAND_COLOR_EXPLOSIVE "#3f1111" #define AMMO_BAND_COLOR_SABOT "#663618" -#define GUN_ICONSTATE_LOADED "loaded" -#define GUN_ICONSTATE_UNLOADED "unloaded" -#define GUN_ICONSTATE_UNRACKED "unracked" -#define GUN_ICONSTATE_OPEN "open" -#define GUN_ICONSTATE_PUMP "pump" - #define GUN_PALETTE_TAN "#3F382E#61574A#807360#978872" #define GUN_PALETTE_RED "#421010#601e1e#762525#9b3a28" #define GUN_PALETTE_DARK_RED "#301a1d#422628#5d3839#815150" diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index a39d5e2d1ee..a8f2014d69b 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -101,6 +101,8 @@ #define isxenospitter(A) (istype(A, /mob/living/carbon/xenomorph/spitter)) #define isxenosentinel(A) (istype(A, /mob/living/carbon/xenomorph/sentinel)) #define isxenowarrior(A) (istype(A, /mob/living/carbon/xenomorph/warrior)) +#define isxenowidow(A) (istype(A, /mob/living/carbon/xenomorph/widow)) +#define isxenospiderling(A) (istype(A, /mob/living/carbon/xenomorph/spiderling)) #define isxenolarva(A) (istype(A, /mob/living/carbon/xenomorph/larva)) #define isxenoqueen(A) (istype(A, /mob/living/carbon/xenomorph/queen)) #define isxenoshrike(A) (istype(A, /mob/living/carbon/xenomorph/shrike)) @@ -311,7 +313,7 @@ #define isstealobjective(O) (istype(O, /datum/objective/steal)) #define isassassinateobjective(O) (istype(O, /datum/objective/assassinate)) -#define isresearcher(A) (ishuman(A) && A.job.title == "Medical Researcher") +#define isresearcher(A) (ishuman(A) && A.job.title == "Field Researcher") #define isyautja(H) (is_species(H, /datum/species/yautja)) #define ispredatorjob(J) (istype(J, /datum/job/predator)) diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 86f5840a28d..dff605b19ae 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -20,7 +20,7 @@ #define JOB_DISPLAY_ORDER_SHIP_TECH 16 #define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 17 #define JOB_DISPLAY_ORDER_DOCTOR 18 -#define JOB_DISPLAY_ORDER_MEDICAL_RESEARCHER 19 +#define JOB_DISPLAY_ORDER_FIELD_RESEARCHER 19 #define JOB_DISPLAY_ORDER_AI 20 #define JOB_DISPLAY_ORDER_SYNTHETIC 21 #define JOB_DISPLAY_ORDER_SURVIVOR 22 @@ -57,7 +57,7 @@ #define SYNTHETIC "Synthetic" #define SHIP_TECH "Ship Technician" #define MEDICAL_DOCTOR "Medical Doctor" -#define MEDICAL_RESEARCHER "Medical Researcher" +#define FIELD_RESEARCHER "Field Researcher" #define SQUAD_LEADER "Squad Leader" #define SQUAD_SPECIALIST "Squad Specialist" #define SQUAD_SMARTGUNNER "Squad Smartgunner" @@ -92,11 +92,11 @@ GLOBAL_LIST_INIT(jobs_officers, list(CAPTAIN, FIELD_COMMANDER, STAFF_OFFICER, CO GLOBAL_LIST_INIT(jobs_support, list(PILOT_OFFICER, TRANSPORT_OFFICER, MECH_PILOT, ASSAULT_CREWMAN, TRANSPORT_CREWMAN, REQUISITIONS_OFFICER, SYNTHETIC, SILICON_AI)) GLOBAL_LIST_INIT(jobs_engineering, list(SQUAD_ENGINEER, SHIP_TECH)) GLOBAL_LIST_INIT(jobs_requisitions, list(REQUISITIONS_OFFICER, SHIP_TECH)) -GLOBAL_LIST_INIT(jobs_medical, list(CHIEF_MEDICAL_OFFICER, MEDICAL_DOCTOR, MEDICAL_RESEARCHER, SQUAD_CORPSMAN)) +GLOBAL_LIST_INIT(jobs_medical, list(CHIEF_MEDICAL_OFFICER, MEDICAL_DOCTOR, FIELD_RESEARCHER, SQUAD_CORPSMAN)) GLOBAL_LIST_INIT(jobs_marines, list(SQUAD_LEADER, SQUAD_SMARTGUNNER, SQUAD_CORPSMAN, SQUAD_ENGINEER, SQUAD_MARINE, SQUAD_ROBOT)) GLOBAL_LIST_INIT(jobs_regular_all, list(CAPTAIN, FIELD_COMMANDER, STAFF_OFFICER, PILOT_OFFICER, TRANSPORT_OFFICER, MECH_PILOT, REQUISITIONS_OFFICER, \ CHIEF_MEDICAL_OFFICER, SYNTHETIC, SILICON_AI, CORPORATE_LIAISON, SHIP_TECH, \ -MEDICAL_DOCTOR, MEDICAL_RESEARCHER, SQUAD_LEADER, SQUAD_SMARTGUNNER, SQUAD_CORPSMAN, SQUAD_ENGINEER, SQUAD_MARINE, SQUAD_ROBOT)) +MEDICAL_DOCTOR, FIELD_RESEARCHER, SQUAD_LEADER, SQUAD_SMARTGUNNER, SQUAD_CORPSMAN, SQUAD_ENGINEER, SQUAD_MARINE, SQUAD_ROBOT)) GLOBAL_LIST_INIT(jobs_xenos, list(ROLE_XENOMORPH, ROLE_XENO_QUEEN)) GLOBAL_LIST_INIT(jobs_fallen_marine, typecacheof(list(/datum/job/fallen/marine), TRUE)) @@ -109,7 +109,10 @@ GLOBAL_LIST_INIT(jobs_fallen_marine, typecacheof(list(/datum/job/fallen/marine), #define EXP_TYPE_MARINES "Marines" #define EXP_TYPE_REQUISITIONS "Requisitions" #define EXP_TYPE_SILICON "Silicon" -#define EXP_TYPE_SYNTHETIC "Medical/Engineering" // this define is used to limit synthetic to those who played at least medical or engineering +/// Used to limit synthetic to those who played at least medical or engineering. +#define EXP_TYPE_SYNTHETIC "Medical/Engineering" +/// Used to limit squad leader to those who played either marine or command. Also helps to unlock fc faster +#define EXP_TYPE_SL "Marines/Command" #define EXP_TYPE_XENO "Xenomorph" #define EXP_TYPE_GHOST "Ghost" #define EXP_TYPE_ADMIN "Admin" diff --git a/code/__DEFINES/keybind.dm b/code/__DEFINES/keybind.dm index a3bde9d9734..2740ea4b8a3 100644 --- a/code/__DEFINES/keybind.dm +++ b/code/__DEFINES/keybind.dm @@ -8,6 +8,8 @@ #define CATEGORY_CARBON "CARBON" #define CATEGORY_HUMAN "HUMAN" #define CATEGORY_PSIONIC "PSIONIC" +#define CATEGORY_WEAPON "WEAPON" +#define CATEGORY_ITEM "ITEM" #define CATEGORY_MISC "MISC" #define CATEGORY_EMOTE "EMOTE" #define CATEGORY_CUSTOM_EMOTE "CUSTOM_EMOTE" diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm index 589241d0108..7bc87cc508f 100644 --- a/code/__DEFINES/loadout.dm +++ b/code/__DEFINES/loadout.dm @@ -61,12 +61,15 @@ GLOBAL_LIST_INIT(marine_selector_cats, list( GLOBAL_LIST_INIT(marine_gear_listed_products, list( /obj/item/storage/backpack/marine/radiopack = list(CAT_MARINE, "Radio Pack", 5, "orange"), + /obj/item/storage/belt/marine/auto_catch = list(CAT_MARINE, "M344 pattern ammo load rig", 10, "orange"), /obj/item/stack/sandbags_empty/half = list(CAT_MARINE, "Sandbags x25", SANDBAG_PRICE_IN_GEAR_VENDOR, "orange"), /obj/item/fulton_extraction_pack = list(CAT_MARINE, "Fulton Extraction Pack", 5, "orange"), /obj/item/explosive/grenade = list(CAT_MARINE, "M40 HEDP grenade", 2, "orange3"), /obj/item/explosive/grenade/sticky = list(CAT_MARINE, "M40 adhesive charge grenade", 2, "orange3"), /obj/item/explosive/grenade/incendiary = list(CAT_MARINE, "M40 HIDP incendiary grenade", 2, "orange3"), /obj/item/explosive/grenade/m15 = list(CAT_MARINE, "M15 fragmentation grenade", 3, "orange3"), + /obj/item/explosive/grenade/smokebomb/drain = list(CAT_MARINE, "M40-T smoke grenade", 25, "orange3"), + /obj/item/explosive/grenade/sticky/cloaker/tangle = list(CAT_MARINE, "M45-T tanglefoot grenade", 20, "orange3"), /obj/structure/closet/crate/mortar_ammo/mortar_kit = list(CAT_MARINE, "Mortar kit", 35, "orange3"), /obj/structure/closet/crate/mortar_ammo/howitzer_kit = list(CAT_MARINE, "Howitzer kit", 35, "orange3"), /obj/structure/closet/crate/mortar_ammo/mlrs_kit = list(CAT_MARINE, "MLRS kit", 35, "orange3"), @@ -81,16 +84,9 @@ GLOBAL_LIST_INIT(marine_gear_listed_products, list( GLOBAL_LIST_INIT(robot_gear_listed_products, list( /obj/item/tool/surgery/solderingtool = list(CAT_ESS, "Essential Soldering Tool", 0, "white"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_rifle = list(CAT_ROBOT, "Terra Experimental laser rifle", 15, "red"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_sniper = list(CAT_ROBOT, "Terra Experimental laser sniper rifle", 20, "red"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_carbine = list(CAT_ROBOT, "Terra Experimental laser carbine", 15, "red"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_mlaser = list(CAT_ROBOT, "Terra Experimental laser machine gun", 20, "red"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol = list(CAT_ROBOT, "Terra Experimental laser pistol", 10, "red"), - /obj/item/weapon/gun/energy/lasgun/lasrifle/tesla = list(CAT_ROBOT, "Terra Experimental tesla shock rifle", 25, "red"), /obj/item/cell/lasgun/lasrifle/recharger = list(CAT_ROBOT, "Terra Experimental recharger battery", 4, "orange2"), /obj/item/cell/lasgun/volkite/powerpack/marine_back = list(CAT_ROBOT, "Terra Experimental powerback", 20, "orange2"), /obj/item/tool/handheld_charger = list(CAT_ROBOT, "Hand-held cell charger", 5, "yellow"), - /obj/item/weapon/powerfist = list(CAT_ROBOT, "Powerfist", 10, "red"), )) GLOBAL_LIST_INIT(engineer_gear_listed_products, list( @@ -204,6 +200,7 @@ GLOBAL_LIST_INIT(leader_gear_listed_products, list( /obj/item/jetpack_marine = list(CAT_LEDSUP, "Jetpack", 5, "yellow"), /obj/item/storage/belt/grenade/b17 = list(CAT_LEDSUP, "High Capacity Grenade Belt", 5, "yellow"), /obj/structure/closet/bodybag/tarp = list(CAT_LEDSUP, "V1 thermal-dampening tarp", 2, "yellow"), + /obj/item/storage/belt/marine/auto_catch = list(CAT_LEDSUP, "M344 pattern ammo load rig", 10, "orange"), /obj/item/weapon/gun/flamer/big_flamer/marinestandard = list(CAT_LEDSUP, "FL-84 flamethrower", 6, "red"), /obj/item/ammo_magazine/flamer_tank/large = list(CAT_LEDSUP, "Flamethrower tank", 2, "orange2"), /obj/item/storage/holster/belt/revolver/mateba/full = list(CAT_LEDSUP, "Mateba Autorevolver belt", 10, "red"), @@ -245,6 +242,7 @@ GLOBAL_LIST_INIT(commander_gear_listed_products, list( /obj/item/armor_module/module/night_vision = list(CAT_FCSUP, "BE-35 night vision kit", 18, "blue"), /obj/item/clothing/glasses/night_vision = list(CAT_FCSUP, "BE-47 night vision goggles", 26, "blue"), /obj/item/cell/night_vision_battery = list(CAT_FCSUP, "night vision battery", 4, "blue"), + /obj/item/storage/belt/marine/auto_catch = list(CAT_FCSUP, "M344 pattern ammo load rig", 10, "orange"), /obj/item/explosive/plastique = list(CAT_FCSUP, "Plastique explosive", 2, "orange3"), /obj/item/detpack = list(CAT_FCSUP, "Detonation pack", 2, "orange3"), /obj/item/storage/box/visual/grenade/sticky = list(CAT_FCSUP, "M40 adhesive charge grenade box", 15, "blue"), @@ -338,6 +336,7 @@ GLOBAL_LIST_INIT(smartgunner_gear_listed_products, list( /obj/item/ammo_magazine/rifle/sg153/plasmaloss = list(CAT_SGSUP, "SG-153 Spotting Rifle Tanglefoot Magazine", 3, "orange2"), /obj/item/ammo_magazine/rifle/sg153/incendiary = list(CAT_SGSUP, "SG-153 Spotting Rifle Incendiary Magazine", 3, "orange2"), /obj/item/ammo_magazine/pistol/p14/smart_pistol = list(CAT_SGSUP, "SP-13 smart pistol ammo", 2, "orange2"), + /obj/item/storage/belt/marine/auto_catch = list(CAT_SGSUP, "M344 pattern ammo load rig", 10, "orange"), )) GLOBAL_LIST_INIT(synthetic_gear_listed_products, list( diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index a39fa66a010..45ebbf713dc 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -738,6 +738,9 @@ GLOBAL_LIST_INIT(xenoupgradetiers, list(XENO_UPGRADE_BASETYPE, XENO_UPGRADE_INVA #define CHIMERA_TELEPORT_DEBUFF_STAGGER_STACKS 2 SECONDS #define CHIMERA_TELEPORT_DEBUFF_SLOWDOWN_STACKS 3 +//Spiderling defines +#define TIME_TO_DISSOLVE 5 SECONDS + //misc #define STANDARD_SLOWDOWN_REGEN 0.3 diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index b524632a64d..12a9a9eae0d 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -12,6 +12,7 @@ #define MOVESPEED_ID_BOILER_DUMP "BOILER_DUMP" #define MOVESPEED_ID_OFF_GUARD_SLOWDOWN "OFF_GUARD_SLOWDOWN" #define MOVESPEED_ID_HUNTER_DISGUISE "HUNTER_DISGUISE" +#define MOVESPEED_ID_SPIDER_VENOM "WIDOW_SPIDER_VENOM" #define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN" #define MOVESPEED_ID_MOB_PARACETAMOL_SPEED "MOB_PARACETAMOL_RUN" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 23f1eabe99b..56afaa9acb7 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -60,6 +60,7 @@ #define STATUS_EFFECT_MINDMEND /datum/status_effect/mindmeld #define STATUS_EFFECT_REKNIT_FORM /datum/status_effect/reknit_form + ///////////// // DEBUFFS // ///////////// @@ -99,6 +100,8 @@ #define STATUS_EFFECT_MICROWAVE /datum/status_effect/stacking/microwave ///armor reduction #define STATUS_EFFECT_SHATTER /datum/status_effect/shatter +//widow's ability +#define STATUS_EFFECT_SPIDER_VENOM /datum/status_effect/incapacitating/spider_venom ///////////// // NEUTRAL // diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e4e9145e5a6..7337cc06229 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -106,6 +106,7 @@ #define PETRIFY_ABILITY_TRAIT "petrify_ability_trait" #define SHATTERING_ROAR_ABILITY_TRAIT "shattering_roar_ability_trait" #define ZERO_FORM_BEAM_ABILITY_TRAIT "zero_form_beam_ability_trait" +#define WIDOW_ABILITY_TRAIT "widow_ability_trait" #define VALHALLA_TRAIT "valhalla" #define WEIGHTBENCH_TRAIT "weightbench" #define BOILER_ROOTED_TRAIT "boiler_rooted" @@ -160,10 +161,6 @@ #define TRAIT_BANISHED "banished" ///Mindmelded with another mob #define TRAIT_MINDMELDED "mindmelded" -///You swing axe good -#define TRAIT_AXE_EXPERT "axe_expert" -///You swing sword good -#define TRAIT_SWORD_EXPERT "sword_expert" ///Pain reduction light #define TRAIT_LIGHT_PAIN_RESIST "light_pain_resist" ///Pain reduction medium diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 2e126ba00da..6b6ee730ee1 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -238,3 +238,9 @@ GLOBAL_LIST_INIT(xeno_utility_upgrades, list( #define PRECRUSH_STOPPED -1 #define PRECRUSH_PLOWED -2 #define PRECRUSH_ENTANGLED -3 + +#define SPIDERLING_RECALL "recall spiderling" +#define SPIDERLING_SEEK_CLOSEST "seeking closest and attack order" //not xeno-usable +#define SPIDERLING_ATTACK "seek and attack order" + +#define SPIDERLING_WITHER_RANGE 15 diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 12afd05a455..a3828b13965 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -595,6 +595,7 @@ GLOBAL_LIST_INIT(bitfields, list( "ABILITY_IGNORE_DEAD_TARGET" = ABILITY_IGNORE_DEAD_TARGET, "ABILITY_IGNORE_SELECTED_ABILITY" = ABILITY_IGNORE_SELECTED_ABILITY, "ABILITY_DO_AFTER_ATTACK" = ABILITY_DO_AFTER_ATTACK, + "ABILITY_USE_BURROWED" = ABILITY_USE_BURROWED ), "pipe_flags" = list( "PIPING_ALL_LAYER" = PIPING_ALL_LAYER, diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index c4872247373..0e6ec53ffec 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -117,12 +117,14 @@ GLOBAL_LIST_INIT(playable_icons, list( "researcher", "runner", "sentinel", + "spiderling", "spitter", "st", "staffofficer", "synth", "warlock", "warrior", + "widow", "xenoking", "xenominion", "xenoqueen", diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 8a781727d67..416824fdfed 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -108,10 +108,13 @@ GLOBAL_LIST_INIT(all_xeno_types, list( /mob/living/carbon/xenomorph/behemoth/primordial, /mob/living/carbon/xenomorph/chimera, /mob/living/carbon/xenomorph/chimera/primordial, + /mob/living/carbon/xenomorph/widow, + /mob/living/carbon/xenomorph/widow/primordial, /mob/living/carbon/xenomorph/beetle, /mob/living/carbon/xenomorph/mantis, /mob/living/carbon/xenomorph/scorpion, /mob/living/carbon/xenomorph/facehugger, + /mob/living/carbon/xenomorph/spiderling, )) GLOBAL_LIST_EMPTY_TYPED(hellhound_list, /mob/living/carbon/xenomorph/hellhound) @@ -146,6 +149,7 @@ GLOBAL_LIST_INIT(xeno_types_tier_three, list( /datum/xeno_caste/praetorian, /datum/xeno_caste/ravager, /datum/xeno_caste/warlock, + /datum/xeno_caste/widow, )) GLOBAL_LIST_INIT(xeno_types_tier_four, list( @@ -217,3 +221,16 @@ GLOBAL_LIST_INIT(hive_ui_static_data, init_hive_status_lists()) // init by make_ for(var/i in GLOB.mob_list) var/mob/M = i M.update_config_movespeed() + +///The actions given to all humans on init +GLOBAL_LIST_INIT(human_init_actions, list( + /datum/action/skill/toggle_orders, + /datum/action/skill/issue_order/move, + /datum/action/skill/issue_order/hold, + /datum/action/skill/issue_order/focus, + /datum/action/innate/order/attack_order/personal, + /datum/action/innate/order/defend_order/personal, + /datum/action/innate/order/retreat_order/personal, + /datum/action/innate/order/rally_order/personal, + /datum/action/innate/message_squad, +)) diff --git a/code/_onclick/hud/screen_objects/menu_text_objects.dm b/code/_onclick/hud/screen_objects/menu_text_objects.dm index bc6226c5d51..f73bdc8a3c5 100644 --- a/code/_onclick/hud/screen_objects/menu_text_objects.dm +++ b/code/_onclick/hud/screen_objects/menu_text_objects.dm @@ -73,11 +73,28 @@ maptext = "ПРИСОЕДИНИТЬСЯ" icon_state = "join" +/atom/movable/screen/text/lobby/clickable/join_game/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_text() + RegisterSignal(SSdcs, COMSIG_GLOB_GAMEMODE_LOADED, TYPE_PROC_REF(/atom/movable/screen/text/lobby, update_text)) + /atom/movable/screen/text/lobby/clickable/join_game/Click() . = ..() var/mob/new_player/player = hud.mymob - player.attempt_late_join() + if(SSticker?.current_state > GAME_STATE_PREGAME) + player.attempt_late_join() + return + player.toggle_ready() + update_text() +/atom/movable/screen/text/lobby/clickable/join_game/update_text() + var/mob/new_player/player = hud.mymob + if(SSticker?.current_state > GAME_STATE_PREGAME) + maptext = "ПРИСОЕДИНИТЬСЯ" + icon_state = "join" + return + maptext = "ВЫ: [player.ready ? "" : "НЕ "]ГОТОВЫ" + icon_state = player.ready ? "ready" : "unready" /atom/movable/screen/text/lobby/clickable/observe maptext = "НАБЛЮДАТЬ" @@ -88,21 +105,6 @@ var/mob/new_player/player = hud.mymob player.try_to_observe() -/atom/movable/screen/text/lobby/clickable/ready - maptext = "ВЫ: НЕ ГОТОВЫ" - icon_state = "unready" - -/atom/movable/screen/text/lobby/clickable/ready/update_text() - var/mob/new_player/player = hud.mymob - maptext = "ВЫ: [player.ready ? "" : "НЕ "]ГОТОВЫ" - -/atom/movable/screen/text/lobby/clickable/ready/Click() - . = ..() - var/mob/new_player/player = hud.mymob - player.toggle_ready() - icon_state = player.ready ? "ready" : "unready" - update_text() - /atom/movable/screen/text/lobby/clickable/manifest maptext = "МАНИФЕСТ" icon_state = "manifest" diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index efdaab4d38e..6b0b114555b 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -89,20 +89,22 @@ SUBSYSTEM_DEF(atoms) count = length(atoms) for(var/I in 1 to count) var/atom/A = atoms[I] - if(!(A.flags_atom & INITIALIZED)) - CHECK_TICK - PROFILE_INIT_ATOM_BEGIN() - InitAtom(A, TRUE, mapload_arg) - PROFILE_INIT_ATOM_END(A) + if(A.flags_atom & INITIALIZED) + continue + CHECK_TICK + PROFILE_INIT_ATOM_BEGIN() + InitAtom(A, TRUE, mapload_arg) + PROFILE_INIT_ATOM_END(A) else count = 0 for(var/atom/A in world) - if(!(A.flags_atom & INITIALIZED)) - PROFILE_INIT_ATOM_BEGIN() - InitAtom(A, FALSE, mapload_arg) - PROFILE_INIT_ATOM_END(A) - ++count - CHECK_TICK + if(A.flags_atom & INITIALIZED) + continue + PROFILE_INIT_ATOM_BEGIN() + InitAtom(A, FALSE, mapload_arg) + PROFILE_INIT_ATOM_END(A) + ++count + CHECK_TICK testing("Initialized [count] atoms") pass(count) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 06568d24082..a6b95ecbe88 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -41,11 +41,12 @@ SUBSYSTEM_DEF(mapping) //dlete dis once #39770 is resolved /datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig() - if(!configs) - configs = load_map_configs(ALL_MAPTYPES, error_if_missing = FALSE) - for(var/i in GLOB.clients) - var/client/C = i - winset(C, null, "mainwindow.title='[CONFIG_GET(string/title)] - [SSmapping.configs[SHIP_MAP].map_name]'") + if(configs) + return + configs = load_map_configs(ALL_MAPTYPES, error_if_missing = FALSE) + for(var/i in GLOB.clients) + var/client/C = i + winset(C, null, "mainwindow.title='[CONFIG_GET(string/title)] - [SSmapping.configs[SHIP_MAP].map_name]'") /datum/controller/subsystem/mapping/Initialize() HACK_LoadMapConfig() @@ -54,17 +55,19 @@ SUBSYSTEM_DEF(mapping) for(var/i in ALL_MAPTYPES) var/datum/map_config/MC = configs[i] - if(MC.defaulted) - var/old_config = configs[i] - configs[i] = global.config.defaultmaps[i] - if(!configs || configs[i].defaulted) - to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting.")) - configs[i] = old_config + if(!MC.defaulted) + continue + var/old_config = configs[i] + configs[i] = global.config.defaultmaps[i] + if(!configs || configs[i].defaulted) + to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting.")) + configs[i] = old_config if(configs[GROUND_MAP]) for(var/datum/game_mode/M AS in config.votable_modes) - if(!(M.config_tag in configs[GROUND_MAP].gamemodes)) - config.votable_modes -= M // remove invalid modes + if(M.config_tag in configs[GROUND_MAP].gamemodes) + continue + config.votable_modes -= M // remove invalid modes loadWorld() repopulate_sorted_areas() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 15b601163d3..e2c40eda063 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -178,9 +178,9 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK PostSetup() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_GAMEMODE_LOADED) return TRUE - /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE mode.post_setup() diff --git a/code/datums/actions/ability_actions.dm b/code/datums/actions/ability_actions.dm index f1f0109ac6b..5c8c7fbb02c 100644 --- a/code/datums/actions/ability_actions.dm +++ b/code/datums/actions/ability_actions.dm @@ -26,14 +26,18 @@ name = "[name] ([ability_cost])" countdown = new(button, src) +/datum/action/ability/Destroy() + if(cooldown_timer) + deltimer(cooldown_timer) + QDEL_NULL(countdown) + return ..() + /datum/action/ability/give_action(mob/living/L) . = ..() var/mob/living/carbon/carbon_owner = L carbon_owner.mob_abilities += src /datum/action/ability/remove_action(mob/living/L) - if(cooldown_timer) - deltimer(cooldown_timer) var/mob/living/carbon/carbon_owner = L if(!istype(carbon_owner)) stack_trace("/datum/action/ability/remove_action called with [L], expecting /mob/living/carbon.") @@ -95,6 +99,11 @@ to_chat(owner, span_warning("We can't do this while in a solid object!")) return FALSE + if(!(flags_to_check & ABILITY_USE_BURROWED) && HAS_TRAIT(carbon_owner, TRAIT_BURROWED)) + if(!silent) + carbon_owner.balloon_alert(carbon_owner, "Cannot while burrowed") + return FALSE + return TRUE /datum/action/ability/fail_activate() @@ -145,9 +154,9 @@ ///override this for cooldown completion /datum/action/ability/proc/on_cooldown_finish() cooldown_timer = null - if(!button) - CRASH("no button object on finishing ability action cooldown") countdown.stop() + if(!button) + return update_button_icon() ///Any changes when a xeno with this ability evolves @@ -159,10 +168,22 @@ /datum/action/ability/activable/Destroy() var/mob/living/carbon/carbon_owner = owner - if(carbon_owner.selected_ability == src) + if(carbon_owner?.selected_ability == src) deselect() return ..() +/datum/action/ability/activable/set_toggle(value) + . = ..() + if(!.) + return + if(!owner) + return + if(toggled) + SEND_SIGNAL(owner, COMSIG_ACTION_EXCLUSIVE_TOGGLE, owner) + RegisterSignal(owner, COMSIG_ACTION_EXCLUSIVE_TOGGLE, PROC_REF(deselect)) + else + UnregisterSignal(owner, COMSIG_ACTION_EXCLUSIVE_TOGGLE) + /datum/action/ability/activable/alternate_action_activate() INVOKE_ASYNC(src, PROC_REF(action_activate)) @@ -174,7 +195,7 @@ if(carbon_owner.selected_ability == src) return if(carbon_owner.selected_ability) - carbon_owner.selected_ability.deselect() + carbon_owner.selected_ability.deselect() //todo: make jetpack/blinkdrive etc activatables select() /datum/action/ability/activable/keybind_activation() @@ -188,6 +209,7 @@ action_activate() /datum/action/ability/activable/remove_action(mob/living/carbon/carbon_owner) + deselect() if(carbon_owner.selected_ability == src) carbon_owner.selected_ability = null return ..() @@ -216,17 +238,18 @@ return ///Setting this ability as the active ability -/datum/action/ability/activable/proc/select() +/datum/action/ability/activable/select() + . = ..() var/mob/living/carbon/carbon_owner = owner - set_toggle(TRUE) carbon_owner.selected_ability = src on_selection() ///Deselecting this ability for use -/datum/action/ability/activable/proc/deselect() - var/mob/living/carbon/carbon_owner = owner - set_toggle(FALSE) - carbon_owner.selected_ability = null +/datum/action/ability/activable/deselect() + . = ..() + if(owner) + var/mob/living/carbon/carbon_owner = owner + carbon_owner.selected_ability = null on_deselection() ///Any effects on selecting this ability @@ -250,7 +273,7 @@ /mob/living/carbon/proc/add_ability(datum/action/ability/new_ability) if(!new_ability) return - new_ability = new new_ability + new_ability = new new_ability(src) new_ability.give_action(src) ///Removes an ability from a mob diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index 505969808b3..3c350c1fe53 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -48,9 +48,9 @@ KEYBINDINGS visual_references[VREF_MUTABLE_MAPTEXT] = maptext_list switch(action_type) if(ACTION_TOGGLE) - visual_references[VREF_MUTABLE_ACTIVE_FRAME] = mutable_appearance('icons/mob/actions.dmi', "active", ACTION_LAYER_ACTION_ICON_STATE, FLOAT_PLANE) + visual_references[VREF_MUTABLE_ACTIVE_FRAME] = mutable_appearance('icons/mob/actions.dmi', "active", ACTION_LAYER_SELECTED, FLOAT_PLANE) if(ACTION_SELECT) - visual_references[VREF_MUTABLE_SELECTED_FRAME] = mutable_appearance('icons/mob/actions.dmi', "selected_frame", ACTION_LAYER_ACTION_ICON_STATE, FLOAT_PLANE) + visual_references[VREF_MUTABLE_SELECTED_FRAME] = mutable_appearance('icons/mob/actions.dmi', "selected_frame", ACTION_LAYER_SELECTED, FLOAT_PLANE) visual_references[VREF_MUTABLE_ACTION_STATE] = mutable_appearance(action_icon, action_icon_state, HUD_LAYER, HUD_PLANE) button.add_overlay(visual_references[VREF_MUTABLE_ACTION_STATE]) @@ -63,6 +63,7 @@ KEYBINDINGS /datum/action/proc/clean_action() SIGNAL_HANDLER + SHOULD_CALL_PARENT(TRUE) qdel(src) /datum/action/proc/should_show() @@ -71,21 +72,19 @@ KEYBINDINGS ///Depending on the action type , toggles the selected/active frame to show without allowing stacking multiple overlays /datum/action/proc/set_toggle(value) if(value == toggled) - return - if(value) - switch(action_type) - if(ACTION_SELECT) - button.add_overlay(visual_references[VREF_MUTABLE_SELECTED_FRAME]) - if(ACTION_TOGGLE) - button.add_overlay(visual_references[VREF_MUTABLE_ACTIVE_FRAME]) - toggled = TRUE - return - switch(action_type) - if(ACTION_SELECT) - button.cut_overlay(visual_references[VREF_MUTABLE_SELECTED_FRAME]) - if(ACTION_TOGGLE) - button.cut_overlay(visual_references[VREF_MUTABLE_ACTIVE_FRAME]) - toggled = FALSE + return FALSE + toggled = value + update_button_icon() + return TRUE + +///Setting this action as the active action +/datum/action/proc/select() + set_toggle(TRUE) + +///Deselecting this action for use +/datum/action/proc/deselect() + SIGNAL_HANDLER + set_toggle(FALSE) ///A handler used to update the maptext and show the change immediately. /datum/action/proc/update_map_text(key_string, key_signal) @@ -120,6 +119,17 @@ KEYBINDINGS button.add_overlay(action_appearence) if(background_icon_state != button.icon_state) button.icon_state = background_icon_state + switch(action_type) + if(ACTION_SELECT) + button.cut_overlay(visual_references[VREF_MUTABLE_SELECTED_FRAME]) + if(ACTION_TOGGLE) + button.cut_overlay(visual_references[VREF_MUTABLE_ACTIVE_FRAME]) + if(toggled) + switch(action_type) + if(ACTION_SELECT) + button.add_overlay(visual_references[VREF_MUTABLE_SELECTED_FRAME]) + if(ACTION_TOGGLE) + button.add_overlay(visual_references[VREF_MUTABLE_ACTIVE_FRAME]) handle_button_status_visuals() return TRUE diff --git a/code/datums/actions/item_action.dm b/code/datums/actions/item_action.dm index f903661917c..cc7d21e3928 100644 --- a/code/datums/actions/item_action.dm +++ b/code/datums/actions/item_action.dm @@ -55,13 +55,13 @@ name = "Toggle [target]" button.name = name +/datum/action/item_action/toggle/action_activate() + . = ..() + set_toggle(!toggled) + /datum/action/item_action/toggle/suit_toggle keybinding_signals = list(KEYBINDING_NORMAL = COMSIG_KB_SUITLIGHT) -/datum/action/item_action/toggle/suit_toggle/update_button_icon() - set_toggle(holder_item.light_on) - return ..() - /datum/action/item_action/toggle/motion_detector/action_activate() . = ..() update_button_icon() diff --git a/code/datums/actions/item_toggles.dm b/code/datums/actions/item_toggles.dm new file mode 100644 index 00000000000..9804364b421 --- /dev/null +++ b/code/datums/actions/item_toggles.dm @@ -0,0 +1,40 @@ +/datum/action/ability/activable/item_toggle + name = "" + /** + *the item that has this action in its list of actions. Is not necessarily the target + * e.g. gun attachment action: target = attachment, holder = gun. + */ + var/obj/item/holder_item + /// Defines wheter we overlay the image of the obj we are linked to + var/use_obj_appeareance = TRUE + +/datum/action/ability/activable/item_toggle/New(Target, obj/item/holder) + . = ..() + if(!holder) + holder = target + holder_item = holder + if(!name) + name = "Use [target]" + button.name = name + +/datum/action/ability/activable/item_toggle/Destroy() + holder_item = null + return ..() + +/datum/action/ability/activable/item_toggle/use_ability(atom/target) + holder_item.ui_action_click(owner, src, target) + succeed_activate() + add_cooldown() + +/datum/action/ability/activable/item_toggle/update_button_icon() + if(visual_references[VREF_MUTABLE_LINKED_OBJ]) + button.cut_overlay(visual_references[VREF_MUTABLE_LINKED_OBJ]) + if(use_obj_appeareance) + var/obj/item/I = target + // -0.5 so its below maptext and above the selected frames + var/item_image = mutable_appearance(I.icon, I.icon_state, ACTION_LAYER_IMAGE_ONTOP, FLOAT_PLANE) + visual_references[VREF_MUTABLE_LINKED_OBJ] = item_image + button.add_overlay(item_image) + else + visual_references[VREF_MUTABLE_LINKED_OBJ] = null + return ..() diff --git a/code/datums/actions/order_action.dm b/code/datums/actions/order_action.dm index 31874e6c3f2..47d49aa0808 100644 --- a/code/datums/actions/order_action.dm +++ b/code/datums/actions/order_action.dm @@ -9,7 +9,7 @@ ///What skill is needed to have this action var/skill_name = SKILL_LEADERSHIP ///What minimum level in that skill is needed to have that action - var/skill_min = SKILL_LEAD_EXPERT + var/skill_min = SKILL_LEAD_TRAINED /datum/action/innate/order/give_action(mob/M) . = ..() diff --git a/code/datums/actions/species_actions/sectoid_action.dm b/code/datums/actions/species_actions/sectoid_action.dm index 01d12f6463f..3dcdcc7e4fb 100644 --- a/code/datums/actions/species_actions/sectoid_action.dm +++ b/code/datums/actions/species_actions/sectoid_action.dm @@ -81,11 +81,12 @@ /// Ends the ability if the Enhancement buff is removed. /datum/action/ability/activable/sectoid/mindmeld/proc/end_ability() SIGNAL_HANDLER + UnregisterSignal(owner, COMSIG_MOB_DEATH) var/mob/living/carbon/carbon_owner = owner - add_cooldown() carbon_owner.remove_status_effect(STATUS_EFFECT_MINDMEND) if(!melded_mob) return + UnregisterSignal(melded_mob, COMSIG_MOB_DEATH) melded_mob.remove_status_effect(STATUS_EFFECT_MINDMEND) melded_mob = null diff --git a/code/datums/actions/weapon_actions.dm b/code/datums/actions/weapon_actions.dm new file mode 100644 index 00000000000..fe8e385fa0a --- /dev/null +++ b/code/datums/actions/weapon_actions.dm @@ -0,0 +1,30 @@ +//Stamina using weapon based abilities +/datum/action/ability/activable/weapon_skill + action_icon = 'icons/mob/actions.dmi' + ///Damage of this attack + var/damage + ///Penetration of this attack + var/penetration + +/datum/action/ability/activable/weapon_skill/New(Target, _damage, _penetration) + . = ..() + damage = _damage + penetration = _penetration + +/datum/action/ability/activable/weapon_skill/can_use_ability(atom/A, silent = FALSE, override_flags) + . = ..() + if(!.) + return + var/mob/living/carbon/carbon_owner = owner + if(carbon_owner.getStaminaLoss() > 0) //this specifically lets you use these abilities with no stamina, but not if you have actual stamina loss + if(!silent) + carbon_owner.balloon_alert(owner, "Catch your breath!") + return FALSE + +/datum/action/ability/activable/weapon_skill/succeed_activate(ability_cost_override) + if(QDELETED(owner)) + return + ability_cost_override = ability_cost_override? ability_cost_override : ability_cost + if(ability_cost_override > 0) + var/mob/living/carbon/carbon_owner = owner + carbon_owner.adjustStaminaLoss(ability_cost_override) diff --git a/code/datums/components/easy_restock.dm b/code/datums/components/easy_restock.dm new file mode 100644 index 00000000000..6e967c8f62e --- /dev/null +++ b/code/datums/components/easy_restock.dm @@ -0,0 +1,51 @@ +/datum/component/easy_restock + ///Parent storage. Use this over checking the item directly. + var/obj/item/storage/reloading_storage + +/datum/component/easy_restock/Initialize() + . = ..() + if(!isstorage(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/easy_restock/Destroy(force, silent) + reloading_storage = null + return ..() + +/datum/component/easy_restock/RegisterWithParent() + reloading_storage = parent + RegisterSignal(parent, COMSIG_ATOM_ATTACKBY_ALTERNATE, PROC_REF(on_parent_attackby_alternate)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + +/datum/component/easy_restock/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_ATTACKBY_ALTERNATE, + COMSIG_ATOM_EXAMINE, + )) + +/datum/component/easy_restock/proc/on_examine(datum/source, mob/user, list/details) + SIGNAL_HANDLER + details += span_notice("You can easily restock magazines inside, right click on the belt with any ammo box.") + +/datum/component/easy_restock/proc/on_parent_attackby_alternate(datum/source, obj/item/ammo_magazine/ammo_box, mob/user, params) + SIGNAL_HANDLER + if(!istype(ammo_box)) + return + if(!reloading_storage) + CRASH("[user] attempted to reload [ammo_box] on [source], but it has no storage attached!") + INVOKE_ASYNC(src, PROC_REF(do_tac_reload), ammo_box, user, params) + +/datum/component/easy_restock/proc/do_tac_reload(obj/item/ammo_magazine/ammo_box, mob/user, params) + for(var/obj/item/ammo_magazine/item_to_restock in reloading_storage.contents) + var/amount_to_transfer = ammo_box.current_rounds + + if(!item_to_restock.can_transfer_ammo(ammo_box, user, amount_to_transfer, TRUE)) + continue + + if(item_to_restock.default_ammo != ammo_box.default_ammo) + if(item_to_restock.current_rounds == 0) + item_to_restock.transfer_ammo(ammo_box, user, amount_to_transfer, TRUE) + return COMPONENT_NO_AFTERATTACK + continue + + item_to_restock.transfer_ammo(ammo_box, user, amount_to_transfer) + return COMPONENT_NO_AFTERATTACK diff --git a/code/datums/components/harvester.dm b/code/datums/components/harvester.dm index 4c5ea82ab5a..cf0ac13dd21 100644 --- a/code/datums/components/harvester.dm +++ b/code/datums/components/harvester.dm @@ -221,7 +221,7 @@ if(/datum/reagent/medicine/kelotane) target.apply_damage(weapon.force*0.6, BRUTE, user.zone_selected) - target.fire_act(10) + target.fire_act(10, FLAME_COLOR_RED) if(/datum/reagent/medicine/tramadol) target.apply_damage(weapon.force*0.6, BRUTE, user.zone_selected) diff --git a/code/datums/components/magazine_catcher.dm b/code/datums/components/magazine_catcher.dm new file mode 100644 index 00000000000..c99c8565d2f --- /dev/null +++ b/code/datums/components/magazine_catcher.dm @@ -0,0 +1,46 @@ +/datum/component/magazine_catcher + var/mob/living/carbon/human/wearer + ///Parent storage in which we want to collect magazines + var/obj/item/storage/storage + +/datum/component/magazine_catcher/Initialize() + . = ..() + if(!isstorage(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/magazine_catcher/Destroy(force, silent) + storage = null + wearer = null + return ..() + +/datum/component/magazine_catcher/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED_TO_SLOT, PROC_REF(equipped_to_slot)) + RegisterSignals(parent, list(COMSIG_ITEM_EQUIPPED_NOT_IN_SLOT, COMSIG_ITEM_DROPPED), PROC_REF(removed_from_slot)) + storage = parent + +/datum/component/magazine_catcher/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED_TO_SLOT, COMSIG_ITEM_EQUIPPED_NOT_IN_SLOT, COMSIG_ITEM_DROPPED)) + +/datum/component/magazine_catcher/proc/equipped_to_slot(datum/source, mob/user, slot) + SIGNAL_HANDLER + wearer = user + RegisterSignal(user, COMSIG_MAGAZINE_DROP, PROC_REF(try_to_catch_magazine)) + +/datum/component/magazine_catcher/proc/removed_from_slot(datum/source, mob/user) + SIGNAL_HANDLER + + if(!iscarbon(user)) + return + + if(!wearer) + return + + wearer = null + UnregisterSignal(user, COMSIG_MAGAZINE_DROP) + +/datum/component/magazine_catcher/proc/try_to_catch_magazine(datum/source, obj/item/mag) + if(!storage.can_be_inserted(mag, FALSE)) + return FALSE + return storage.handle_item_insertion(mag, TRUE) diff --git a/code/datums/components/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm index 0f654437a80..3d85e1c1edd 100644 --- a/code/datums/components/riding/riding_mob.dm +++ b/code/datums/components/riding/riding_mob.dm @@ -276,3 +276,76 @@ . = riding_offsets["[mob_type]"] else if(riding_offsets["[RIDING_OFFSET_ALL]"]) . = riding_offsets["[RIDING_OFFSET_ALL]"] + +// *************************************** +// *********** Widow +// *************************************** +/datum/component/riding/creature/widow + can_be_driven = FALSE + +/datum/component/riding/creature/widow/handle_specials() + . = ..() + var/mob/living/widow = parent + if(widow.stat == UNCONSCIOUS) //For spiderling guard + set_riding_offsets(1, list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0))) + set_riding_offsets(2, list(TEXT_NORTH = list(16, 16), TEXT_SOUTH = list(16, 16), TEXT_EAST = list(16, 16), TEXT_WEST = list(16, 16))) + set_riding_offsets(3, list(TEXT_NORTH = list(-16, 16), TEXT_SOUTH = list(-16, 16), TEXT_EAST = list(-16, 16), TEXT_WEST = list(-16, 16))) + set_riding_offsets(4, list(TEXT_NORTH = list(16, 32), TEXT_SOUTH = list(16, -16), TEXT_EAST = list(16, -16), TEXT_WEST = list(16, -16))) + set_riding_offsets(5, list(TEXT_NORTH = list(0, -16), TEXT_SOUTH = list(-16, -16), TEXT_EAST = list(-16, -16), TEXT_WEST = list(-16, -16))) + set_vehicle_dir_layer(SOUTH, ABOVE_ALL_MOB_LAYER) + set_vehicle_dir_layer(NORTH, ABOVE_ALL_MOB_LAYER) + set_vehicle_dir_layer(EAST, ABOVE_ALL_MOB_LAYER) + set_vehicle_dir_layer(WEST, ABOVE_ALL_MOB_LAYER) + return + set_riding_offsets(1, list(TEXT_NORTH = list(-16, 9), TEXT_SOUTH = list(-16, 17), TEXT_EAST = list(-21, 7), TEXT_WEST = list(-6, 7))) + set_riding_offsets(2, list(TEXT_NORTH = list(16, 16), TEXT_SOUTH = list(16, 17), TEXT_EAST = list(21, 7), TEXT_WEST = list(6, 7))) + set_riding_offsets(3, list(TEXT_NORTH = list(8, 8), TEXT_SOUTH = list(-8, 21), TEXT_EAST = list(14, 11), TEXT_WEST = list(0, 2))) + set_riding_offsets(4, list(TEXT_NORTH = list(-8, 16), TEXT_SOUTH = list(-16, 13), TEXT_EAST = list(-21, 2), TEXT_WEST = list(6, 11))) + set_riding_offsets(5, list(TEXT_NORTH = list(8, 8), TEXT_SOUTH = list(8, 12), TEXT_EAST = list(21, 2), TEXT_WEST = list(-6, 11))) + set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER) + set_vehicle_dir_layer(NORTH, ABOVE_LYING_MOB_LAYER) + set_vehicle_dir_layer(EAST, ABOVE_LYING_MOB_LAYER) + set_vehicle_dir_layer(WEST, ABOVE_LYING_MOB_LAYER) + +/datum/component/riding/creature/widow/Initialize(mob/living/riding_mob, force = FALSE, check_loc, lying_buckle, hands_needed, target_hands_needed, silent) + . = ..() + riding_mob.density = FALSE + +// If we call parent here , we get registered for COMSIG_MOVABLE_BUMP, and when we do bump, there will be a bad index runtime +/datum/component/riding/creature/widow/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(vehicle_turned)) + RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, PROC_REF(vehicle_mob_unbuckle)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(vehicle_moved)) + RegisterSignals(parent, list(COMSIG_XENOMORPH_ATTACK_LIVING, COMSIG_XENOMORPH_ATTACK_OBJ), PROC_REF(check_widow_attack)) + +/datum/component/riding/creature/widow/vehicle_mob_unbuckle(datum/source, mob/living/former_rider, force = FALSE) + unequip_buckle_inhands(parent) + former_rider.density = initial(former_rider.density) + REMOVE_TRAIT(former_rider, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT) + return ..() + +/// If the widow gets knocked over, force the riding rounys off and see if someone got hurt +/datum/component/riding/creature/widow/proc/check_widow_attack(mob/living/carbon/xenomorph/widow/carrying_widow) + SIGNAL_HANDLER + for(var/mob/living/rider AS in carrying_widow.buckled_mobs) + carrying_widow.unbuckle_mob(rider) + REMOVE_TRAIT(rider, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT) + +// Spiderlings latch on to crit widows when guarding and cannot be kicked off.. +/datum/component/riding/creature/widow/ride_check(mob/living/rider) + var/mob/living/widow = parent + return widow.stat == UNCONSCIOUS + +//..nor can they be laid under widow.. +/datum/component/riding/creature/widow/handle_vehicle_layer(dir) + var/mob/living/widow = parent + if(widow.stat == UNCONSCIOUS) + return + return ..() + +//..and nor will they change direction. +/datum/component/riding/creature/widow/handle_vehicle_offsets(dir) + var/mob/living/widow = parent + if(widow.stat == UNCONSCIOUS) + dir = SOUTH + return ..() diff --git a/code/datums/components/stun_mitigation.dm b/code/datums/components/stun_mitigation.dm index c881f1fb105..3ae59d1e2f1 100644 --- a/code/datums/components/stun_mitigation.dm +++ b/code/datums/components/stun_mitigation.dm @@ -90,7 +90,7 @@ ///Actually deactivates the mitigation effect /datum/component/stun_mitigation/proc/deactivate_with_user() - UnregisterSignal(affected, COMSIG_LIVING_PROJECTILE_STUN) + UnregisterSignal(affected, list(COMSIG_LIVING_PROJECTILE_STUN, COMSIG_LIVING_JETPACK_STUN)) ///Handles removing the mitigation from a user /datum/component/stun_mitigation/proc/shield_detach_from_user() diff --git a/code/datums/elements/riding.dm b/code/datums/elements/riding.dm index c89ad27ba62..c17f3ddb2b0 100644 --- a/code/datums/elements/riding.dm +++ b/code/datums/elements/riding.dm @@ -96,9 +96,6 @@ qdel(O) return TRUE - - - /obj/item/riding_offhand name = "offhand" icon = 'icons/obj/items/weapons.dmi' diff --git a/code/datums/gamemodes/_game_mode.dm b/code/datums/gamemodes/_game_mode.dm index 6d718ef3a64..0de7a051b96 100644 --- a/code/datums/gamemodes/_game_mode.dm +++ b/code/datums/gamemodes/_game_mode.dm @@ -517,7 +517,7 @@ GLOBAL_LIST_INIT(bioscan_locations, list( var/mob/living/carbon/human/H = i if(!istype(H)) // Small fix? continue - if(isyautja(H)) //RU TGMC EDIT + if(isyautja(H)) continue if(count_flags & COUNT_IGNORE_HUMAN_SSD && !H.client && H.afk_status == MOB_DISCONNECTED) continue @@ -534,7 +534,9 @@ GLOBAL_LIST_INIT(bioscan_locations, list( for(var/z in z_levels) for(var/i in GLOB.hive_datums[XENO_HIVE_NORMAL].xenos_by_zlevel["[z]"]) var/mob/living/carbon/xenomorph/X = i - if(!istype(X) || isxenohellhound(X)) // Small fix? and // RU TGMC EDIT + if(!istype(X)) // Small fix? + continue + if(isxenohellhound(X)) continue if(count_flags & COUNT_IGNORE_XENO_SSD && !X.client && X.afk_status == MOB_DISCONNECTED) continue diff --git a/code/datums/greyscale/json_configs/attachments.json b/code/datums/greyscale/json_configs/attachments.json deleted file mode 100644 index 40f151503a0..00000000000 --- a/code/datums/greyscale/json_configs/attachments.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "verticalgrip":[ - { - "type":"hyperscale", - "icon_state":"verticalgrip" - } - ], - "verticalgrip_a":[ - { - "type":"hyperscale", - "icon_state":"verticalgrip_a" - } - ], - "angledgrip":[ - { - "type":"hyperscale", - "icon_state":"angledgrip" - } - ], - "angledgrip_a":[ - { - "type":"hyperscale", - "icon_state":"angledgrip_a" - } - ], - "t60stock_a":[ - { - "type":"hyperscale", - "icon_state":"t60stock_a" - }, - { - "type":"icon_state", - "icon_state":"t60stock_no_color_a", - "blend_mode":"overlay" - } - ], - "tl127stock_a":[ - { - "type":"hyperscale", - "icon_state":"tl127stock_a" - }, - { - "type":"icon_state", - "icon_state":"tl127stock_no_color_a", - "blend_mode":"overlay" - } - ], - "sg29stock_a":[ - { - "type":"hyperscale", - "icon_state":"sg29stock_a" - } - ] -} diff --git a/code/datums/greyscale/json_configs/attachments_64.json b/code/datums/greyscale/json_configs/attachments_64.json deleted file mode 100644 index 34434035f02..00000000000 --- a/code/datums/greyscale/json_configs/attachments_64.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "t35stock":[ - { - "type":"hyperscale", - "icon_state":"t35stock_color" - }, - { - "type":"icon_state", - "icon_state":"t35stock", - "blend_mode":"overlay" - } - ], - "t35stock_a":[ - { - "type":"hyperscale", - "icon_state":"t35stock_color" - }, - { - "type":"icon_state", - "icon_state":"t35stock_a", - "blend_mode":"overlay" - } - ], - "t35stock_open":[ - { - "type":"hyperscale", - "icon_state":"t35stock_color" - }, - { - "type":"icon_state", - "icon_state":"t35stock_open", - "blend_mode":"overlay" - } - ], - "t35stock_open_a":[ - { - "type":"hyperscale", - "icon_state":"t35stock_color" - }, - { - "type":"icon_state", - "icon_state":"t35stock_open_a", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun.json b/code/datums/greyscale/json_configs/gun.json deleted file mode 100644 index f36537ef47a..00000000000 --- a/code/datums/greyscale/json_configs/gun.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"loaded", - "blend_mode":"overlay" - } - ], - "loaded_fire":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"fire", - "blend_mode":"overlay" - } - ], - "unloaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"unloaded", - "blend_mode":"overlay" - } - ], - "belt":[ - { - "type":"hyperscale", - "icon_state":"belt_color" - }, - { - "type":"icon_state", - "icon_state":"belt_no_color", - "blend_mode":"overlay" - } - ], - "loaded_l":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"linked", - "blend_mode":"overlay" - } - ], - "loaded_a":[ - { - "type":"hyperscale", - "icon_state":"colored_a" - }, - { - "type":"icon_state", - "icon_state":"loaded_a", - "blend_mode":"overlay" - } - ], - "unloaded_a":[ - { - "type":"hyperscale", - "icon_state":"colored_a" - }, - { - "type":"icon_state", - "icon_state":"unloaded_a", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun_fire.json b/code/datums/greyscale/json_configs/gun_fire.json deleted file mode 100644 index af62066e45a..00000000000 --- a/code/datums/greyscale/json_configs/gun_fire.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"loaded", - "blend_mode":"overlay" - } - ], - "loaded_fire":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"fire", - "blend_mode":"overlay" - } - ], - "unloaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"unloaded", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun_hands.json b/code/datums/greyscale/json_configs/gun_hands.json deleted file mode 100644 index 9cdfc6e047a..00000000000 --- a/code/datums/greyscale/json_configs/gun_hands.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"color" - }, - { - "type":"icon_state", - "icon_state":"no_color", - "blend_mode":"overlay" - } - ], - "loaded_w":[ - { - "type":"hyperscale", - "icon_state":"color_w" - }, - { - "type":"icon_state", - "icon_state":"no_color_w", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun_mob.json b/code/datums/greyscale/json_configs/gun_mob.json deleted file mode 100644 index ec509495346..00000000000 --- a/code/datums/greyscale/json_configs/gun_mob.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"color" - }, - { - "type":"icon_state", - "icon_state":"no_color", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun_revolver.json b/code/datums/greyscale/json_configs/gun_revolver.json deleted file mode 100644 index 68e4f0c4441..00000000000 --- a/code/datums/greyscale/json_configs/gun_revolver.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"loaded", - "blend_mode":"overlay" - } - ], - "unloaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"unloaded", - "blend_mode":"overlay" - } - - ], - "open":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"open", - "blend_mode":"overlay" - } - ], - "belt":[ - { - "type":"hyperscale", - "icon_state":"belt_color" - }, - { - "type":"icon_state", - "icon_state":"belt_no_color", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/greyscale/json_configs/gun_shotgun.json b/code/datums/greyscale/json_configs/gun_shotgun.json deleted file mode 100644 index 5a52f581fce..00000000000 --- a/code/datums/greyscale/json_configs/gun_shotgun.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "loaded":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"loaded", - "blend_mode":"overlay" - } - ], - "unloaded":[ - { - "type":"hyperscale", - "icon_state":"colored_unloaded" - }, - { - "type":"icon_state", - "icon_state":"unloaded", - "blend_mode":"overlay" - } - ], - "unracked":[ - { - "type":"hyperscale", - "icon_state":"colored" - }, - { - "type":"icon_state", - "icon_state":"unprimed", - "blend_mode":"overlay" - } - ], - "pump":[ - { - "type":"hyperscale", - "icon_state":"colored_pump" - }, - { - "type":"icon_state", - "icon_state":"pump", - "blend_mode":"overlay" - } - ] -} diff --git a/code/datums/jobs/job/job.dm b/code/datums/jobs/job/job.dm index 68d7b1008c0..0d6d9437bb6 100644 --- a/code/datums/jobs/job/job.dm +++ b/code/datums/jobs/job/job.dm @@ -6,6 +6,7 @@ GLOBAL_LIST_INIT(exp_jobsmap, list( EXP_TYPE_MARINES = list("titles" = GLOB.jobs_marines), EXP_TYPE_REQUISITIONS = list("titles" = GLOB.jobs_requisitions), EXP_TYPE_SYNTHETIC = list("titles" = GLOB.jobs_engineering + GLOB.jobs_medical), + EXP_TYPE_SL = list("titles" = GLOB.jobs_marines + GLOB.jobs_command), EXP_TYPE_XENO = list("titles" = GLOB.jobs_xenos), )) @@ -322,7 +323,7 @@ GLOBAL_PROTECT(exp_specialmap) else equip_role_outfit(job) - if(SSdiscord.get_boosty_tier(player.ckey) >= BOOSTY_TIER_2) + if(SSdiscord.get_boosty_tier(player?.ckey) >= BOOSTY_TIER_2) equip_to_slot_or_del(new /obj/item/facepaint/premium, SLOT_IN_BACKPACK) if((job.job_flags & JOB_FLAG_ALLOWS_PREFS_GEAR) && player) diff --git a/code/datums/jobs/job/marines.dm b/code/datums/jobs/job/marines.dm index bd6e70ed058..267c50b2bf9 100644 --- a/code/datums/jobs/job/marines.dm +++ b/code/datums/jobs/job/marines.dm @@ -398,7 +398,7 @@ You can serve a variety of roles, so choose carefully."}) minimal_access = list(ACCESS_MARINE_PREP, ACCESS_MARINE_LEADER, ACCESS_MARINE_DROPSHIP, ACCESS_MARINE_TADPOLE) skills_type = /datum/skills/sl - exp_type = EXP_TYPE_MARINES + exp_type = EXP_TYPE_SL exp_requirements = XP_REQ_INTERMEDIATE display_order = JOB_DISPLAY_ORDER_SQUAD_LEADER diff --git a/code/datums/jobs/job/shipside.dm b/code/datums/jobs/job/shipside.dm index 937f88f97ad..c1fa2875a82 100644 --- a/code/datums/jobs/job/shipside.dm +++ b/code/datums/jobs/job/shipside.dm @@ -971,7 +971,7 @@ You are also an expert when it comes to medication and treatment. If you do not //Researcher /datum/job/terragov/medical/researcher - title = MEDICAL_RESEARCHER + title = FIELD_RESEARCHER comm_title = "Rsr" paygrade = "CD" total_positions = 2 @@ -979,7 +979,7 @@ You are also an expert when it comes to medication and treatment. If you do not access = list(ACCESS_MARINE_MEDBAY, ACCESS_MARINE_RESEARCH, ACCESS_MARINE_CHEMISTRY, ACCESS_MARINE_ENGINEERING, ACCESS_CIVILIAN_ENGINEERING) minimal_access = list(ACCESS_MARINE_MEDBAY, ACCESS_MARINE_RESEARCH, ACCESS_MARINE_CHEMISTRY, ACCESS_MARINE_CARGO, ACCESS_MARINE_DROPSHIP) skills_type = /datum/skills/researcher - display_order = JOB_DISPLAY_ORDER_MEDICAL_RESEARCHER + display_order = JOB_DISPLAY_ORDER_FIELD_RESEARCHER outfit = /datum/outfit/job/medical/researcher exp_type = EXP_TYPE_MEDICAL exp_requirements = XP_REQ_UNSEASONED @@ -1025,7 +1025,7 @@ It is also recommended that you gear up like a regular marine, or your 'internsh /datum/outfit/job/medical/researcher - name = MEDICAL_RESEARCHER + name = FIELD_RESEARCHER jobtype = /datum/job/terragov/medical/researcher id = /obj/item/card/id diff --git a/code/datums/jobs/squads.dm b/code/datums/jobs/squads.dm index 06c31b6f23d..699fa9ffd34 100644 --- a/code/datums/jobs/squads.dm +++ b/code/datums/jobs/squads.dm @@ -353,8 +353,8 @@ GLOBAL_LIST_EMPTY_TYPED(custom_squad_radio_freqs, /datum/squad) new_squad.faction = squad_faction if(new_squad.faction == FACTION_TERRAGOV) var/list/terragov_server_freqs = GLOB.telecomms_freq_listening_list[/obj/machinery/telecomms/server/presets/alpha] - var/list/terragov_bus_freqs = GLOB.telecomms_freq_listening_list[/obj/machinery/telecomms/bus/preset_three] - var/list/terragov_receiver_freqs = GLOB.telecomms_freq_listening_list[/obj/machinery/telecomms/receiver/preset_left] + var/list/terragov_bus_freqs = GLOB.telecomms_freq_listening_list[/obj/machinery/telecomms/bus/preset/three] + var/list/terragov_receiver_freqs = GLOB.telecomms_freq_listening_list[/obj/machinery/telecomms/receiver/preset/left] LAZYADDASSOCSIMPLE(terragov_server_freqs, 1, freq) LAZYADDASSOCSIMPLE(terragov_bus_freqs, 1, freq) LAZYADDASSOCSIMPLE(terragov_receiver_freqs, 1, freq) diff --git a/code/datums/keybinding/item_toggles.dm b/code/datums/keybinding/item_toggles.dm new file mode 100644 index 00000000000..0fbbe17c03d --- /dev/null +++ b/code/datums/keybinding/item_toggles.dm @@ -0,0 +1,17 @@ +/datum/keybinding/item + category = CATEGORY_ITEM + weight = WEIGHT_MOB + +/datum/keybinding/item/jetpack + name = "Jetpack" + full_name = "Toggle jetpack" + description = "Toggles your jetpack on, allowing you to fly a short distance." + keybind_signal = COMSIG_ITEM_TOGGLE_JETPACK + hotkey_keys = list("G") + +/datum/keybinding/item/blinkdrive + name = "Blink drive" + full_name = "Toggle blink drive" + description = "Toggles your blink drive on, allowing you to instantly teleport short distances." + keybind_signal = COMSIG_ITEM_TOGGLE_BLINKDRIVE + hotkey_keys = list("G") diff --git a/code/datums/keybinding/weapons.dm b/code/datums/keybinding/weapons.dm new file mode 100644 index 00000000000..5a5077bf42e --- /dev/null +++ b/code/datums/keybinding/weapons.dm @@ -0,0 +1,17 @@ +/datum/keybinding/weapon + category = CATEGORY_WEAPON + weight = WEIGHT_MOB + +/datum/keybinding/weapon/axe_sweep + name = "Axe sweep" + full_name = "Breaching axe: Axe sweep" + description = "A powerful sweeping blow that hits foes in the direction you are facing. Cannot stun." + keybind_signal = COMSIG_WEAPONABILITY_AXESWEEP + hotkey_keys = list("G") + +/datum/keybinding/weapon/sword_lunge + name = "Lunging strike" + full_name = "Sword: Lunging strike" + description = "Dash a short distance to inflict a staggering blow on an opponent. Cannot stun." + keybind_signal = COMSIG_WEAPONABILITY_SWORDLUNGE + hotkey_keys = list("G") diff --git a/code/datums/keybinding/xeno.dm b/code/datums/keybinding/xeno.dm index 36b3f66e92b..cf6a86e5dc7 100644 --- a/code/datums/keybinding/xeno.dm +++ b/code/datums/keybinding/xeno.dm @@ -1111,3 +1111,59 @@ description = "Sprays some acid" keybind_signal = COMSIG_XENOABILITY_SHORT_SPRAY_ACID hotkey_keys = list("E") + +/datum/keybinding/xeno/burrow + name = "burrow" + full_name = "Burrow" + description = "Dig to the ground, making you invisible." + keybind_signal = COMSIG_XENOABILITY_BURROW + hotkey_keys = list("C") + +/datum/keybinding/xeno/leash_ball + name = "Leash Ball" + full_name = "Widow: Leash Ball" + description = "Spit a huge web ball of web that snares groups of targets for a brief while." + keybind_signal = COMSIG_XENOABILITY_LEASH_BALL + hotkey_keys = list("E") + +/datum/keybinding/xeno/create_spiderling + name = "Birth Spiderling" + full_name = "Widow: Birth Spiderling" + description = "Give birth to a spiderling after a short charge-up." + keybind_signal = COMSIG_XENOABILITY_CREATE_SPIDERLING + hotkey_keys = list("F") + +/datum/keybinding/xeno/attach_spiderlings + name = "Attach Spiderlings" + full_name = "Widow: Attach Spiderlings" + description = "Scoop up and carry your spawn with you." + keybind_signal = COMSIG_XENOABILITY_ATTACH_SPIDERLINGS + hotkey_keys = list("X") + +/datum/keybinding/xeno/web_spit + name = "Web Spit" + full_name = "Widow: Web Spit" + description = "Stun and blind the target with a web projectile" + keybind_signal = COMSIG_XENOABILITY_WEB_SPIT + hotkey_keys = list("R") + +/datum/keybinding/xeno/create_hugger + name = "Create Facehugger" + full_name = "Widow: Create Facehugger" + description = "Create a facehugger." + keybind_signal = COMSIG_XENOABILITY_CREATE_HUGGER + hotkey_keys = list("G") + +/datum/keybinding/xeno/widow_unleash + name = "Unleash Spiderlings" + full_name = "Widow: Unleash Spiderlings" + description = "Send out your spawn to attack nearby humans" + keybind_signal = COMSIG_XENOABILITY_UNLEASH_SPIDERLINGS + hotkey_keys = list("N") + +/datum/keybinding/xeno/widow_recall + name = "Recall Spiderlings" + full_name = "Widow: Recall Spiderlings" + description = "Recall your siderlings to follow you once more" + keybind_signal = COMSIG_XENOABILITY_RECALL_SPIDERLINGS + hotkey_keys = list("M") diff --git a/code/datums/skills.dm b/code/datums/skills.dm index 2b25bf06112..ff9d1d6f2e5 100644 --- a/code/datums/skills.dm +++ b/code/datums/skills.dm @@ -326,10 +326,8 @@ engineer, construction, leadership, medical, surgery, pilot, police, powerloader /datum/skills/researcher name = "Researcher" cqc = SKILL_CQC_WEAK - firearms = SKILL_FIREARMS_UNTRAINED medical = SKILL_MEDICAL_EXPERT surgery = SKILL_SURGERY_PROFESSIONAL - melee_weapons = SKILL_MELEE_WEAK /datum/skills/cmo name = "CMO" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 3466f5a0eaf..8e82abff5f5 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -847,3 +847,19 @@ name = "Freezing" desc = "Space is very very cold, who would've thought?" icon_state = "cold3" + +/datum/status_effect/incapacitating/spider_venom + id = "spider_venom" + status_type = STATUS_EFFECT_REFRESH + duration = 1 SECONDS + var/slowdown = 2 + +/datum/status_effect/incapacitating/spider_venom/on_apply() + . = ..() + if(!.) + return + owner.add_movespeed_modifier(MOVESPEED_ID_SPIDER_VENOM, TRUE, 0, NONE, TRUE, slowdown) + +/datum/status_effect/incapacitating/spider_venom/on_remove() + owner.remove_movespeed_modifier(MOVESPEED_ID_SPIDER_VENOM) + return ..() diff --git a/code/datums/status_effects/sectoid.dm b/code/datums/status_effects/sectoid.dm index 3a5c17cc8a9..40351afc848 100644 --- a/code/datums/status_effects/sectoid.dm +++ b/code/datums/status_effects/sectoid.dm @@ -47,7 +47,14 @@ /datum/status_effect/mindmeld/on_remove() link_target.balloon_alert(link_target, "mindmeld inactive") REMOVE_TRAIT(link_target, TRAIT_MINDMELDED, TRAIT_STATUS_EFFECT(id)) - UnregisterSignal(link_target, COMSIG_MOB_DEATH) + link_target.UnregisterSignal(link_target, list( + COMSIG_LIVING_STATUS_STUN, + COMSIG_LIVING_STATUS_KNOCKDOWN, + COMSIG_LIVING_STATUS_PARALYZE, + COMSIG_LIVING_STATUS_UNCONSCIOUS, + COMSIG_LIVING_STATUS_CONFUSED, + COMSIG_LIVING_STATUS_STAGGER, + )) check_range() return ..() diff --git a/code/game/area/bigred.dm b/code/game/area/bigred.dm index 395abb5058b..58920b6680c 100644 --- a/code/game/area/bigred.dm +++ b/code/game/area/bigred.dm @@ -78,6 +78,7 @@ icon_state = "yellow" ceiling = CEILING_DEEP_UNDERGROUND_METAL requires_power = TRUE + always_unpowered = FALSE /area/bigredv2/caves/secomplex name = "Underground research complex" diff --git a/code/game/atoms/_atom.dm b/code/game/atoms/_atom.dm index c922cc32c54..9783f8c1618 100644 --- a/code/game/atoms/_atom.dm +++ b/code/game/atoms/_atom.dm @@ -386,14 +386,14 @@ directive is properly returned. contents_explosion(severity, explosion_direction) ///Effects of fire -/atom/proc/fire_act(burn_level) +/atom/proc/fire_act(burn_level, flame_color) return ///Effects of lava. Return true where we want the lava to keep processing /atom/proc/lava_act() if(resistance_flags & INDESTRUCTIBLE) return FALSE - fire_act(LAVA_BURN_LEVEL) + fire_act(LAVA_BURN_LEVEL, FLAME_COLOR_RED) return TRUE /atom/proc/hitby(atom/movable/AM, speed = 5) diff --git a/code/game/data_huds/xenomorph.dm b/code/game/data_huds/xenomorph.dm index 61bffd003cc..ce7045677ad 100644 --- a/code/game/data_huds/xenomorph.dm +++ b/code/game/data_huds/xenomorph.dm @@ -31,8 +31,9 @@ if(!holder) return + holder.icon = 'icons/mob/hud/xeno_health.dmi' if(status_flags & INCORPOREAL) - holder.icon_state = "" + holder.icon_state = "xenohealth0" return var/amount = round(health * 100 / maxHealth, 10) diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index ed2bcdc0639..5279315aa8b 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -10,3 +10,7 @@ layer = ABOVE_TURF_LAYER mouse_opacity = MOUSE_OPACITY_TRANSPARENT icon = 'icons/turf/decals.dmi' + +/obj/effect/turf_decal/ex_act(severity) + if(prob(severity * 0.3)) + qdel(src) diff --git a/code/game/objects/effects/decals/turfdecals/markings.dm b/code/game/objects/effects/decals/turfdecals/markings.dm index ea9acc99c95..671c2c5241a 100644 --- a/code/game/objects/effects/decals/turfdecals/markings.dm +++ b/code/game/objects/effects/decals/turfdecals/markings.dm @@ -2,10 +2,6 @@ icon = 'icons/turf/decals.dmi' icon_state = "whitedecal" -/obj/effect/turf_decal/tile/ex_act(severity) - if(prob(severity * 0.3)) - qdel(src) - /obj/effect/turf_decal/tile/full icon_state = "floor_large" diff --git a/code/game/objects/effects/effect.dm b/code/game/objects/effects/effect.dm index b650a43e53d..bb1d9a765d5 100644 --- a/code/game/objects/effects/effect.dm +++ b/code/game/objects/effects/effect.dm @@ -5,3 +5,6 @@ /obj/effect/add_debris_element() //they're not hittable, and prevents recursions return + +/obj/effect/ex_act() + return diff --git a/code/game/objects/effects/effect_system/foam.dm b/code/game/objects/effects/effect_system/foam.dm index 06d461d9671..1e3822c1f61 100644 --- a/code/game/objects/effects/effect_system/foam.dm +++ b/code/game/objects/effects/effect_system/foam.dm @@ -101,7 +101,7 @@ // foam disolves when heated // except metal foams -/obj/effect/particle_effect/foam/fire_act(burn_level) +/obj/effect/particle_effect/foam/fire_act(burn_level, flame_color) if(!(foam_flags & METAL_FOAM|RAZOR_FOAM) && prob(min(burn_level * 3, 100))) kill_foam() @@ -173,6 +173,6 @@ SMOOTH_GROUP_FOAM_WALL, ) -/obj/structure/foamedmetal/fire_act(burn_level) +/obj/structure/foamedmetal/fire_act(burn_level, flame_color) take_damage(burn_level, BURN, FIRE) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 4bd51f895a0..88f8bb5052d 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -152,16 +152,16 @@ if(ishuman(user)) . += span_danger("It's a laser to designate CAS targets, get away from it!") -/obj/effect/overlay/temp/laser_target/OB //This is a subtype of CAS so that CIC gets cameras on the lase +/obj/effect/overlay/temp/laser_target/ob //This is a subtype of CAS so that CIC gets cameras on the lase icon_state = "laser_target2" lasertype = LASER_TYPE_OB -/obj/effect/overlay/temp/laser_target/OB/Initialize(mapload, effect_duration, named, assigned_squad) +/obj/effect/overlay/temp/laser_target/ob/Initialize(mapload, effect_duration, named, assigned_squad) . = ..() linked_cam = new(src, name) GLOB.active_laser_targets += src -/obj/effect/overlay/temp/laser_target/OB/Destroy() +/obj/effect/overlay/temp/laser_target/ob/Destroy() GLOB.active_laser_targets -= src return ..() diff --git a/code/game/objects/explosion_recursive.dm b/code/game/objects/explosion_recursive.dm index 68a657093fd..a4915763a7e 100644 --- a/code/game/objects/explosion_recursive.dm +++ b/code/game/objects/explosion_recursive.dm @@ -73,10 +73,13 @@ explosion resistance exactly as much as their health epicenter.explosion_spread(src, power, null) - spawn(2) //just in case something goes wrong - if(explosion_in_progress) - explosion_damage() - QDEL_IN(src, 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(explosion_delete)), 0.2 SECONDS) + +/obj/effect/explosion/proc/explosion_delete() + if(!explosion_in_progress) + return + explosion_damage() + QDEL_IN(src, 2 SECONDS) //direction is the direction that the spread took to come to this tile. So it is pointing in the main blast direction - meaning where this tile should spread most of it's force. /turf/proc/explosion_spread(obj/effect/explosion/Controller, power, direction) @@ -97,11 +100,7 @@ explosion resistance exactly as much as their health var/obj/effect/step_trigger/teleporter/our_tp = our_atom var/turf/our_turf = locate(our_tp.x + our_tp.teleport_x, our_tp.y + our_tp.teleport_y, our_tp.z) if(our_turf) - spawn(0) - our_turf.explosion_spread(Controller, power, direction) - Controller.active_spread_num-- - if(Controller.active_spread_num <= 0 && Controller.explosion_in_progress) - Controller.explosion_damage() + INVOKE_ASYNC(our_turf, PROC_REF(explosion_step)) return if(istype(our_atom, /obj/structure/ladder)) //check for ladders @@ -116,81 +115,85 @@ explosion resistance exactly as much as their health Controller.reflected_power += max(0, min(resistance, power)) power -= resistance + INVOKE_ASYNC(src, PROC_REF(explosion_spread_power), Controller, power, direction, our_ladder) + +/turf/proc/explosion_spread_power(obj/effect/explosion/Controller, power, direction, obj/structure/ladder/our_ladder) + //spread in each ordinal direction + var/direction_angle = dir2angle(direction) + for(var/spread_direction in GLOB.alldirs) + var/spread_power = power + + if(direction) //false if, for example, this turf was the explosion source + var/spread_direction_angle = dir2angle(spread_direction) + + var/angle = 180 - abs( abs( direction_angle - spread_direction_angle ) - 180 ) // the angle difference between the spread direction and initial direction + + switch(angle) //this reduces power when the explosion is going around corners + if(0) + EMPTY_BLOCK_GUARD //no change + if(45) + if(spread_power >= 0) + spread_power *= 0.75 + else + spread_power *= 1.25 + if(90) + if(spread_power >= 0) + spread_power *= 0.50 + else + spread_power *= 1.5 + else //turns out angles greater than 90 degrees almost never happen. This bit also prevents trying to spread backwards + continue + + switch(spread_direction) + if(NORTH, SOUTH, EAST, WEST) + spread_power -= Controller.falloff + else + spread_power -= Controller.falloff * 1.414 //diagonal spreading + + if(spread_power <= Controller.minimum_spread_power) + continue + + var/turf/T = get_step(src, spread_direction) - //spawn(0) is important because it paces the explosion in an expanding circle, rather than a series of squiggly lines constantly checking overlap. Reduces lag by a lot. Note that INVOKE_ASYNC doesn't have the same effect as spawn(0) for this purpose. - spawn(0) - - //spread in each ordinal direction - var/direction_angle = dir2angle(direction) - for(var/spread_direction in GLOB.alldirs) - var/spread_power = power - - if(direction) //false if, for example, this turf was the explosion source - var/spread_direction_angle = dir2angle(spread_direction) - - var/angle = 180 - abs( abs( direction_angle - spread_direction_angle ) - 180 ) // the angle difference between the spread direction and initial direction - - switch(angle) //this reduces power when the explosion is going around corners - if (0) - EMPTY_BLOCK_GUARD //no change - if (45) - if(spread_power >= 0) - spread_power *= 0.75 - else - spread_power *= 1.25 - if (90) - if(spread_power >= 0) - spread_power *= 0.50 - else - spread_power *= 1.5 - else //turns out angles greater than 90 degrees almost never happen. This bit also prevents trying to spread backwards - continue - - switch(spread_direction) - if(NORTH,SOUTH,EAST,WEST) - spread_power -= Controller.falloff - else - spread_power -= Controller.falloff * 1.414 //diagonal spreading - - if (spread_power <= Controller.minimum_spread_power) - continue - - var/turf/T = get_step(src, spread_direction) - - if(!T) //prevents trying to spread into "null" (edge of the map?) - continue - - T.explosion_spread(Controller, spread_power, spread_direction) - - - //spreading up/down ladders - if(our_ladder) - var/ladder_spread_power - if(direction) - if(power >= 0) - ladder_spread_power = power * 0.75 - Controller.falloff - else - ladder_spread_power = power * 1.25 - Controller.falloff + if(!T) //prevents trying to spread into "null" (edge of the map?) + continue + + T.explosion_spread(Controller, spread_power, spread_direction) + + //spreading up/down ladders + if(our_ladder) + var/ladder_spread_power + if(direction) + if(power >= 0) + ladder_spread_power = power * 0.75 - Controller.falloff else - if(power >= 0) - ladder_spread_power = power * 0.5 - Controller.falloff - else - ladder_spread_power = power * 1.5 - Controller.falloff - - if(ladder_spread_power > Controller.minimum_spread_power) - if(our_ladder.up) - var/turf/T_up = get_turf(our_ladder.up) - if(T_up) - T_up.explosion_spread(Controller, ladder_spread_power, null) - if(our_ladder.down) - var/turf/T_down = get_turf(our_ladder.down) - if(T_down) - T_down.explosion_spread(Controller, ladder_spread_power, null) - - //if this is the last explosion spread, initiate explosion damage - Controller.active_spread_num-- - if(Controller.active_spread_num <= 0 && Controller.explosion_in_progress) - Controller.explosion_damage() + ladder_spread_power = power * 1.25 - Controller.falloff + else + if(power >= 0) + ladder_spread_power = power * 0.5 - Controller.falloff + else + ladder_spread_power = power * 1.5 - Controller.falloff + + if(ladder_spread_power > Controller.minimum_spread_power) + if(our_ladder.up) + var/turf/T_up = get_turf(our_ladder.up) + if(T_up) + T_up.explosion_spread(Controller, ladder_spread_power, null) + if(our_ladder.down) + var/turf/T_down = get_turf(our_ladder.down) + if(T_down) + T_down.explosion_spread(Controller, ladder_spread_power, null) + + //if this is the last explosion spread, initiate explosion damage + Controller.active_spread_num-- + if(Controller.active_spread_num <= 0 && Controller.explosion_in_progress) + Controller.explosion_damage() + +/turf/proc/explosion_step(obj/effect/explosion/Controller, power, direction) + explosion_spread(Controller, power, direction) + Controller.active_spread_num-- + if(Controller.active_spread_num <= 0 && Controller.explosion_in_progress) + Controller.explosion_damage() /obj/effect/explosion/proc/explosion_damage() //This step applies the ex_act effects for the explosion explosion_in_progress = 0 @@ -223,20 +226,18 @@ explosion resistance exactly as much as their health our_turf = locate(x, y, z) for(var/atom/our_atom in our_turf) - spawn(0) - log_game("Explosion with power of [power] and falloff of [falloff] at [AREACOORD(our_turf)]!") - if(is_mainship_level(our_turf.z)) - message_admins("Explosion with power of [power] and falloff of [falloff] in [ADMIN_VERBOSEJMP(our_turf)]!") - - our_atom.ex_act(severity, direction) - + INVOKE_ASYNC(src, PROC_REF(explosion_damage_logging), our_atom, severity, direction) tiles_processed++ if(tiles_processed >= increment) tiles_processed = 0 sleep(0.1 SECONDS) + QDEL_IN(src, 0.8 SECONDS) - spawn(8) - qdel(src) +/obj/effect/explosion/proc/explosion_damage_logging(atom/our_atom, severity, direction) + log_game("Explosion with power of [power] and falloff of [falloff] at [AREACOORD(src)]!") + if(is_mainship_level(z)) + message_admins("Explosion with power of [power] and falloff of [falloff] in [ADMIN_VERBOSEJMP(src)]!") + our_atom.ex_act(severity, direction) /atom/proc/get_explosion_resistance() return 0 @@ -260,18 +261,18 @@ explosion resistance exactly as much as their health if(!direction) direction = pick(GLOB.alldirs) - var/range = min(round(severity * 0.2, 1), 14) + var/range = min(round(severity * 0.07, 1), 14) if(!direction) range = round(range * 0.5, 1) if(range < 1) return - var/speed = max(range * 2.5, 4) + var/speed = max(range, 3) var/atom/target = get_ranged_target_turf(src, direction, range) if(range >= 2) - var/scatter = range / 4 * scatter_multiplier + var/scatter = range * 0.25 * scatter_multiplier var/scatter_x = rand(-scatter, scatter) var/scatter_y = rand(-scatter, scatter) target = locate(target.x + round(scatter_x, 1), target.y + round(scatter_y, 1), target.z) //Locate an adjacent turf. diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4bb47694b0a..728c761485b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -955,7 +955,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. A.update_button_icon() /obj/item/proc/extinguish(atom/target, mob/user) - if (reagents.total_volume < 1) + if(reagents.total_volume < 1) to_chat(user, span_warning("\The [src]'s water reserves are empty.")) return @@ -964,91 +964,95 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. playsound(user.loc, 'sound/effects/extinguish.ogg', 52, 1, 7) - var/direction = get_dir(user,target) - - if(user.buckled && isobj(user.buckled) && !user.buckled.anchored ) - spawn(0) - var/obj/structure/bed/chair/C = null - if(istype(user.buckled, /obj/structure/bed/chair)) - C = user.buckled - var/obj/B = user.buckled - var/movementdirection = REVERSE_DIR(direction) - if(C) - C.propelled = 4 - B.Move(get_step(user,movementdirection), movementdirection) - sleep(0.1 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - if(C) - C.propelled = 3 - sleep(0.1 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - sleep(0.1 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - if(C) - C.propelled = 2 - sleep(0.2 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - if(C) - C.propelled = 1 - sleep(0.2 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - if(C) - C.propelled = 0 - sleep(0.3 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - sleep(0.3 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) - sleep(0.3 SECONDS) - B.Move(get_step(user,movementdirection), movementdirection) + var/direction = get_dir(user, target) - var/turf/T = get_turf(target) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) + if(user.buckled && isobj(user.buckled) && !user.buckled.anchored) + INVOKE_ASYNC(src, PROC_REF(propelle), target, user, direction) - var/list/the_targets = list(T,T1,T2) - - for(var/a=0, a<7, a++) - spawn(0) - var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water( get_turf(user) ) - var/turf/my_target = pick(the_targets) - var/datum/reagents/R = new/datum/reagents(5) - if(!W) - return - W.reagents = R - R.my_atom = WEAKREF(W) - if(!W || !src) - return - reagents.trans_to(W,1) - for(var/b=0, b<7, b++) - step_towards(W,my_target) - if(!(W?.reagents)) - return - W.reagents.reaction(get_turf(W)) - for(var/atom/atm in get_turf(W)) - if(!W) - return - if(!W.reagents) - break - W.reagents.reaction(atm) - if(isfire(atm)) - var/obj/fire/FF = atm - FF.set_fire(FF.burn_ticks - EXTINGUISH_AMOUNT) - continue - if(isliving(atm)) //For extinguishing mobs on fire - var/mob/living/M = atm - M.ExtinguishMob() - for(var/obj/item/clothing/mask/cigarette/C in M.contents) - if(C.item_state == C.icon_on) - C.die() - if(W.loc == my_target) - break - sleep(0.2 SECONDS) - qdel(W) + for(var/a = 0, a < 7, a++) + INVOKE_ASYNC(src, PROC_REF(extinguish_stage_two), target, user, direction) if(isspaceturf(user.loc)) user.inertia_dir = get_dir(target, user) step(user, user.inertia_dir) +/obj/item/proc/propelle(atom/target, mob/user, direction) + var/obj/structure/bed/chair/C = null + if(istype(user.buckled, /obj/structure/bed/chair)) + C = user.buckled + var/obj/B = user.buckled + var/movementdirection = REVERSE_DIR(direction) + if(C) + C.propelled = 4 + B.Move(get_step(user, movementdirection), movementdirection) + sleep(0.1 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + if(C) + C.propelled = 3 + sleep(0.1 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + sleep(0.1 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + if(C) + C.propelled = 2 + sleep(0.2 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + if(C) + C.propelled = 1 + sleep(0.2 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + if(C) + C.propelled = 0 + sleep(0.3 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + sleep(0.3 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + sleep(0.3 SECONDS) + B.Move(get_step(user, movementdirection), movementdirection) + +/obj/item/proc/extinguish_stage_two(atom/target, mob/user, direction) + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T, turn(direction, 90)) + var/turf/T2 = get_step(T, turn(direction, -90)) + + var/list/the_targets = list(T, T1, T2) + + var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water( get_turf(user) ) + var/turf/my_target = pick(the_targets) + var/datum/reagents/R = new/datum/reagents(5) + if(!W) + return + W.reagents = R + R.my_atom = WEAKREF(W) + if(!W || !src) + return + reagents.trans_to(W, 1) + for(var/b = 0, b < 7, b++) + step_towards(W,my_target) + if(!(W?.reagents)) + return + W.reagents.reaction(get_turf(W)) + for(var/atom/atm in get_turf(W)) + if(!W) + return + if(!W.reagents) + break + W.reagents.reaction(atm) + if(isfire(atm)) + var/obj/fire/FF = atm + FF.set_fire(FF.burn_ticks - EXTINGUISH_AMOUNT) + continue + if(isliving(atm)) //For extinguishing mobs on fire + var/mob/living/M = atm + M.ExtinguishMob() + for(var/obj/item/clothing/mask/cigarette/C in M.contents) + if(C.item_state != C.icon_on) + continue + C.die() + if(W.loc == my_target) + break + sleep(0.2 SECONDS) + qdel(W) // Called when a mob tries to use the item as a tool. // Handles most checks. @@ -1265,8 +1269,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. basic_spin_trick(arglist(arguments)) if(7) if(istype(double)) - spawn(0) - double.throw_catch_trick(user) + INVOKE_ASYNC(double, PROC_REF(throw_catch_trick), user) throw_catch_trick(user) else throw_catch_trick(user) diff --git a/code/game/objects/items/autopsy_scanner.dm b/code/game/objects/items/autopsy_scanner.dm index f4231813c6e..5a4ef605680 100644 --- a/code/game/objects/items/autopsy_scanner.dm +++ b/code/game/objects/items/autopsy_scanner.dm @@ -1,6 +1,7 @@ /obj/item/autopsy_scanner name = "autopsy scanner" desc = "Extracts information on wounds." + icon = 'icons/obj/items/surgery_tools.dmi' icon_state = "autopsy_scanner" flags_atom = CONDUCT w_class = WEIGHT_CLASS_SMALL diff --git a/code/game/objects/items/binoculars.dm b/code/game/objects/items/binoculars.dm index cc296f64e84..302d8b1e588 100644 --- a/code/game/objects/items/binoculars.dm +++ b/code/game/objects/items/binoculars.dm @@ -289,7 +289,7 @@ if(!targ_area) to_chat(user, "[icon2html(src, user)] [span_warning("No target detected!")]") else - var/obj/effect/overlay/temp/laser_target/OB/OBL = new (TU, 0, laz_name, S) + var/obj/effect/overlay/temp/laser_target/ob/OBL = new (TU, 0, laz_name, S) laser = OBL playsound(src, 'sound/effects/binoctarget.ogg', 35) if(!do_after(user, 15 SECONDS, NONE, user, BUSY_ICON_GENERIC)) diff --git a/code/game/objects/items/blink_drive.dm b/code/game/objects/items/blink_drive.dm index 4d5f031511e..69f65e79c99 100644 --- a/code/game/objects/items/blink_drive.dm +++ b/code/game/objects/items/blink_drive.dm @@ -19,14 +19,18 @@ light_color = LIGHT_COLOR_BLUE ///Number of teleport charges you currently have var/charges = 3 - ///True if you can use shift click/middle click to use it - var/selected = FALSE ///The timer for recharging the drive var/charge_timer ///The mob wearing the blink drive. Needed for item updates. var/mob/equipped_user + ///Controlling action + var/datum/action/ability/activable/item_toggle/blink_drive/blink_action COOLDOWN_DECLARE(blink_stability_cooldown) +/obj/item/blink_drive/Initialize(mapload) + . = ..() + blink_action = new(src) + /obj/item/blink_drive/update_icon() . = ..() equipped_user?.update_inv_back() @@ -52,68 +56,28 @@ . = ..() equipped_user = user if(slot == SLOT_BACK) - RegisterSignal(user, COMSIG_MOB_CLICK_ALT_RIGHT, PROC_REF(can_use)) - var/datum/action/item_action/toggle/action = new(src) - action.give_action(user) + blink_action.give_action(user) /obj/item/blink_drive/dropped(mob/user) . = ..() - UnregisterSignal(user, list(COMSIG_MOB_CLICK_ALT_RIGHT, COMSIG_MOB_MIDDLE_CLICK)) - UnregisterSignal(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE) - selected = FALSE + blink_action.remove_action(user) equipped_user = null - LAZYCLEARLIST(actions) -/obj/item/blink_drive/ui_action_click(mob/user, datum/action/item_action/action) - if(selected) - UnregisterSignal(user, COMSIG_MOB_MIDDLE_CLICK) - action.set_toggle(FALSE) - UnregisterSignal(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE) - else - RegisterSignal(user, COMSIG_MOB_MIDDLE_CLICK, PROC_REF(can_use)) - action.set_toggle(TRUE) - SEND_SIGNAL(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE, user) - RegisterSignal(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE, PROC_REF(unselect)) - selected = !selected /obj/item/blink_drive/apply_custom(mutable_appearance/standing, inhands, icon_used, state_used) . = ..() var/mutable_appearance/emissive_overlay = emissive_appearance(icon_used, "[state_used]_emissive") standing.overlays.Add(emissive_overlay) -///Signal handler for making it impossible to use middleclick to use the blink drive -/obj/item/blink_drive/proc/unselect(datum/source, mob/user) - SIGNAL_HANDLER - if(!selected) - return - selected = FALSE - UnregisterSignal(user, COMSIG_MOB_MIDDLE_CLICK) - UnregisterSignal(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE) - - for(var/action in user.actions) - if(!istype(action, /datum/action/item_action)) - continue - var/datum/action/item_action/iaction = action - if(iaction?.holder_item == src) - iaction.set_toggle(FALSE) - -///Check if we can use the blink drive and give feedback to the user -/obj/item/blink_drive/proc/can_use(datum/source, atom/A) - SIGNAL_HANDLER - var/mob/living/carbon/human/human_user = usr - if(human_user.incapacitated() || human_user.lying_angle) - return - if(is_mainship_level(human_user.z)) - human_user.balloon_alert(human_user, "can't use here") - return - if(charges <= 0) - human_user.balloon_alert(human_user, "no charge") - playsound(src, 'sound/items/blink_empty.ogg', 25, 1) - return - INVOKE_ASYNC(src, PROC_REF(teleport), A, human_user) +/obj/item/blink_drive/ui_action_click(mob/user, datum/action/item_action/action, target) + teleport(target, user) ///Handles the actual teleportation /obj/item/blink_drive/proc/teleport(atom/A, mob/user) + if(charges <= 0) + user.balloon_alert(user, "no charge") + playsound(src, 'sound/items/blink_empty.ogg', 25, 1) + return var/turf/target_turf = get_turf(A) if(target_turf == user.loc) @@ -219,3 +183,19 @@ traits += "Shared use:
If the user has grabbed another mob when activating the drive, the grabbed mob will be teleported with them.
" . += jointext(traits, "
") + +/datum/action/ability/activable/item_toggle/blink_drive + name = "Use Blink Drive" + action_icon_state = "axe_sweep" + desc = "Teleport a short distance instantly." + keybind_flags = ABILITY_USE_STAGGERED|ABILITY_USE_BUSY + keybinding_signals = list(KEYBINDING_NORMAL = COMSIG_ITEM_TOGGLE_BLINKDRIVE) + +/datum/action/ability/activable/item_toggle/blink_drive/can_use_ability(silent, override_flags, selecting) + var/mob/living/carbon/carbon_owner = owner + if(carbon_owner.incapacitated() || carbon_owner.lying_angle) + return FALSE + if(is_mainship_level(carbon_owner.z)) + carbon_owner.balloon_alert(carbon_owner, "can't use here") + return FALSE + return ..() diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 6dc713c188a..34f5077f0e6 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -4,8 +4,8 @@ desc = "A kit designed for customizing various pieces of armor and clothing. Comes with facepaint!" icon = 'icons/obj/items/cosmetics.dmi' icon_state = "camo" - var/colour = "green" w_class = WEIGHT_CLASS_TINY + var/colour = "green" var/uses = 100 /obj/item/facepaint/green @@ -46,22 +46,21 @@ return if(H == user) paint_face(H, user) - return 1 + return TRUE else to_chat(user, span_notice("You attempt to apply [src] on [H]...")) to_chat(H, span_notice("[user] is trying to apply [src] on your face...")) - if(tgui_alert(H, "Will you allow [user] to paint your face?", null, list("Sure","No")) == "Sure") - if( user && loc == user && (user in range(1,H)) ) //Have to be close and hold the thing. - paint_face(H, user) - return 1 + if(tgui_alert(H, "Will you allow [user] to paint your face?", null, list("Sure","No")) != "Sure") + return + if(user && loc == user && (user in range(1, H))) //Have to be close and hold the thing. + paint_face(H, user) + return TRUE to_chat(user, span_warning("Foiled!")) - /obj/item/facepaint/proc/paint_face(mob/living/carbon/human/H, mob/user) if(!H || !user) return //In case they're passed as null. - user.visible_message(span_notice("[user] carefully applies [src] on [H]'s face."), \ - span_notice("You apply [src].")) + user.visible_message(span_notice("[user] carefully applies [src] on [H]'s face."), span_notice("You apply [src].")) H.lip_style = colour H.alpha = max(0, initial(H.alpha) - 1) // decreases your alpha by 1 H.update_body() diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm index e37fedea0c1..734b097ed05 100644 --- a/code/game/objects/items/explosives/grenades/marines.dm +++ b/code/game/objects/items/explosives/grenades/marines.dm @@ -312,7 +312,7 @@ icon = 'icons/obj/items/grenade.dmi' icon_state = "ags_grenade" item_state = "ags_grenade" - det_time = 2 SECONDS + det_time = 1 SECONDS power = 80 falloff = 20 overlay_type = "yellow" @@ -407,7 +407,7 @@ name = "\improper AGLS-37 SCDP smoke grenade" desc = "A small tiny smart grenade, it is about to blow up in your face, unless you found it inert. Otherwise a pretty normal grenade, other than it is somehow in a primeable state." icon_state = "ags_cloak" - smokeradius = 4 + smokeradius = 3 overlay_type = "green" /obj/item/explosive/grenade/smokebomb/drain @@ -422,12 +422,23 @@ smoketype = /datum/effect_system/smoke_spread/plasmaloss overlay_type = "purple" +/obj/item/explosive/grenade/sticky/cloaker/tangle + name = "\improper M45-T Tanglefoot grenade" + desc = "Capsule based grenade that sticks to sufficiently hard surfaces, causing a trail of air combustable gel to form. This one creates tanglefoot smoke! It is set to detonate in 5 seconds." + icon_state = "grenade_sticky_pgas" + item_state = "grenade_sticky_pgas" + det_time = 5 SECONDS + self_sticky = TRUE + overlay_type = "purple" + smoketype = /datum/effect_system/smoke_spread/plasmaloss + smoke_duration = 3 + /obj/item/explosive/grenade/smokebomb/drain/agls name = "\improper AGLS-T smoke grenade" desc = "A small tiny smart grenade, it is about to blow up in your face, unless you found it inert. Otherwise a pretty normal grenade, other than it is somehow in a primeable state." icon_state = "ags_pgas" - det_time = 3 SECONDS - smokeradius = 4 + det_time = 1 SECONDS + smokeradius = 2 overlay_type = "purple" /obj/item/explosive/grenade/phosphorus @@ -506,8 +517,8 @@ light_color = LIGHT_COLOR_FLARE G_throw_sound = null var/fuel = 0 - var/lower_fuel_limit = 450 - var/upper_fuel_limit = 750 + var/lower_fuel_limit = 60 + var/upper_fuel_limit = 75 /obj/item/explosive/grenade/flare/dissolvability(acid_strength) return 2 diff --git a/code/game/objects/items/flashlight.dm b/code/game/objects/items/flashlight.dm index c5c1137cd34..a1dc5d91768 100644 --- a/code/game/objects/items/flashlight.dm +++ b/code/game/objects/items/flashlight.dm @@ -209,4 +209,5 @@ raillight_compatible = FALSE /obj/item/flashlight/lantern/turned_on + icon_state = "lantern-on" light_on = TRUE diff --git a/code/game/objects/items/jetpack.dm b/code/game/objects/items/jetpack.dm index 2ae8a9f9396..10f1f7ed39c 100644 --- a/code/game/objects/items/jetpack.dm +++ b/code/game/objects/items/jetpack.dm @@ -26,11 +26,12 @@ var/speed = 1 ///True when jetpack has flame overlay var/lit = FALSE - ///True if you can use shift click/middle click to use it - var/selected = FALSE + ///Controlling action + var/datum/action/ability/activable/item_toggle/jetpack/toggle_action /obj/item/jetpack_marine/Initialize(mapload) . = ..() + toggle_action = new(src) update_icon() /obj/item/jetpack_marine/examine(mob/user, distance, infix, suffix) @@ -45,40 +46,14 @@ /obj/item/jetpack_marine/equipped(mob/user, slot) . = ..() if(slot == SLOT_BACK) - var/datum/action/item_action/toggle/action = new(src) - action.give_action(user) + toggle_action.give_action(user) /obj/item/jetpack_marine/dropped(mob/user) . = ..() - UnregisterSignal(user, list(COMSIG_MOB_MIDDLE_CLICK, COMSIG_MOB_CLICK_ALT_RIGHT, COMSIG_ITEM_EXCLUSIVE_TOGGLE)) - selected = FALSE - LAZYCLEARLIST(actions) - -/obj/item/jetpack_marine/ui_action_click(mob/user, datum/action/item_action/action) - if(selected) - UnregisterSignal(user, list(COMSIG_MOB_MIDDLE_CLICK, COMSIG_MOB_CLICK_ALT_RIGHT, COMSIG_ITEM_EXCLUSIVE_TOGGLE)) - action.set_toggle(FALSE) - else - RegisterSignals(user, list(COMSIG_MOB_MIDDLE_CLICK, COMSIG_MOB_CLICK_ALT_RIGHT), PROC_REF(can_use_jetpack)) - SEND_SIGNAL(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE, user) - RegisterSignal(user, COMSIG_ITEM_EXCLUSIVE_TOGGLE, PROC_REF(unselect)) - action.set_toggle(TRUE) - selected = !selected - -///Signal handler for making it impossible to use middleclick to use the jetpack -/obj/item/jetpack_marine/proc/unselect(datum/source, mob/user) - SIGNAL_HANDLER - if(!selected) - return - selected = FALSE - UnregisterSignal(user, list(COMSIG_MOB_MIDDLE_CLICK, COMSIG_MOB_CLICK_ALT_RIGHT, COMSIG_ITEM_EXCLUSIVE_TOGGLE)) - for(var/action in user.actions) - if (!istype(action, /datum/action/item_action)) - continue - var/datum/action/item_action/iaction = action - if(iaction?.holder_item == src) - iaction.set_toggle(FALSE) + toggle_action.remove_action(user) +/obj/item/jetpack_marine/ui_action_click(mob/user, datum/action/item_action/action, target) + use_jetpack(target, user) ///remove the flame overlay /obj/item/jetpack_marine/proc/reset_flame(mob/living/carbon/human/human_user) @@ -122,21 +97,6 @@ if(1.2 to INFINITY)//heavy armor with shield and tyr mk2 return 2 -///Check if we can use the jetpack and give feedback to the users -/obj/item/jetpack_marine/proc/can_use_jetpack(datum/source, atom/A) - SIGNAL_HANDLER - var/mob/living/carbon/human/human_user = usr - if(human_user.incapacitated() || human_user.lying_angle) - return - var/time_left = S_TIMER_COOLDOWN_TIMELEFT(src, COOLDOWN_JETPACK) - if(time_left) - balloon_alert(human_user, "[time_left * 0.1] seconds") - return - if(fuel_left < FUEL_USE) - balloon_alert(human_user, "No fuel") - return - INVOKE_ASYNC(src, PROC_REF(use_jetpack), A, human_user) - /obj/item/jetpack_marine/update_overlays() . = ..() switch(fuel_indicator) @@ -206,6 +166,28 @@ balloon_alert(user, "Refilled") update_icon() +/datum/action/ability/activable/item_toggle/jetpack + name = "Use jetpack" + action_icon_state = "axe_sweep" + desc = "Briefly fly using your jetpack." + keybind_flags = ABILITY_USE_STAGGERED|ABILITY_USE_BUSY + keybinding_signals = list(KEYBINDING_NORMAL = COMSIG_ITEM_TOGGLE_JETPACK) + use_state_flags = ABILITY_USE_STAGGERED + +/datum/action/ability/activable/item_toggle/jetpack/New(Target, obj/item/holder) + . = ..() + var/obj/item/jetpack_marine/jetpack = Target + cooldown_duration = jetpack.cooldown_time + +/datum/action/ability/activable/item_toggle/jetpack/can_use_ability(silent, override_flags, selecting) + var/mob/living/carbon/carbon_owner = owner + if(carbon_owner.incapacitated() || carbon_owner.lying_angle) + return FALSE + var/obj/item/jetpack_marine/jetpack = holder_item + if(jetpack.fuel_left < FUEL_USE) + carbon_owner.balloon_alert(carbon_owner, "No fuel") + return + return ..() /obj/item/jetpack_marine/heavy name = "heavy lift jetpack" diff --git a/code/game/objects/items/power_cells.dm b/code/game/objects/items/power_cells.dm index 27dd09a990a..1bfdc6d7f42 100644 --- a/code/game/objects/items/power_cells.dm +++ b/code/game/objects/items/power_cells.dm @@ -90,9 +90,11 @@ var/mob/living/carbon/C = user C.throw_mode_on() overlays += new/obj/effect/overlay/danger - spawn(rand(3,50)) - spark_system.start(src) - explode() + addtimer(CALLBACK(src, PROC_REF(delayed_explosion), spark_system), rand(3, 50)) + +/obj/item/cell/proc/delayed_explosion(datum/effect_system/spark_spread/spark_system) + spark_system.start(src) + explode() /obj/item/cell/attackby(obj/item/I, mob/user, params) . = ..() diff --git a/code/game/objects/items/reagent_containers/food/snacks.dm b/code/game/objects/items/reagent_containers/food/snacks.dm index 040a474a61f..0b941ab097e 100644 --- a/code/game/objects/items/reagent_containers/food/snacks.dm +++ b/code/game/objects/items/reagent_containers/food/snacks.dm @@ -545,21 +545,25 @@ icon_state = "donkpocket" filling_color = "#DEDEAB" list_reagents = list(/datum/reagent/consumable/nutriment = 4) - var/warm = 0 tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) + var/warm = FALSE /obj/item/reagent_containers/food/snacks/donkpocket/proc/cooltime() - if(warm) - spawn( 4200 ) - if(!gc_destroyed) //not cdel'd - warm = 0 - reagents.del_reagent(/datum/reagent/medicine/tricordrazine) - name = "donk-pocket" + if(!warm) + return + addtimer(CALLBACK(src, PROC_REF(cool_down)), 7 MINUTES) + +/obj/item/reagent_containers/food/snacks/donkpocket/proc/cool_down() + if(QDELETED(src)) + return + warm = FALSE + reagents.del_reagent(/datum/reagent/medicine/tricordrazine) + name = "donk-pocket" /obj/item/reagent_containers/food/snacks/human + filling_color = "#D63C3C" var/hname = "" var/job = null - filling_color = "#D63C3C" /obj/item/reagent_containers/food/snacks/omelette name = "Omelette Du Fromage" diff --git a/code/game/objects/items/reagent_containers/pill.dm b/code/game/objects/items/reagent_containers/pill.dm index c9ec3fa405d..1f82d994d15 100644 --- a/code/game/objects/items/reagent_containers/pill.dm +++ b/code/game/objects/items/reagent_containers/pill.dm @@ -14,8 +14,9 @@ /obj/item/reagent_containers/pill/Initialize(mapload) . = ..() - if(icon_state == "pill1") - icon_state = pill_id ? GLOB.randomized_pill_icons[pill_id] : pick(GLOB.randomized_pill_icons) + if(icon_state != "pill1") + return + icon_state = pill_id ? GLOB.randomized_pill_icons[pill_id] : pick(GLOB.randomized_pill_icons) /obj/item/reagent_containers/pill/attack_self(mob/user) . = ..() diff --git a/code/game/objects/items/reagent_containers/spray.dm b/code/game/objects/items/reagent_containers/spray.dm index ddec7099e39..218ef32af4b 100644 --- a/code/game/objects/items/reagent_containers/spray.dm +++ b/code/game/objects/items/reagent_containers/spray.dm @@ -58,26 +58,26 @@ /obj/item/reagent_containers/spray/proc/Spray_at(atom/A) var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src)) D.create_reagents(amount_per_transfer_from_this) - reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_size) + reagents.trans_to(D, amount_per_transfer_from_this, 1 / spray_size) D.color = mix_color_from_reagents(D.reagents.reagent_list) - var/turf/A_turf = get_turf(A)//BS12 + INVOKE_ASYNC(src, PROC_REF(spray_step), A, D) +/obj/item/reagent_containers/spray/proc/spray_step(atom/our_atom, obj/effect/decal/chempuff/our_decal) + var/turf/A_turf = get_turf(our_atom)//BS12 var/spray_dist = spray_size - spawn(0) - for(var/i=0, i= reagents.maximum_volume && mode==SYRINGE_INJECT) - mode = SYRINGE_DRAW - update_icon() + if(!do_after(user, 0.5 SECONDS, NONE, target, BUSY_ICON_DANGER, BUSY_ICON_DANGER)) + return + var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + if(iscarbon(target) && locate(/datum/reagent/blood) in reagents.reagent_list) + var/mob/living/carbon/C = target + C.inject_blood(src, amount_per_transfer_from_this) + else + reagents.reaction(target, INJECT) + trans = reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, span_notice("You inject [trans] units of the solution. The syringe now contains [reagents.total_volume] units.")) + if(reagents.total_volume >= reagents.maximum_volume && mode == SYRINGE_INJECT) + mode = SYRINGE_DRAW + update_icon() //////////////////////////////////////////////////////////////////////////////// /// Syringes. END diff --git a/code/game/objects/items/scanners.dm b/code/game/objects/items/scanners.dm index a6b76dd3a19..05c2ed909d8 100644 --- a/code/game/objects/items/scanners.dm +++ b/code/game/objects/items/scanners.dm @@ -53,13 +53,15 @@ REAGENT SCANNER if(O.invisibility == INVISIBILITY_MAXIMUM) O.invisibility = 0 O.alpha = 128 - spawn(10) - if(O && !O.gc_destroyed) - var/turf/U = O.loc - if(U.intact_tile) - O.invisibility = INVISIBILITY_MAXIMUM - O.alpha = 255 + addtimer(CALLBACK(src, PROC_REF(scan_for_items), O), 1 SECONDS) +/obj/item/t_scanner/proc/scan_for_items(obj/our_object) + if(our_object.gc_destroyed) + return + var/turf/U = our_object.loc + if(U.intact_tile) + our_object.invisibility = INVISIBILITY_MAXIMUM + our_object.alpha = 255 /obj/item/healthanalyzer name = "\improper HF2 health analyzer" diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 7c440bcb3f5..301d98394df 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -111,7 +111,7 @@ //Step two - washing..... it's actually in washing machine code. //Step three - drying -/obj/item/stack/sheet/wetleather/fire_act(burn_level) +/obj/item/stack/sheet/wetleather/fire_act(burn_level, flame_color) . = ..() if(!wetness) return diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index e0885293991..35305327f8a 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -439,6 +439,17 @@ /obj/item/reagent_containers/food/snacks, ) +/obj/item/storage/belt/marine/auto_catch + name = "\improper M344 pattern ammo load rig" + icon_state = "autocathbelt" + desc = "The M344 is the modern load-bearing equipment of the TGMC. It consists of a modular belt with various clips. Allows you to quickly obtain and use equipment during combat operations." + storage_slots = 4 + +/obj/item/storage/belt/marine/auto_catch/Initialize(mapload, ...) + . = ..() + AddComponent(/datum/component/magazine_catcher) + AddComponent(/datum/component/easy_restock) + /obj/item/storage/belt/marine/ar18/Initialize(mapload) . = ..() new /obj/item/ammo_magazine/rifle/ar18(src) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 8dba804d8a4..99430fda68f 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -1120,6 +1120,13 @@ spawn_type = /obj/item/explosive/grenade/smokebomb/drain closed_overlay = "grenade_box_overlay_drain" +/obj/item/storage/box/visual/grenade/drain/sticky + name = "\improper M45-T grenade box" + desc = "A secure box holding 25 M40-T gas grenades. 100% safe to use around masked marines." + spawn_number = 25 + spawn_type = /obj/item/explosive/grenade/sticky/cloaker/tangle + closed_overlay = "grenade_box_overlay_drain" + /obj/item/storage/box/visual/grenade/razorburn name = "razorburn grenade box" desc = "A secure box holding 15 razor burn grenades. Used for quick flank coverage." diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index e2bed884d6f..419de82fa11 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -27,7 +27,6 @@ storage_type_limits = list(/obj/item/weapon/gun = 1) can_hold = list( /obj/item/weapon/gun/revolver/standard_magnum, - /obj/item/attachable/stock/t76, /obj/item/attachable/scope/standard_magnum, /obj/item/ammo_magazine/revolver/standard_magnum, ) @@ -35,31 +34,23 @@ /obj/item/storage/briefcase/standard_magnum/PopulateContents() new /obj/item/weapon/gun/revolver/standard_magnum(src) new /obj/item/attachable/scope/standard_magnum(src) - new /obj/item/attachable/stock/t76(src) - new /obj/item/attachable/compensator(src) for(var/i in 1 to 15) new /obj/item/ammo_magazine/revolver/standard_magnum(src) /obj/item/storage/briefcase/standard_magnum/gold/PopulateContents() new /obj/item/weapon/gun/revolver/standard_magnum/fancy/gold(src) new /obj/item/attachable/scope/standard_magnum(src) - new /obj/item/attachable/stock/t76(src) - new /obj/item/attachable/compensator(src) for(var/i in 1 to 15) new /obj/item/ammo_magazine/revolver/standard_magnum(src) /obj/item/storage/briefcase/standard_magnum/silver/PopulateContents() new /obj/item/weapon/gun/revolver/standard_magnum/fancy/silver(src) new /obj/item/attachable/scope/standard_magnum(src) - new /obj/item/attachable/stock/t76(src) - new /obj/item/attachable/compensator(src) for(var/i in 1 to 15) new /obj/item/ammo_magazine/revolver/standard_magnum(src) /obj/item/storage/briefcase/standard_magnum/nickle/PopulateContents() new /obj/item/weapon/gun/revolver/standard_magnum/fancy/nickle(src) new /obj/item/attachable/scope/standard_magnum(src) - new /obj/item/attachable/stock/t76(src) - new /obj/item/attachable/compensator(src) for(var/i in 1 to 15) new /obj/item/ammo_magazine/revolver/standard_magnum(src) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index bd6d20a34dc..c5a73d645d0 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -16,6 +16,7 @@ slot_r_hand_str = 'icons/mob/inhands/equipment/medkits_right.dmi', ) icon_state = "firstaid" + base_icon_state = "firstaid" use_sound = 'sound/effects/toolbox.ogg' w_class = WEIGHT_CLASS_BULKY throw_speed = 2 @@ -25,38 +26,28 @@ /obj/item/explosive/grenade, ) var/empty = FALSE //whether the kit starts empty - var/icon_full //icon state to use when kit is full - -/obj/item/storage/firstaid/Initialize(mapload, ...) - . = ..() - icon_full = icon_state - if(empty) - icon_state = icon_state += "_empty" - else - fill_firstaid_kit() - /obj/item/storage/firstaid/update_icon_state() . = ..() if(!length(contents)) icon_state = icon_state += "_empty" else - icon_state = icon_full - - -//to fill medkits with stuff when spawned -/obj/item/storage/firstaid/proc/fill_firstaid_kit() - return + icon_state = base_icon_state +/obj/item/storage/firstaid/PopulateContents() + if(empty) + return + new /obj/item/healthanalyzer(src) /obj/item/storage/firstaid/fire name = "fire first-aid kit" desc = "It's an emergency medical kit for when the toxins lab -spontaneously- burns down." icon_state = "firefirstaid" + base_icon_state = "firefirstaid" item_state = "firefirstaid" -/obj/item/storage/firstaid/fire/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/fire/PopulateContents() + . = ..() new /obj/item/storage/pill_bottle/kelotane(src) new /obj/item/storage/pill_bottle/tramadol(src) new /obj/item/stack/medical/heal_pack/advanced/burn_pack(src) @@ -64,13 +55,13 @@ new /obj/item/storage/pill_bottle/packet/leporazine(src) new /obj/item/storage/syringe_case/burn(src) - /obj/item/storage/firstaid/regular icon_state = "firstaid" + base_icon_state = "firstaid" item_state = "firstaid" -/obj/item/storage/firstaid/regular/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/regular/PopulateContents() + . = ..() new /obj/item/stack/medical/heal_pack/gauze(src) new /obj/item/stack/medical/heal_pack/ointment(src) new /obj/item/reagent_containers/hypospray/autoinjector/combat(src) @@ -78,30 +69,29 @@ new /obj/item/reagent_containers/hypospray/autoinjector/tramadol(src) new /obj/item/stack/medical/splint(src) - /obj/item/storage/firstaid/toxin name = "toxin first aid" desc = "Used to treat when you have a high amount of toxins in your body." icon_state = "antitoxfirstaid" + base_icon_state = "antitoxfirstaid" item_state = "antitoxfirstaid" -/obj/item/storage/firstaid/toxin/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/toxin/PopulateContents() + . = ..() new /obj/item/storage/pill_bottle/dylovene(src) -// new /obj/item/storage/pill_bottle/packet/ryetalyn(src) new /obj/item/reagent_containers/hypospray/autoinjector/hypervene(src) new /obj/item/reagent_containers/hypospray/autoinjector/hypervene(src) new /obj/item/storage/syringe_case/tox(src) - /obj/item/storage/firstaid/o2 name = "oxygen deprivation first aid" desc = "A box full of oxygen goodies." icon_state = "o2firstaid" + base_icon_state = "o2firstaid" item_state = "o2firstaid" -/obj/item/storage/firstaid/o2/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/o2/PopulateContents() + . = ..() new /obj/item/storage/pill_bottle/dexalin(src) new /obj/item/storage/pill_bottle/inaprovaline(src) new /obj/item/reagent_containers/hypospray/autoinjector/dexalinplus(src) @@ -109,15 +99,15 @@ new /obj/item/reagent_containers/hypospray/autoinjector/dexalinplus(src) new /obj/item/storage/syringe_case/oxy(src) - /obj/item/storage/firstaid/adv name = "advanced first-aid kit" desc = "Contains advanced medical treatments." icon_state = "advfirstaid" + base_icon_state = "advfirstaid" item_state = "advfirstaid" -/obj/item/storage/firstaid/adv/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/adv/PopulateContents() + . = ..() new /obj/item/stack/medical/heal_pack/advanced/bruise_pack(src) new /obj/item/stack/medical/heal_pack/advanced/burn_pack(src) new /obj/item/storage/pill_bottle/bicaridine(src) @@ -125,15 +115,15 @@ new /obj/item/storage/pill_bottle/tramadol(src) new /obj/item/stack/medical/splint(src) - /obj/item/storage/firstaid/rad name = "radiation first-aid kit" desc = "Contains treatment for radiation exposure" icon_state = "purplefirstaid" + base_icon_state = "purplefirstaid" item_state = "purplefirstaid" -/obj/item/storage/firstaid/rad/fill_firstaid_kit() - new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/rad/PopulateContents() + . = ..() new /obj/item/storage/pill_bottle/dylovene(src) new /obj/item/reagent_containers/hypospray/autoinjector/combat(src) new /obj/item/reagent_containers/hypospray/autoinjector/tricordrazine(src) @@ -141,7 +131,6 @@ new /obj/item/reagent_containers/hypospray/autoinjector/bicaridine(src) new /obj/item/reagent_containers/hypospray/autoinjector/bicaridine(src) - /* * Syringe Case */ @@ -159,9 +148,11 @@ /obj/item/reagent_containers/syringe, ) -/obj/item/storage/syringe_case/empty/Initialize(mapload, ...) - . = ..() +/obj/item/storage/syringe_case/PopulateContents() new /obj/item/reagent_containers/syringe(src) + +/obj/item/storage/syringe_case/empty/PopulateContents() + . = ..() new /obj/item/reagent_containers/glass/bottle/empty(src) new /obj/item/reagent_containers/glass/bottle/empty(src) @@ -171,7 +162,6 @@ /obj/item/storage/syringe_case/regular/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/inaprovaline(src) new /obj/item/reagent_containers/glass/bottle/tricordrazine(src) @@ -181,7 +171,6 @@ /obj/item/storage/syringe_case/burn/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/kelotane(src) new /obj/item/reagent_containers/glass/bottle/oxycodone(src) @@ -191,7 +180,6 @@ /obj/item/storage/syringe_case/tox/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/dylovene(src) new /obj/item/reagent_containers/glass/bottle/hypervene(src) @@ -201,7 +189,6 @@ /obj/item/storage/syringe_case/oxy/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/inaprovaline(src) new /obj/item/reagent_containers/glass/bottle/dexalin(src) @@ -211,7 +198,6 @@ /obj/item/storage/syringe_case/meralyne/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/meralyne(src) new /obj/item/reagent_containers/glass/bottle/meralyne(src) @@ -221,7 +207,6 @@ /obj/item/storage/syringe_case/dermaline/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/dermaline(src) new /obj/item/reagent_containers/glass/bottle/dermaline(src) @@ -231,7 +216,6 @@ /obj/item/storage/syringe_case/meraderm/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/meraderm(src) new /obj/item/reagent_containers/glass/bottle/meraderm(src) @@ -241,7 +225,6 @@ /obj/item/storage/syringe_case/nanoblood/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/nanoblood(src) new /obj/item/reagent_containers/glass/bottle/nanoblood(src) @@ -251,16 +234,13 @@ /obj/item/storage/syringe_case/tricordrazine/PopulateContents() . = ..() - new /obj/item/reagent_containers/syringe(src) new /obj/item/reagent_containers/glass/bottle/tricordrazine(src) new /obj/item/reagent_containers/glass/bottle/tricordrazine(src) - /* * Pill Bottles */ - /obj/item/storage/pill_bottle name = "pill bottle" desc = "It's an airtight container for storing medication." @@ -284,18 +264,18 @@ max_storage_space = 16 greyscale_config = /datum/greyscale_config/pillbottle greyscale_colors = "#d9cd07#f2cdbb" //default colors + refill_types = list(/obj/item/storage/pill_bottle) + refill_sound = 'sound/items/pills.ogg' var/pill_type_to_fill //type of pill to use to fill in the bottle in New() /// Short description in overlay var/description_overlay = "" - refill_types = list(/obj/item/storage/pill_bottle) - refill_sound = 'sound/items/pills.ogg' -/obj/item/storage/pill_bottle/Initialize(mapload, ...) - . = ..() - if(pill_type_to_fill) - for(var/i in 1 to max_storage_space) - new pill_type_to_fill(src) - update_icon() +/obj/item/storage/pill_bottle/PopulateContents() + if(!pill_type_to_fill) + return + for(var/i in 1 to max_storage_space) + new pill_type_to_fill(src) + update_icon(UPDATE_OVERLAYS) /obj/item/storage/pill_bottle/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/reagent_containers/hypospray)) @@ -613,9 +593,7 @@ ) var/is_open = FALSE -/obj/item/storage/ai2/Initialize(mapload, ...) - . = ..() - +/obj/item/storage/ai2/PopulateContents() new /obj/item/storage/pill_bottle/penal/meralyne(src) new /obj/item/storage/pill_bottle/penal/dermaline(src) new /obj/item/storage/pill_bottle/penal/hyronalin(src) @@ -625,8 +603,6 @@ new /obj/item/reagent_containers/hypospray/autoinjector/pen/inaprovaline(src) new /obj/item/reagent_containers/hypospray/autoinjector/pen/hypervene(src) - update_icon() - /obj/item/storage/ai2/update_icon_state() cut_overlays() diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index e5f6027560a..30c99425162 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -578,10 +578,13 @@ /obj/item/storage/holster/belt/pistol name = "generic pistol belt" desc = "A pistol belt that is not a revolver belt" + flags_equip_slot = ITEM_SLOT_BELT|ITEM_SLOT_SUITSTORE /obj/item/storage/holster/belt/pistol/Initialize(mapload, ...) . = ..() AddComponent(/datum/component/tac_reload_storage) + AddComponent(/datum/component/magazine_catcher) + AddComponent(/datum/component/easy_restock) /obj/item/storage/holster/belt/pistol/m4a3 name = "\improper M4A3 holster rig" diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm index 19f7f062794..406675cbbf3 100644 --- a/code/game/objects/items/tools/kitchen_tools.dm +++ b/code/game/objects/items/tools/kitchen_tools.dm @@ -200,11 +200,7 @@ I.loc = M.loc carrying.Remove(I) if(isturf(I.loc)) - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) + drop_tray_contents(I) var/mob/living/carbon/human/H = M ///////////////////////////////////// /Let's have this ready for later. @@ -339,7 +335,7 @@ overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer) /obj/item/tool/kitchen/tray/dropped(mob/user) - ..() + . = ..() var/mob/living/M for(M in src.loc) //to handle hand switching return @@ -356,8 +352,11 @@ carrying.Remove(I) if(!foundtable && isturf(loc)) // if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere! - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) + INVOKE_ASYNC(src, PROC_REF(drop_tray_contents), I) + +/obj/item/tool/kitchen/tray/proc/drop_tray_contents(obj/item/our_item) + for(var/i = 1, i <= rand(1, 2), i++) + if(!our_item) + break + step(our_item, pick(GLOB.cardinals)) + sleep(rand(2,4)) diff --git a/code/game/objects/items/tools/misc_tools.dm b/code/game/objects/items/tools/misc_tools.dm index b9b8df77ce6..d7da5ecba96 100644 --- a/code/game/objects/items/tools/misc_tools.dm +++ b/code/game/objects/items/tools/misc_tools.dm @@ -46,6 +46,8 @@ var/str = reject_bad_text(stripped_input(user, "Label text?", "Set label","", MAX_NAME_LEN)) if(!str) to_chat(user, span_notice("Invalid label.")) + on = !on + icon_state = "labeler[on]" return label = str to_chat(user, span_notice("You set the label text to '[str]'.")) diff --git a/code/game/objects/items/toys/toy_weapons.dm b/code/game/objects/items/toys/toy_weapons.dm index 589a30318b0..603f2f37005 100644 --- a/code/game/objects/items/toys/toy_weapons.dm +++ b/code/game/objects/items/toys/toy_weapons.dm @@ -106,7 +106,7 @@ if(!isturf(target.loc) || target == user) return if(flag) return - if (locate (/obj/structure/table, src.loc)) + if(locate (/obj/structure/table, src.loc)) return else if (bullets) var/turf/trg = get_turf(target) @@ -116,14 +116,17 @@ D.name = "foam dart" playsound(user.loc, 'sound/items/syringeproj.ogg', 15, 1) - for(var/i=0, i<6, i++) - if (D) - if(D.loc == trg) break - step_towards(D,trg) + for(var/i = 0, i < 6, i++) + if(D) + if(D.loc == trg) + break + step_towards(D, trg) for(var/mob/living/M in D.loc) - if(!istype(M,/mob/living)) continue - if(M == user) continue + if(!istype(M, /mob/living)) + continue + if(M == user) + continue visible_message(span_warning("[M] was hit by the foam dart!"), visible_message_flags = COMBAT_MESSAGE) new /obj/item/toy/crossbow_ammo(M.loc) qdel(D) @@ -137,10 +140,7 @@ sleep(0.1 SECONDS) - spawn(10) - if(D) - new /obj/item/toy/crossbow_ammo(D.loc) - qdel(D) + addtimer(CALLBACK(src, PROC_REF(convert_proj_to_item), D), 1 SECONDS) return else if(!bullets && isliving(user)) @@ -148,6 +148,12 @@ L.Paralyze(10 SECONDS) visible_message(span_warning("[user] realized they were out of ammo and starting scrounging for some!")) +/obj/item/toy/crossbow/proc/convert_proj_to_item(obj/effect/foam_dart_dummy/dart) + if(!dart) + return + new /obj/item/toy/crossbow_ammo(dart.loc) + qdel(dart) + /obj/item/toy/crossbow/attack(mob/M as mob, mob/user as mob) diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm index b8718803ac1..6b867e46725 100644 --- a/code/game/objects/items/toys/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -206,7 +206,7 @@ if (istype(A, /obj/item/storage/backpack )) return - else if (locate (/obj/structure/table, src.loc)) + else if (locate (/obj/structure/table, loc)) return else if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) @@ -215,34 +215,35 @@ return else if (src.reagents.total_volume < 1) - src.empty = 1 + empty = 1 to_chat(user, span_notice("Your flower has run dry!")) return else - src.empty = 0 + empty = 0 var/obj/effect/decal/D = new/obj/effect/decal/(get_turf(src)) D.name = "water" D.icon = 'icons/obj/items/chemistry.dmi' D.icon_state = "chempuff" D.create_reagents(5) - src.reagents.trans_to(D, 1) - playsound(src.loc, 'sound/effects/spray3.ogg', 15, 1, 3) - - spawn(0) - for(var/i=0, i<1, i++) - step_towards(D,A) - D.reagents.reaction(get_turf(D)) - for(var/atom/T in get_turf(D)) - D.reagents.reaction(T) - if(ismob(T) && T:client) - to_chat(T:client, span_warning("[user] has sprayed you with water!")) - sleep(0.4 SECONDS) - qdel(D) + reagents.trans_to(D, 1) + playsound(loc, 'sound/effects/spray3.ogg', 15, 1, 3) + INVOKE_ASYNC(src, PROC_REF(spray_water), A, D, user) return +/obj/item/toy/waterflower/proc/spray_water(atom/our_atom, obj/effect/decal/our_decal, mob/user) + for(var/i = 0, i < 1, i++) + step_towards(our_decal, our_atom) + our_decal.reagents.reaction(get_turf(our_decal)) + for(var/atom/T in get_turf(our_decal)) + our_decal.reagents.reaction(T) + if(ismob(T) && T:client) + to_chat(T:client, span_warning("[user] has sprayed you with water!")) + sleep(0.4 SECONDS) + qdel(our_decal) + /obj/item/toy/waterflower/examine(mob/user) . = ..() . += "[reagents.total_volume] units of water left!" diff --git a/code/game/objects/items/weapons/blades.dm b/code/game/objects/items/weapons/blades.dm index 503d12d1b80..17381822bc1 100644 --- a/code/game/objects/items/weapons/blades.dm +++ b/code/game/objects/items/weapons/blades.dm @@ -30,10 +30,82 @@ edge = 1 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + ///Special attack action granted to users with the right trait + var/datum/action/ability/activable/weapon_skill/sword_lunge/special_attack /obj/item/weapon/claymore/Initialize(mapload) . = ..() AddElement(/datum/element/scalping) + special_attack = new(src, force, penetration) + +/obj/item/weapon/claymore/Destroy() + QDEL_NULL(special_attack) + return ..() + +/obj/item/weapon/claymore/equipped(mob/user, slot) + . = ..() + if(user.skills.getRating(SKILL_MELEE_WEAPONS) > SKILL_MELEE_DEFAULT) + special_attack.give_action(user) + +/obj/item/weapon/claymore/dropped(mob/user) + . = ..() + special_attack?.remove_action(user) + +//Special attack +/datum/action/ability/activable/weapon_skill/sword_lunge + name = "Lunging strike" + action_icon_state = "sword_lunge" + desc = "A powerful leaping strike. Cannot stun." + ability_cost = 8 + cooldown_duration = 6 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_WEAPONABILITY_SWORDLUNGE, + ) + +/datum/action/ability/activable/weapon_skill/sword_lunge/use_ability(atom/A) + var/mob/living/carbon/carbon_owner = owner + + RegisterSignal(carbon_owner, COMSIG_MOVABLE_MOVED, PROC_REF(movement_fx)) + RegisterSignals(carbon_owner, list(COMSIG_MOVABLE_IMPACT, COMSIG_MOVABLE_BUMP), PROC_REF(lunge_impact)) + RegisterSignal(carbon_owner, COMSIG_MOVABLE_POST_THROW, PROC_REF(charge_complete)) + + carbon_owner.visible_message(span_danger("[carbon_owner] charges towards \the [A]!")) + playsound(owner, "sound/effects/alien_tail_swipe2.ogg", 50, 0, 4) + carbon_owner.throw_at(A, 2, 1, carbon_owner) + succeed_activate() + add_cooldown() + +///Create an after image +/datum/action/ability/activable/weapon_skill/sword_lunge/proc/movement_fx() + SIGNAL_HANDLER + new /obj/effect/temp_visual/xenomorph/afterimage(get_turf(owner), owner) + +///Unregisters signals after lunge complete +/datum/action/ability/activable/weapon_skill/sword_lunge/proc/charge_complete() + SIGNAL_HANDLER + UnregisterSignal(owner, list(COMSIG_MOVABLE_IMPACT, COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_POST_THROW, COMSIG_MOVABLE_MOVED)) + +///Sig handler for atom impacts during lunge +/datum/action/ability/activable/weapon_skill/sword_lunge/proc/lunge_impact(datum/source, obj/target, speed) + SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(do_lunge_impact), source, target) + charge_complete() + +///Actual effects of lunge impact +/datum/action/ability/activable/weapon_skill/sword_lunge/proc/do_lunge_impact(datum/source, obj/target) + var/mob/living/carbon/carbon_owner = source + if(isobj(target)) + var/obj/obj_victim = target + obj_victim.take_damage(damage, BRUTE, MELEE, TRUE, TRUE, get_dir(obj_victim, carbon_owner), penetration, carbon_owner) + if(!obj_victim.anchored && obj_victim.move_resist < MOVE_FORCE_VERY_STRONG) + obj_victim.knockback(carbon_owner, 1, 2) + else if(ishuman(target)) + var/mob/living/carbon/human/human_victim = target + human_victim.apply_damage(damage, BRUTE, BODY_ZONE_CHEST, MELEE, TRUE, TRUE, TRUE, penetration) + human_victim.adjust_stagger(1 SECONDS) + playsound(human_victim, "sound/weapons/wristblades_hit.ogg", 25, 0, 5) + shake_camera(human_victim, 2, 1) /obj/item/weapon/claymore/mercsword name = "combat sword" diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 3809ce7da60..dd12272821c 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -131,16 +131,14 @@ else wield(user) - ///////////OFFHAND/////////////// /obj/item/weapon/twohanded/offhand - w_class = WEIGHT_CLASS_HUGE - icon_state = "offhand" name = "offhand" + icon_state = "offhand" + w_class = WEIGHT_CLASS_HUGE flags_item = DELONDROP|TWOHANDED|WIELDED resistance_flags = RESIST_ALL - /obj/item/weapon/twohanded/offhand/Destroy() if(ismob(loc)) var/mob/user = loc @@ -215,24 +213,97 @@ penetration = 35 flags_equip_slot = ITEM_SLOT_BACK attack_speed = 15 + ///Special attack action granted to users with the right trait + var/datum/action/ability/activable/weapon_skill/axe_sweep/special_attack /obj/item/weapon/twohanded/fireaxe/som/Initialize(mapload) . = ..() AddComponent(/datum/component/shield, SHIELD_TOGGLE|SHIELD_PURE_BLOCKING, shield_cover = list(MELEE = 45, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0)) AddComponent(/datum/component/stun_mitigation, SHIELD_TOGGLE, shield_cover = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 60, BOMB = 60, BIO = 60, FIRE = 60, ACID = 60)) AddElement(/datum/element/strappable) + special_attack = new(src, force_wielded, penetration) + +/obj/item/weapon/twohanded/fireaxe/som/Destroy() + QDEL_NULL(special_attack) + return ..() /obj/item/weapon/twohanded/fireaxe/som/wield(mob/user) . = ..() if(!.) return toggle_item_bump_attack(user, TRUE) + if(user.skills.getRating(SKILL_MELEE_WEAPONS) > SKILL_MELEE_DEFAULT) + special_attack.give_action(user) /obj/item/weapon/twohanded/fireaxe/som/unwield(mob/user) . = ..() if(!.) return toggle_item_bump_attack(user, FALSE) + special_attack.remove_action(user) + +//Special attack +/datum/action/ability/activable/weapon_skill/axe_sweep + name = "Sweeping blow" + action_icon_state = "axe_sweep" + desc = "A powerful sweeping blow that hits foes in the direction you are facing. Cannot stun." + ability_cost = 10 + cooldown_duration = 6 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_WEAPONABILITY_AXESWEEP, + ) + /// Used for particles. Holds the particles instead of the mob. See particle_holder for documentation. + var/obj/effect/abstract/particle_holder/particle_holder + +/datum/action/ability/activable/weapon_skill/axe_sweep/use_ability(atom/A) + succeed_activate() + add_cooldown() + var/mob/living/carbon/carbon_owner = owner + carbon_owner.Move(get_step_towards(carbon_owner, A), get_dir(src, A)) + carbon_owner.face_atom(A) + activate_particles(owner.dir) + playsound(owner, "sound/effects/alien_tail_swipe3.ogg", 50, 0, 5) + owner.visible_message(span_danger("[owner] Swing their weapon in a deadly arc!")) + + var/list/atom/movable/atoms_to_ravage = get_step(owner, owner.dir).contents.Copy() + atoms_to_ravage += get_step(owner, turn(owner.dir, -45)).contents + atoms_to_ravage += get_step(owner, turn(owner.dir, 45)).contents + for(var/atom/movable/victim AS in atoms_to_ravage) + if((victim.resistance_flags & INDESTRUCTIBLE)) + continue + if(!ishuman(victim)) + var/obj/obj_victim = victim + obj_victim.take_damage(damage, BRUTE, MELEE, TRUE, TRUE, get_dir(obj_victim, carbon_owner), penetration, carbon_owner) + if(!obj_victim.anchored && obj_victim.move_resist < MOVE_FORCE_VERY_STRONG) + obj_victim.knockback(owner, 1, 2) + continue + var/mob/living/carbon/human/human_victim = victim + if(human_victim.lying_angle) + continue + human_victim.apply_damage(damage, BRUTE, BODY_ZONE_CHEST, MELEE, TRUE, TRUE, TRUE, penetration) + human_victim.knockback(owner, 1, 2) + human_victim.adjust_stagger(1 SECONDS) + playsound(human_victim, "sound/weapons/wristblades_hit.ogg", 25, 0, 5) + shake_camera(human_victim, 2, 1) + +/// Handles the activation and deactivation of particles, as well as their appearance. +/datum/action/ability/activable/weapon_skill/axe_sweep/proc/activate_particles(direction) + particle_holder = new(get_turf(owner), /particles/ravager_slash) + QDEL_NULL_IN(src, particle_holder, 5) + particle_holder.particles.rotation += dir2angle(direction) + switch(direction) // There's no shared logic here because sprites are magical. + if(NORTH) // Gotta define stuff for each angle so it looks good. + particle_holder.particles.position = list(8, 4) + particle_holder.particles.velocity = list(0, 20) + if(EAST) + particle_holder.particles.position = list(3, -8) + particle_holder.particles.velocity = list(20, 0) + if(SOUTH) + particle_holder.particles.position = list(-9, -3) + particle_holder.particles.velocity = list(0, -20) + if(WEST) + particle_holder.particles.position = list(-4, 9) + particle_holder.particles.velocity = list(-20, 0) /* * Double-Bladed Energy Swords - Cheridan diff --git a/code/game/objects/machinery/bioprinter.dm b/code/game/objects/machinery/bioprinter.dm index 9f6c94d5de6..a6b664d7f27 100644 --- a/code/game/objects/machinery/bioprinter.dm +++ b/code/game/objects/machinery/bioprinter.dm @@ -47,16 +47,17 @@ to_chat(user, span_notice("\The [src] is now printing the selected organ. Please hold.")) working = 1 update_icon() - spawn(products[choice][4]) //Time - var/new_organ = products[choice][1] - new new_organ(get_turf(src)) - working = 0 - visible_message("The bio/synthetic printer spits out a new organ.") - update_icon() - + addtimer(CALLBACK(src, PROC_REF(spawn_new_organ), choice), products[choice][4]) else to_chat(user, "There is not enough materials in the printer.") +/obj/machinery/bioprinter/proc/spawn_new_organ(choice) + var/new_organ = products[choice][1] + new new_organ(get_turf(src)) + working = 0 + visible_message("The bio/synthetic printer spits out a new organ.") + update_icon() + /obj/machinery/bioprinter/attackby(obj/item/I, mob/user, params) . = ..() if(istype(I, /obj/item/reagent_containers/glass/beaker)) diff --git a/code/game/objects/machinery/buttons.dm b/code/game/objects/machinery/buttons.dm index b31c4ff8404..865b3c28f21 100644 --- a/code/game/objects/machinery/buttons.dm +++ b/code/game/objects/machinery/buttons.dm @@ -136,8 +136,6 @@ name = "lockdown override" id = "landing_zone" icon_state = "shutter" - light_range = 0 - light_power = 0 use_power = NO_POWER_USE resistance_flags = RESIST_ALL req_one_access = list(ACCESS_MARINE_DROPSHIP) @@ -165,7 +163,7 @@ flick("[initial(icon_state)]_denied", src) return use_power(active_power_usage) - icon_state = "[initial(icon_state)]1" + icon_state = "[initial(icon_state)]_on" alarm_played = TRUE playsound_z(z, 'sound/effects/shutters_alarm.ogg', 15) // woop woop, shutters opening. diff --git a/code/game/objects/machinery/camera/tracking.dm b/code/game/objects/machinery/camera/tracking.dm index 78d1a899d5e..e562eea4256 100644 --- a/code/game/objects/machinery/camera/tracking.dm +++ b/code/game/objects/machinery/camera/tracking.dm @@ -95,40 +95,40 @@ to_chat(src, span_notice("Now tracking [target.get_visible_name()] on camera.")) + INVOKE_ASYNC(src, PROC_REF(start_tracking), target) + +/mob/living/silicon/ai/proc/start_tracking(mob/living/target) var/cameraticks = 0 - spawn(0) - while(cameraFollow == target) - if(cameraFollow == null) + while(cameraFollow == target) + if(cameraFollow == null) + return + + if(!target.can_track(src)) + tracking = TRUE + if(!cameraticks) + to_chat(src, span_warning("Target is not near any active cameras. Attempting to reacquire...")) + cameraticks++ + if(cameraticks > 9) + cameraFollow = null + to_chat(src, span_warning("Unable to reacquire, cancelling track...")) + tracking = FALSE return - - if(!target.can_track(src)) - tracking = TRUE - if(!cameraticks) - to_chat(src, span_warning("Target is not near any active cameras. Attempting to reacquire...")) - cameraticks++ - if(cameraticks > 9) - cameraFollow = null - to_chat(src, span_warning("Unable to reacquire, cancelling track...")) - tracking = FALSE - return - else - sleep(1 SECONDS) - continue - else - cameraticks = 0 - tracking = FALSE - - if(eyeobj) - eyeobj.setLoc(get_turf(target)) + sleep(1 SECONDS) + continue + else + cameraticks = 0 + tracking = FALSE - else - view_core() - cameraFollow = null - return + if(eyeobj) + eyeobj.setLoc(get_turf(target)) - sleep(1 SECONDS) + else + view_core() + cameraFollow = null + return + sleep(1 SECONDS) /proc/near_camera(mob/living/M) if(!isturf(M.loc)) diff --git a/code/game/objects/machinery/computer/area_air_control.dm b/code/game/objects/machinery/computer/area_air_control.dm index d609fb2bd46..4e22333b94a 100644 --- a/code/game/objects/machinery/computer/area_air_control.dm +++ b/code/game/objects/machinery/computer/area_air_control.dm @@ -87,20 +87,21 @@ var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber = locate(href_list["scrub"]) if(!validscrubber(scrubber)) - spawn(20) - status = "ERROR: Couldn't connect to scrubber! (timeout)" - connectedscrubbers -= scrubber - src.updateUsrDialog() + addtimer(CALLBACK(src, PROC_REF(send_error_message), scrubber), 2 SECONDS) return scrubber.on = text2num(href_list["toggle"]) scrubber.update_icon() -/obj/machinery/computer/area_atmos/proc/validscrubber( obj/machinery/portable_atmospherics/scrubber/huge/scrubber as obj ) - if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z) - return 0 +/obj/machinery/computer/area_atmos/proc/send_error_message(obj/machinery/portable_atmospherics/scrubber/huge/scrubber) + status = "ERROR: Couldn't connect to scrubber! (timeout)" + connectedscrubbers -= scrubber + updateUsrDialog() - return 1 +/obj/machinery/computer/area_atmos/proc/validscrubber(obj/machinery/portable_atmospherics/scrubber/huge/scrubber as obj) + if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z) + return FALSE + return TRUE /obj/machinery/computer/area_atmos/proc/scanscrubbers() connectedscrubbers = new() diff --git a/code/game/objects/machinery/computer/communications.dm b/code/game/objects/machinery/computer/communications.dm index 4571f2daceb..29c62ad5836 100644 --- a/code/game/objects/machinery/computer/communications.dm +++ b/code/game/objects/machinery/computer/communications.dm @@ -98,11 +98,14 @@ if("announce") if(authenticated == 2) + if(TIMER_COOLDOWN_CHECK(usr, COOLDOWN_HUD_ORDER)) + to_chat(usr, span_warning("You've sent an announcement or message too recently!")) + return if(world.time < cooldown_message + COOLDOWN_COMM_MESSAGE) to_chat(usr, span_warning("Please allow at least [COOLDOWN_COMM_MESSAGE*0.1] second\s to pass between announcements.")) return FALSE - var/input = tgui_input_text(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "",multiline = TRUE, encode = FALSE) + var/input = tgui_input_text(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "",multiline = TRUE, encode = FALSE, max_length = 100) if(!input || !(usr in view(1,src)) || authenticated != 2 || world.time < cooldown_message + COOLDOWN_COMM_MESSAGE) return FALSE @@ -121,6 +124,7 @@ priority_announce(input, subtitle = "Sent by [usr]", type = ANNOUNCEMENT_COMMAND) message_admins("[ADMIN_TPMONTY(usr)] has just sent a command announcement") log_game("[key_name(usr)] has just sent a command announcement.") + TIMER_COOLDOWN_START(usr, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN) cooldown_message = world.time if("award") @@ -177,14 +181,8 @@ if(!SSevacuation.cancel_evacuation()) to_chat(usr, span_warning("You are unable to cancel the evacuation right now!")) return FALSE - - spawn(35)//some time between AI announcements for evac cancel and SD cancel. - if(SSevacuation.evac_status == EVACUATION_STATUS_STANDING_BY)//nothing changed during the wait - //if the self_destruct is active we try to cancel it (which includes lowering alert level to red) - if(!SSevacuation.cancel_self_destruct(1)) - //if SD wasn't active (likely canceled manually in the SD room), then we lower the alert level manually. - GLOB.marine_main_ship.set_security_level(SEC_LEVEL_RED, TRUE) //both SD and evac are inactive, lowering the security level. - + //some time between AI announcements for evac cancel and SD cancel. + addtimer(CALLBACK(src, PROC_REF(evacuation_cancel)), 3.5 SECONDS) log_game("[key_name(usr)] has canceled the emergency evacuation.") message_admins("[ADMIN_TPMONTY(usr)] has canceled the emergency evacuation.") return TRUE @@ -328,6 +326,14 @@ updateUsrDialog() +/obj/machinery/computer/communications/proc/evacuation_cancel() + if(SSevacuation.evac_status != EVACUATION_STATUS_STANDING_BY) // nothing changed during the wait + return + //if the self_destruct is active we try to cancel it (which includes lowering alert level to red) + if(SSevacuation.cancel_self_destruct(TRUE)) + return + //if SD wasn't active (likely canceled manually in the SD room), then we lower the alert level manually. + GLOB.marine_main_ship.set_security_level(SEC_LEVEL_RED, TRUE) //both SD and evac are inactive, lowering the security level. /obj/machinery/computer/communications/interact(mob/user) . = ..() diff --git a/code/game/objects/machinery/doors/airlock.dm b/code/game/objects/machinery/doors/airlock.dm index 7d9fb62f079..229553d728e 100644 --- a/code/game/objects/machinery/doors/airlock.dm +++ b/code/game/objects/machinery/doors/airlock.dm @@ -9,33 +9,45 @@ active_power_usage = 360 flags_atom = HTML_USE_INITAL_ICON_1 obj_flags = CAN_BE_HIT - var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. - var/hackProof = 0 // if 1, this door can't be hacked by the AI - var/secondsMainPowerLost = 0 //The number of seconds until power is restored. - var/secondsBackupPowerLost = 0 //The number of seconds until power is restored. + autoclose = TRUE + /** + * If 1, AI control is disabled until the AI hacks back in and disables the lock. + * If 2, the AI has bypassed the lock. + * If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. + */ + var/aiControlDisabled = 0 + /// if 1, this door can't be hacked by the AI + var/hackProof = 0 + ///The number of seconds until power is restored. + var/secondsMainPowerLost = 0 + ///The number of seconds until power is restored. + var/secondsBackupPowerLost = 0 var/spawnPowerRestoreRunning = 0 - var/lights = 1 // bolt lights show by default - secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + /// bolt lights show by default + var/lights = 1 var/aiDisabledIdScanner = 0 var/aiHacking = 0 var/obj/machinery/door/airlock/closeOther = null var/closeOtherId = null var/list/signalers[12] var/lockdownbyai = 0 - autoclose = 1 var/assembly_type = /obj/structure/door_assembly var/mineral = null var/justzap = 0 var/safe = 1 normalspeed = 1 var/obj/item/circuitboard/airlock/electronics = null - var/hasShocked = 0 //Prevents multiple shocks from happening - var/secured_wires = 0 //for mapping use - var/no_panel = 0 //the airlock has no panel that can be screwdrivered open + ///Prevents multiple shocks from happening + var/hasShocked = FALSE + ///for mapping use + var/secured_wires = 0 + ///the airlock has no panel that can be screwdrivered open + var/no_panel = 0 ///used to determine various abandoned door effects var/abandoned = FALSE smoothing_groups = list(SMOOTH_GROUP_AIRLOCK) + /obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite if(issilicon(user)) return ..(user) @@ -43,8 +55,7 @@ if(!justzap) if(shock(user, 100)) justzap = TRUE - spawn (openspeed) - justzap = FALSE + addtimer(VARSET_CALLBACK(src, justzap, FALSE), openspeed) return else /*if(justzap)*/ return @@ -57,7 +68,7 @@ return ..(user) /obj/machinery/door/airlock/Initialize() - ..() + . = ..() return INITIALIZE_HINT_LATELOAD /obj/machinery/door/airlock/LateInitialize() @@ -160,17 +171,16 @@ // The preceding comment was borrowed from the grille's shock script /obj/machinery/door/airlock/shock(mob/user, prb) if(!hasPower()) - return 0 + return FALSE if(hasShocked) - return 0 //Already shocked someone recently? + return FALSE //Already shocked someone recently? if(..()) - hasShocked = 1 + hasShocked = TRUE sleep(1 SECONDS) - hasShocked = 0 - return 1 + hasShocked = FALSE + return TRUE else - return 0 - + return FALSE /obj/machinery/door/airlock/update_icon_state() . = ..() @@ -197,14 +207,16 @@ /obj/machinery/door/airlock/do_animate(animation) switch(animation) if("opening") - if(overlays) overlays.Cut() + if(overlays) + overlays.Cut() if(CHECK_BITFIELD(machine_stat, PANEL_OPEN)) spawn(2) // The only work around that works. Downside is that the door will be gone for a millisecond. flick("o_door_opening", src) //can not use flick due to BYOND bug updating overlays right before flicking else flick("door_opening", src) if("closing") - if(overlays) overlays.Cut() + if(overlays) + overlays.Cut() if(CHECK_BITFIELD(machine_stat, PANEL_OPEN)) flick("o_door_closing", src) else @@ -450,9 +462,9 @@ else if(!operating) if(density) - open(1) + open(TRUE) else - close(1) + close(TRUE) return TRUE @@ -519,7 +531,7 @@ playsound(src.loc, 'sound/machines/airlock.ogg', 25, 0) for(var/turf/turf in locs) var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) - killthis?.ex_act(2)//Smashin windows + killthis?.ex_act(200)//Smashin windows return ..() /obj/machinery/door/airlock/proc/lock(forced = FALSE) @@ -718,5 +730,4 @@ if(psi_power < PSIONIC_INTERACTION_STRENGTH_STANDARD && hasPower()) to_chat(user, span_warning("The airlock's motors resist your efforts to force it.")) return - return ..() diff --git a/code/game/objects/machinery/doors/airlock_types.dm b/code/game/objects/machinery/doors/airlock_types.dm index 6cd005249a5..c8087bf74ec 100644 --- a/code/game/objects/machinery/doors/airlock_types.dm +++ b/code/game/objects/machinery/doors/airlock_types.dm @@ -56,24 +56,22 @@ /obj/machinery/door/airlock/centcom name = "\improper Airlock" icon = 'icons/obj/doors/mainship/securedoor.dmi' - opacity = TRUE + openspeed = 4 //shorter open animation. /obj/machinery/door/airlock/vault name = "\improper Vault" icon = 'icons/obj/doors/vault.dmi' - opacity = TRUE assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. /obj/machinery/door/airlock/freezer name = "\improper Freezer Airlock" icon = 'icons/obj/doors/mainship/personaldoor.dmi' - opacity = TRUE assembly_type = /obj/structure/door_assembly/door_assembly_fre /obj/machinery/door/airlock/hatch name = "\improper Airtight Hatch" icon = 'icons/obj/doors/mainship/securedoor.dmi' - opacity = TRUE + openspeed = 4 //shorter open animation. assembly_type = /obj/structure/door_assembly/door_assembly_hatch /obj/machinery/door/airlock/hatch/engineering @@ -82,7 +80,6 @@ /obj/machinery/door/airlock/maintenance_hatch name = "\improper Maintenance Hatch" icon = 'icons/obj/doors/mainship/maintdoor.dmi' - opacity = TRUE assembly_type = /obj/structure/door_assembly/door_assembly_mhatch /obj/machinery/door/airlock/glass_command diff --git a/code/game/objects/machinery/doors/door.dm b/code/game/objects/machinery/doors/door.dm index c894d7153de..76bbe4f2c16 100644 --- a/code/game/objects/machinery/doors/door.dm +++ b/code/game/objects/machinery/doors/door.dm @@ -6,6 +6,7 @@ anchored = TRUE opacity = TRUE density = TRUE + dir = EAST allow_pass_flags = NONE move_resist = MOVE_FORCE_VERY_STRONG layer = DOOR_OPEN_LAYER @@ -16,6 +17,7 @@ var/open_layer = DOOR_OPEN_LAYER var/closed_layer = DOOR_CLOSED_LAYER var/id + ///How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. var/secondsElectrified = 0 var/visible = TRUE var/operating = FALSE @@ -24,14 +26,14 @@ var/normalspeed = TRUE var/locked = FALSE var/welded = FALSE - var/not_weldable = FALSE // stops people welding the door if true - var/openspeed = 10 //How many seconds does it take to open it? Default 1 second. Use only if you have long door opening animations + /// stops people welding the door if true + var/not_weldable = FALSE + ///How many seconds does it take to open it? Use only if you have long door opening animations + var/openspeed = 1 SECONDS var/list/fillers //used for determining emergency access var/emergency = FALSE - - //Multi-tile doors - dir = EAST + ///Multi-tile doors var/width = 1 /obj/machinery/door/Initialize(mapload) @@ -132,16 +134,14 @@ else if(density) flick("door_deny", src) - /obj/machinery/door/emp_act(severity) if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) open() if(prob(40/severity)) if(secondsElectrified == 0) secondsElectrified = -1 - spawn(300) - secondsElectrified = 0 - ..() + addtimer(VARSET_CALLBACK(src, secondsElectrified, 0), 30 SECONDS) + return ..() /obj/machinery/door/ex_act(severity) if(CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) @@ -175,7 +175,6 @@ if("deny") flick("door_deny", src) - /obj/machinery/door/proc/open() SIGNAL_HANDLER_DOES_SLEEP if(operating || welded || locked || !loc) diff --git a/code/game/objects/machinery/doors/firedoor.dm b/code/game/objects/machinery/doors/firedoor.dm index eb41d9fb34c..236fa75ec29 100644 --- a/code/game/objects/machinery/doors/firedoor.dm +++ b/code/game/objects/machinery/doors/firedoor.dm @@ -136,10 +136,12 @@ to_chat(xeno_attacker, span_warning("\The [src] is welded shut.")) return FALSE if(density) //Make sure it's still closed - spawn(0) - open(1) - xeno_attacker.visible_message(span_danger("\The [xeno_attacker] pries \the [src] open."), \ - span_danger("We pry \the [src] open."), null, 5) + INVOKE_ASYNC(src, PROC_REF(xeno_open), xeno_attacker) + +/obj/machinery/door/firedoor/proc/xeno_open(mob/living/carbon/xenomorph/xeno_attacker) + open(TRUE) + xeno_attacker.visible_message(span_danger("\The [xeno_attacker] pries \the [src] open."), \ + span_danger("We pry \the [src] open."), null, 5) /obj/machinery/door/firedoor/attack_hand(mob/living/user) . = ..() @@ -187,14 +189,16 @@ close() if(needs_to_close) - spawn(50) - alarmed = FALSE - for(var/area/A in areas_added) //Just in case a fire alarm is turned off while the firedoor is going through an autoclose cycle - if(A.flags_alarm_state & ALARM_WARNING_FIRE || A.air_doors_activated) - alarmed = TRUE - if(alarmed) - nextstate = FIREDOOR_CLOSED - close() + addtimer(CALLBACK(src, PROC_REF(closing_process)), 5 SECONDS) + +/obj/machinery/door/firedoor/proc/closing_process() + var/alarmed = FALSE + for(var/area/A in areas_added) // Just in case a fire alarm is turned off while the firedoor is going through an autoclose cycle + if(A.flags_alarm_state & ALARM_WARNING_FIRE || A.air_doors_activated) + alarmed = TRUE + if(alarmed) + nextstate = FIREDOOR_CLOSED + close() /obj/machinery/door/firedoor/attackby(obj/item/I, mob/user, params) . = ..() diff --git a/code/game/objects/machinery/fire_alarm.dm b/code/game/objects/machinery/fire_alarm.dm index aab95bc9892..498d250372e 100644 --- a/code/game/objects/machinery/fire_alarm.dm +++ b/code/game/objects/machinery/fire_alarm.dm @@ -83,7 +83,7 @@ if(A.flags_alarm_state & ALARM_WARNING_FIRE) . += mutable_appearance(icon, "fire_o1") -/obj/machinery/firealarm/fire_act(burn_level) +/obj/machinery/firealarm/fire_act(burn_level, flame_color) if(!detecting) return alarm() @@ -128,13 +128,15 @@ to_chat(user, span_warning("You need 5 pieces of cable to do wire \the [src].")) return else if(iscrowbar(I)) - to_chat(user, "You pry out the circuit!") + to_chat(user, "You start prying out the circuit!") playsound(loc, 'sound/items/crowbar.ogg', 25, 1) - spawn(20) - new /obj/item/circuitboard/firealarm(loc) - electronics = null - buildstage = 0 - update_icon() + + if(!do_after(user, 2 SECONDS, NONE, src, BUSY_ICON_BUILD)) + return + new /obj/item/circuitboard/firealarm(loc) + electronics = null + buildstage = 0 + update_icon() if(0) if(istype(I, /obj/item/circuitboard/firealarm)) to_chat(user, "You insert the circuit!") diff --git a/code/game/objects/machinery/hologram.dm b/code/game/objects/machinery/hologram.dm index 9e02e1a1bd6..dbd45017db1 100644 --- a/code/game/objects/machinery/hologram.dm +++ b/code/game/objects/machinery/hologram.dm @@ -246,7 +246,6 @@ updateUsrDialog() -//do not allow AIs to answer calls or people will use it to meta the AI sattelite /obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return diff --git a/code/game/objects/machinery/kitchen/smartfridge.dm b/code/game/objects/machinery/kitchen/smartfridge.dm index a7b045e0a83..214015960b9 100644 --- a/code/game/objects/machinery/kitchen/smartfridge.dm +++ b/code/game/objects/machinery/kitchen/smartfridge.dm @@ -193,30 +193,27 @@ /obj/machinery/smartfridge/proc/throw_item() var/obj/throw_item = null - var/mob/living/target = locate() in view(7,src) + var/mob/living/target = locate() in view(7, src) if(!target) - return 0 + return FALSE - for (var/O in item_quants) + for(var/O in item_quants) if(item_quants[O] <= 0) //Try to use a record that actually has something to dump. continue item_quants[O]-- for(var/obj/T in contents) - if(T.name == O) - T.loc = src.loc - throw_item = T - break + if(T.name != O) + continue + T.loc = loc + throw_item = T + break break if(!throw_item) - return 0 - spawn(0) - throw_item.throw_at(target,16,3,src) - src.visible_message(span_danger("[src] launches [throw_item.name] at [target.name]!")) - return 1 - - - + return FALSE + INVOKE_ASYNC(throw_item, TYPE_PROC_REF(/atom/movable, throw_at), target, 16, 3, src) + visible_message(span_danger("[src] launches [throw_item.name] at [target.name]!")) + return TRUE /******************** * Smartfridge types diff --git a/code/game/objects/machinery/overwatch.dm b/code/game/objects/machinery/overwatch.dm index 7fbe86dbe85..adb8d859298 100644 --- a/code/game/objects/machinery/overwatch.dm +++ b/code/game/objects/machinery/overwatch.dm @@ -8,7 +8,6 @@ #define SPOTLIGHT_COOLDOWN_DURATION 6 MINUTES #define SPOTLIGHT_DURATION 2 MINUTES - #define MESSAGE_SINGLE "Message this marine" #define ASL "Set or un-set as aSL" #define SWITCH_SQUAD "Switch this marine's squad" @@ -23,6 +22,9 @@ #define MESSAGE_SQUAD "Message all marines in a squad" #define SWITCH_SQUAD_NEAR "Move all nearby marines to a squad" +/// The maximum length we should use for sending messages with stuff like `message_member`, +/// `message_squad` etc. +#define MAX_COMMAND_MESSAGE_LENGTH 100 GLOBAL_LIST_EMPTY(active_orbital_beacons) GLOBAL_LIST_EMPTY(active_laser_targets) @@ -69,7 +71,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets) ///Overrides the minimap action minimap and marker flags var/map_flags = MINIMAP_FLAG_MARINE ///Ref of the lase that's had an OB warning mark placed on the minimap - var/obj/effect/overlay/temp/laser_target/OB/marked_lase + var/obj/effect/overlay/temp/laser_target/ob/marked_lase ///Static list of CIC radial options for the camera when clicking on a marine var/static/list/human_radial_options = list( MESSAGE_SINGLE = image(icon = 'icons/mob/radial.dmi', icon_state = "cic_message_single"), @@ -296,18 +298,8 @@ GLOBAL_LIST_EMPTY(active_cas_targets) state = OW_MAIN if("monitor") state = OW_MONITOR - if("monitoralpha_squad") - state = OW_MONITOR - current_squad = get_squad_by_id(ALPHA_SQUAD) - if("monitorbravo_squad") - state = OW_MONITOR - current_squad = get_squad_by_id(BRAVO_SQUAD) - if("monitorcharlie_squad") - state = OW_MONITOR - current_squad = get_squad_by_id(CHARLIE_SQUAD) - if("monitordelta_squad") - state = OW_MONITOR - current_squad = get_squad_by_id(DELTA_SQUAD) + if(href_list["squad_id"]) + current_squad = get_squad_by_id(href_list["squad_id"]) if("change_operator") if(operator != usr) if(current_squad) @@ -363,7 +355,10 @@ GLOBAL_LIST_EMPTY(active_cas_targets) attack_hand(operator) if("message") if(current_squad && operator == usr) - var/input = tgui_input_text(operator, "Please write a message to announce to the squad:", "Squad Message") + if(TIMER_COOLDOWN_CHECK(operator, COOLDOWN_HUD_ORDER)) + to_chat(operator, span_warning("You've sent an announcement or message too recently!")) + return + var/input = tgui_input_text(operator, "Please write a message to announce to the squad:", "Squad Message", max_length = MAX_COMMAND_MESSAGE_LENGTH) if(input) current_squad.message_squad(input, operator) //message, adds username if(issilicon(operator)) @@ -371,14 +366,18 @@ GLOBAL_LIST_EMPTY(active_cas_targets) visible_message(span_boldnotice("Message sent to all Marines of squad '[current_squad]'.")) if("sl_message") if(current_squad && operator == usr) - var/input = tgui_input_text(operator, "Please write a message to announce to the squad leader:", "SL Message") + if(TIMER_COOLDOWN_CHECK(operator, COOLDOWN_HUD_ORDER)) + to_chat(operator, span_warning("You've sent an announcement or message too recently!")) + return + var/input = tgui_input_text(operator, "Please write a message to announce to the squad leader:", "SL Message", max_length = MAX_COMMAND_MESSAGE_LENGTH) if(input) + TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN) message_member(current_squad.squad_leader, input, operator) if(issilicon(operator)) to_chat(operator, span_boldnotice("Message sent to Squad Leader [current_squad.squad_leader] of squad '[current_squad]'.")) visible_message(span_boldnotice("Message sent to Squad Leader [current_squad.squad_leader] of squad '[current_squad]'.")) if("set_primary") - var/input = tgui_input_text(operator, "What will be the squad's primary objective?", "Primary Objective") + var/input = tgui_input_text(operator, "What will be the squad's primary objective?", "Primary Objective", max_length = MAX_COMMAND_MESSAGE_LENGTH * 0.75) if( is_ic_filtered(input) || NON_ASCII_CHECK(input)) to_chat(operator, span_boldnotice("Message invalid. Check your message does not contain filtered words or characters.")) return @@ -388,7 +387,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets) to_chat(operator, span_boldnotice("Primary objective of squad '[current_squad]' set.")) visible_message(span_boldnotice("Primary objective of squad '[current_squad]' set.")) if("set_secondary") - var/input = tgui_input_text(operator, "What will be the squad's secondary objective?", "Secondary Objective") + var/input = tgui_input_text(operator, "What will be the squad's secondary objective?", "Secondary Objective", max_length = MAX_COMMAND_MESSAGE_LENGTH * 0.75) if( is_ic_filtered(input) || NON_ASCII_CHECK(input)) to_chat(operator, span_boldnotice("Message invalid. Check your message does not contain filtered words or characters.")) return @@ -468,13 +467,13 @@ GLOBAL_LIST_EMPTY(active_cas_targets) state = OW_MAIN if("use_cam") selected_target = locate(href_list["selected_target"]) + var/atom/cam_target = locate(href_list["cam_target"]) + if(!cam_target) + return + var/turf/cam_target_turf = get_turf(cam_target) + if(!cam_target_turf) + return if(!isAI(operator)) - var/atom/cam_target = locate(href_list["cam_target"]) - if(!cam_target) - return - var/turf/cam_target_turf = get_turf(cam_target) - if(!cam_target_turf) - return open_prompt(operator) eyeobj.setLoc(cam_target_turf) if(isliving(cam_target)) @@ -482,6 +481,14 @@ GLOBAL_LIST_EMPTY(active_cas_targets) track(L) else to_chat(operator, "[icon2html(src, operator)] [span_notice("Jumping to the latest available location of [cam_target].")]") + else + // If we are an AI + to_chat(operator, "[icon2html(src, operator)] [span_notice("Jumping to the latest available location of [cam_target].")]") + var/turf/T = get_turf(cam_target) + if(T) + var/mob/living/silicon/ai/recipientai = operator + recipientai.eyeobj.setLoc(T) + // operator.eyeobj.setLoc(get_turf(src)) updateUsrDialog() @@ -511,7 +518,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets) dat += "Squad Overwatch: [S.overwatch_officer.name]
" else dat += "Squad Overwatch: NONE
" - dat += "[S.name] Squad Monitor
" + dat += "[S.name] Squad Monitor
" dat += "----------------------
" dat += "Orbital Bombardment Control
" dat += "Current Cannon Status: " @@ -579,7 +586,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets) dat += "Squad Overwatch: [S.overwatch_officer.name]
" else dat += "Squad Overwatch: NONE
" - dat += "[S.name] Squad Monitor
" + dat += "[S.name] Squad Monitor
" if(OW_MONITOR)//Info screen. dat += get_squad_info() @@ -633,7 +640,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets) addtimer(CALLBACK(src, PROC_REF(do_fire_bombard), T, operator), 3.1 SECONDS) ///Lets anyone using an overwatch console know that an OB has just been lased -/obj/machinery/computer/camera_advanced/overwatch/proc/alert_lase(datum/source, obj/effect/overlay/temp/laser_target/OB/incoming_laser) +/obj/machinery/computer/camera_advanced/overwatch/proc/alert_lase(datum/source, obj/effect/overlay/temp/laser_target/ob/incoming_laser) SIGNAL_HANDLER if(!operator) return @@ -740,7 +747,9 @@ GLOBAL_LIST_EMPTY(active_cas_targets) /obj/machinery/computer/camera_advanced/overwatch/proc/message_member(mob/living/target, message, mob/living/carbon/human/sender) if(!target.client) return - target.play_screen_text("CIC MESSAGE FROM [sender.real_name]:
" + message, /atom/movable/screen/text/screen_text/command_order) + target.playsound_local(target, "sound/machines/dotprinter.ogg", 35) + to_chat(target, span_notice("New message from [sender.real_name]: [message]")) + target.play_screen_text("CIC MESSAGE FROM [sender.real_name]:
" + message, /atom/movable/screen/text/screen_text/command_order, "#32cd32") return TRUE ///Signal handler for radial menu @@ -751,14 +760,14 @@ GLOBAL_LIST_EMPTY(active_cas_targets) ///Quick-select radial menu for Overwatch /obj/machinery/computer/camera_advanced/overwatch/proc/do_radial(datum/source, atom/A, params) var/mob/living/carbon/human/human_target - var/obj/effect/overlay/temp/laser_target/OB/laser_target + var/obj/effect/overlay/temp/laser_target/ob/laser_target var/turf/turf_target var/choice if(ishuman(A)) human_target = A choice = show_radial_menu(source, human_target, human_radial_options, null, 48, null, FALSE, TRUE) - else if(istype(A, /obj/effect/overlay/temp/laser_target/OB)) + else if(istype(A, /obj/effect/overlay/temp/laser_target/ob)) laser_target = A choice = show_radial_menu(source, laser_target, bombardment_radial_options, null, 48, null, FALSE, TRUE) else @@ -767,8 +776,12 @@ GLOBAL_LIST_EMPTY(active_cas_targets) switch(choice) if(MESSAGE_SINGLE) - var/input = tgui_input_text(source, "Please write a message to announce to this marine:", "CIC Message") + if(TIMER_COOLDOWN_CHECK(operator, COOLDOWN_HUD_ORDER)) + to_chat(operator, span_warning("You've sent an announcement or message too recently!")) + return + var/input = tgui_input_text(source, "Please write a message to announce to this marine:", "CIC Message", max_length = MAX_COMMAND_MESSAGE_LENGTH) message_member(human_target, input, source) + TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN) if(ASL) if(human_target == human_target.assigned_squad.squad_leader) human_target.assigned_squad.demote_leader() @@ -789,7 +802,10 @@ GLOBAL_LIST_EMPTY(active_cas_targets) if(ORBITAL_SPOTLIGHT) attempt_spotlight(source, turf_target, params) if(MESSAGE_NEAR) - var/input = tgui_input_text(source, "Please write a message to announce to all marines nearby:", "CIC Proximity Message") + if(TIMER_COOLDOWN_CHECK(operator, COOLDOWN_HUD_ORDER)) + to_chat(operator, span_warning("You've sent an announcement or message too recently!")) + return + var/input = tgui_input_text(source, "Please write a message to announce to all marines nearby:", "CIC Proximity Message", max_length = MAX_COMMAND_MESSAGE_LENGTH) for(var/mob/living/carbon/human/target in GLOB.alive_human_list_faction[faction]) if(!target) return @@ -797,14 +813,19 @@ GLOBAL_LIST_EMPTY(active_cas_targets) continue message_member(target, input, source) message_member(source, input, source) + TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN) if(SQUAD_ACTIONS) choice = show_radial_menu(source, turf_target, squad_radial_options, null, 48, null, FALSE, TRUE) var/datum/squad/chosen_squad = squad_select(source, turf_target) switch(choice) if(MESSAGE_SQUAD) - var/input = tgui_input_text(source, "Please write a message to announce to the squad:", "Squad Message") + if(TIMER_COOLDOWN_CHECK(operator, COOLDOWN_HUD_ORDER)) + to_chat(operator, span_warning("You've sent an announcement or message too recently!")) + return + var/input = tgui_input_text(source, "Please write a message to announce to the squad:", "Squad Message", max_length = MAX_COMMAND_MESSAGE_LENGTH) if(input) chosen_squad.message_squad(input, source) + TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN) if(SWITCH_SQUAD_NEAR) for(var/mob/living/carbon/human/target in GLOB.human_mob_list) if(!target.faction == faction || get_dist(target, turf_target) > 9) @@ -949,8 +970,8 @@ GLOBAL_LIST_EMPTY(active_cas_targets) /datum/action/skill/issue_order name = "Issue Order" - skill_name = SKILL_LEADERSHIP action_icon = 'icons/mob/order_icons.dmi' + skill_name = SKILL_LEADERSHIP skill_min = SKILL_LEAD_TRAINED var/order_type = null @@ -1000,8 +1021,8 @@ GLOBAL_LIST_EMPTY(active_cas_targets) name = "Show/Hide Order Options" skill_name = SKILL_LEADERSHIP skill_min = SKILL_LEAD_TRAINED - var/orders_visible = TRUE action_icon_state = "hide_order" + var/orders_visible = TRUE /datum/action/skill/toggle_orders/action_activate() var/mob/living/carbon/human/H = owner @@ -1021,7 +1042,6 @@ GLOBAL_LIST_EMPTY(active_cas_targets) var/datum/action/skill/issue_order/A = new path() A.give_action(H) - /obj/machinery/computer/camera_advanced/overwatch/proc/get_squad_by_id(id) for(var/datum/squad/squad AS in watchable_squads) if(squad.id == id) @@ -1189,3 +1209,4 @@ GLOBAL_LIST_EMPTY(active_cas_targets) #undef OW_MAIN #undef OW_MONITOR +#undef MAX_COMMAND_MESSAGE_LENGTH diff --git a/code/game/objects/machinery/telecomms/machines/allinone.dm b/code/game/objects/machinery/telecomms/machines/allinone.dm index db409ecf552..463d9c4550c 100644 --- a/code/game/objects/machinery/telecomms/machines/allinone.dm +++ b/code/game/objects/machinery/telecomms/machines/allinone.dm @@ -10,7 +10,6 @@ use_power = NO_POWER_USE idle_power_usage = 0 - /obj/machinery/telecomms/allinone/receive_signal(datum/signal/subspace/signal) if(!istype(signal) || signal.transmission_method != TRANSMISSION_SUBSPACE) // receives on subspace only return @@ -28,7 +27,9 @@ return signal.broadcast() - /obj/machinery/telecomms/allinone/attackby(obj/item/P, mob/user, params) if(ismultitool(P)) return attack_hand(user) + +/obj/machinery/telecomms/allinone/needs_power + use_power = IDLE_POWER_USE diff --git a/code/game/objects/machinery/telecomms/machines/broadcaster.dm b/code/game/objects/machinery/telecomms/machines/broadcaster.dm index 0e346ae40ee..14d399caaba 100644 --- a/code/game/objects/machinery/telecomms/machines/broadcaster.dm +++ b/code/game/objects/machinery/telecomms/machines/broadcaster.dm @@ -52,13 +52,14 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages if(!GLOB.message_delay) GLOB.message_delay = 1 - spawn(10) - GLOB.message_delay = 0 - GLOB.recentmessages = list() + addtimer(CALLBACK(src, PROC_REF(clear_recent_messages)), 1 SECONDS) /* --- Do a snazzy animation! --- */ flick("broadcaster_send", src) +/obj/machinery/telecomms/broadcaster/proc/clear_recent_messages() + GLOB.message_delay = 0 + GLOB.recentmessages = list() /obj/machinery/telecomms/broadcaster/Destroy() // In case message_delay is left on 1, otherwise it won't reset the list and people can't say the same thing twice anymore. @@ -67,20 +68,21 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages return ..() //Preset Broadcasters + +/obj/machinery/telecomms/broadcaster/preset + network = "tcommsat" + //--PRESET LEFT--// -/obj/machinery/telecomms/broadcaster/preset_left +/obj/machinery/telecomms/broadcaster/preset/left id = "Broadcaster A" - network = "tcommsat" autolinkers = list("broadcasterA") //--PRESET RIGHT--// -/obj/machinery/telecomms/broadcaster/preset_right +/obj/machinery/telecomms/broadcaster/preset/right id = "Broadcaster B" - network = "tcommsat" autolinkers = list("broadcasterB") //proper cicbackup broadcaster -/obj/machinery/telecomms/broadcaster/preset_right/cicbackup +/obj/machinery/telecomms/broadcaster/preset/right/cicbackup id = "Backup Broadcaster B" - network = "tcommsat" autolinkers = list("broadcasterB") diff --git a/code/game/objects/machinery/telecomms/machines/bus.dm b/code/game/objects/machinery/telecomms/machines/bus.dm index a37107c0282..585a4782ea9 100644 --- a/code/game/objects/machinery/telecomms/machines/bus.dm +++ b/code/game/objects/machinery/telecomms/machines/bus.dm @@ -48,42 +48,37 @@ //Preset Buses -/obj/machinery/telecomms/bus/preset_one - id = "Bus 1" +/obj/machinery/telecomms/bus/preset network = "tcommsat" + +/obj/machinery/telecomms/bus/preset/one + id = "Bus 1" freq_listening = list(FREQ_COMMAND, FREQ_CAS, FREQ_MEDICAL, FREQ_ENGINEERING, FREQ_REQUISITIONS) autolinkers = list("processor1", "command", "firesupport", "medical", "engineering", "requisitions") - -/obj/machinery/telecomms/bus/preset_two +/obj/machinery/telecomms/bus/preset/two id = "Bus 2" - network = "tcommsat" freq_listening = list(FREQ_PMC, FREQ_COLONIST, FREQ_USL, FREQ_DEATHSQUAD, FREQ_IMPERIAL, FREQ_SOM, FREQ_SECTOID, FREQ_ECHO, YAUT_FREQ) autolinkers = list("processor2", "ert") - -/obj/machinery/telecomms/bus/preset_three +/obj/machinery/telecomms/bus/preset/three id = "Bus 3" - network = "tcommsat" freq_listening = list(FREQ_ALPHA, FREQ_BRAVO, FREQ_CHARLIE, FREQ_DELTA, FREQ_ECHO) autolinkers = list("processor3", "alpha", "bravo", "charlie", "delta", "echo") - -/obj/machinery/telecomms/bus/preset_four +/obj/machinery/telecomms/bus/preset/four id = "Bus 4" - network = "tcommsat" freq_listening = list(FREQ_COMMON) autolinkers = list("processor4", "common") +/obj/machinery/telecomms/bus/preset/four/Initialize(mapload) + . = ..() + for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) + freq_listening |= i + //proper cicbackup bus -/obj/machinery/telecomms/bus/preset_four/cicbackup +/obj/machinery/telecomms/bus/preset/four/cicbackup on = 0 id = "Backup Bus 4" - network = "tcommsat" freq_listening = list(FREQ_COMMON) autolinkers = list("processor4", "common") - -/obj/machinery/telecomms/bus/preset_four/Initialize(mapload) - . = ..() - for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) - freq_listening |= i diff --git a/code/game/objects/machinery/telecomms/machines/processor.dm b/code/game/objects/machinery/telecomms/machines/processor.dm index d7e80c2683d..9079a8f1dfc 100644 --- a/code/game/objects/machinery/telecomms/machines/processor.dm +++ b/code/game/objects/machinery/telecomms/machines/processor.dm @@ -30,34 +30,27 @@ signal.data["slow"] += rand(5, 10) // slow the signal down relay_information(signal, signal.server_type) - //Preset Processors -/obj/machinery/telecomms/processor/preset_one - id = "Processor 1" +/obj/machinery/telecomms/processor/preset network = "tcommsat" - autolinkers = list("processor1") // processors are sort of isolated; they don't need backward links +/obj/machinery/telecomms/processor/preset/one + id = "Processor 1" + autolinkers = list("processor1")// processors are sort of isolated; they don't need backward links -/obj/machinery/telecomms/processor/preset_two +/obj/machinery/telecomms/processor/preset/two id = "Processor 2" - network = "tcommsat" autolinkers = list("processor2") - -/obj/machinery/telecomms/processor/preset_three +/obj/machinery/telecomms/processor/preset/three id = "Processor 3" - network = "tcommsat" autolinkers = list("processor3") - -/obj/machinery/telecomms/processor/preset_four +/obj/machinery/telecomms/processor/preset/four id = "Processor 4" - network = "tcommsat" autolinkers = list("processor4") //proper backup server for CIC -/obj/machinery/telecomms/processor/preset_four/cicbackup - on = 0 +/obj/machinery/telecomms/processor/preset/four/cicbackup + on = FALSE id = "Backup Processor 4" - network = "tcommsat" - autolinkers = list("processor4") diff --git a/code/game/objects/machinery/telecomms/machines/receiver.dm b/code/game/objects/machinery/telecomms/machines/receiver.dm index 9ce8cf277e1..896c67d51a0 100644 --- a/code/game/objects/machinery/telecomms/machines/receiver.dm +++ b/code/game/objects/machinery/telecomms/machines/receiver.dm @@ -41,38 +41,36 @@ return FALSE - //Preset Receivers + +/obj/machinery/telecomms/receiver/preset + network = "tcommsat" + //--PRESET LEFT--// -/obj/machinery/telecomms/receiver/preset_left + +/obj/machinery/telecomms/receiver/preset/left id = "Receiver A" - network = "tcommsat" autolinkers = list("receiverA") // link to relay freq_listening = list(FREQ_MEDICAL, FREQ_REQUISITIONS, FREQ_ALPHA, FREQ_BRAVO, FREQ_CHARLIE, FREQ_DELTA, FREQ_COMMAND, FREQ_ENGINEERING, FREQ_CAS, FREQ_PMC, FREQ_COLONIST, FREQ_USL, FREQ_DEATHSQUAD, FREQ_IMPERIAL, FREQ_SOM, FREQ_SECTOID, FREQ_ECHO, YAUT_FREQ) //--PRESET RIGHT--// -/obj/machinery/telecomms/receiver/preset_right +/obj/machinery/telecomms/receiver/preset/right id = "Receiver B" - network = "tcommsat" autolinkers = list("receiverB") // link to relay freq_listening = list(FREQ_COMMON) //proper cicbackup reciver -/obj/machinery/telecomms/receiver/preset_right/cicbackup - on = 0 +/obj/machinery/telecomms/receiver/preset/right/cicbackup + on = FALSE id = "Backup Receiver B" - network = "tcommsat" - autolinkers = list("receiverB") // link to relay - freq_listening = list(FREQ_COMMON) -/obj/machinery/telecomms/receiver/preset_right/som +/obj/machinery/telecomms/receiver/preset/right/som id = "Receiver B som" autolinkers = list("receiverB_som") // link to relay freq_listening = list(FREQ_SOM) - //Common and other radio frequencies for people to freely use -/obj/machinery/telecomms/receiver/preset_right/Initialize(mapload) +/obj/machinery/telecomms/receiver/preset/right/Initialize(mapload) . = ..() for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i diff --git a/code/game/objects/machinery/telecomms/machines/server.dm b/code/game/objects/machinery/telecomms/machines/server.dm index 50e8a7cc3c6..3db65d8bd7e 100644 --- a/code/game/objects/machinery/telecomms/machines/server.dm +++ b/code/game/objects/machinery/telecomms/machines/server.dm @@ -16,7 +16,6 @@ var/list/log_entries = list() var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes) - /obj/machinery/telecomms/server/receive_information(datum/signal/subspace/vocal/signal, obj/machinery/telecomms/machine_from) // can't log non-vocal signals if(!istype(signal) || !signal.data["message"] || !is_freq_listening(signal)) @@ -53,72 +52,60 @@ if(!can_send) relay_information(signal, /obj/machinery/telecomms/broadcaster) - // Simple log entry datum /datum/comm_log_entry var/input_type = "Speech File" var/name = "data packet (#)" var/parameters = list() // copied from signal.data above - // Preset Servers /obj/machinery/telecomms/server/presets network = "tcommsat" - /obj/machinery/telecomms/server/presets/Initialize(mapload) . = ..() name = id - /obj/machinery/telecomms/server/presets/medical id = "Medical Server" freq_listening = list(FREQ_MEDICAL) autolinkers = list("medical") - /obj/machinery/telecomms/server/presets/requisitions id = "Requisitions Server" freq_listening = list(FREQ_REQUISITIONS) autolinkers = list("requisitions") - /obj/machinery/telecomms/server/presets/alpha id = "Alpha Server" freq_listening = list(FREQ_ALPHA) autolinkers = list("alpha") - /obj/machinery/telecomms/server/presets/bravo id = "Bravo Server" freq_listening = list(FREQ_BRAVO) autolinkers = list("bravo") - /obj/machinery/telecomms/server/presets/charlie id = "Charlie Server" freq_listening = list(FREQ_CHARLIE) autolinkers = list("charlie") - /obj/machinery/telecomms/server/presets/delta id = "Delta Server" freq_listening = list(FREQ_DELTA) autolinkers = list("delta") - /obj/machinery/telecomms/server/presets/command id = "Command Server" freq_listening = list(FREQ_COMMAND) autolinkers = list("command") - /obj/machinery/telecomms/server/presets/engineering id = "Engineering Server" freq_listening = list(FREQ_ENGINEERING) autolinkers = list("engineering") - /obj/machinery/telecomms/server/presets/cas id = "Fire Support Server" freq_listening = list(FREQ_CAS) diff --git a/code/game/objects/machinery/vending/marine_vending.dm b/code/game/objects/machinery/vending/marine_vending.dm index 915a3ff5f5c..abff9bd66a3 100644 --- a/code/game/objects/machinery/vending/marine_vending.dm +++ b/code/game/objects/machinery/vending/marine_vending.dm @@ -9,11 +9,15 @@ isshared = TRUE products = list( - "Rifles" = list( + "Винтовки" = list( /obj/item/weapon/gun/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12/ap = -1, /obj/item/ammo_magazine/rifle/ar12/hp = -1, + /obj/item/weapon/gun/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18/ap = -1, + /obj/item/ammo_magazine/rifle/ar18/hp = -1, /obj/item/weapon/gun/shotgun/pump/lever/repeater = -1, /obj/item/ammo_magazine/packet/p4570 = -1, /obj/item/weapon/gun/shotgun/double/martini = -1, @@ -28,13 +32,13 @@ /obj/item/ammo_magazine/rifle/ar21/ap = -1, /obj/item/ammo_magazine/rifle/ar21/hp = -1, ), - "SMGs" = list( + "Пистолеты-пулемёты" = list( /obj/item/weapon/gun/smg/vector = -1, /obj/item/ammo_magazine/smg/vector = -1, /obj/item/ammo_magazine/smg/vector/ap = -1, /obj/item/ammo_magazine/smg/vector/hp = -1, ), - "Marksman" = list( + "Снайперские винтовки" = list( /obj/item/weapon/gun/rifle/dmr37 = -1, /obj/item/ammo_magazine/rifle/dmr37 = -1, /obj/item/weapon/gun/rifle/sniper/antimaterial/sr127= -1, @@ -42,7 +46,16 @@ /obj/item/weapon/gun/rifle/sniper/svd = -1, /obj/item/ammo_magazine/sniper/svd = -1, ), - "Shotgun" = list( + "Энергетическое" = list( + /obj/item/cell/lasgun/lasrifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_rifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_sniper = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_carbine = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_mlaser = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/tesla = -1, + ), + "Дробовики" = list( /obj/item/weapon/gun/shotgun/pump/t35 = -1, /obj/item/weapon/gun/shotgun/combat/standardmarine = -1, /obj/item/weapon/gun/shotgun/combat/shq6 = -1, @@ -55,13 +68,17 @@ /obj/item/ammo_magazine/rifle/sh15_slug = -1, /obj/item/storage/holster/belt/ts34/full = 5, ), - "Machinegun" = list( + "Пулемёты" = list( /obj/item/weapon/gun/rifle/mg60 = -1, /obj/item/ammo_magazine/mg60 = -1, /obj/item/weapon/gun/mg27 = 5, /obj/item/ammo_magazine/mg27 = -1, + /obj/item/storage/box/hsg102 = 1, + /obj/item/weapon/gun/hmg08 = 1, + /obj/item/ammo_magazine/hmg08 = 5, + /obj/item/ammo_magazine/hmg08/small = 10, ), - "Melee" = list( + "Ближний бой" = list( /obj/item/weapon/combat_knife = -1, /obj/item/attachable/bayonetknife = -1, /obj/item/stack/throwing_knife = -1, @@ -71,12 +88,13 @@ /obj/item/storage/holster/blade/harvester/full = -1, /obj/item/weapon/twohanded/spear/tactical = -1, /obj/item/weapon/twohanded/spear/tactical/harvester = -1, + /obj/item/weapon/powerfist = -1, /obj/item/weapon/twohanded/glaive/harvester = -1, /obj/item/weapon/shield/riot/marine = 6, /obj/item/weapon/shield/riot/marine/deployable = 6, /obj/item/weapon/combat_knife/harvester = 12, ), - "Sidearm" = list( + "Пистолеты" = list( /obj/item/weapon/gun/revolver/r44 = 5, /obj/item/ammo_magazine/revolver/r44 = -1, /obj/item/storage/box/t500case = 10, @@ -93,7 +111,7 @@ /obj/item/weapon/gun/shotgun/double/derringer = -1, /obj/item/ammo_magazine/pistol/derringer = -1, ), - "Grenades" = list( + "Гранаты" = list( /obj/item/weapon/gun/grenade_launcher/single_shot = 4, /obj/item/weapon/gun/rifle/tx54 = 2, /obj/item/ammo_magazine/rifle/tx54 = 10, @@ -113,8 +131,8 @@ /obj/item/storage/box/m94 = -1, /obj/item/storage/box/m94/cas = -1, ), - "Specialized" = list( - /obj/item/cell/lasgun/lasrifle = -1, + "Специализированное" = list( + /obj/item/storage/box/crate/sentry = 4, /obj/item/weapon/gun/rifle/pepperball = 4, /obj/item/ammo_magazine/rifle/pepperball = -1, /obj/item/weapon/gun/flamer/big_flamer/marinestandard = 4, @@ -127,14 +145,7 @@ /obj/item/mortar_kit/knee = 4, /obj/item/mortal_shell/knee = 40, ), - "Heavy Weapons" = list( - /obj/item/storage/box/crate/sentry = 4, - /obj/item/storage/box/hsg102 = 1, - /obj/item/weapon/gun/hmg08 = 1, - /obj/item/ammo_magazine/hmg08 = 5, - /obj/item/ammo_magazine/hmg08/small = 10, - ), - "Attachments" = list( + "Модули" = list( /obj/item/attachable/bayonet = -1, /obj/item/attachable/compensator = -1, /obj/item/attachable/extended_barrel = -1, @@ -168,7 +179,7 @@ /obj/item/attachable/flamer_nozzle/wide = -1, /obj/item/attachable/flamer_nozzle/long = -1, ), - "Boxes" = list( + "Коробки" = list( /obj/item/ammo_magazine/packet/p9mm = -1, /obj/item/ammo_magazine/packet/p9mm/ap = -1, /obj/item/ammo_magazine/packet/acp = -1, @@ -213,7 +224,7 @@ /obj/structure/closet/crate/mass_produced_crate/supply = 5, /obj/structure/closet/crate/mass_produced_crate/weapon = 5, ), - "Utility" = list( + "Утилити" = list( /obj/item/flashlight/combat = -1, /obj/item/weapon/gun/grenade_launcher/single_shot/flare/marine = -1, /obj/item/tool/shovel/etool = -1, @@ -229,17 +240,21 @@ ) seasonal_items = list( - SEASONAL_GUNS = "Seasonal", - SEASONAL_HEAVY = "Operational Weapons", + SEASONAL_GUNS = "Сезонное", + SEASONAL_HEAVY = "Сезонное тяжёлое вооружение", ) /obj/machinery/vending/weapon/crash products = list( - "Rifles" = list( + "Винтовки" = list( /obj/item/weapon/gun/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12/ap = -1, /obj/item/ammo_magazine/rifle/ar12/hp = -1, + /obj/item/weapon/gun/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18/ap = -1, + /obj/item/ammo_magazine/rifle/ar18/hp = -1, /obj/item/weapon/gun/shotgun/pump/lever/repeater = -1, /obj/item/ammo_magazine/packet/p4570 = -1, /obj/item/weapon/gun/shotgun/double/martini = -1, @@ -254,13 +269,22 @@ /obj/item/ammo_magazine/rifle/ar21/ap = -1, /obj/item/ammo_magazine/rifle/ar21/hp = -1, ), - "SMGs" = list( + "Пистолеты-пулемёты" = list( /obj/item/weapon/gun/smg/vector = -1, /obj/item/ammo_magazine/smg/vector = -1, /obj/item/ammo_magazine/smg/vector/ap = -1, /obj/item/ammo_magazine/smg/vector/hp = -1, ), - "Marksman" = list( + "Энергетическое" = list( + /obj/item/cell/lasgun/lasrifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_rifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_sniper = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_carbine = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_mlaser = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/tesla = -1, + ), + "Снайперские винтовки" = list( /obj/item/weapon/gun/rifle/dmr37 = -1, /obj/item/ammo_magazine/rifle/dmr37 = -1, /obj/item/weapon/gun/rifle/sniper/antimaterial/sr127= -1, @@ -270,7 +294,7 @@ /obj/item/weapon/gun/rifle/sniper/svd = -1, /obj/item/ammo_magazine/sniper/svd = -1, ), - "Shotgun" = list( + "Дробовики" = list( /obj/item/weapon/gun/shotgun/pump/t35 = -1, /obj/item/weapon/gun/shotgun/combat/standardmarine = -1, /obj/item/weapon/gun/shotgun/combat/shq6 = -1, @@ -283,13 +307,13 @@ /obj/item/ammo_magazine/rifle/sh15_slug = -1, /obj/item/storage/holster/belt/ts34/full = 5, ), - "Machinegun" = list( + "Пулемёты" = list( /obj/item/weapon/gun/rifle/mg60 = -1, /obj/item/ammo_magazine/mg60 = -1, /obj/item/weapon/gun/mg27 = 5, /obj/item/ammo_magazine/mg27 = -1, ), - "Melee" = list( + "Ближний бой" = list( /obj/item/weapon/combat_knife = -1, /obj/item/attachable/bayonetknife = -1, /obj/item/stack/throwing_knife = -1, @@ -305,7 +329,7 @@ /obj/item/weapon/shield/riot/marine/deployable = 6, /obj/item/weapon/combat_knife/harvester = 12, ), - "Sidearm" = list( + "Пистолеты" = list( /obj/item/weapon/gun/revolver/r44 = 5, /obj/item/ammo_magazine/revolver/r44 = -1, /obj/item/storage/box/t500case = 10, @@ -322,7 +346,7 @@ /obj/item/weapon/gun/shotgun/double/derringer = -1, /obj/item/ammo_magazine/pistol/derringer = -1, ), - "Grenades" = list( + "Гранаты" = list( /obj/item/weapon/gun/grenade_launcher/single_shot = 4, /obj/item/explosive/grenade = 50, /obj/item/explosive/grenade/m15 = 10, @@ -334,7 +358,7 @@ /obj/item/storage/box/m94 = 200, /obj/item/storage/box/m94/cas = 50, ), - "Specialized" = list( + "Специализированное" = list( /obj/item/cell/lasgun/lasrifle = -1, /obj/item/weapon/gun/rifle/pepperball = 4, /obj/item/ammo_magazine/rifle/pepperball = 40, @@ -345,7 +369,7 @@ /obj/item/ammo_magazine/flamer_tank/water = -1, /obj/item/jetpack_marine = 3, ), - "Attachments" = list( + "Модули" = list( /obj/item/attachable/bayonet = -1, /obj/item/attachable/compensator = -1, /obj/item/attachable/extended_barrel = -1, @@ -379,7 +403,7 @@ /obj/item/attachable/flamer_nozzle/wide = -1, /obj/item/attachable/flamer_nozzle/long = -1, ), - "Boxes" = list( + "Коробки" = list( /obj/item/ammo_magazine/packet/p9mm = -1, /obj/item/ammo_magazine/packet/p9mm/ap = -1, /obj/item/ammo_magazine/packet/p9mm/hp = -1, @@ -419,7 +443,7 @@ /obj/structure/closet/crate/mass_produced_crate/supply = 5, /obj/structure/closet/crate/mass_produced_crate/weapon = 5, ), - "Utility" = list( + "Утилити" = list( /obj/item/flashlight/combat = -1, /obj/item/weapon/gun/grenade_launcher/single_shot/flare/marine = -1, /obj/item/tool/shovel/etool = -1, @@ -435,18 +459,22 @@ ) seasonal_items = list( - SEASONAL_GUNS = "Seasonal", + SEASONAL_GUNS = "Сезонное", ) /obj/machinery/vending/weapon/valhalla resistance_flags = INDESTRUCTIBLE use_power = NO_POWER_USE products = list( - "Rifles" = list( + "Винтовки" = list( /obj/item/weapon/gun/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12 = -1, /obj/item/ammo_magazine/rifle/ar12/ap = -1, /obj/item/ammo_magazine/rifle/ar12/hp = -1, + /obj/item/weapon/gun/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18 = -1, + /obj/item/ammo_magazine/rifle/ar18/ap = -1, + /obj/item/ammo_magazine/rifle/ar18/hp = -1, /obj/item/weapon/gun/shotgun/pump/lever/repeater = -1, /obj/item/ammo_magazine/packet/p4570 = -1, /obj/item/weapon/gun/shotgun/double/martini = -1, @@ -461,23 +489,14 @@ /obj/item/ammo_magazine/rifle/ar21/ap = -1, /obj/item/ammo_magazine/rifle/ar21/hp = -1, ), - "Energy Weapons" = list( - /obj/item/cell/lasgun/lasrifle = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_rifle = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_sniper = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_carbine = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_mlaser = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol = -1, - /obj/item/weapon/gun/energy/lasgun/lasrifle/tesla = -1, - ), - "SMGs" = list( + "Пистолеты-пулемёты" = list( /obj/item/weapon/gun/smg/vector = -1, /obj/item/ammo_magazine/smg/vector = -1, /obj/item/ammo_magazine/smg/vector/ap = -1, /obj/item/ammo_magazine/smg/vector/hp = -1, /obj/item/ammo_magazine/smg/vector/incendiary = -1, ), - "Marksman" = list( + "Снайперские винтовки" = list( /obj/item/weapon/gun/rifle/dmr37 = -1, /obj/item/ammo_magazine/rifle/dmr37 = -1, /obj/item/weapon/gun/rifle/sniper/antimaterial/sr127= -1, @@ -487,7 +506,16 @@ /obj/item/weapon/gun/revolver/r44/coltrifle = -1, /obj/item/ammo_magazine/revolver/rifle = -1, ), - "Shotgun" = list( + "Энергетическое" = list( + /obj/item/cell/lasgun/lasrifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_rifle = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_sniper = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_carbine = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_mlaser = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol = -1, + /obj/item/weapon/gun/energy/lasgun/lasrifle/tesla = -1, + ), + "Дробовики" = list( /obj/item/weapon/gun/shotgun/pump/t35 = -1, /obj/item/weapon/gun/shotgun/combat/standardmarine = -1, /obj/item/weapon/gun/shotgun/combat/shq6 = -1, @@ -501,13 +529,17 @@ /obj/item/weapon/gun/shotgun/double/marine = -1, /obj/item/storage/holster/belt/ts34/full = -1, ), - "Machinegun" = list( + "Пулемёты" = list( /obj/item/weapon/gun/rifle/mg60 = -1, /obj/item/ammo_magazine/mg60 = -1, /obj/item/weapon/gun/mg27 = -1, /obj/item/ammo_magazine/mg27 = -1, + /obj/item/storage/box/hsg102 = -1, + /obj/item/weapon/gun/hmg08 = -1, + /obj/item/ammo_magazine/hmg08 = -1, + /obj/item/ammo_magazine/hmg08/small = -1, ), - "Melee" = list( + "Ближний бой" = list( /obj/item/weapon/combat_knife = -1, /obj/item/attachable/bayonetknife = -1, /obj/item/stack/throwing_knife = -1, @@ -523,7 +555,7 @@ /obj/item/weapon/shield/riot/marine/deployable = -1, /obj/item/weapon/combat_knife/harvester = -1, ), - "Sidearm" = list( + "Пистолеты" = list( /obj/item/weapon/gun/revolver/r44 = -1, /obj/item/ammo_magazine/revolver/r44 = -1, /obj/item/storage/box/t500case = -1, @@ -540,7 +572,7 @@ /obj/item/weapon/gun/shotgun/double/derringer = -1, /obj/item/ammo_magazine/pistol/derringer = -1, ), - "Grenades" = list( + "Гранаты" = list( /obj/item/weapon/gun/grenade_launcher/single_shot = -1, /obj/item/weapon/gun/grenade_launcher/multinade_launcher/unloaded = -1, /obj/item/weapon/gun/rifle/tx54 = -1, @@ -563,7 +595,7 @@ /obj/item/storage/box/m94 = -1, /obj/item/storage/box/m94/cas = -1, ), - "Specialized" = list( + "Специализированное" = list( /obj/item/weapon/gun/rifle/pepperball = -1, /obj/item/ammo_magazine/rifle/pepperball = -1, /obj/item/weapon/gun/flamer/big_flamer/marinestandard = -1, @@ -575,15 +607,12 @@ /obj/item/mortar_kit/knee = 4, /obj/item/mortal_shell/knee = 40, ), - "Heavy Weapons" = list( + "Тяжёлое вооружение" = list( /obj/structure/closet/crate/mortar_ammo/mortar_kit = -1, /obj/structure/closet/crate/mortar_ammo/howitzer_kit = -1, /obj/structure/largecrate/supply/weapons/at36 = -1, /obj/item/storage/box/crate/sentry = -1, /obj/item/sentry_upgrade_kit = -1, - /obj/item/storage/box/hsg102 = -1, - /obj/item/weapon/gun/hmg08 = -1, - /obj/item/ammo_magazine/hmg08 = -1, /obj/item/storage/holster/backholster/rpg/full = -1, /obj/item/ammo_magazine/rocket/recoilless = -1, /obj/item/ammo_magazine/rocket/recoilless/light = -1, @@ -592,7 +621,7 @@ /obj/item/ammo_magazine/rocket/recoilless/smoke = -1, /obj/item/ammo_magazine/rocket/recoilless/plasmaloss = -1, ), - "Attachments" = list( + "Модули" = list( /obj/item/attachable/bayonet = -1, /obj/item/attachable/compensator = -1, /obj/item/attachable/extended_barrel = -1, @@ -626,7 +655,7 @@ /obj/item/attachable/flamer_nozzle/wide = -1, /obj/item/attachable/flamer_nozzle/long = -1, ), - "Boxes" = list( + "Коробки" = list( /obj/item/ammo_magazine/packet/p9mm = -1, /obj/item/ammo_magazine/packet/p9mm/ap = -1, /obj/item/ammo_magazine/packet/p9mm/hp = -1, @@ -672,7 +701,7 @@ /obj/structure/closet/crate/mass_produced_crate/supply = -1, /obj/structure/closet/crate/mass_produced_crate/weapon = -1, ), - "Utility" = list( + "Утилити" = list( /obj/item/flashlight/combat = -1, /obj/item/weapon/gun/grenade_launcher/single_shot/flare/marine = -1, /obj/item/tool/shovel/etool = -1, diff --git a/code/game/objects/machinery/vending/vending.dm b/code/game/objects/machinery/vending/vending.dm index d26262b8afe..f3adae81c46 100644 --- a/code/game/objects/machinery/vending/vending.dm +++ b/code/game/objects/machinery/vending/vending.dm @@ -480,10 +480,8 @@ vend_ready = 0 //One thing at a time!! R.amount-- - if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply) - spawn(0) - src.speak(src.vend_reply) - src.last_reply = world.time + if(((last_reply + (src.vend_delay + 200)) <= world.time) && vend_reply) + INVOKE_ASYNC(src, PROC_REF(speak_on_vend)) var/obj/item/new_item = release_item(R, vend_delay) @@ -491,6 +489,10 @@ new_item.on_vend(user, faction, fill_container = TRUE) vend_ready = 1 +/obj/machinery/vending/proc/speak_on_vend() + speak(vend_reply) + last_reply = world.time + /obj/machinery/vending/proc/release_item(datum/vending_product/R, delay_vending = 0, dump_product = 0) if(delay_vending) if(powered(power_channel)) @@ -649,6 +651,7 @@ var/obj/item/storage/S = item_to_stock.loc S.remove_from_storage(item_to_stock, user.loc, user) + item_to_stock.removed_from_inventory(user) qdel(item_to_stock) if(amount >= 0) //R negative means infinite item, no need to restock @@ -778,8 +781,7 @@ break if (!throw_item) return FALSE - spawn(0) - throw_item.throw_at(target, 16, 3, src) + INVOKE_ASYNC(throw_item, TYPE_PROC_REF(/atom/movable, throw_at), target, 16, 3, src) src.visible_message(span_warning("[src] launches [throw_item.name] at [target]!")) . = TRUE diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 206d0fc7001..385b963e518 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -68,7 +68,7 @@ return FALSE if(QDELETED(src)) return FALSE - fire_act(LAVA_BURN_LEVEL) + fire_act(LAVA_BURN_LEVEL, FLAME_COLOR_RED) return TRUE /obj/hitby(atom/movable/AM, speed = 5) diff --git a/code/game/objects/structures/barricade.dm b/code/game/objects/structures/barricade.dm index e18c35d6c0a..41229db0680 100644 --- a/code/game/objects/structures/barricade.dm +++ b/code/game/objects/structures/barricade.dm @@ -151,18 +151,20 @@ return ..() /obj/structure/barricade/ex_act(severity, direction) + if(QDELETED(src)) + return for(var/obj/structure/barricade/barricade in get_step(src, dir)) //discourage double-stacking barricades by removing health from opposing barricade - if(barricade.dir == REVERSE_DIR(dir)) - spawn(1) - if(barricade) - barricade.ex_act(severity, direction) + if(barricade.dir != REVERSE_DIR(dir)) + continue + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, ex_act), severity, direction) take_damage(severity, BRUTE, BOMB, attack_dir = direction) update_icon() /obj/structure/barricade/on_explosion_destruction(severity, direction) create_shrapnel(get_turf(src), rand(2,5), direction, shrapnel_type = /datum/ammo/bullet/shrapnel/light) if(prob(50)) // no message spam pls - visible_message(span_warning("[src] blows apart in the explosion, sending shards flying!")) + return + visible_message(span_warning("[src] blows apart in the explosion, sending shards flying!")) /obj/structure/barricade/get_explosion_resistance(direction) if(!density || direction == turn(dir, 90) || direction == turn(dir, -90)) diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index 69449f3b73a..2d3beb7b887 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -2,17 +2,18 @@ /obj/structure/closet/fireaxecabinet name = "Fire Axe Cabinet" desc = "There is small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if." - var/obj/item/weapon/twohanded/fireaxe/fireaxe = new/obj/item/weapon/twohanded/fireaxe icon_state = "fireaxe1000" icon_closed = "fireaxe1000" icon_opened = "fireaxe1100" anchored = TRUE density = FALSE - var/localopened = 0 //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri opened = 1 - var/hitstaken = 0 locked = TRUE + var/hitstaken = 0 + ///Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri + var/localopened = 0 var/smashed = 0 + var/obj/item/weapon/twohanded/fireaxe/fireaxe = new/obj/item/weapon/twohanded/fireaxe /obj/structure/closet/fireaxecabinet/attackby(obj/item/O, mob/user) //Marker -Agouri //..() //That's very useful, Erro @@ -21,7 +22,7 @@ if(fireaxe) hasaxe = 1 - if (locked) + if(locked) if(ismultitool(O)) to_chat(user, span_warning("Resetting circuitry...")) playsound(user, 'sound/machines/lockreset.ogg', 25, 1) @@ -32,65 +33,62 @@ return else if(!(O.flags_item & NOBLUDGEON) && O.force) var/obj/item/W = O - if(src.smashed || src.localopened) + if(smashed || localopened) if(localopened) localopened = 0 icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) update_icon() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) return else playsound(user, 'sound/effects/Glasshit.ogg', 25, 1) //We don't want this playing every time if(W.force < 15) to_chat(user, span_notice("The cabinet's protective glass glances off the hit.")) else - src.hitstaken++ - if(src.hitstaken == 4) + hitstaken++ + if(hitstaken == 4) playsound(user, 'sound/effects/glassbr3.ogg', 50, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that. - src.smashed = 1 - src.locked = 0 - src.localopened = 1 + smashed = 1 + locked = 0 + localopened = 1 update_icon() return - if (istype(O, /obj/item/weapon/twohanded/fireaxe) && src.localopened) + if(istype(O, /obj/item/weapon/twohanded/fireaxe) && localopened) if(!fireaxe) if(O.flags_item & WIELDED) to_chat(user, span_warning("Unwield the axe first.")) return fireaxe = O user.drop_held_item() - src.contents += O - to_chat(user, span_notice("You place the fire axe back in the [src.name].")) + contents += O + to_chat(user, span_notice("You place the fire axe back in the [name].")) update_icon() else - if(src.smashed) + if(smashed) return else localopened = !localopened if(localopened) icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" - spawn(10) - update_icon() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else - if(src.smashed) + if(smashed) return if(ismultitool(O)) if(localopened) localopened = 0 icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) return else to_chat(user, span_warning("Resetting circuitry...")) sleep(5 SECONDS) - src.locked = 1 + locked = 1 to_chat(user, span_notice("You re-enable the locking modules.")) playsound(user, 'sound/machines/lockenable.ogg', 25, 1) - if(do_after(user,20, NONE, src, BUSY_ICON_BUILD)) + if(do_after(user, 20, NONE, src, BUSY_ICON_BUILD)) locked = TRUE to_chat(user, " You re-enable the locking modules.") return @@ -98,22 +96,17 @@ localopened = !localopened if(localopened) icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" - spawn(10) - update_icon() + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() - - - + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) /obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob) var/hasaxe = 0 if(fireaxe) hasaxe = 1 if(!ishuman(user)) return - if(src.locked) + if(locked) to_chat(user, span_warning("The cabinet won't budge!")) return if(localopened) @@ -123,38 +116,34 @@ to_chat(user, span_notice("You take the fire axe from the [name].")) update_icon() else - if(src.smashed) + if(smashed) return else localopened = !localopened if(localopened) - src.icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" - spawn(10) - update_icon() + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else - src.icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else - localopened = !localopened //I'm pretty sure we don't need an if(src.smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri + localopened = !localopened //I'm pretty sure we don't need an if(smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri if(localopened) - src.icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" - spawn(10) - update_icon() + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) else - src.icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" - spawn(10) - update_icon() + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 1 SECONDS) /obj/structure/closet/fireaxecabinet/verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri set name = "Open/Close" set category = "Object" if (locked || smashed) - if(src.locked) + if(locked) to_chat(usr, span_warning("The cabinet won't budge!")) - else if(src.smashed) + else if(smashed) to_chat(usr, span_notice("The protective glass is broken!")) return @@ -165,22 +154,22 @@ set name = "Remove Fire Axe" set category = "Object" - if (istype(usr, /mob/living/carbon/xenomorph)) + if(istype(usr, /mob/living/carbon/xenomorph)) return - if (localopened) + if(localopened) if(fireaxe) usr.put_in_hands(fireaxe) fireaxe = null to_chat(usr, span_notice("You take the Fire axe from the [name].")) else - to_chat(usr, span_notice("The [src.name] is empty.")) + to_chat(usr, span_notice("The [name] is empty.")) else - to_chat(usr, span_notice("The [src.name] is closed.")) + to_chat(usr, span_notice("The [name] is closed.")) update_icon() /obj/structure/closet/fireaxecabinet/attack_ai(mob/user as mob) - if(src.smashed) + if(smashed) to_chat(user, span_warning("The security of the cabinet is compromised.")) return else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 07777c888d3..580a09e09b8 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -59,7 +59,6 @@ icon_off = "secure_closed_medical_white" /obj/structure/closet/secure_closet/medical3/PopulateContents() - . = ..() new /obj/item/clothing/glasses/hud/health(src) new /obj/item/storage/belt/lifesaver/full(src) new /obj/item/storage/backpack/marine/satchel(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 66933b9cb5f..cc9cbb66fc5 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -160,6 +160,28 @@ icon_opened = "open_medical" icon_closed = "closed_medical" +/obj/structure/closet/crate/mounted + name = "mounted weapon crate" + desc = "A robust crate containing stationary weapons." + icon_state = "closed_mounted_weapon" + icon_opened = "open_mounted_weapon" + icon_closed = "closed_mounted_weapon" + +/obj/structure/closet/crate/smart + name = "smart weapon crate" + desc = "A robust crate containing high-tech smartgun weapons and ammunitions." + icon_state = "closed_smart" + overlay_welded = "welded_smart" + icon_opened = "open_smart" + icon_closed = "closed_smart" + +/obj/structure/closet/crate/operations + name = "operations crate" + desc = "A robust crate containing support stuff." + icon_state = "close_operate" + icon_opened = "open_operate" + icon_closed = "close_operate" + /obj/structure/closet/crate/plastic name = "plastic crate" desc = "A rectangular plastic crate." diff --git a/code/game/objects/structures/crates_lockers/secure_crates.dm b/code/game/objects/structures/crates_lockers/secure_crates.dm index ac69840f78c..97483d65894 100644 --- a/code/game/objects/structures/crates_lockers/secure_crates.dm +++ b/code/game/objects/structures/crates_lockers/secure_crates.dm @@ -32,7 +32,6 @@ /obj/structure/closet/crate/secure/can_open() return !locked - /obj/structure/closet/crate/secure/verb/verb_togglelock() set src in oview(1) // One square distance set category = "Object" @@ -42,28 +41,30 @@ return togglelock(usr) - /obj/structure/closet/crate/secure/emp_act(severity) for(var/obj/O in src) O.emp_act(severity) - if(!broken && !opened && prob(50/severity)) + if(!broken && !opened && prob(50 / severity)) if(!locked) locked = 1 else overlays.Cut() overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* + addtimer(CALLBACK(src, PROC_REF(clear_sparks)), 0.6 SECONDS) playsound(src.loc, 'sound/effects/sparks4.ogg', 25, 1) locked = 0 update_icon() - if(!opened && prob(20/severity)) + if(!opened && prob(20 / severity)) if(!locked) open() else req_access = list() req_access += pick(ALL_ACCESS) - ..() + return ..() +/// Used in emp_act to clear sparks with delay +/obj/structure/closet/crate/secure/proc/clear_sparks() + overlays -= sparks //------------------------------------ // Secure Crates diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 5f8b89f5a62..1fc932f21ec 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -128,7 +128,7 @@ to_chat(user, span_notice("You place the [WD] on [src].")) WD.update_icon() -/obj/structure/grille/fire_act(burn_level) +/obj/structure/grille/fire_act(burn_level, flame_color) if(obj_integrity <= integrity_failure) return take_damage(1, BURN, FIRE) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 869b506bc49..9e94dfb7949 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -51,22 +51,12 @@ qdel(src) /obj/structure/lattice/proc/updateOverlays() - //if(!isspaceturf(loc)) - // qdel(src) - spawn(1) - overlays = list() - - var/dir_sum = 0 - - for (var/direction in GLOB.cardinals) - if(locate(/obj/structure/lattice, get_step(src, direction))) - dir_sum += direction - else - if(!isspaceturf(get_step(src, direction))) - dir_sum += direction - - icon_state = "lattice[dir_sum]" - return + var/dir_sum = 0 + for(var/direction in GLOB.cardinals) + if(!locate(/obj/structure/lattice, get_step(src, direction)) || isspaceturf(get_step(src, direction))) + continue + dir_sum += direction + icon_state = "lattice[dir_sum]" /obj/structure/catwalk icon = 'icons/obj/smooth_objects/catwalk.dmi' diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 6084c8ac4b7..f6f0a4af0b4 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -184,7 +184,7 @@ return ..() -/obj/structure/mineral_door/transparent/phoron/fire_act(burn_level) +/obj/structure/mineral_door/transparent/phoron/fire_act(burn_level, flame_color) if(burn_level > 30) var/turf/T = get_turf(src) T.ignite(25, 25) diff --git a/code/game/objects/structures/reagent_dispensers.dm b/code/game/objects/structures/reagent_dispensers.dm index 44d61aca7f1..223f1131fe7 100644 --- a/code/game/objects/structures/reagent_dispensers.dm +++ b/code/game/objects/structures/reagent_dispensers.dm @@ -186,7 +186,7 @@ flame_radius(round(reagents.total_volume * 0.005), loc) qdel(src) -/obj/structure/reagent_dispensers/fueltank/fire_act(burn_level) +/obj/structure/reagent_dispensers/fueltank/fire_act(burn_level, flame_color) explode() /obj/structure/reagent_dispensers/fueltank/Moved(atom/old_loc, movement_dir, forced, list/old_locs) diff --git a/code/game/objects/structures/supplypod.dm b/code/game/objects/structures/supplypod.dm index 4feff8ff194..5d8bbf52f8a 100644 --- a/code/game/objects/structures/supplypod.dm +++ b/code/game/objects/structures/supplypod.dm @@ -248,7 +248,6 @@ GLOBAL_LIST_INIT(pod_styles, list(\ return ..() - /obj/effect/DPtarget name = "Landing Zone Indicator" desc = "A holographic projection designating the landing zone of something. It's probably best to stand back." @@ -258,11 +257,6 @@ GLOBAL_LIST_INIT(pod_styles, list(\ var/obj/effect/temp_visual/fallingPod var/obj/structure/closet/supplypod/pod - -/obj/effect/ex_act() - return - - /obj/effect/DPtarget/Initialize(mapload, podParam, single_order) . = ..() if(!podParam) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index b546c2c910b..ad608ce8c3f 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -234,21 +234,27 @@ if(watertemp == WATER_TEMP_FREEZING) return if(!ismist) - spawn(50) - if(src && on) - ismist = TRUE - mymist = new /obj/effect/mist(loc) + addtimer(CALLBACK(src, PROC_REF(spawn_mist)), 5 SECONDS) else ismist = TRUE mymist = new /obj/effect/mist(loc) else if(ismist) ismist = TRUE mymist = new /obj/effect/mist(loc) - spawn(250) - if(src && !on) - qdel(mymist) - mymist = null - ismist = FALSE + addtimer(CALLBACK(src, PROC_REF(clean_mist)), 25 SECONDS) + +/obj/machinery/shower/proc/spawn_mist() + if(!on) + return + ismist = TRUE + mymist = new /obj/effect/mist(loc) + +/obj/machinery/shower/proc/clean_mist() + if(on) + return + qdel(mymist) + mymist = null + ismist = FALSE /obj/machinery/shower/update_overlays() . = ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 9bc46b88902..0baa51f4fec 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -301,7 +301,7 @@ explosion_block = EXPLOSION_BLOCK_PROC real_explosion_block = 4 -/obj/structure/window/phoronreinforced/fire_act(burn_level) +/obj/structure/window/phoronreinforced/fire_act(burn_level, flame_color) return /obj/structure/window/reinforced diff --git a/code/game/turfs/floor.dm b/code/game/turfs/floor.dm index 8feee5b0cc8..cff2727aa38 100644 --- a/code/game/turfs/floor.dm +++ b/code/game/turfs/floor.dm @@ -35,7 +35,7 @@ break_tile() return ..() -/turf/open/floor/fire_act(burn_level) +/turf/open/floor/fire_act(burn_level, flame_color) if(hull_floor) return if(!burnt && prob(5)) diff --git a/code/game/turfs/floor_ground.dm b/code/game/turfs/floor_ground.dm index 06be18e2d1b..871fb521586 100644 --- a/code/game/turfs/floor_ground.dm +++ b/code/game/turfs/floor_ground.dm @@ -11,7 +11,7 @@ /turf/open/floor/plating/ground/burnt_states() return icon_state -/turf/open/floor/plating/ground/fire_act(burn_level) +/turf/open/floor/plating/ground/fire_act(burn_level, flame_color) return /turf/open/floor/plating/ground/dirt diff --git a/code/game/turfs/floor_types.dm b/code/game/turfs/floor_types.dm index 04857157c53..f1f97d03357 100644 --- a/code/game/turfs/floor_types.dm +++ b/code/game/turfs/floor_types.dm @@ -166,7 +166,7 @@ /turf/open/floor/mainship/empty/is_weedable() return FALSE -/turf/open/floor/mainship/empty/fire_act(burn_level) +/turf/open/floor/mainship/empty/fire_act(burn_level, flame_color) return /turf/open/floor/mainship/empty/attackby(obj/item/I, mob/user, params) //This should fix everything else. No cables, etc diff --git a/code/game/turfs/plating.dm b/code/game/turfs/plating.dm index 0c20dd16944..182951ef0fa 100644 --- a/code/game/turfs/plating.dm +++ b/code/game/turfs/plating.dm @@ -17,7 +17,7 @@ /turf/open/floor/plating/make_plating() return //we don't dig past plating -/turf/open/floor/plating/fire_act(burn_level) +/turf/open/floor/plating/fire_act(burn_level, flame_color) if(hull_floor) return if(!burnt && prob(5)) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ba783d10d62..1e8a6abafaf 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -108,7 +108,7 @@ stack_trace("Incorrect turf deletion") changing_turf = FALSE if(force) - ..() + . = ..() //this will completely wipe turf state var/turf/B = new world.turf(src) for(var/A in B.contents) @@ -120,7 +120,7 @@ DISABLE_BITFIELD(flags_atom, INITIALIZED) soft_armor = null hard_armor = null - ..() + . = ..() return QDEL_HINT_IWILLGC /// WARNING WARNING @@ -411,44 +411,41 @@ /turf/proc/ceiling_debris(size = 1) //debris falling in response to airstrikes, etc var/area/A = get_area(src) if(!A.ceiling) return - - var/amount = size - var/spread = round(sqrt(size)*1.5) + var/spread = round(sqrt(size) * 1.5) var/list/turfs = list() - for(var/turf/open/floor/F in range(src,spread)) + for(var/turf/open/floor/F in range(src, spread)) turfs += F + var/drop_message + var/list/debris_list switch(A.ceiling) + if(CEILING_NONE) + return if(CEILING_GLASS) playsound(src, 'sound/effects/glassbr1.ogg', 60, 1) - spawn(8) - if(amount >1) - visible_message(span_boldnotice("Shards of glass rain down from above!")) - for(var/i=1, i<=amount, i++) - new /obj/item/shard(pick(turfs)) - new /obj/item/shard(pick(turfs)) + drop_message = "Shards of glass rain down from above!" + debris_list = list(/obj/item/shard, /obj/item/shard) if(CEILING_METAL, CEILING_OBSTRUCTED) playsound(src, 'sound/effects/metal_crash.ogg', 30, 1) - spawn(8) - if(amount >1) - visible_message(span_boldnotice("Pieces of metal crash down from above!")) - for(var/i=1, i<=amount, i++) - new /obj/item/stack/sheet/metal(pick(turfs)) + drop_message = "Pieces of metal crash down from above!" + debris_list = list(/obj/item/stack/sheet/metal) if(CEILING_UNDERGROUND, CEILING_DEEP_UNDERGROUND) playsound(src, 'sound/effects/meteorimpact.ogg', 60, 1) - spawn(8) - if(amount >1) - visible_message(span_boldnotice("Chunks of rock crash down from above!")) - for(var/i = 1, i <= amount, i++) - new /obj/item/ore(pick(turfs)) - new /obj/item/ore(pick(turfs)) + drop_message = "Chunks of rock crash down from above!" + debris_list = list(/obj/item/ore, /obj/item/ore) if(CEILING_UNDERGROUND_METAL, CEILING_DEEP_UNDERGROUND_METAL) playsound(src, 'sound/effects/metal_crash.ogg', 60, 1) - spawn(8) - for(var/i = 1, i <= amount, i++) - new /obj/item/stack/sheet/metal(pick(turfs)) - new /obj/item/ore(pick(turfs)) + debris_list = list(/obj/item/stack/sheet/metal, /obj/item/ore) + addtimer(CALLBACK(src, PROC_REF(drop_ceiling_debris), debris_list, size, drop_message, turfs), 0.8 SECONDS) + +/// Drop amount of listed stuff in listed turfs, with a message if amount is more than 1 +/turf/proc/drop_ceiling_debris(list/stuff_to_drop, amount, drop_message, list/turfs) + if(amount > 1 && drop_message) + visible_message(span_boldnotice(drop_message)) + for(var/i = 1, i <= amount, i++) + for(var/item_to_drop AS in stuff_to_drop) + new item_to_drop(pick(turfs)) /turf/proc/ceiling_desc() var/area/A = get_area(src) diff --git a/code/game/turfs/walls/resin.dm b/code/game/turfs/walls/resin.dm index 1a3c34285be..d12a9cf6649 100644 --- a/code/game/turfs/walls/resin.dm +++ b/code/game/turfs/walls/resin.dm @@ -10,7 +10,7 @@ smoothing_flags = SMOOTH_BITMASK smoothing_groups = list(SMOOTH_GROUP_XENO_STRUCTURES) canSmoothWith = list(SMOOTH_GROUP_XENO_STRUCTURES) - soft_armor = list(MELEE = 0, BULLET = 70, LASER = 60, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) + soft_armor = list(MELEE = 30, BULLET = 70, LASER = 60, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) resistance_flags = UNACIDABLE /turf/closed/wall/resin/add_debris_element() @@ -186,7 +186,7 @@ icon_state = "resin-wall-0" walltype = "resin-wall" base_icon_state = "resin-wall" - soft_armor = list(MELEE = 0, BULLET = 70, LASER = 60, ENERGY = 0, BOMB = 100, BIO = 0, FIRE = 0, ACID = 0) + soft_armor = list(MELEE = 15, BULLET = 35, LASER = 30, ENERGY = 0, BOMB = 100, BIO = 0, FIRE = 0, ACID = 0) max_upgradable_health = 200 /turf/closed/wall/resin/regenerating/bulletproof @@ -196,7 +196,7 @@ icon_state = "resin-wall-0" walltype = "resin-wall" base_icon_state = "resin-wall" - soft_armor = list(MELEE = 0, BULLET = 150, LASER = 150, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) + soft_armor = list(MELEE = 15, BULLET = 150, LASER = 150, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) max_upgradable_health = 200 /turf/closed/wall/resin/regenerating/fireproof @@ -206,7 +206,7 @@ icon_state = "resin-wall-0" walltype = "resin-wall" base_icon_state = "resin-wall" - soft_armor = list(MELEE = 0, BULLET = 70, LASER = 60, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 100, ACID = 0) + soft_armor = list(MELEE = 15, BULLET = 35, LASER = 30, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 100, ACID = 0) max_upgradable_health = 200 /turf/closed/wall/resin/regenerating/meleeproof @@ -216,5 +216,5 @@ icon_state = "resin-wall-0" walltype = "resin-wall" base_icon_state = "resin-wall" - soft_armor = list(MELEE = 100, BULLET = 70, LASER = 60, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) + soft_armor = list(MELEE = 100, BULLET = 35, LASER = 30, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) max_upgradable_health = 200 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 93580c1ba36..e97b048c92f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -800,7 +800,7 @@ /client/proc/ticket_reply(whom) - if(prefs.muted & MUTE_ADMINHELP) + if(prefs.muted & MUTE_ADMINHELP || is_banned_from(ckey, "Adminhelp")) to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_warning("Error: You are unable to use admin PMs (muted).")) @@ -849,7 +849,7 @@ /client/proc/private_message(whom, msg) - if(prefs.muted & MUTE_ADMINHELP) + if(prefs.muted & MUTE_ADMINHELP || is_banned_from(ckey, "Adminhelp")) to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_warning("You are unable to use admin PMs (muted).")) @@ -918,7 +918,7 @@ if(!msg) return - if(prefs.muted & MUTE_ADMINHELP) + if(prefs.muted & MUTE_ADMINHELP || is_banned_from(ckey, "Adminhelp")) to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_warning("You are unable to use admin PMs (muted).")) diff --git a/code/modules/admin/panels/ban_panel.dm b/code/modules/admin/panels/ban_panel.dm index eb3c8c0217d..61cdc54aa24 100644 --- a/code/modules/admin/panels/ban_panel.dm +++ b/code/modules/admin/panels/ban_panel.dm @@ -316,7 +316,7 @@ break_counter++ output += "" //departments/groups that don't have command staff would throw a javascript error since there's no corresponding reference for toggle_head() - var/list/headless_job_lists = list("Abstract" = list("Appearance", "IC", "Emote", "OOC", "LOOC", "Deadchat")) + var/list/headless_job_lists = list("Abstract" = list("Appearance", "IC", "Emote", "OOC", "LOOC", "Deadchat", "Adminhelp")) for(var/department in headless_job_lists) output += "
" var/break_counter = 0 diff --git a/code/modules/admin/panels/player_panel.dm b/code/modules/admin/panels/player_panel.dm index 80836fe1029..10e3e831d38 100644 --- a/code/modules/admin/panels/player_panel.dm +++ b/code/modules/admin/panels/player_panel.dm @@ -492,6 +492,7 @@ Crusher | Gorger | Warlock | + Widow | Behemoth | Chimera
Alien Tier 4: diff --git a/code/modules/admin/server_verbs.dm b/code/modules/admin/server_verbs.dm index 086f4e6ba2b..8fcddcdabe2 100644 --- a/code/modules/admin/server_verbs.dm +++ b/code/modules/admin/server_verbs.dm @@ -444,6 +444,9 @@ if(!check_rights(R_SERVER)) return + if(tgui_alert(usr, "Are you sure you want to reload admins?", "Reload admins", list("No", "Yes")) != "Yes") + return + load_admins() log_admin("[key_name(src)] manually reloaded admins.") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 3f617d74cdf..f4ad78eea8e 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -432,6 +432,8 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"] newmob = M.change_mob_type(/mob/living/carbon/xenomorph/gorger, location, null, delmob) if("warlock") newmob = M.change_mob_type(/mob/living/carbon/xenomorph/warlock, location, null, delmob) + if("widow") + newmob = M.change_mob_type(/mob/living/carbon/xenomorph/widow, location, null, delmob) if("shrike") newmob = M.change_mob_type(/mob/living/carbon/xenomorph/shrike, location, null, delmob) if("hivemind") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 118b6fc0432..0a01db3b1ee 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -784,7 +784,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) set name = "Adminhelp" //handle muting and automuting - if(prefs.muted & MUTE_ADMINHELP) + if(prefs.muted & MUTE_ADMINHELP || is_banned_from(ckey, "Adminhelp")) to_chat(src, span_warning("Error: You cannot send adminhelps (Muted).")) return @@ -815,7 +815,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) set name = "Mentorhelp" //handle muting and automuting - if(prefs.muted & MUTE_ADMINHELP) + if(prefs.muted & MUTE_ADMINHELP || is_banned_from(ckey, "Adminhelp")) to_chat(src, span_warning("Error: You cannot send mentorhelps (Muted).")) return diff --git a/code/modules/ai/ai_behaviors/ai_behavior.dm b/code/modules/ai/ai_behaviors/ai_behavior.dm index 0771c6f2d54..86a7430165c 100644 --- a/code/modules/ai/ai_behaviors/ai_behavior.dm +++ b/code/modules/ai/ai_behaviors/ai_behavior.dm @@ -345,6 +345,9 @@ These are parameter based so the ai behavior can choose to (un)register the sign /datum/ai_behavior/proc/ai_do_move() if(!mob_parent?.canmove || mob_parent.do_actions) return + //This allows minions to be buckled to their atom_to_escort without disrupting the movement of atom_to_escort + if(current_action == ESCORTING_ATOM && (get_dist(mob_parent, atom_to_walk_to) <= 0)) //todo: Entirely remove this shitcode snowflake check for one specific interaction that doesn't specifically relate to ai_behavior + return mob_parent.next_move_slowdown = 0 var/step_dir if(get_dist(mob_parent, atom_to_walk_to) == distance_to_maintain) @@ -359,6 +362,7 @@ These are parameter based so the ai behavior can choose to (un)register the sign SEND_SIGNAL(mob_parent, COMSIG_OBSTRUCTED_MOVE, step_dir) else if(ISDIAGONALDIR(step_dir)) mob_parent.next_move_slowdown += (DIAG_MOVEMENT_ADDED_DELAY_MULTIPLIER - 1) * mob_parent.cached_multiplicative_slowdown //Not perfect but good enough + mob_parent.set_glide_size(DELAY_TO_GLIDE_SIZE(mob_parent.cached_multiplicative_slowdown)) return if(prob(sidestep_prob)) step_dir = pick(LeftAndRightOfDir(get_dir(mob_parent, atom_to_walk_to))) @@ -367,6 +371,7 @@ These are parameter based so the ai behavior can choose to (un)register the sign SEND_SIGNAL(mob_parent, COMSIG_OBSTRUCTED_MOVE, step_dir) else if(ISDIAGONALDIR(step_dir)) mob_parent.next_move_slowdown += (DIAG_MOVEMENT_ADDED_DELAY_MULTIPLIER - 1) * mob_parent.cached_multiplicative_slowdown + mob_parent.set_glide_size(DELAY_TO_GLIDE_SIZE(mob_parent.cached_multiplicative_slowdown)) return if(get_dist(mob_parent, atom_to_walk_to) < distance_to_maintain) //We're too close, back it up step_dir = get_dir(atom_to_walk_to, mob_parent) diff --git a/code/modules/animations/animation_library.dm b/code/modules/animations/animation_library.dm index ad35e283ead..21ce7ed07d2 100644 --- a/code/modules/animations/animation_library.dm +++ b/code/modules/animations/animation_library.dm @@ -52,9 +52,7 @@ Instead of being uniform, it starts out a littler slower, goes fast in the middl A.status_flags |= INCORPOREAL var/initial_matrix = A.transform animate(A, transform = matrix(0, 4, MATRIX_SCALE), alpha = 0, time = speed, easing = BACK_EASING) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) return speed //We want to make sure to reset color here as it can be changed by other animations. @@ -64,9 +62,7 @@ Instead of being uniform, it starts out a littler slower, goes fast in the middl A.transform = matrix(0, 4, MATRIX_SCALE) A.alpha = 0 //Start with transparency, just in case. animate(A, alpha = 255, transform = null, color = "#FFFFFF", time = speed, easing = BACK_EASING) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) return speed /*A magical teleport animation, for when the person is transported with some magic. Good for Halloween type events. @@ -79,10 +75,8 @@ Can look good elsewhere as well.*/ animate(alpha = 0, time = speed) var/image/I = image('icons/effects/effects.dmi',A,"sparkle") flick_overlay_view(I, A, 9) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL - return speed*3 + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) + return speed * 3 /proc/animation_teleport_magic_in(atom/A, speed = 6) A.status_flags |= INCORPOREAL @@ -94,9 +88,7 @@ Can look good elsewhere as well.*/ animate(transform = null, time = speed-1) var/image/I = image('icons/effects/effects.dmi',A,"sparkle") flick_overlay_view(I, A, 10) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) return speed //A spooky teleport for evil dolls, horrors, and whatever else. Halloween type stuff. @@ -108,9 +100,7 @@ Can look good elsewhere as well.*/ animate(alpha = 0, time = speed) var/image/I = image('icons/effects/effects.dmi',A,"spooky") flick_overlay_view(I, A, 9) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) return speed*3 /proc/animation_teleport_spooky_in(atom/A, speed = 4) @@ -122,9 +112,7 @@ Can look good elsewhere as well.*/ animate(transform = null, color = "#FFFFFF", time = speed, easing = QUAD_EASING|EASE_OUT) var/image/I = image('icons/effects/effects.dmi',A,"spooky") flick_overlay_view(I, A, 10) - spawn(speed) - A.transform = initial_matrix - A.status_flags &= ~INCORPOREAL + addtimer(CALLBACK(A, PROC_REF(transform_initial_matrix), A, initial_matrix), speed) return speed //Regular fadeout disappear, for most objects. @@ -166,3 +154,7 @@ Can look good elsewhere as well.*/ animate(src, transform = matrix_list[1], time = speed, loop_amount) for(var/i in 2 to sections) animate(transform = matrix_list[i], time = speed) + +/proc/transform_initial_matrix(atom/our_atom, initial_matrix) + our_atom.transform = initial_matrix + our_atom.status_flags &= ~INCORPOREAL diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f0917608b8d..b85f6ddc9f0 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -77,10 +77,14 @@ return storage_attachment.storage.do_quick_equip(user) return src -//Updates the icons of the mob wearing the clothing item, if any. +///Updates the icons of the mob wearing the clothing item, if any. /obj/item/clothing/proc/update_clothing_icon() return +///Change the look of the clothing, when it's antihug reaches 0 +/obj/item/clothing/proc/on_hugger_damage() + return + /obj/item/clothing/update_greyscale() . = ..() if(!greyscale_config) @@ -188,7 +192,6 @@ flags_armor_features ^= ARMOR_LAMP_ON playsound(src, 'sound/items/flashlight.ogg', 15, TRUE) update_icon() - update_action_button_icons() /obj/item/clothing/suit/update_clothing_icon() if(ismob(loc)) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 0f15f57890b..edd75d49b60 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -111,7 +111,7 @@ desc = "Standard issue TGMC Regulation Prescription Glasses. This pair has been fitted with an internal HealthMate HUD projector." icon_state = "medglasses" item_state = "medglasses" - deactive_state = "deactivated__medglasses" + deactive_state = "deactivated_medglasses" species_exception = list(/datum/species/robot) sprite_sheets = list( "Combat Robot" = 'icons/mob/species/robot/glasses.dmi', diff --git a/code/modules/clothing/glasses/thermal.dm b/code/modules/clothing/glasses/thermal.dm index f93bbc91c8c..d34cc6edc93 100644 --- a/code/modules/clothing/glasses/thermal.dm +++ b/code/modules/clothing/glasses/thermal.dm @@ -15,10 +15,7 @@ if(M.glasses == src) M.blind_eyes(3) M.blur_eyes(5) - M.disabilities |= NEARSIGHTED - spawn(100) - M.disabilities &= ~NEARSIGHTED - ..() + return ..() /obj/item/clothing/glasses/thermal/yautja name = "bio-mask thermal" @@ -37,14 +34,14 @@ /obj/item/clothing/glasses/thermal/yautja/dropped(mob/living/carbon/human/user) if(istype(user) && user.glasses == src) user.clear_fullscreen("machine", 5) - ..() + return ..() /obj/item/clothing/glasses/thermal/yautja/equipped(mob/living/carbon/human/user, slot) if(slot == SLOT_GLASSES) user.overlay_fullscreen("machine", /atom/movable/screen/fullscreen/machine/pred) - ..() + return ..() /obj/item/clothing/glasses/thermal/yautja/unequipped(mob/living/carbon/human/user, slot) if(slot == SLOT_GLASSES) user.clear_fullscreen("machine", 5) - ..() + return ..() diff --git a/code/modules/clothing/head/head.dm b/code/modules/clothing/head/head.dm index 0a7471c49cb..e7caed60523 100644 --- a/code/modules/clothing/head/head.dm +++ b/code/modules/clothing/head/head.dm @@ -11,6 +11,7 @@ blood_sprite_state = "helmetblood" attachments_by_slot = list(ATTACHMENT_SLOT_BADGE) attachments_allowed = list(/obj/item/armor_module/armor/badge) + soft_armor = MARINE_HAT_ARMOR var/anti_hug = 0 /obj/item/clothing/head/update_clothing_icon() @@ -49,7 +50,6 @@ icon_state = "beanie_cargo" flags_inv_hide = HIDETOPHAIR species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR /obj/item/clothing/head/tgmcberet name = "\improper Dark gray beret" @@ -60,7 +60,6 @@ slot_l_hand_str = 'icons/mob/items_lefthand_1.dmi', slot_r_hand_str = 'icons/mob/items_righthand_1.dmi',) icon_state = "beret" - soft_armor = MARINE_HAT_ARMOR flags_item_map_variant = NONE flags_armor_features = ARMOR_NO_DECAP @@ -108,7 +107,6 @@ name = "\improper Command Master at Arms beret" desc = "A beret with the lieutenant insignia emblazoned on it. It shines with the glow of corrupt authority and a smudge of doughnut." icon_state = "beretwo" - soft_armor = MARINE_HAT_ARMOR flags_item_map_variant = NONE /obj/item/clothing/head/tgmcberet/fc @@ -128,7 +126,6 @@ slot_l_hand_str = 'icons/mob/items_lefthand_1.dmi', slot_r_hand_str = 'icons/mob/items_righthand_1.dmi',) species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR var/flipped_cap = FALSE var/base_cap_icon flags_item_map_variant = (ITEM_ICE_VARIANT) @@ -174,7 +171,6 @@ icon_state = "booniehat" item_state = "booniehat" species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR /obj/item/clothing/head/ornamented_cap name = "\improper ornamented cap" @@ -184,7 +180,6 @@ item_icons = list( slot_head_str = 'icons/mob/clothing/headwear/marine_hats.dmi',) species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR flags_armor_features = ARMOR_NO_DECAP /obj/item/clothing/head/slouch @@ -196,7 +191,6 @@ slot_head_str = 'icons/mob/clothing/headwear/marine_hats.dmi', ) species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR /obj/item/clothing/head/headband name = "\improper Cyan headband" @@ -208,7 +202,6 @@ slot_r_hand_str = 'icons/mob/items_righthand_1.dmi',) icon_state = "headband" species_exception = list(/datum/species/robot) - soft_armor = MARINE_HAT_ARMOR flags_armor_features = ARMOR_NO_DECAP /obj/item/clothing/head/headband/red @@ -249,7 +242,6 @@ name = "marine officer beret" desc = "A beret with the TGMC insignia emblazoned on it. It radiates respect and authority." icon_state = "hosberet" - soft_armor = MARINE_HAT_ARMOR flags_inventory = BLOCKSHARPOBJ /obj/item/clothing/head/beret/marine/captain @@ -276,7 +268,6 @@ icon_state = "ushankadown" item_state = "ushankadown" species_exception = list(/datum/species/robot) - soft_armor = list(MELEE = 35, BULLET = 35, LASER = 20, ENERGY = 10, BOMB = 10, BIO = 0, FIRE = 10, ACID = 10) flags_cold_protection = HEAD min_cold_protection_temperature = ICE_PLANET_MIN_COLD_PROTECTION_TEMPERATURE flags_inventory = BLOCKSHARPOBJ @@ -415,7 +406,6 @@ icon = 'icons/obj/clothing/headwear/ert_headwear.dmi' icon_state = "straw_hat" species_exception = list(/datum/species/robot) - soft_armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 15, BIO = 10, FIRE = 20, ACID = 20) /obj/item/clothing/head/squad_headband name = "\improper Squad headband" @@ -623,7 +613,6 @@ item_icons = list( slot_head_str = 'icons/mob/clothing/headwear/marine_hats.dmi') icon_state = "cap_black" - soft_armor = MARINE_HAT_ARMOR flags_inventory = BLOCKSHARPOBJ flags_armor_features = ARMOR_NO_DECAP species_exception = list(/datum/species/robot) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 9ca5b62b411..c7bfef122e6 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -89,6 +89,12 @@ siemens_coefficient = 0.7 flags_armor_protection = FACE|EYES +/obj/item/clothing/mask/gas/swat/on_hugger_damage() + name = "\improper torn SWAT mask" + icon_state = "swat_torn" + update_clothing_icon() + playsound(src, 'sound/items/velpro_rip.ogg', 25) + /obj/item/clothing/mask/gas/syndicate name = "syndicate mask" desc = "A close-fitting tactical mask that can be connected to an air supply." diff --git a/code/modules/clothing/modular_armor/attachments.dm b/code/modules/clothing/modular_armor/attachments.dm index 779cff9f0c4..2f1f9de34ef 100644 --- a/code/modules/clothing/modular_armor/attachments.dm +++ b/code/modules/clothing/modular_armor/attachments.dm @@ -119,7 +119,6 @@ /obj/item/armor_module/ui_action_click(mob/user, datum/action/item_action/toggle/action) action.set_toggle(activate(user)) - action.update_button_icon() ///Called on ui_action_click. Used for activating the module. /obj/item/armor_module/proc/activate(mob/living/user) diff --git a/code/modules/clothing/modular_armor/attachments/storage.dm b/code/modules/clothing/modular_armor/attachments/storage.dm index 8ec92eac84d..19983e0bc95 100644 --- a/code/modules/clothing/modular_armor/attachments/storage.dm +++ b/code/modules/clothing/modular_armor/attachments/storage.dm @@ -363,6 +363,7 @@ /obj/item/storage/internal/modular/integrated bypass_w_limit = list() + cant_hold = list() storage_slots = null max_storage_space = 15 max_w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/clothing/modular_armor/modular.dm b/code/modules/clothing/modular_armor/modular.dm index ac656e7bea4..28b0aa1aec2 100644 --- a/code/modules/clothing/modular_armor/modular.dm +++ b/code/modules/clothing/modular_armor/modular.dm @@ -156,7 +156,6 @@ return FALSE return ..() - /obj/item/clothing/suit/modular/attack_self(mob/user) . = ..() if(.) diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index 1da5cd8857d..497d330dc88 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -16,52 +16,51 @@ . = ..() machine_id = "EFTPOS #[GLOB.num_financial_terminals++]" access_code = rand(1111,111111) - spawn(0) - print_reference() - - //create a short manual as well - var/obj/item/paper/R = new(src.loc) - R.name = "Steps to success: Correct EFTPOS Usage" - /* - R.info += "When first setting up your EFTPOS device:" - R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).
" - R.info += "2. Confirm that your EFTPOS device is connected to your local accounts database. For additional assistance with this step, contact NanoTrasen IT Support
" - R.info += "3. Confirm that your EFTPOS device has been linked to the account that you wish to recieve funds for all transactions processed on this device.
" - R.info += "When starting a new transaction with your EFTPOS device:" - R.info += "1. Ensure the device is UNLOCKED so that new data may be entered.
" - R.info += "2. Enter a sum of money and reference message for the new transaction.
" - R.info += "3. Lock the transaction, it is now ready for your customer.
" - R.info += "4. If at this stage you wish to modify or cancel your transaction, you may simply reset (unlock) your EFTPOS device.
" - R.info += "5. Give your EFTPOS device to the customer, they must authenticate the transaction by swiping their ID card and entering their PIN number.
" - R.info += "6. If done correctly, the transaction will be logged to both accounts with the reference you have entered, the terminal ID of your EFTPOS device and the money transferred across accounts.
" - */ - //Temptative new manual: - R.info += "First EFTPOS setup:
" - R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).
" - R.info += "2. Connect the EFTPOS to the account in which you want to receive the funds.

" - R.info += "When starting a new transaction:
" - R.info += "1. Enter the amount of money you want to charge and a purpose message for the new transaction.
" - R.info += "2. Lock the new transaction. If you want to modify or cancel the transaction, you simply have to reset your EFTPOS device.
" - R.info += "3. Give the EFTPOS device to your customer, he/she must finish the transaction by swiping their ID card or a charge card with enough funds.
" - R.info += "4. If everything is done correctly, the money will be transferred. To unlock the device you will have to reset the EFTPOS device.
" - - - //stamp the paper - var/image/stampoverlay = image('icons/obj/items/paper.dmi') - stampoverlay.icon_state = "paper_stamp-cent" - if(!R.stamped) - R.stamped = new - R.offset_x += 0 - R.offset_y += 0 - R.ico += "paper_stamp-cent" - R.stamped += /obj/item/tool/stamp - R.overlays += stampoverlay - R.stamps += "
This paper has been stamped by the EFTPOS device." - + INVOKE_ASYNC(src, PROC_REF(print_paper)) //by default, connect to the station account //the user of the EFTPOS device can change the target account though, and no-one will be the wiser (except whoever's being charged) linked_account = GLOB.station_account +/obj/item/eftpos/proc/print_paper() + print_reference() + //create a short manual as well + var/obj/item/paper/R = new(src.loc) + R.name = "Steps to success: Correct EFTPOS Usage" + /* + R.info += "When first setting up your EFTPOS device:" + R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).
" + R.info += "2. Confirm that your EFTPOS device is connected to your local accounts database. For additional assistance with this step, contact NanoTrasen IT Support
" + R.info += "3. Confirm that your EFTPOS device has been linked to the account that you wish to recieve funds for all transactions processed on this device.
" + R.info += "When starting a new transaction with your EFTPOS device:" + R.info += "1. Ensure the device is UNLOCKED so that new data may be entered.
" + R.info += "2. Enter a sum of money and reference message for the new transaction.
" + R.info += "3. Lock the transaction, it is now ready for your customer.
" + R.info += "4. If at this stage you wish to modify or cancel your transaction, you may simply reset (unlock) your EFTPOS device.
" + R.info += "5. Give your EFTPOS device to the customer, they must authenticate the transaction by swiping their ID card and entering their PIN number.
" + R.info += "6. If done correctly, the transaction will be logged to both accounts with the reference you have entered, the terminal ID of your EFTPOS device and the money transferred across accounts.
" + */ + //Temptative new manual: + R.info += "First EFTPOS setup:
" + R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).
" + R.info += "2. Connect the EFTPOS to the account in which you want to receive the funds.

" + R.info += "When starting a new transaction:
" + R.info += "1. Enter the amount of money you want to charge and a purpose message for the new transaction.
" + R.info += "2. Lock the new transaction. If you want to modify or cancel the transaction, you simply have to reset your EFTPOS device.
" + R.info += "3. Give the EFTPOS device to your customer, he/she must finish the transaction by swiping their ID card or a charge card with enough funds.
" + R.info += "4. If everything is done correctly, the money will be transferred. To unlock the device you will have to reset the EFTPOS device.
" + + //stamp the paper + var/image/stampoverlay = image('icons/obj/items/paper.dmi') + stampoverlay.icon_state = "paper_stamp-cent" + if(!R.stamped) + R.stamped = new + R.offset_x += 0 + R.offset_y += 0 + R.ico += "paper_stamp-cent" + R.stamped += /obj/item/tool/stamp + R.overlays += stampoverlay + R.stamps += "
This paper has been stamped by the EFTPOS device." + /obj/item/eftpos/proc/print_reference() var/obj/item/paper/R = new(src.loc) R.name = "Reference: [eftpos_name]" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index e1c233a5dc9..178669835ef 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -64,21 +64,13 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) CE = /datum/config_entry/number/error_silence_time configured_error_silence_time = initial(CE.config_entry_value) - //Each occurence of a unique error adds to its cooldown time... cooldown = max(0, cooldown - (world.time - last_seen)) + configured_error_cooldown // ... which is used to silence an error if it occurs too often, too fast if(cooldown > configured_error_cooldown * configured_error_limit) cooldown = -1 silencing = TRUE - spawn(0) //Has to be used here - usr = null - sleep(configured_error_silence_time) //Has to be used here - var/skipcount = abs(error_cooldown[erroruid]) - 1 - error_cooldown[erroruid] = 0 - if(skipcount > 0) - SEND_TEXT(world.log, "\[[time_stamp()]] Skipped [skipcount] runtimes in [E.file],[E.line].") - GLOB.error_cache.log_error(E, skip_count = skipcount) + INVOKE_ASYNC(src, PROC_REF(log_errors), configured_error_silence_time, error_cooldown, erroruid, E) error_last_seen[erroruid] = world.time error_cooldown[erroruid] = cooldown @@ -125,6 +117,14 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) GLOB.current_test.Fail("[main_line]\n[desclines.Join("\n")]") #endif - // This writes the regular format (unwrapping newlines and inserting timestamps as needed). log_runtime("runtime error: [E.name]\n[E.desc]") + +/world/proc/log_errors(silence_time, error_cooldown, erroruid, exception/our_exception) + usr = null + sleep(silence_time) //Has to be used here + var/skipcount = abs(error_cooldown[erroruid]) - 1 + error_cooldown[erroruid] = 0 + if(skipcount > 0) + SEND_TEXT(world.log, "\[[time_stamp()]] Skipped [skipcount] runtimes in [our_exception.file], [our_exception.line].") + GLOB.error_cache.log_error(our_exception, skip_count = skipcount) diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm index 4910bcb06ad..6cb041df313 100644 --- a/code/modules/hydroponics/vines.dm +++ b/code/modules/hydroponics/vines.dm @@ -205,7 +205,7 @@ die() // Hotspots kill vines. -/obj/effect/plantsegment/fire_act(burn_level) +/obj/effect/plantsegment/fire_act(burn_level, flame_color) qdel(src) /obj/effect/plantsegment/proc/die() diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 71107ca43df..0b610d8aedd 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -8,10 +8,12 @@ var/tmp/list/atom/movable/lighting_mask/hybrid_lights_affecting /turf/Destroy(force) - if(hybrid_lights_affecting) - for(var/atom/movable/lighting_mask/mask AS in hybrid_lights_affecting) - LAZYREMOVE(mask.affecting_turfs, src) - hybrid_lights_affecting.Cut() + if(!hybrid_lights_affecting) + return ..() + + for(var/atom/movable/lighting_mask/mask AS in hybrid_lights_affecting) + LAZYREMOVE(mask.affecting_turfs, src) + hybrid_lights_affecting.Cut() return ..() /// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index e72b354e1d5..51eb4f53c37 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -35,18 +35,17 @@ for(var/path in subtypesof(/datum/action/observer_action)) if(!actions_by_path[path]) - var/datum/action/observer_action/A = new path() + var/datum/action/observer_action/A = new path(src) A.give_action(src) client.AddComponent(/datum/component/larva_queue) if(!actions_by_path[/datum/action/minimap/observer]) - var/datum/action/minimap/observer/mini = new + var/datum/action/minimap/observer/mini = new(src) mini.give_action(src) if(length(GLOB.offered_mob_list)) to_chat(src, span_boldnotice("There's mobs available for taking! Ghost > Take Offered Mob")) -//RUTGMC EDIT + if(SSticker.mode && SSticker.mode.flags_round_type & MODE_PREDATOR) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), src, "This is a PREDATOR ROUND! If you are whitelisted, you may Join the Hunt!"), 2 SECONDS) -//RUTGMC EDIT diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index d31395e6682..21b4372887d 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -55,7 +55,10 @@ if(!l_hand) W.forceMove(src) l_hand = W - W.layer = ABOVE_HUD_LAYER + if(istype(W, /obj/item/weapon/twohanded/offhand) || istype(W, /obj/item/riding_offhand)) + W.layer = ABOVE_HUD_LAYER - 0.1 // so it doesn't cover items inhands + else + W.layer = ABOVE_HUD_LAYER W.plane = ABOVE_HUD_PLANE update_inv_l_hand() W.pixel_x = initial(W.pixel_x) @@ -83,7 +86,10 @@ if(!r_hand) W.forceMove(src) r_hand = W - W.layer = ABOVE_HUD_LAYER + if(istype(W, /obj/item/weapon/twohanded/offhand) || istype(W, /obj/item/riding_offhand)) + W.layer = ABOVE_HUD_LAYER - 0.1 // so it doesn't cover items inhands + else + W.layer = ABOVE_HUD_LAYER W.plane = ABOVE_HUD_PLANE update_inv_r_hand() W.pixel_x = initial(W.pixel_x) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 7731e685e58..d7a3b2fa053 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -202,7 +202,7 @@ user.dropItemToGround(src, TRUE) return src -/mob/living/carbon/fire_act(burn_level) +/mob/living/carbon/fire_act(burn_level, flame_color) . = ..() adjust_bodytemperature(100, 0, BODYTEMP_HEAT_DAMAGE_LIMIT_ONE+10) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1ff71b195a7..8b96aeb7f44 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -13,24 +13,9 @@ if(z) LAZYADD(GLOB.humans_by_zlevel["[z]"], src) - var/datum/action/skill/toggle_orders/toggle_orders_action = new - toggle_orders_action.give_action(src) - var/datum/action/skill/issue_order/move/issue_order_move = new - issue_order_move.give_action(src) - var/datum/action/skill/issue_order/hold/issue_order_hold = new - issue_order_hold.give_action(src) - var/datum/action/skill/issue_order/focus/issue_order_focus = new - issue_order_focus.give_action(src) - var/datum/action/innate/order/attack_order/personal/send_attack_order = new - send_attack_order.give_action(src) - var/datum/action/innate/order/defend_order/personal/send_defend_order = new - send_defend_order.give_action(src) - var/datum/action/innate/order/retreat_order/personal/send_retreat_order = new - send_retreat_order.give_action(src) - var/datum/action/innate/order/rally_order/personal/send_rally_order = new - send_rally_order.give_action(src) - var/datum/action/innate/message_squad/screen_orders = new - screen_orders.give_action(src) + for(var/action in GLOB.human_init_actions) + var/datum/action/human_action = new action(src) + human_action.give_action(src) //makes order hud visible var/datum/atom_hud/H = GLOB.huds[DATA_HUD_ORDER] diff --git a/code/modules/mob/living/carbon/xenomorph/abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities.dm index 62b1ca1d3c5..7df6bc58996 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities.dm @@ -258,6 +258,8 @@ var/mob/living/carbon/xenomorph/X = owner var/atom/A = X.selected_resin action_icon_state = initial(A.name) + if(!is_gameplay_level(X.loc.z)) + return ..() // prevents runtimes if(SSmonitor.gamestate == SHUTTERS_CLOSED && CHECK_BITFIELD(SSticker.mode?.flags_round_type, MODE_ALLOW_XENO_QUICKBUILD) && SSresinshaping.active) button.cut_overlay(visual_references[VREF_MUTABLE_BUILDING_COUNTER]) var/mutable_appearance/number = visual_references[VREF_MUTABLE_BUILDING_COUNTER] @@ -364,10 +366,15 @@ return if(X.selected_resin == /obj/structure/bed/nest) - for(var/obj/structure/bed/nest/xeno_nest in range (2,T)) + for(var/obj/structure/bed/nest/xeno_nest in range(2, T)) owner.balloon_alert(owner, span_notice("Another nest is too close!")) return + if(X.selected_resin == /obj/structure/mineral_door/resin) + for(var/obj/structure/mineral_door/resin/door in range(2, T)) + owner.balloon_alert(owner, span_notice("Another door is too close!")) + return + var/atom/new_resin if(ispath(X.selected_resin, /turf)) // We should change turfs, not spawn them in directly var/list/baseturfs = islist(T.baseturfs) ? T.baseturfs : list(T.baseturfs) @@ -390,6 +397,10 @@ for(var/obj/structure/bed/nest/xeno_nest in range (2, T)) owner.balloon_alert(owner, span_notice("Another nest is too close!")) return + if(X.selected_resin == /obj/structure/mineral_door/resin) + for(var/obj/structure/mineral_door/resin/door in range(2, T)) + owner.balloon_alert(owner, span_notice("Another door is too close!")) + return switch(is_valid_for_resin_structure(T, X.selected_resin == /obj/structure/mineral_door/resin, X.selected_resin)) if(ERROR_CANT_WEED) owner.balloon_alert(owner, span_notice("This spot cannot support a garden!")) @@ -1157,7 +1168,7 @@ /mob/living/carbon/xenomorph/proc/add_abilities() for(var/action_path in xeno_caste.actions) - var/datum/action/ability/xeno_action/action = new action_path() + var/datum/action/ability/xeno_action/action = new action_path(src) if(!SSticker.mode || SSticker.mode.flags_xeno_abilities & action.gamemode_flags) action.give_action(src) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm index 9247bf8bd9c..766f348870f 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm @@ -1004,14 +1004,12 @@ RU TGMC EDIT */ block_overlay = new(null, src) owner.vis_contents += block_overlay START_PROCESSING(SSprocessing, src) - RegisterSignals(owner, list(COMSIG_QDELETING, COMSIG_MOB_DEATH, COMSIG_XENOMORPH_EVOLVED, COMSIG_XENOMORPH_DEEVOLVED), PROC_REF(stop_ability)) + RegisterSignals(owner, list(COMSIG_MOB_DEATH, COMSIG_XENOMORPH_EVOLVED, COMSIG_XENOMORPH_DEEVOLVED), PROC_REF(stop_ability)) RegisterSignals(owner, list(COMSIG_XENOMORPH_BRUTE_DAMAGE, COMSIG_XENOMORPH_BURN_DAMAGE), PROC_REF(taking_damage)) -/datum/action/ability/xeno_action/primal_wrath/remove_action(mob/living/L) - . = ..() - stop_ability() - /datum/action/ability/xeno_action/primal_wrath/process() + if(!owner) + return PROCESS_KILL var/mob/living/carbon/xenomorph/xeno_owner = owner if(xeno_owner.hivenumber == XENO_HIVE_FALLEN) if(xeno_owner.wrath_stored < xeno_owner.xeno_caste.wrath_max) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/behemoth.dm index 5c969e39433..6346df738de 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/behemoth.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/behemoth.dm @@ -14,8 +14,8 @@ drag_delay = 6 mob_size = MOB_SIZE_BIG max_buckled_mobs = 2 - pixel_x = -16 - old_x = -16 + pixel_x = -28.5 + old_x = -28.5 footstep_type = FOOTSTEP_XENO_HEAVY diff --git a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm index 132f87d1799..c637430f43e 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm @@ -29,7 +29,7 @@ // *** Defense *** // soft_armor = list(MELEE = 20, BULLET = 40, LASER = 40, ENERGY = 20, BOMB = 50, BIO = 50, FIRE = 20, ACID = 50) - hard_armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) + hard_armor = list(MELEE = 0, BULLET = 12, LASER = 6, ENERGY = 10, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) // *** Minimap Icon *** // minimap_icon = "behemoth" @@ -39,6 +39,7 @@ /datum/action/ability/xeno_action/xeno_resting, /datum/action/ability/xeno_action/watch_xeno, /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/xeno_action/ready_charge/behemoth_roll, /datum/action/ability/activable/xeno/landslide, /datum/action/ability/activable/xeno/earth_riser, /datum/action/ability/activable/xeno/seismic_fracture, @@ -60,6 +61,7 @@ /datum/action/ability/xeno_action/xeno_resting, /datum/action/ability/xeno_action/watch_xeno, /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/xeno_action/ready_charge/behemoth_roll, /datum/action/ability/activable/xeno/landslide, /datum/action/ability/activable/xeno/earth_riser, /datum/action/ability/activable/xeno/seismic_fracture, diff --git a/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm index 37d58819815..2a832977002 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm @@ -37,7 +37,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list( keybinding_signals = list( KEYBINDING_NORMAL = COMSIG_XENOABILITY_THROW_HUGGER, ) - cooldown_duration = 3 SECONDS + cooldown_duration = 2 SECONDS /datum/action/ability/activable/xeno/throw_hugger/get_cooldown() var/mob/living/carbon/xenomorph/carrier/caster = owner @@ -150,7 +150,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list( action_icon_state = "spawn_hugger" desc = "Spawn a facehugger that is stored on your body." ability_cost = 100 - cooldown_duration = 10 SECONDS + cooldown_duration = 5 SECONDS keybinding_signals = list( KEYBINDING_NORMAL = COMSIG_XENOABILITY_SPAWN_HUGGER, ) @@ -378,7 +378,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list( action_icon_state = "call_younger" desc = "Appeals to the larva inside the Marine. The Marine loses his balance, and larva's progress accelerates." ability_cost = 150 - cooldown_duration = 20 SECONDS + cooldown_duration = 10 SECONDS keybinding_signals = list( KEYBINDING_NORMAL = COMSIG_XENOABILITY_CALL_YOUNGER, ) @@ -456,3 +456,56 @@ GLOBAL_LIST_INIT(hugger_images_list, list( succeed_activate() add_cooldown() + +// *************************************** +// *********** Build nest +// *************************************** + +/datum/action/ability/xeno_action/build_nest + name = "Build nest" + action_icon_state = ALIEN_NEST + desc = "Build nest for host" + ability_cost = 200 + cooldown_duration = 20 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_SECRETE_RESIN, + ) + +/datum/action/ability/xeno_action/build_nest/can_use_action(silent, override_flags) + . = ..() + var/turf/T = get_turf(owner) + var/mob/living/carbon/xenomorph/blocker = locate() in T + if(blocker && blocker != owner && blocker.stat != DEAD) + if(!silent) + to_chat(owner, span_xenowarning("You cannot build with [blocker] in the way!")) + return FALSE + + if(!T.is_weedable()) + return FALSE + + var/mob/living/carbon/xenomorph/owner_xeno = owner + if(!owner_xeno.loc_weeds_type) + if(!silent) + to_chat(owner, span_xenowarning("No weeds here!")) + return FALSE + + if(!T.check_alien_construction(owner, silent, /obj/structure/bed/nest) || !T.check_disallow_alien_fortification(owner)) + return FALSE + +/datum/action/ability/xeno_action/build_nest/action_activate() + + var/turf/T = get_turf(owner) + for(var/obj/structure/bed/nest/nest in range(2, T)) + owner.balloon_alert(owner, "Another nest too close!") + return FALSE + + if(!do_after(owner, 2 SECONDS, NONE, owner, BUSY_ICON_BUILD)) + return FALSE + + if(!can_use_action()) + return FALSE + + new /obj/structure/bed/nest(T) + playsound(T, "alien_resin_build", 25) + succeed_activate() + add_cooldown() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/carrier/carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/carrier/carrier.dm index 38d6163e646..7b7390f21c7 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/carrier/carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/carrier/carrier.dm @@ -9,8 +9,6 @@ health = 200 maxHealth = 200 plasma_stored = 50 - ///Number of huggers the carrier is currently carrying - var/huggers = 0 tier = XENO_TIER_TWO upgrade = XENO_UPGRADE_NORMAL pixel_x = -16 //Needed for 2x2 @@ -18,6 +16,8 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) + ///Number of huggers the carrier is currently carrying + var/huggers = 0 ///Facehuggers overlay var/mutable_appearance/hugger_overlays_icon ///The number of huggers the carrier reserves against observer possession. @@ -28,7 +28,7 @@ // *************************************** /mob/living/carbon/xenomorph/carrier/Initialize(mapload) . = ..() - hugger_overlays_icon = mutable_appearance('icons/Xeno/castes/carrier/effects.dmi',"empty") + hugger_overlays_icon = mutable_appearance(effects_icon, "empty") /mob/living/carbon/xenomorph/carrier/get_status_tab_items() . = ..() @@ -47,19 +47,17 @@ return ///Dispayed number of huggers - var/displayed = round(( huggers / xeno_caste.huggers_max ) * 3.999) + 1 - + var/displayed = round((huggers / xeno_caste.huggers_max) * 3.999) + 1 for(var/i = 1; i <= displayed; i++) if(stat == DEAD) - hugger_overlays_icon.overlays += mutable_appearance(icon, "clinger_[i] Knocked Down") + hugger_overlays_icon.overlays += mutable_appearance(effects_icon, "clinger_[i] Knocked Down") else if(lying_angle) if((resting || IsSleeping()) && (!IsParalyzed() && !IsUnconscious() && health > 0)) - hugger_overlays_icon.overlays += mutable_appearance(icon, "clinger_[i] Sleeping") + hugger_overlays_icon.overlays += mutable_appearance(effects_icon, "clinger_[i] Sleeping") else - hugger_overlays_icon.overlays +=mutable_appearance(icon, "clinger_[i] Knocked Down") + hugger_overlays_icon.overlays += mutable_appearance(effects_icon, "clinger_[i] Knocked Down") else - hugger_overlays_icon.overlays +=mutable_appearance(icon, "clinger_[i]") - + hugger_overlays_icon.overlays += mutable_appearance(effects_icon, "clinger_[i]") overlays += hugger_overlays_icon //Observers can become playable facehuggers by clicking on the carrier diff --git a/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm index 1c0c767aaaf..516630e40a3 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm @@ -11,17 +11,17 @@ wound_type = "carrier" //used to match appropriate wound overlays // *** Melee Attacks *** // - melee_damage = 20 + melee_damage = 22 // *** Speed *** // speed = -0.4 // *** Plasma *** // - plasma_max = 800 - plasma_gain = 38 + plasma_max = 1000 + plasma_gain = 45 // *** Health *** // - max_health = 325 + max_health = 425 // *** Evolution *** // evolution_threshold = 225 @@ -33,7 +33,7 @@ caste_traits = null // *** Defense *** // - soft_armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 0, BIO = 5, FIRE = 0, ACID = 5) + soft_armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 0, BIO = 5, FIRE = 25, ACID = 5) // *** Pheromones *** // aura_strength = 2.5 @@ -42,8 +42,8 @@ minimap_icon = "carrier" // *** Carrier Abilities *** // - huggers_max = 7 - hugger_delay = 1.5 SECONDS + huggers_max = 9 + hugger_delay = 1.25 SECONDS actions = list( /datum/action/ability/xeno_action/xeno_resting, @@ -61,6 +61,7 @@ /datum/action/ability/xeno_action/pheromones/emit_warding, /datum/action/ability/xeno_action/pheromones/emit_frenzy, /datum/action/ability/xeno_action/carrier_panic, + /datum/action/ability/xeno_action/build_nest, /datum/action/ability/xeno_action/choose_hugger_type, /datum/action/ability/xeno_action/set_hugger_reserve, ) @@ -90,6 +91,7 @@ /datum/action/ability/xeno_action/pheromones/emit_warding, /datum/action/ability/xeno_action/pheromones/emit_frenzy, /datum/action/ability/xeno_action/carrier_panic, + /datum/action/ability/xeno_action/build_nest, /datum/action/ability/xeno_action/choose_hugger_type, /datum/action/ability/xeno_action/set_hugger_reserve, /datum/action/ability/xeno_action/build_hugger_turret, diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm index b9249ffac33..0357165bf18 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm @@ -21,14 +21,14 @@ plasma_gain = 30 // *** Health *** // - max_health = 400 + max_health = 500 // *** Flags *** // can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER caste_traits = list(TRAIT_STOPS_TANK_COLLISION) // *** Defense *** // - soft_armor = list(MELEE = 90, BULLET = 80, LASER = 80, ENERGY = 75, BOMB = 130, BIO = 100, FIRE = 10, ACID = 100) + soft_armor = list(MELEE = 50, BULLET = 80, LASER = 65, ENERGY = 75, BOMB = 130, BIO = 100, FIRE = 10, ACID = 100) // *** Sunder *** // sunder_multiplier = 0.5 diff --git a/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm b/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm index 4880522dcd5..167214217df 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm @@ -21,7 +21,7 @@ plasma_gain = 15 // *** Health *** // - max_health = 320 + max_health = 410 // *** Evolution *** // evolution_threshold = 100 @@ -33,6 +33,7 @@ // *** Defense *** // soft_armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 40, BOMB = 20, BIO = 30, FIRE = 10, ACID = 30) + hard_armor = list(MELEE = 0, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) // *** Minimap Icon *** // minimap_icon = "defender" diff --git a/code/modules/mob/living/carbon/xenomorph/castes/drone/abilities_drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/drone/abilities_drone.dm index fe6ce450b2b..f0929e9bab1 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/drone/abilities_drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/drone/abilities_drone.dm @@ -144,7 +144,7 @@ KEYBINDING_NORMAL = COMSIG_XENOABILITY_ENHANCEMENT, ) /// References Essence Link and its vars. - var/datum/action/ability/activable/xeno/essence_link/essence_link_action + var/datum/action/ability/activable/xeno/essence_link/essence_link_action //todo: All this link stuff is handled in a stinky way /// Used to determine whether Enhancement is already active or not. Also allows access to its vars. var/datum/status_effect/drone_enhancement/existing_enhancement /// Damage bonus given by this ability. @@ -152,12 +152,14 @@ /// Speed bonus given by this ability. var/speed_addition = -0.4 +/datum/action/ability/xeno_action/enhancement/New(Target) + . = ..() + INVOKE_NEXT_TICK(src, PROC_REF(link_essence_action)) + /datum/action/ability/xeno_action/enhancement/can_use_action() - var/mob/living/carbon/xenomorph/X = owner - essence_link_action = X.actions_by_path[/datum/action/ability/activable/xeno/essence_link] if(existing_enhancement) return TRUE - if(!HAS_TRAIT(X, TRAIT_ESSENCE_LINKED)) + if(!HAS_TRAIT(owner, TRAIT_ESSENCE_LINKED)) return FALSE if(!essence_link_action.existing_link.was_within_range) return FALSE @@ -174,6 +176,21 @@ existing_enhancement = essence_link_action.linked_target.has_status_effect(STATUS_EFFECT_XENO_ENHANCEMENT) succeed_activate() +///Links this action to +/datum/action/ability/xeno_action/enhancement/proc/link_essence_action() + if(essence_link_action) + return + var/mob/living/carbon/xenomorph/X = owner + essence_link_action = X.actions_by_path[/datum/action/ability/activable/xeno/essence_link] + if(!essence_link_action) + CRASH("[type] loaded with a drone_enhancement to link to") + RegisterSignal(essence_link_action, COMSIG_QDELETING, PROC_REF(unlink_essence_action)) + +///Signal proc to delink essence_link. Should only happen when the owner is being deleted to begin with +/datum/action/ability/xeno_action/enhancement/proc/unlink_essence_action() + SIGNAL_HANDLER + essence_link_action = null + /// Ends the ability if the Enhancement buff is removed. /datum/action/ability/xeno_action/enhancement/proc/end_ability() if(existing_enhancement) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm index ea6323f4cab..00efedefec0 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm @@ -572,7 +572,7 @@ var/swap_used = FALSE /datum/action/ability/xeno_action/mirage/remove_action() - clean_illusions() + illusions = list() //the actual illusions fade on their own, and the cooldown object may be qdel'd return ..() /datum/action/ability/xeno_action/mirage/can_use_action(silent = FALSE, override_flags) @@ -637,7 +637,7 @@ . = ..() RegisterSignal(L, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(on_attack)) -/datum/action/ability/xeno_action/deathstroke/remove_action(mob/living/L) +/datum/action/ability/xeno_action/hunter_army/remove_action(mob/living/L) . = ..() UnregisterSignal(L, COMSIG_XENOMORPH_ATTACK_LIVING) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm index 9141f6de69a..d455a1fa1a5 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm @@ -19,14 +19,14 @@ plasma_gain = 80 // *** Health *** // - max_health = 460 + max_health = 570 // *** Flags *** // can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER|CASTE_CAN_HOLD_FACEHUGGERS|CASTE_CAN_HOLD_JELLY caste_traits = null // *** Defense *** // - soft_armor = list(MELEE = 45, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 40, FIRE = 20, ACID = 40) + soft_armor = list(MELEE = 45, BULLET = 25, LASER = 15, ENERGY = 50, BOMB = 10, BIO = 40, FIRE = 20, ACID = 40) // *** Ranged Attack *** // spit_delay = 1 SECONDS diff --git a/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm index de0646270f2..2b1215319b2 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm @@ -190,10 +190,7 @@ carbon.apply_damage(base_damage + damage_scale * min(xeno.life_kills_total, xeno.max_bonus_life_kills), BRUTE, "chest", MELEE, FALSE, FALSE, TRUE, 20) xeno.do_attack_animation(carbon, ATTACK_EFFECT_CLAW) - spawn() - for(var/x in 1 to 4) - sleep(1) - xeno.setDir(turn(xeno.dir, 90)) + INVOKE_ASYNC(src, PROC_REF(ability_spin)) xeno.do_attack_animation(carbon, ATTACK_EFFECT_BITE) playsound(xeno, 'sound/voice/alien/predalien/growl.ogg', 75, 0) @@ -207,3 +204,9 @@ add_cooldown() succeed_activate() + +/datum/action/ability/activable/xeno/devastate/proc/ability_spin() + var/mob/living/carbon/xenomorph/predalien/xeno = owner + for(var/x in 1 to 4) + sleep(1) + xeno.setDir(turn(xeno.dir, 90)) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm index 1954859ba08..42f6c894b19 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm @@ -28,6 +28,7 @@ if(C.has_status_effect(STATUS_EFFECT_INTOXICATED)) var/datum/status_effect/stacking/intoxicated/debuff = C.has_status_effect(STATUS_EFFECT_INTOXICATED) debuff.add_stacks(intoxication_stacks) + return C.apply_status_effect(STATUS_EFFECT_INTOXICATED, intoxication_stacks) // *************************************** @@ -65,6 +66,7 @@ particle_holder = new(owner, /particles/toxic_slash) particle_holder.pixel_x = 9 particle_holder.pixel_y = 2 + xeno_owner.soft_armor = xeno_owner.soft_armor.modifyRating(bullet = 60) succeed_activate() add_cooldown() @@ -80,7 +82,8 @@ if(xeno_target.has_status_effect(STATUS_EFFECT_INTOXICATED)) var/datum/status_effect/stacking/intoxicated/debuff = xeno_target.has_status_effect(STATUS_EFFECT_INTOXICATED) debuff.add_stacks(intoxication_stacks) - xeno_target.apply_status_effect(STATUS_EFFECT_INTOXICATED, intoxication_stacks) + else + xeno_target.apply_status_effect(STATUS_EFFECT_INTOXICATED, intoxication_stacks) remaining_slashes-- //Decrement the toxic slash count if(!remaining_slashes) //Deactivate if we have no toxic slashes remaining toxic_slash_deactivate(xeno_owner) @@ -95,6 +98,7 @@ xeno_owner.balloon_alert(xeno_owner, "Toxic Slash over") //Let the user know xeno_owner.playsound_local(xeno_owner, 'sound/voice/alien/hiss8.ogg', 25) action_icon_state = "neuroclaws_off" + xeno_owner.soft_armor = xeno_owner.soft_armor.modifyRating(bullet = -60) /datum/action/ability/xeno_action/toxic_slash/on_cooldown_finish() owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1) @@ -204,14 +208,18 @@ ///Type of nade to be thrown var/nade_type = /obj/item/explosive/grenade/smokebomb/xeno -/datum/action/ability/activable/xeno/toxic_grenade/use_ability(atom/A) +/datum/action/ability/activable/xeno/toxic_grenade/use_ability(atom/our_atom) . = ..() succeed_activate() add_cooldown() + grenade_act(our_atom) + +/// All the grenade activations go here, so we don't overwrite the use_ability +/datum/action/ability/activable/xeno/toxic_grenade/proc/grenade_act(atom/our_atom) var/obj/item/explosive/grenade/smokebomb/xeno/nade = new nade_type(get_turf(owner)) - nade.throw_at(A, 5, 1, owner, TRUE) + nade.throw_at(our_atom, 5, 1, owner, TRUE) nade.activate(owner) - owner.visible_message(span_warning("[owner] vomits up a bulbous lump and throws it at [A]!"), span_warning("We vomit up a bulbous lump and throw it at [A]!")) + owner.visible_message(span_warning("[owner] vomits up a bulbous lump and throws it at [our_atom]!"), span_warning("We vomit up a bulbous lump and throw it at [our_atom]!")) /obj/item/explosive/grenade/smokebomb/xeno name = "toxic grenade" @@ -224,6 +232,7 @@ smoketype = /datum/effect_system/smoke_spread/xeno/toxic arm_sound = 'sound/voice/alien/yell_alt.ogg' smokeradius = 3 + overlay_type = null /obj/item/explosive/grenade/smokebomb/xeno/update_overlays() . = ..() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm index 24766973096..2667ac23ba8 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm @@ -21,7 +21,7 @@ plasma_gain = 21 // *** Health *** // - max_health = 300 + max_health = 400 // *** Evolution *** // evolution_threshold = 100 diff --git a/code/modules/mob/living/carbon/xenomorph/castes/shrike/abilities_shrike.dm b/code/modules/mob/living/carbon/xenomorph/castes/shrike/abilities_shrike.dm index 1dc64203280..287586e48d3 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/shrike/abilities_shrike.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/shrike/abilities_shrike.dm @@ -377,6 +377,10 @@ /datum/action/ability/xeno_action/place_acidwell/action_activate() var/turf/T = get_turf(owner) + for(var/obj/structure/xeno/acidwell/well in range(1, T)) + owner.balloon_alert(owner, span_notice("Another acid well is too close!")) + return + if(!do_after(owner, 0.5 SECONDS, NONE, T, BUSY_ICON_BUILD)) return diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm new file mode 100644 index 00000000000..f19a362fc49 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm @@ -0,0 +1,25 @@ +/datum/xeno_caste/spiderling + caste_name = "spiderling" + display_name = "spiderling" + upgrade_name = "" + caste_desc = "An anthropod xenomorph without any qualms to obey their widow, even if it will never grow up and will face death." + wound_type = "" + caste_type_path = /mob/living/carbon/xenomorph/spiderling + tier = XENO_TIER_MINION + upgrade = XENO_UPGRADE_BASETYPE + // *** Melee Attacks *** // + melee_damage = 8 + // *** Speed *** // + speed = -0.6 + // *** Plasma *** // + plasma_max = 200 + plasma_gain = 1 + // *** Health *** // + max_health = 225 + // *** Flags *** // + caste_flags = CASTE_NOT_IN_BIOSCAN|CASTE_DO_NOT_ANNOUNCE_DEATH|CASTE_DO_NOT_ALERT_LOW_LIFE|CASTE_IS_A_MINION + // *** Minimap Icon *** // + minimap_icon = "spiderling" + // *** Defense *** // + soft_armor = list(MELEE = 15, BULLET = 0, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0) + diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm new file mode 100644 index 00000000000..7b35567b085 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm @@ -0,0 +1,246 @@ +/mob/living/carbon/xenomorph/spiderling + caste_base_type = /datum/xeno_caste/spiderling + name = "Spiderling" + desc = "A widow spawn, it chitters angrily without any sense of self-preservation, only to obey the widow's will." + icon = 'icons/Xeno/Effects.dmi' + icon_state = "Spiderling Running" + health = 150 + maxHealth = 150 + plasma_stored = 200 + tier = XENO_TIER_MINION + upgrade = XENO_UPGRADE_BASETYPE + pull_speed = -2 + allow_pass_flags = PASS_XENO + pass_flags = PASS_XENO|PASS_LOW_STRUCTURE + density = FALSE + /// The widow that this spiderling belongs to + var/mob/living/carbon/xenomorph/spidermother + +/mob/living/carbon/xenomorph/spiderling/Initialize(mapload, mob/living/carbon/xenomorph/mother) + . = ..() + spidermother = mother + if(spidermother) + AddComponent(/datum/component/ai_controller, /datum/ai_behavior/spiderling, spidermother) + transfer_to_hive(spidermother.get_xeno_hivenumber()) + else + AddComponent(/datum/component/ai_controller, /datum/ai_behavior/xeno) + +/mob/living/carbon/xenomorph/spiderling/on_death() + //We QDEL them as cleanup and preventing them from being sold + QDEL_IN(src, TIME_TO_DISSOLVE) + spidermother = null + return ..() + +/mob/living/carbon/xenomorph/spiderling/Destroy() + spidermother = null + return ..() + +///If we're covering our widow, any clicks should be transferred to them +/mob/living/carbon/xenomorph/spiderling/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, armor_type = MELEE, effects = TRUE, isrightclick = FALSE) + if(!get_dist(src, spidermother) && isxeno(x)) + spidermother.attack_alien(xeno_attacker, damage_amount, damage_type, armor_type, effects, isrightclick) + return + return ..() + +/mob/living/carbon/xenomorph/spiderling/Life(seconds_per_tick, times_fired) + . = ..() + if(!spidermother) + return + if(get_dist(src, spidermother) > SPIDERLING_WITHER_RANGE) + adjustBruteLoss(25) + +// *************************************** +// *********** Spiderling AI Section +// *************************************** +/datum/ai_behavior/spiderling + target_distance = 1 + base_action = ESCORTING_ATOM + identifier = IDENTIFIER_XENO + ///should we go back to escorting the widow if we stray too far + var/too_far_escort = TRUE + ///weakref to our mother + var/datum/weakref/master_ref + +/datum/ai_behavior/spiderling/New(loc, parent_to_assign, escorted_atom) + . = ..() + master_ref = WEAKREF(escorted_atom) + change_order(null, SPIDERLING_RECALL) + +///starts AI and registers obstructed move signal +/datum/ai_behavior/spiderling/start_ai() + var/master = master_ref?.resolve() + if(master) + RegisterSignal(master, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, PROC_REF(change_order)) + RegisterSignal(mob_parent, COMSIG_OBSTRUCTED_MOVE, PROC_REF(deal_with_obstacle)) + RegisterSignal(mob_parent, COMSIG_SPIDERLING_CHANGE_ORDER, PROC_REF(change_order)) + RegisterSignal(escorted_atom, COMSIG_XENOMORPH_REST, PROC_REF(start_resting)) + RegisterSignal(escorted_atom, COMSIG_XENOMORPH_UNREST, PROC_REF(stop_resting)) + RegisterSignal(escorted_atom, COMSIG_ELEMENT_JUMP_STARTED, PROC_REF(do_jump)) + RegisterSignal(escorted_atom, COMSIG_LIVING_DO_RESIST, PROC_REF(parent_resist)) + RegisterSignal(escorted_atom, COMSIG_XENOMORPH_RESIN_JELLY_APPLIED, PROC_REF(apply_spiderling_jelly)) + return ..() + +///cleans up signals and unregisters obstructed move signal +/datum/ai_behavior/spiderling/cleanup_signals() + . = ..() + UnregisterSignal(mob_parent, list(COMSIG_OBSTRUCTED_MOVE,COMSIG_SPIDERLING_CHANGE_ORDER)) + var/master = master_ref?.resolve() + if(master) + UnregisterSignal(master, COMSIG_SPIDERLING_CHANGE_ALL_ORDER) + +///Signal handler to try to attack our target +///Attack our current atom we are moving to, if targetted is specified attack that instead +/datum/ai_behavior/spiderling/proc/attack_target(datum/source, atom/targetted) + SIGNAL_HANDLER + if(world.time < mob_parent.next_move) + return + var/atom/target = targetted ? targetted : atom_to_walk_to + if(!mob_parent.Adjacent(target)) + return + if(mob_parent.z != target.z) + return + mob_parent.face_atom(target) + mob_parent.UnarmedAttack(target, mob_parent) + +///looks for a new state, handles recalling if too far and some AI shenanigans +/datum/ai_behavior/spiderling/look_for_new_state() + switch(current_action) + if(ESCORTING_ATOM) + if(!escorted_atom && master_ref) + escorted_atom = master_ref.resolve() + if(MOVING_TO_ATOM) + if(isliving(atom_to_walk_to)) + var/mob/living/target = atom_to_walk_to + if(target.stat == DEAD) + change_order(null, SPIDERLING_RECALL) + if(QDELETED(atom_to_walk_to)) + change_order(null, SPIDERLING_RECALL) + return ..() + +///override for MOVING_TO_ATOM to register signals for maintaining distance with our target and attacking +/datum/ai_behavior/spiderling/register_action_signals(action_type) + if(action_type == MOVING_TO_ATOM) + RegisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE, PROC_REF(attack_target)) + RegisterSignals(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(look_for_new_state)) + return ..() + +///override for MOVING_TO_ATOM to unregister signals for maintaining distance with our target and attacking +/datum/ai_behavior/spiderling/unregister_action_signals(action_type) + if(action_type == MOVING_TO_ATOM) + UnregisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE) + if(!isnull(atom_to_walk_to)) + UnregisterSignal(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING)) + return ..() + +///attack the first closest human, by moving towards it +/datum/ai_behavior/spiderling/proc/seek_and_attack_closest(mob/living/source) + var/victim = get_nearest_target(mob_parent, target_distance, TARGET_HUMAN, mob_parent.faction) + if(!victim) + return FALSE + change_action(MOVING_TO_ATOM, victim) + return TRUE + +///seeks a living humans in a 9 tile range near our parent, picks one, then changes our action to move towards it and attack. +/datum/ai_behavior/spiderling/proc/seek_and_attack() + var/list/possible_victims = list() + for(var/mob/living/carbon/human/victim in cheap_get_humans_near(mob_parent, 9)) + if(victim.stat == DEAD) + continue + if(HAS_TRAIT(victim, TRAIT_STEALTH)) + continue + possible_victims += victim + + for(var/atom/nearby_turret AS in GLOB.marine_turrets) + if(mob_parent.z != nearby_turret.z) + continue + if(!(get_dist(mob_parent, nearby_turret) < 9)) + continue + possible_victims += nearby_turret + + if(!length(possible_victims)) + return FALSE + + change_action(MOVING_TO_ATOM, pick(possible_victims)) + return TRUE + +///changes our current behavior with a define (order), optionally with a target, FALSE means fail and TRUE means success +/datum/ai_behavior/spiderling/proc/change_order(mob/living/source, order, atom/target) + SIGNAL_HANDLER + if(!order) + stack_trace("spiderling AI was somehow passed a null order") + return FALSE + switch(order) + if(SPIDERLING_SEEK_CLOSEST) //internal order, to attack closest enemy + return seek_and_attack_closest() + if(SPIDERLING_RECALL) //reset our escorted atom to master_ref and change our action to escorting it, and turn on recalling if out of range. + escorted_atom = master_ref?.resolve() + base_action = ESCORTING_ATOM + change_action(ESCORTING_ATOM, escorted_atom) + too_far_escort = TRUE + return TRUE + if(SPIDERLING_ATTACK) //turns on recalling out of range, if there is a target, attacks it, otherwise seeks and attacks one + too_far_escort = TRUE + source?.unbuckle_all_mobs() + if(target) + change_action(MOVING_TO_ATOM, target) + return TRUE + else + return seek_and_attack() + +///behavior to deal with obstacles +/datum/ai_behavior/spiderling/deal_with_obstacle(datum/source, direction) + var/turf/obstacle_turf = get_step(mob_parent, direction) + if(obstacle_turf.flags_atom & AI_BLOCKED) + return + for(var/thing in obstacle_turf.contents) + if(istype(thing, /obj/structure/window_frame)) //if its a window, climb it after 2 seconds + LAZYINCREMENT(mob_parent.do_actions, obstacle_turf) + addtimer(CALLBACK(src, PROC_REF(climb_window_frame), obstacle_turf), 2 SECONDS) + return COMSIG_OBSTACLE_DEALT_WITH + if(istype(thing, /obj/alien)) //dont attack resin and such + return + if(isobj(thing)) //otherwise smash it if its damageable + var/obj/obstacle = thing + if(obstacle.resistance_flags & XENO_DAMAGEABLE) + INVOKE_ASYNC(src, PROC_REF(attack_target), null, obstacle) + return COMSIG_OBSTACLE_DEALT_WITH + if(ISDIAGONALDIR(direction) && ((deal_with_obstacle(null, turn(direction, -45)) & COMSIG_OBSTACLE_DEALT_WITH) || (deal_with_obstacle(null, turn(direction, 45)) & COMSIG_OBSTACLE_DEALT_WITH))) + return COMSIG_OBSTACLE_DEALT_WITH + +///makes our parent climb over a turf with a window by setting its location to it +/datum/ai_behavior/spiderling/proc/climb_window_frame(turf/window_turf) + mob_parent.loc = window_turf + mob_parent.last_move_time = world.time + LAZYDECREMENT(mob_parent.do_actions, window_turf) + +/// rest when widow does +/datum/ai_behavior/spiderling/proc/start_resting(mob/source) + SIGNAL_HANDLER + var/mob/living/living = mob_parent + living?.set_resting(TRUE) + +/// stop resting when widow does +/datum/ai_behavior/spiderling/proc/stop_resting(mob/source) + SIGNAL_HANDLER + var/mob/living/living = mob_parent + living?.set_resting(FALSE) + source?.unbuckle_all_mobs() + +/// jump when widow does +/datum/ai_behavior/spiderling/proc/do_jump() + SIGNAL_HANDLER + var/datum/component/jump/spider_jump = mob_parent.GetComponent(/datum/component/jump) + spider_jump?.do_jump(mob_parent) + +/// resist when widow does +/datum/ai_behavior/spiderling/proc/parent_resist() + SIGNAL_HANDLER + var/mob/living/carbon/xenomorph/spiderling/spiderling_parent = mob_parent + spiderling_parent?.do_resist() + +/// Signal handler to apply resin jelly to the spiderling whenever widow gets it +/datum/ai_behavior/spiderling/proc/apply_spiderling_jelly() + SIGNAL_HANDLER + var/mob/living/carbon/xenomorph/spiderling/beno_to_coat = mob_parent + beno_to_coat?.apply_status_effect(STATUS_EFFECT_RESIN_JELLY_COATING) + diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm b/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm index 50f04fac227..2d235079b67 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm @@ -137,3 +137,57 @@ to_chat(owner, span_xenodanger("Our auxiliary sacks fill to bursting; we can use scatter spit again.")) owner.playsound_local(owner, 'sound/voice/alien/drool1.ogg', 25, 0, 1) return ..() + +// *************************************** +// *********** Sticky Grenade ************ +// *************************************** +/datum/action/ability/activable/xeno/toxic_grenade/sticky + name = "Slime grenade" + desc = "Throws a lump of compressed acid to stick to a target, which will leave a trail of acid behind them." + ability_cost = 75 + cooldown_duration = 45 SECONDS + nade_type = /obj/item/explosive/grenade/sticky/xeno + +/datum/action/ability/activable/xeno/toxic_grenade/sticky/grenade_act(atom/our_atom) + var/obj/item/explosive/grenade/sticky/xeno/nade = new nade_type(get_turf(owner)) + nade.throw_at(our_atom, 5, 1, owner, TRUE) + nade.activate(owner) + owner.visible_message(span_warning("[owner] vomits up a sticky lump and throws it at [our_atom]!"), span_warning("We vomit up a sticky lump and throw it at [our_atom]!")) + +/obj/item/explosive/grenade/sticky/xeno + name = "\improper slime grenade" + desc = "A fleshy mass oozing acid. It appears to be rapidly decomposing." + greyscale_colors = "#42A500" + greyscale_config = /datum/greyscale_config/xenogrenade + self_sticky = TRUE + arm_sound = 'sound/voice/alien/yell_alt.ogg' + overlay_type = null + var/acid_spray_damage = 15 + +/obj/item/explosive/grenade/sticky/xeno/update_overlays() + . = ..() + if(active) + . += image('icons/obj/items/grenade.dmi', "xenonade_active") + +/obj/item/explosive/grenade/sticky/xeno/prime() + for(var/turf/acid_tile AS in RANGE_TURFS(1, loc)) + new /obj/effect/temp_visual/acid_splatter(acid_tile) //SFX + new /obj/effect/xenomorph/spray(acid_tile, 5 SECONDS, acid_spray_damage) + playsound(loc, "acid_bounce", 35) + if(stuck_to) + clean_refs() + qdel(src) + +/obj/item/explosive/grenade/sticky/xeno/stuck_to(atom/hit_atom) + . = ..() + RegisterSignal(stuck_to, COMSIG_MOVABLE_MOVED, PROC_REF(drop_acid)) + new /obj/effect/xenomorph/spray(get_turf(src), 5 SECONDS, acid_spray_damage) + +///causes acid tiles underneath target when stuck_to +/obj/item/explosive/grenade/sticky/xeno/proc/drop_acid(datum/source, old_loc, movement_dir, forced, old_locs) + SIGNAL_HANDLER + new /obj/effect/xenomorph/spray(get_turf(src), 5 SECONDS, acid_spray_damage) + +/obj/item/explosive/grenade/sticky/xeno/clean_refs() + UnregisterSignal(stuck_to, COMSIG_MOVABLE_MOVED) + return ..() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm b/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm index 5a8f8a8067c..956681905ed 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm @@ -19,7 +19,7 @@ plasma_gain = 50 // *** Health *** // - max_health = 310 + max_health = 450 // *** Evolution *** // evolution_threshold = 225 @@ -30,7 +30,7 @@ caste_traits = list(TRAIT_CAN_VENTCRAWL) // *** Defense *** // - soft_armor = list(MELEE = 25, BULLET = 35, LASER = 35, ENERGY = 35, BOMB = 0, BIO = 20, FIRE = 10, ACID = 20) + soft_armor = list(MELEE = 25, BULLET = 20, LASER = 10, ENERGY = 35, BOMB = 0, BIO = 20, FIRE = 10, ACID = 20) // *** Minimap Icon *** // minimap_icon = "spitter" @@ -67,3 +67,15 @@ spit_delay = 0.3 SECONDS spit_types = list(/datum/ammo/xeno/acid/medium/passthrough, /datum/ammo/xeno/acid/auto) + + // *** Abilities *** // + actions = list( + /datum/action/ability/xeno_action/xeno_resting, + /datum/action/ability/xeno_action/watch_xeno, + /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/activable/xeno/corrosive_acid/strong, + /datum/action/ability/activable/xeno/xeno_spit, + /datum/action/ability/activable/xeno/scatter_spit, + /datum/action/ability/activable/xeno/spray_acid/line, + /datum/action/ability/activable/xeno/toxic_grenade/sticky, + ) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm new file mode 100644 index 00000000000..53e96c87446 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm @@ -0,0 +1,433 @@ + +// *************************************** +// *********** Leash Ball +// *************************************** + +/datum/action/ability/activable/xeno/leash_ball + name = "Leash Ball" + desc = "Spit a huge web ball that snares groups of targets for a brief while." + action_icon_state = "leash_ball" + action_icon = 'icons/Xeno/actions.dmi' + ability_cost = 75 + cooldown_duration = 15 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_LEASH_BALL, + ) + +/datum/action/ability/activable/xeno/leash_ball/use_ability(atom/A) + var/turf/target = get_turf(A) + var/mob/living/carbon/xenomorph/X = owner + X.face_atom(target) + if(!do_after(X, 0.5 SECONDS, IGNORE_LOC_CHANGE, X, BUSY_ICON_DANGER)) + return fail_activate() + var/datum/ammo/xeno/leash_ball = GLOB.ammo_list[/datum/ammo/xeno/leash_ball] + leash_ball.hivenumber = X.hivenumber + var/obj/projectile/newspit = new (get_turf(X)) + + newspit.generate_bullet(leash_ball) + newspit.fire_at(target, X, X, newspit.ammo.max_range) + succeed_activate() + add_cooldown() + +/obj/structure/xeno/aoe_leash + name = "Snaring Web" + icon = 'icons/Xeno/Effects.dmi' + icon_state = "aoe_leash" + desc = "Sticky and icky. Destroy it when you are stuck!" + destroy_sound = 'sound/effects/alien/resin_break1.ogg' + max_integrity = 150 + layer = ABOVE_ALL_MOB_LAYER + anchored = TRUE + allow_pass_flags = NONE + density = FALSE + obj_flags = CAN_BE_HIT | PROJ_IGNORE_DENSITY + /// How long the leash ball lasts untill it dies + var/leash_life = 10 SECONDS + /// Radius for how far the leash should affect humans and how far away they may walk + var/leash_radius = 3 + /// List of beams to be removed on obj_destruction + var/list/obj/effect/ebeam/beams = list() + /// List of victims to unregister aoe_leash is destroyed + var/list/mob/living/carbon/human/leash_victims = list() + +/// Humans caught get beamed and registered for proc/check_dist, aoe_leash also gains increased integrity for each caught human +/obj/structure/xeno/aoe_leash/Initialize(mapload, _hivenumber) + . = ..() + for(var/mob/living/carbon/human/victim in GLOB.humans_by_zlevel["[z]"]) + if(get_dist(src, victim) > leash_radius) + continue + if(victim.stat == DEAD) /// Add || CONSCIOUS after testing + continue + if(HAS_TRAIT(victim, TRAIT_LEASHED)) + continue + if(!check_path(src, victim, projectile = TRUE)) + continue + leash_victims += victim + for(var/mob/living/carbon/human/snared_victim AS in leash_victims) + ADD_TRAIT(snared_victim, TRAIT_LEASHED, src) + beams += beam(snared_victim, "beam_web", 'icons/effects/beam.dmi', INFINITY, INFINITY) + RegisterSignal(snared_victim, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(check_dist)) + if(!length(beams)) + return INITIALIZE_HINT_QDEL + QDEL_IN(src, leash_life) + +/// To remove beams after the leash_ball is destroyed and also unregister all victims +/obj/structure/xeno/aoe_leash/Destroy() + for(var/mob/living/carbon/human/victim AS in leash_victims) + UnregisterSignal(victim, COMSIG_MOVABLE_PRE_MOVE) + REMOVE_TRAIT(victim, TRAIT_LEASHED, src) + leash_victims = null + QDEL_LIST(beams) + return ..() + +/// Humans caught in the aoe_leash will be pulled back if they leave it's radius +/obj/structure/xeno/aoe_leash/proc/check_dist(datum/leash_victim, atom/newloc) + SIGNAL_HANDLER + if(get_dist(newloc, src) >= leash_radius) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +/// This is so that xenos can remove leash balls +/obj/structure/xeno/aoe_leash/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, armor_type = MELEE, effects = TRUE, armor_penetration, isrightclick = FALSE) + if(xeno_attacker.status_flags & INCORPOREAL) + return + xeno_attacker.visible_message(span_xenonotice("\The [xeno_attacker] starts tearing down \the [src]!"), \ + span_xenonotice("We start to tear down \the [src].")) + if(!do_after(xeno_attacker, 1 SECONDS, NONE, xeno_attacker, BUSY_ICON_GENERIC) || QDELETED(src)) + return + xeno_attacker.do_attack_animation(src, ATTACK_EFFECT_CLAW) + xeno_attacker.visible_message(span_xenonotice("\The [xeno_attacker] tears down \the [src]!"), \ + span_xenonotice("We tear down \the [src].")) + playsound(src, destroy_sound, 25) + take_damage(max_integrity) + +// *************************************** +// *********** Spiderling Section +// *************************************** + +/datum/action/ability/xeno_action/create_spiderling + name = "Birth Spiderling" + desc = "Give birth to a spiderling after a short charge-up. The spiderlings will follow you until death. You can only deploy 5 spiderlings at one time." + action_icon_state = "spawn_spiderling" + ability_cost = 80 + cooldown_duration = 15 SECONDS + use_state_flags = ABILITY_USE_LYING|ABILITY_IGNORE_COOLDOWN + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_CREATE_SPIDERLING, + ) + var/current_charges = 5 + + /// List of all our spiderlings + var/list/mob/living/carbon/xenomorph/spiderling/spiderlings = list() + +/datum/action/ability/xeno_action/create_spiderling/give_action(mob/living/L) + . = ..() + var/mob/living/carbon/xenomorph/X = L + var/max_spiderlings = X?.xeno_caste.max_spiderlings ? X.xeno_caste.max_spiderlings : 5 + desc = "Give birth to a spiderling after a short charge-up. The spiderlings will follow you until death. You can only deploy [max_spiderlings] spiderlings at one time." + + var/mutable_appearance/counter_maptext = mutable_appearance(icon = null, icon_state = null, layer = ACTION_LAYER_MAPTEXT) + counter_maptext.pixel_x = 16 + counter_maptext.pixel_y = -4 + counter_maptext.maptext = MAPTEXT("[current_charges]/[initial(current_charges)]") + visual_references[VREF_MUTABLE_SPIDERLING_CHARGES] = counter_maptext + +/datum/action/ability/xeno_action/create_spiderling/remove_action(mob/living/carbon/xenomorph/X) + . = ..() + button.cut_overlay(visual_references[VREF_MUTABLE_SPIDERLING_CHARGES]) + visual_references[VREF_MUTABLE_SPIDERLING_CHARGES] = null + +/datum/action/ability/xeno_action/create_spiderling/update_button_icon() + button.cut_overlay(visual_references[VREF_MUTABLE_SPIDERLING_CHARGES]) + var/mutable_appearance/number = visual_references[VREF_MUTABLE_SPIDERLING_CHARGES] + number?.maptext = MAPTEXT("[current_charges]/[initial(current_charges)]") + visual_references[VREF_MUTABLE_SPIDERLING_CHARGES] = number + button.add_overlay(visual_references[VREF_MUTABLE_SPIDERLING_CHARGES]) + return ..() + +/datum/action/ability/xeno_action/create_spiderling/on_cooldown_finish() + current_charges = clamp(current_charges+1, 0, initial(current_charges)) + update_button_icon() + if(current_charges < initial(current_charges)) + cooldown_timer = addtimer(CALLBACK(src, PROC_REF(on_cooldown_finish)), cooldown_duration, TIMER_STOPPABLE) + return + return ..() + +/datum/action/ability/xeno_action/create_spiderling/can_use_action(silent = FALSE, override_flags) + . = ..() + if(cooldown_timer && current_charges) + return TRUE + +/// The action to create spiderlings +/datum/action/ability/xeno_action/create_spiderling/action_activate() + . = ..() + + if(owner.do_actions) + return fail_activate() + + var/mob/living/carbon/xenomorph/X = owner + if(length(spiderlings) >= X.xeno_caste.max_spiderlings) + X.balloon_alert(X, "Max Spiderlings") + return fail_activate() + + if(!do_after(owner, 0.5 SECONDS, IGNORE_LOC_CHANGE, owner, BUSY_ICON_DANGER)) + return fail_activate() + + current_charges-- + add_spiderling() + succeed_activate() + add_cooldown() + +/// Adds spiderlings to spiderling list and registers them for death so we can remove them later +/datum/action/ability/xeno_action/create_spiderling/proc/add_spiderling() + /// This creates and stores the spiderling so we can reassign the owner for spider swarm and cap how many spiderlings you can have at once + var/mob/living/carbon/xenomorph/spiderling/new_spiderling = new(owner.loc, owner, owner) + RegisterSignals(new_spiderling, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(remove_spiderling)) + spiderlings += new_spiderling + new_spiderling.pixel_x = rand(-8, 8) + new_spiderling.pixel_y = rand(-8, 8) + return TRUE + +/// Removes spiderling from spiderling list and unregisters death signal +/datum/action/ability/xeno_action/create_spiderling/proc/remove_spiderling(datum/source) + SIGNAL_HANDLER + spiderlings -= source + UnregisterSignal(source, list(COMSIG_MOB_DEATH, COMSIG_QDELETING)) + + +// *************************************** +// *********** Burrow +// *************************************** + +/datum/action/ability/xeno_action/burrow + name = "Burrow" + desc = "Burrow into the ground, allowing you and your active spiderlings to hide in plain sight. You cannot use abilities, attack nor move while burrowed. Use the ability again to unburrow if you're already burrowed." + action_icon_state = "burrow" + ability_cost = 0 + cooldown_duration = 20 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_BURROW, + ) + use_state_flags = ABILITY_USE_BURROWED + +/datum/action/ability/xeno_action/burrow/action_activate() + . = ..() + /// We need the list of spiderlings so that we can burrow them + var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = owner.actions_by_path[/datum/action/ability/xeno_action/create_spiderling] + /// Here we make every single spiderling that we have also burrow and assign a signal so that they unburrow too + for(var/mob/living/carbon/xenomorph/spiderling/spiderling AS in create_spiderling_action?.spiderlings) + /// Here we trigger the burrow proc, the registering happens there + var/datum/action/ability/xeno_action/burrow/spiderling_burrow = spiderling.actions_by_path[/datum/action/ability/xeno_action/burrow] + spiderling_burrow.xeno_burrow() + xeno_burrow() + succeed_activate() + +/// Burrow code for xenomorphs +/datum/action/ability/xeno_action/burrow/proc/xeno_burrow() + SIGNAL_HANDLER + var/mob/living/carbon/xenomorph/X = owner + if(!HAS_TRAIT(X, TRAIT_BURROWED)) + to_chat(X, span_xenowarning("We start burrowing into the ground...")) + INVOKE_ASYNC(src, PROC_REF(xeno_burrow_doafter)) + return + UnregisterSignal(X, COMSIG_XENOMORPH_TAKING_DAMAGE) + X.soft_armor = X.soft_armor.modifyRating(fire = -100) + X.hard_armor = X.hard_armor.modifyRating(fire = -100) + REMOVE_TRAIT(X, TRAIT_NON_FLAMMABLE, initial(name)) + X.mouse_opacity = initial(X.mouse_opacity) + X.density = TRUE + X.allow_pass_flags &= ~PASSABLE + REMOVE_TRAIT(X, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT) + REMOVE_TRAIT(X, TRAIT_BURROWED, WIDOW_ABILITY_TRAIT) + REMOVE_TRAIT(X, TRAIT_HANDS_BLOCKED, WIDOW_ABILITY_TRAIT) + X.update_icons() + add_cooldown() + owner.unbuckle_all_mobs(TRUE) + +/// Called by xeno_burrow only when burrowing +/datum/action/ability/xeno_action/burrow/proc/xeno_burrow_doafter() + if(!do_after(owner, 3 SECONDS, NONE, null, BUSY_ICON_DANGER)) + return + to_chat(owner, span_xenowarning("We are now burrowed, hidden in plain sight and ready to strike.")) + // This part here actually burrows the xeno + owner.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + owner.density = FALSE + owner.allow_pass_flags |= PASSABLE + // Here we prevent the xeno from moving or attacking or using abilities until they unburrow by clicking the ability + ADD_TRAIT(owner, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT) + ADD_TRAIT(owner, TRAIT_BURROWED, WIDOW_ABILITY_TRAIT) + ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, WIDOW_ABILITY_TRAIT) + // We register for movement so that we unburrow if bombed + var/mob/living/carbon/xenomorph/X = owner + ADD_TRAIT(X, TRAIT_NON_FLAMMABLE, initial(name)) + X.soft_armor = X.soft_armor.modifyRating(fire = 100) + X.hard_armor = X.hard_armor.modifyRating(fire = 100) + // Update here without waiting for life + X.update_icons() + RegisterSignal(X, COMSIG_XENOMORPH_TAKING_DAMAGE, PROC_REF(xeno_burrow)) + +// *************************************** +// *********** Attach Spiderlings +// *************************************** +/datum/action/ability/xeno_action/attach_spiderlings + name = "Attach Spiderlings" + desc = "Attach your current spiderlings to you " + action_icon_state = "attach_spiderling" + ability_cost = 0 + cooldown_duration = 0 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_ATTACH_SPIDERLINGS, + ) + ///the attached spiderlings + var/list/mob/living/carbon/xenomorph/spiderling/attached_spiderlings = list() + ///how many times we attempt to attach adjacent spiderligns + var/attach_attempts = 5 + +/datum/action/ability/xeno_action/attach_spiderlings/action_activate() + . = ..() + if(owner.buckled_mobs) + /// yeet off all spiderlings if we are carrying any + owner.unbuckle_all_mobs(TRUE) + return + var/mob/living/carbon/xenomorph/widow/X = owner + var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = X.actions_by_path[/datum/action/ability/xeno_action/create_spiderling] + if(!(length(create_spiderling_action.spiderlings))) + X.balloon_alert(X, "No spiderlings") + return fail_activate() + var/list/mob/living/carbon/xenomorph/spiderling/remaining_spiderlings = create_spiderling_action.spiderlings.Copy() + // First make the spiderlings stop what they are doing and return to the widow + for(var/mob/spider in remaining_spiderlings) + var/datum/component/ai_controller/AI = spider.GetComponent(/datum/component/ai_controller) + AI?.ai_behavior.change_action(ESCORTING_ATOM, AI.ai_behavior.escorted_atom) + grab_spiderlings(remaining_spiderlings, attach_attempts) + succeed_activate() + +/// this proc scoops up adjacent spiderlings and then calls ride_widow on them +/datum/action/ability/xeno_action/attach_spiderlings/proc/grab_spiderlings(list/mob/living/carbon/xenomorph/spiderling/remaining_list, number_of_attempts_left) + if(number_of_attempts_left <= 0) + return + for(var/mob/living/carbon/xenomorph/spiderling/remaining_spiderling AS in remaining_list) + SEND_SIGNAL(owner, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, SPIDERLING_RECALL) //So spiderlings move towards the buckle + if(!owner.Adjacent(remaining_spiderling)) + continue + remaining_list -= remaining_spiderling + owner.buckle_mob(remaining_spiderling, TRUE, TRUE, 90, FALSE, FALSE) + ADD_TRAIT(remaining_spiderling, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT) + addtimer(CALLBACK(src, PROC_REF(grab_spiderlings), remaining_list, number_of_attempts_left - 1), 1) + +// *************************************** +// *********** Web Spit +// *************************************** + +/datum/action/ability/activable/xeno/web_spit + name = "Web Spit" + desc = "Stun and blind the target with a web projectile" + action_icon_state = "web_projectile" + action_icon = 'icons/Xeno/actions.dmi' + ability_cost = 100 + cooldown_duration = 15 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_WEB_SPIT, + ) + +/datum/action/ability/activable/xeno/web_spit/use_ability(atom/target) + var/mob/living/carbon/xenomorph/X = owner + var/datum/ammo/xeno/web_projectile/web = GLOB.ammo_list[/datum/ammo/xeno/web_projectile] + var/obj/projectile/newspit = new /obj/projectile(get_turf(X)) + + newspit.generate_bullet(web) + newspit.def_zone = X.get_limbzone_target() + + newspit.fire_at(target, X, X, newspit.ammo.max_range) + succeed_activate() + add_cooldown() + +/datum/action/ability/xeno_action/create_hugger + name = "Create Hugger" + action_icon_state = "larval hugger" + desc = "Create a facehugger." + ability_cost = 60 + cooldown_duration = 20 SECONDS + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_CREATE_HUGGER, + ) + +/datum/action/ability/xeno_action/create_hugger/can_use_action(silent = FALSE, override_flags) + . = ..() + if(!.) + return + if(owner.l_hand || owner.r_hand) + if(!silent) + owner.balloon_alert(owner, "Need empty hands") + return FALSE + +/datum/action/ability/xeno_action/create_hugger/action_activate() + if(!do_after(owner, 1 SECONDS, IGNORE_LOC_CHANGE, owner, BUSY_ICON_HOSTILE)) + return FALSE + var/obj/item/clothing/mask/facehugger/hugger = new(owner.loc) + hugger.hivenumber = owner.get_xeno_hivenumber() + owner.put_in_hands(hugger) + add_cooldown() + succeed_activate() + +// *************************************** +// *********** Unleash spiderlings +// *************************************** +/datum/action/ability/xeno_action/widow_unleash + name = "Unleash Spiderlings" + action_icon_state = "unleash" + action_icon = 'icons/Xeno/actions.dmi' + desc = "Send out your spiderlings to attack nearby humans" + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_UNLEASH_SPIDERLINGS, + ) + +/datum/action/ability/xeno_action/widow_unleash/action_activate(mob/living/victim) + if(SEND_SIGNAL(owner, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, SPIDERLING_ATTACK)) + owner.balloon_alert(owner, "attacking") + else + owner.balloon_alert(owner, "fail") + +// *************************************** +// *********** Recall spiderlings +// *************************************** +/datum/action/ability/xeno_action/widow_recall + name = "Recall Spiderlings" + action_icon = 'icons/Xeno/actions.dmi' + action_icon_state = "recall" + desc = "Recall your siderlings to follow you once more" + keybinding_signals = list( + KEYBINDING_NORMAL = COMSIG_XENOABILITY_RECALL_SPIDERLINGS, + ) + +/datum/action/ability/xeno_action/widow_recall/action_activate(mob/living/victim) + if(SEND_SIGNAL(owner, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, SPIDERLING_RECALL)) + owner.balloon_alert(owner, "recalling") + else + owner.balloon_alert(owner, "fail") + +/datum/action/ability/xeno_action/spider_venom + name = "Widow's Poison" + desc = "Poison your target with incapacitating venom" + ability_cost = 0 + cooldown_duration = 0 + keybind_flags = ABILITY_USE_STAGGERED | ABILITY_IGNORE_SELECTED_ABILITY + +/datum/action/ability/xeno_action/spider_venom/give_action(mob/living/L) + . = ..() + RegisterSignal(L, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(on_bite)) + +/datum/action/ability/xeno_action/spider_venom/remove_action(mob/living/L) + . = ..() + UnregisterSignal(L, COMSIG_XENOMORPH_ATTACK_LIVING) + +/datum/action/ability/xeno_action/spider_venom/proc/on_bite(datum/source, mob/living/target) + SIGNAL_HANDLER + if(target.stat == DEAD) + return + if(!ishuman(target)) + return + + target.apply_status_effect(STATUS_EFFECT_SPIDER_VENOM) + +/datum/action/ability/xeno_action/spider_venom/should_show() + return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm new file mode 100644 index 00000000000..592a89bc391 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm @@ -0,0 +1,84 @@ +/datum/xeno_caste/widow + caste_name = "Widow" + display_name = "Widow" + upgrade_name = "" + caste_desc = "You don't think you've seen a tarantula this giant before." + caste_type_path = /mob/living/carbon/xenomorph/widow + tier = XENO_TIER_THREE + upgrade = XENO_UPGRADE_BASETYPE + wound_type = "widow" + + // *** Melee Attacks *** // + melee_damage = 18 + + // *** Speed *** // + speed = -0.5 + + // *** Plasma *** // + plasma_max = 600 + plasma_gain = 55 + + // *** Health *** // + max_health = 550 + + // *** Flags *** // + caste_flags = CASTE_EVOLUTION_ALLOWED + can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER|CASTE_CAN_HOLD_FACEHUGGERS|CASTE_CAN_HOLD_JELLY + caste_traits = null + + // *** Defense *** // + soft_armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 15, BIO = 10, FIRE = 15, ACID = 10) + + // *** Minimap Icon *** // + minimap_icon = "widow" + + // *** Widow Abilities *** // + max_spiderlings = 5 + + // *** Abilities *** /// + actions = list( + /datum/action/ability/xeno_action/xeno_resting, + /datum/action/ability/xeno_action/watch_xeno, + /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/activable/xeno/cocoon, + /datum/action/ability/xeno_action/create_hugger, + /datum/action/ability/xeno_action/widow_unleash, + /datum/action/ability/xeno_action/widow_recall, + /datum/action/ability/activable/xeno/web_spit, + /datum/action/ability/activable/xeno/leash_ball, + /datum/action/ability/xeno_action/create_spiderling, + /datum/action/ability/xeno_action/attach_spiderlings, + ) + +/datum/xeno_caste/widow/on_caste_applied(mob/xenomorph) + . = ..() + xenomorph.AddElement(/datum/element/ridable, /datum/component/riding/creature/widow) + +/datum/xeno_caste/widow/on_caste_removed(mob/xenomorph) + . = ..() + xenomorph.RemoveElement(/datum/element/ridable, /datum/component/riding/creature/widow) + +/datum/xeno_caste/widow/normal + upgrade = XENO_UPGRADE_NORMAL + +/datum/xeno_caste/widow/primordial + upgrade_name = "Primordial" + caste_desc = "At times, life is just like a web. You fall, and a spider called accident, at the center, takes you to hell." + primordial_message = "We weave the threads of fate that our victims life hangs from." + upgrade = XENO_UPGRADE_PRIMO + + // *** Abilities *** /// + actions = list( + /datum/action/ability/xeno_action/xeno_resting, + /datum/action/ability/xeno_action/watch_xeno, + /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/activable/xeno/cocoon, + /datum/action/ability/xeno_action/create_hugger, + /datum/action/ability/xeno_action/widow_unleash, + /datum/action/ability/xeno_action/widow_recall, + /datum/action/ability/activable/xeno/web_spit, + /datum/action/ability/activable/xeno/leash_ball, + /datum/action/ability/xeno_action/create_spiderling, + /datum/action/ability/xeno_action/attach_spiderlings, + /datum/action/ability/xeno_action/spider_venom, + ) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm new file mode 100644 index 00000000000..7c5846082dd --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm @@ -0,0 +1,61 @@ +/mob/living/carbon/xenomorph/widow + caste_base_type = /datum/xeno_caste/widow + name = "Widow" + desc = "A large arachnid xenomorph, with fangs ready to bear and crawling with many little spiderlings ready to grow." + icon = 'icons/Xeno/castes/widow/basic.dmi' + effects_icon = 'icons/Xeno/castes/widow/effects.dmi' + icon_state = "Widow Walking" + bubble_icon = "alienroyal" + health = 200 + maxHealth = 200 + plasma_stored = 150 + tier = XENO_TIER_THREE + upgrade = XENO_UPGRADE_NORMAL + buckle_flags = CAN_BUCKLE + pixel_x = -16 + old_x = -16 + max_buckled_mobs = 5 + +/mob/living/carbon/xenomorph/widow/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_LIGHT_STEP, XENO_TRAIT) + RegisterSignals(src, list(COMSIG_XENOMORPH_POSTATTACK_LIVING, COMSIG_XENOMORPH_ATTACK_OBJ), PROC_REF(postattack)) + +/mob/living/carbon/xenomorph/widow/proc/postattack(mob/living/source, atom/target, damage) + SIGNAL_HANDLER + SEND_SIGNAL(src, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, SPIDERLING_ATTACK, target) + SEND_SIGNAL(src, COMSIG_SPIDERLING_CHANGE_ALL_ORDER, SPIDERLING_ATTACK, target) + +/mob/living/carbon/xenomorph/widow/buckle_mob(mob/living/buckling_mob, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0, silent) + if(!force) + return FALSE + return ..() + +/mob/living/carbon/xenomorph/widow/post_unbuckle_mob(mob/living/M) + M.layer = initial(M.layer) + M.pixel_x = rand(-8, 8) + M.pixel_y = rand(-8, 8) + +//Prevents humans unbuckling spiderlings +/mob/living/carbon/xenomorph/widow/user_unbuckle_mob(mob/living/buckled_mob, mob/user, silent) + if(ishuman(user)) + return + return ..() + +/mob/living/carbon/xenomorph/widow/death(gibbing, deathmessage, silent) + unbuckle_all_mobs(TRUE) //RELEASE THE HORDE + return ..() + +/mob/living/carbon/xenomorph/widow/transfer_to_hive(hivenumber) + . = ..() + var/mob/living/carbon/xenomorph/widow/X = src + var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = X.actions_by_path[/datum/action/ability/xeno_action/create_spiderling] + for(var/mob/living/carbon/xenomorph/spider AS in create_spiderling_action.spiderlings) + spider.transfer_to_hive(hivenumber) + +/mob/living/carbon/xenomorph/widow/on_eord(turf/destination) + . = ..() + var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = actions_by_path[/datum/action/ability/xeno_action/create_spiderling] + for(var/mob/living/carbon/xenomorph/spider AS in create_spiderling_action.spiderlings) + spider.revive(TRUE) + spider.forceMove(destination) diff --git a/code/modules/mob/living/carbon/xenomorph/embryo.dm b/code/modules/mob/living/carbon/xenomorph/embryo.dm index c84b898d281..ca3a6e056df 100644 --- a/code/modules/mob/living/carbon/xenomorph/embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/embryo.dm @@ -86,7 +86,7 @@ counter += 2.5 //Doubles larval growth progress. Burst time in ~3 min. adjust_boost_timer(-1) - if(stage < 5 && counter >= 120) + if(stage < 5 && counter >= 100) counter = 0 stage++ log_combat(affected_mob, null, "had their embryo advance to stage [stage]") diff --git a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm index 61e3a882ba7..a5d19a964ac 100644 --- a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm +++ b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm @@ -448,9 +448,6 @@ if(species?.species_flags & (IS_SYNTHETIC|ROBOTIC_LIMBS)) return FALSE - if(on_fire) - return FALSE - if(check_mask) if(wear_mask) var/obj/item/W = wear_mask @@ -473,82 +470,86 @@ ///////////////////////////// // ATTACHING AND IMPREGNATION ////////////////////////////// -/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/carbon/M, can_catch = TRUE) +/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/carbon/hugged_carbon, can_catch = TRUE) set_throwing(FALSE) leaping = FALSE update_icon() - if(!istype(M)) + if(!istype(hugged_carbon)) return FALSE if(attached) return TRUE - if(M.status_flags & XENO_HOST || M.status_flags & GODMODE || isxeno(M)) + if(hugged_carbon.status_flags & XENO_HOST || hugged_carbon.status_flags & GODMODE || isxeno(hugged_carbon)) return FALSE if(isxeno(loc)) //Being carried? Drop it - var/mob/living/carbon/xenomorph/X = loc - X.dropItemToGround(src) - X.update_icons() + var/mob/living/carbon/xenomorph/carrier = loc + carrier.dropItemToGround(src) + carrier.update_icons() - if(M.in_throw_mode && M.dir != dir && !M.incapacitated() && !M.get_active_held_item() && can_catch) + if(hugged_carbon.in_throw_mode && hugged_carbon.dir != dir && !hugged_carbon.incapacitated() && !hugged_carbon.get_active_held_item() && can_catch) var/catch_chance = 50 - if(M.dir == REVERSE_DIR(dir)) + if(hugged_carbon.dir == REVERSE_DIR(dir)) catch_chance += 20 - catch_chance -= M.painloss * 0.3 - if(M.get_inactive_held_item()) + catch_chance -= hugged_carbon.painloss * 0.3 + if(hugged_carbon.get_inactive_held_item()) catch_chance -= 25 if(prob(catch_chance)) - M.visible_message(span_notice("[M] snatches [src] out of the air and [pickweight(list("clobbers" = 30, "kills" = 30, "squashes" = 25, "dunks" = 10, "dribbles" = 5))] it!")) + hugged_carbon.visible_message(span_notice("[hugged_carbon] snatches [src] out of the air and [pickweight(list("clobbers" = 30, "kills" = 30, "squashes" = 25, "dunks" = 10, "dribbles" = 5))] it!")) kill_hugger() return TRUE var/blocked = null //To determine if the hugger just rips off the protection or can infect. - if(ishuman(M)) - var/mob/living/carbon/human/H = M + if(ishuman(hugged_carbon)) + var/mob/living/carbon/human/hugged_human = hugged_carbon - if(!H.has_limb(HEAD)) - visible_message(span_warning("[src] looks for a face to hug on [H], but finds none!")) + if(!hugged_human.has_limb(HEAD)) + visible_message(span_warning("[src] looks for a face to hug on [hugged_human], but finds none!")) return FALSE - if(H.head) - var/obj/item/clothing/head/D = H.head - if(istype(D)) - if(D.anti_hug > 0 || HAS_TRAIT(D, TRAIT_NODROP)) - blocked = D - D.anti_hug = max(0, --D.anti_hug) - H.visible_message(span_danger("[src] smashes against [H]'s [D.name], damaging it!")) + if(hugged_human.head) + var/obj/item/clothing/head/headwear = hugged_human.head + if(istype(headwear)) + if(headwear.anti_hug > 0 || HAS_TRAIT(headwear, TRAIT_NODROP)) + blocked = headwear + headwear.anti_hug = max(0, --headwear.anti_hug) + hugged_human.visible_message(span_danger("[src] smashes against [hugged_human]'s [headwear.name], damaging it!")) + if(headwear.anti_hug == 0) + headwear.on_hugger_damage() return FALSE else - H.update_inv_head() + hugged_human.update_inv_head() - if(M.wear_mask) - var/obj/item/clothing/mask/W = M.wear_mask - if(istype(W)) - if(istype(W, /obj/item/clothing/mask/facehugger)) - var/obj/item/clothing/mask/facehugger/hugger = W + if(hugged_carbon.wear_mask) + var/obj/item/clothing/mask/worn_mask = hugged_carbon.wear_mask + if(istype(worn_mask)) + if(istype(worn_mask, /obj/item/clothing/mask/facehugger)) + var/obj/item/clothing/mask/facehugger/hugger = worn_mask if(hugger.stat != DEAD) return FALSE - if(W.anti_hug > 0 || HAS_TRAIT(W, TRAIT_NODROP)) + if(worn_mask.anti_hug > 0 || HAS_TRAIT(worn_mask, TRAIT_NODROP)) if(!blocked) - blocked = W - W.anti_hug = max(0, --W.anti_hug) - M.visible_message(span_danger("[src] smashes against [M]'s [blocked]!")) + blocked = worn_mask + worn_mask.anti_hug = max(0, --worn_mask.anti_hug) + hugged_carbon.visible_message(span_danger("[src] smashes against [hugged_carbon]'s [blocked]!")) + if(worn_mask.anti_hug == 0) + worn_mask.on_hugger_damage() return FALSE if(!blocked) - M.visible_message(span_danger("[src] smashes against [M]'s [W.name] and rips it off!")) - M.dropItemToGround(W) + hugged_carbon.visible_message(span_danger("[src] smashes against [hugged_carbon]'s [worn_mask.name] and rips it off!")) + hugged_carbon.dropItemToGround(worn_mask) if(blocked) - M.visible_message(span_danger("[src] smashes against [M]'s [blocked]!")) + hugged_carbon.visible_message(span_danger("[src] smashes against [hugged_carbon]'s [blocked]!")) return FALSE - M.equip_to_slot(src, SLOT_WEAR_MASK) + hugged_carbon.equip_to_slot(src, SLOT_WEAR_MASK) return TRUE /obj/item/clothing/mask/facehugger/equipped(mob/living/user, slot) @@ -663,9 +664,6 @@ proj.ammo.on_hit_obj(src, proj) return TRUE -/obj/item/clothing/mask/facehugger/fire_act(burn_level, flame_color) - kill_hugger() - /obj/item/clothing/mask/facehugger/dropped(mob/user) . = ..() go_idle() diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm index cc9af820119..19f50b8ae84 100644 --- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm +++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm @@ -101,7 +101,7 @@ wound_overlay.layer = layer + 0.3 wound_overlay.icon = src.icon wound_overlay.vis_flags |= VIS_HIDE - if(HAS_TRAIT(src, TRAIT_MOB_ICON_UPDATE_BLOCKED)) + if(HAS_TRAIT(src, TRAIT_MOB_ICON_UPDATE_BLOCKED) || HAS_TRAIT(src, TRAIT_BURROWED)) wound_overlay.icon_state = "none" return if(health > health_threshold_crit) diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm index d669faf858f..c8dd5e558df 100644 --- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm +++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm @@ -189,6 +189,10 @@ ///Base range of Blink var/blink_range = 0 + // *** Widow Abilities *** // + ///maximum amount of spiderlings a widow can carry at one time. + var/max_spiderlings = 0 + ///the 'abilities' available to a caste. var/list/actions diff --git a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm index 5300dcc0a36..5c99bc33589 100644 --- a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm +++ b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm @@ -354,6 +354,15 @@ //----BEHEMOTH END----// //============// +//----WIDOW START----// +/mob/living/carbon/xenomorph/widow + upgrade = XENO_UPGRADE_NORMAL + +/mob/living/carbon/xenomorph/widow/primordial + upgrade = XENO_UPGRADE_PRIMO + +//----WIDOW END----// + //----PANTHER START----// /mob/living/carbon/xenomorph/panther/primordial upgrade = XENO_UPGRADE_PRIMO diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 51db202422e..7510773844b 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -163,8 +163,8 @@ //TODO: Make firetypes, colour types are terrible if(flame_color == FLAME_COLOR_LIME) - var/datum/status_effect/stacking/melting/debuff = has_status_effect(STATUS_EFFECT_MELTING) - if(debuff) + if(has_status_effect(STATUS_EFFECT_MELTING)) + var/datum/status_effect/stacking/melting/debuff = has_status_effect(STATUS_EFFECT_MELTING) debuff.add_stacks(2) else apply_status_effect(STATUS_EFFECT_MELTING, 2) diff --git a/code/modules/mob/living/living_health_procs.dm b/code/modules/mob/living/living_health_procs.dm index b3812ccb5ec..38f7a321bec 100644 --- a/code/modules/mob/living/living_health_procs.dm +++ b/code/modules/mob/living/living_health_procs.dm @@ -300,7 +300,6 @@ // make the icons look correct regenerate_icons() - med_hud_set_status() med_pain_set_perceived_health() med_hud_set_health() handle_regular_hud_updates() @@ -361,11 +360,12 @@ return ..() /mob/living/carbon/xenomorph/revive(admin_revive = FALSE) + . = ..() set_plasma(xeno_caste.plasma_max) sunder = 0 + hud_update_primo() if(stat == DEAD) hive?.on_xeno_revive(src) - return ..() ///Revive the huamn up to X health points /mob/living/carbon/human/proc/revive_to_crit(should_offer_to_ghost = FALSE, should_zombify = FALSE) diff --git a/code/modules/mob/living/silicon/ai/ai_notifications.dm b/code/modules/mob/living/silicon/ai/ai_notifications.dm index 7c3b481b6c2..1ce070af5a7 100644 --- a/code/modules/mob/living/silicon/ai/ai_notifications.dm +++ b/code/modules/mob/living/silicon/ai/ai_notifications.dm @@ -23,7 +23,7 @@ alertnotification.add_overlay(alert_overlay) ///Receive notifications about OB laser dots that have been deployed -/mob/living/silicon/ai/proc/receive_laser_ob(datum/source, obj/effect/overlay/temp/laser_target/OB/incoming_laser) +/mob/living/silicon/ai/proc/receive_laser_ob(datum/source, obj/effect/overlay/temp/laser_target/ob/incoming_laser) SIGNAL_HANDLER to_chat(src, span_notice("Orbital Bombardment laser detected. Target: [AREACOORD_NO_Z(incoming_laser)]")) notify_ai(src, " An Orbital Bombardment laser has been detected at [AREACOORD_NO_Z(incoming_laser)]!", ai_sound = 'sound/effects/obalarm.ogg', source = incoming_laser, action = NOTIFY_AI_ALERT, notify_volume = 15) @@ -80,4 +80,4 @@ SIGNAL_HANDLER var/area/A = get_area(callingholopad) to_chat(src, span_notice("Your presence is requested at [A]!")) - notify_ai(src, " Your presence is requested at [A]! ", source = callingholopad, action = NOTIFY_AI_ALERT, notify_volume = 15) + notify_ai(src, " Your presence is requested at [A]! ", source = callingholopad, action = NOTIFY_AI_ALERT, notify_volume = 35) diff --git a/code/modules/mob/living/silicon/ai/ai_verbs.dm b/code/modules/mob/living/silicon/ai/ai_verbs.dm index b89f3a35fcd..35aa86eecb8 100644 --- a/code/modules/mob/living/silicon/ai/ai_verbs.dm +++ b/code/modules/mob/living/silicon/ai/ai_verbs.dm @@ -112,7 +112,7 @@ "floating face" = 'icons/mob/ai.dmi', "xeno_queen" = 'icons/mob/ai.dmi', "void_horror" = 'icons/mob/ai.dmi', - "holo4" = 'icons/mob/ai.dmi' + "carp" = 'icons/mob/ai.dmi' ) hologram = tgui_input_list(src, "Please select a hologram:", null, icon_list) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index e11d50dbcb8..e4cc0a91146 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -79,25 +79,24 @@ to_chat(src, span_userdanger("You are tipped over by [user]!")) Paralyze(20 SECONDS) icon_state = icon_dead - spawn(rand(20, 50)) - if(!stat && user) - icon_state = icon_living - var/external - var/internal - switch(pick(1,2,3,4)) - if(1,2,3) - var/text = pick("imploringly.", "pleadingly.", - "with a resigned expression.") - external = "[src] looks at [user] [text]" - internal = "You look at [user] [text]" - if(4) - external = "[src] seems resigned to its fate." - internal = "You resign yourself to your fate." - visible_message(span_notice("[external]"), - span_revennotice("[internal]")) + addtimer(CALLBACK(src, PROC_REF(tip_message), user), rand(2 SECONDS, 5 SECONDS)) else return ..() +/mob/living/simple_animal/cow/proc/tip_message(mob/living/user) + if(stat || !user) + return + icon_state = icon_living + var/external + var/internal + if(prob(75)) + var/text = pick("imploringly.", "pleadingly.", "with a resigned expression.") + external = "[src] looks at [user] [text]" + internal = "You look at [user] [text]" + else + external = "[src] seems resigned to its fate." + internal = "You resign yourself to your fate." + visible_message(span_notice("[external]"), span_revennotice("[internal]")) /mob/living/simple_animal/chick name = "\improper chick" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index aa8693dd92a..8d410fbd1ec 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -219,27 +219,28 @@ /obj/item/paper/proc/burnpaper(obj/item/P, mob/user) var/class = "" - if(P.heat >= 400 && !user.restrained()) - if(istype(P, /obj/item/tool/lighter/zippo)) - class = "" - - user.visible_message("[class][user] holds \the [P] up to \the [src], it looks like [user.p_theyre()] trying to burn it!", \ - "[class]You hold \the [P] up to \the [src], burning it slowly.") + if(P.heat < 400 || user.restrained()) + return + if(istype(P, /obj/item/tool/lighter/zippo)) + class = "" - spawn(20) - if(get_dist(src, user) < 2 && user.get_active_held_item() == P && P.heat) - user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ - "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") + user.visible_message("[class][user] holds \the [P] up to \the [src], it looks like [user.p_theyre()] trying to burn it!", \ + "[class]You hold \the [P] up to \the [src], burning it slowly.") - if(user.get_inactive_held_item() == src) - user.dropItemToGround(src) + if(!do_after(user, 2 SECONDS, NONE, src)) + to_chat(user, span_warning("You must hold \the [P] steady to burn \the [src].")) + return - new /obj/effect/decal/cleanable/ash(src.loc) - qdel(src) + if(!P.heat) + return + user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ + "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") - else - to_chat(user, span_warning("You must hold \the [P] steady to burn \the [src].")) + if(user.get_inactive_held_item() == src) + user.dropItemToGround(src) + new /obj/effect/decal/cleanable/ash(src.loc) + qdel(src) /obj/item/paper/Topic(href, href_list) . = ..() @@ -389,7 +390,7 @@ then, for every time you included a field, increment fields. */ /obj/item/paper/jobs name = "Job Information" - info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
\nThe data will be in the following form.
\nGenerally lower ranking positions come first in this list.
\n
\nJob Name general access>lab access-engine access-systems access (atmosphere control)
\n\tJob Description
\nJob Duties (in no particular order)
\nTips (where applicable)
\n
\nResearch Assistant 1>1-0-0
\n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
\n1. Assist the researchers.
\n2. Clean up the labs.
\n3. Prepare materials.
\n
\nStaff Assistant 2>0-0-0
\n\tThis position assists the security officer in his duties. The staff assisstants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
\n1. Patrol ship/Guard key areas
\n2. Assist security officer
\n3. Perform other security duties.
\n
\nTechnical Assistant 1>0-0-1
\n\tThis is yet another low level position. The technical assistant helps the engineer and the statian\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
\n1. Assist Station technician and Engineers.
\n2. Perform general maintenance of station.
\n3. Prepare materials.
\n
\nMedical Assistant 1>1-0-0
\n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
\n1. Assist the medical personnel.
\n2. Update medical files.
\n3. Prepare materials for medical operations.
\n
\nResearch Technician 2>3-0-0
\n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
\n1. Inform superiors of research.
\n2. Perform research alongside of official researchers.
\n
\nDetective 3>2-0-0
\n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crine scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should stroe the evidence ly.
\n1. Perform crime-scene investigations/draw conclusions.
\n2. Store and catalogue evidence properly.
\n3. Testify to superiors/inquieries on findings.
\n
\nStation Technician 2>0-2-3
\n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
\n1. Maintain SS13 systems.
\n2. Repair equipment.
\n
\nAtmospheric Technician 3>0-0-4
\n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
\n1. Maintain atmosphere on SS13
\n2. Research atmospheres on the space station. (safely please!)
\n
\nEngineer 2>1-3-0
\n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
\n1. Upkeep the engine.
\n2. Prevent fires in the engine.
\n3. Maintain a safe orbit.
\n
\nMedical Researcher 2>5-0-0
\n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
\n1. Make sure the station is kept safe.
\n2. Research medical properties of materials studied of Space Station 13.
\n
\nScientist 2>5-0-0
\n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Phoron Technicians as phoron is the material they routinly handle.
\n1. Research phoron
\n2. Make sure all phoron is properly handled.
\n
\nMedical Doctor (Officer) 2>0-0-0
\n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
\n1. Heal wounded people.
\n2. Perform examinations of all personnel.
\n3. Moniter usage of medical equipment.
\n
\nSecurity Officer 3>0-0-0
\n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
\n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
\n1. Maintain order.
\n2. Assist others.
\n3. Repair structural problems.
\n
\nHead of Security 4>5-2-2
\n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
\n1. Oversee security.
\n2. Assign patrol duties.
\n3. Protect the station and staff.
\n
\nHead of Personnel 4>4-2-2
\n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
\n1. Assign duties.
\n2. Moderate personnel.
\n3. Moderate research.
\n
\nCaptain 5>5-5-5 (unrestricted station wide access)
\n\tThis is the highest position youi can aquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
\n1. Assign all positions on SS13
\n2. Inspect the station for any problems.
\n3. Perform administrative duties.
\n" + info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
\nThe data will be in the following form.
\nGenerally lower ranking positions come first in this list.
\n
\nJob Name general access>lab access-engine access-systems access (atmosphere control)
\n\tJob Description
\nJob Duties (in no particular order)
\nTips (where applicable)
\n
\nResearch Assistant 1>1-0-0
\n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
\n1. Assist the researchers.
\n2. Clean up the labs.
\n3. Prepare materials.
\n
\nStaff Assistant 2>0-0-0
\n\tThis position assists the security officer in his duties. The staff assisstants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
\n1. Patrol ship/Guard key areas
\n2. Assist security officer
\n3. Perform other security duties.
\n
\nTechnical Assistant 1>0-0-1
\n\tThis is yet another low level position. The technical assistant helps the engineer and the statian\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
\n1. Assist Station technician and Engineers.
\n2. Perform general maintenance of station.
\n3. Prepare materials.
\n
\nMedical Assistant 1>1-0-0
\n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
\n1. Assist the medical personnel.
\n2. Update medical files.
\n3. Prepare materials for medical operations.
\n
\nResearch Technician 2>3-0-0
\n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
\n1. Inform superiors of research.
\n2. Perform research alongside of official researchers.
\n
\nDetective 3>2-0-0
\n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crine scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should stroe the evidence ly.
\n1. Perform crime-scene investigations/draw conclusions.
\n2. Store and catalogue evidence properly.
\n3. Testify to superiors/inquieries on findings.
\n
\nStation Technician 2>0-2-3
\n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
\n1. Maintain SS13 systems.
\n2. Repair equipment.
\n
\nAtmospheric Technician 3>0-0-4
\n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
\n1. Maintain atmosphere on SS13
\n2. Research atmospheres on the space station. (safely please!)
\n
\nEngineer 2>1-3-0
\n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
\n1. Upkeep the engine.
\n2. Prevent fires in the engine.
\n3. Maintain a safe orbit.
\n
\nField Researcher 2>5-0-0
\n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
\n1. Make sure the station is kept safe.
\n2. Research medical properties of materials studied of Space Station 13.
\n
\nScientist 2>5-0-0
\n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Phoron Technicians as phoron is the material they routinly handle.
\n1. Research phoron
\n2. Make sure all phoron is properly handled.
\n
\nMedical Doctor (Officer) 2>0-0-0
\n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
\n1. Heal wounded people.
\n2. Perform examinations of all personnel.
\n3. Moniter usage of medical equipment.
\n
\nSecurity Officer 3>0-0-0
\n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
\n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
\n1. Maintain order.
\n2. Assist others.
\n3. Repair structural problems.
\n
\nHead of Security 4>5-2-2
\n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
\n1. Oversee security.
\n2. Assign patrol duties.
\n3. Protect the station and staff.
\n
\nHead of Personnel 4>4-2-2
\n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
\n1. Assign duties.
\n2. Moderate personnel.
\n3. Moderate research.
\n
\nCaptain 5>5-5-5 (unrestricted station wide access)
\n\tThis is the highest position youi can aquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
\n1. Assign all positions on SS13
\n2. Inspect the station for any problems.
\n3. Perform administrative duties.
\n" /obj/item/paper/photograph name = "photo" diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 7197a28b951..58ed494b9fb 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -62,30 +62,31 @@ update_icon() attack_self(user) //Update the browsed page. - /obj/item/paper_bundle/proc/burnpaper(obj/item/P, mob/user) var/class = "" - if(P.heat >= 400 && !user.restrained()) - if(istype(P, /obj/item/tool/lighter/zippo)) - class = "" + if(P.heat < 400 || user.restrained()) + return + if(istype(P, /obj/item/tool/lighter/zippo)) + class = "" - user.visible_message("[class][user] holds \the [P] up to \the [src], it looks like [user.p_theyre()] trying to burn it!", \ + user.visible_message("[class][user] holds \the [P] up to \the [src], it looks like [user.p_theyre()] trying to burn it!", \ "[class]You hold \the [P] up to \the [src], burning it slowly.") - spawn(20) - if(get_dist(src, user) < 2 && user.get_active_held_item() == P && P.heat) - user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ - "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") + if(!do_after(user, 2 SECONDS, NONE, src)) + to_chat(user, span_warning("You must hold \the [P] steady to burn \the [src].")) + return - if(user.get_inactive_held_item() == src) - user.dropItemToGround(src) + if(!P.heat) + return + user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ + "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") - new /obj/effect/decal/cleanable/ash(src.loc) - qdel(src) + if(user.get_inactive_held_item() == src) + user.dropItemToGround(src) - else - to_chat(user, span_warning("You must hold \the [P] steady to burn \the [src].")) + new /obj/effect/decal/cleanable/ash(src.loc) + qdel(src) /obj/item/paper_bundle/examine(mob/user) . = ..() diff --git a/code/modules/power/apc/apc.dm b/code/modules/power/apc/apc.dm index 11b44ea56db..e7f853abacb 100644 --- a/code/modules/power/apc/apc.dm +++ b/code/modules/power/apc/apc.dm @@ -10,7 +10,7 @@ name = "area power controller" desc = "A control terminal for the area electrical systems." icon = 'icons/obj/machines/apc.dmi' - icon_state = "apc0" + icon_state = "apc_closed" anchored = TRUE use_power = NO_POWER_USE req_access = list(ACCESS_CIVILIAN_ENGINEERING) diff --git a/code/modules/power/apc/apc_appearance.dm b/code/modules/power/apc/apc_appearance.dm index fe95cfb6809..4b3a1419eaf 100644 --- a/code/modules/power/apc/apc_appearance.dm +++ b/code/modules/power/apc/apc_appearance.dm @@ -19,30 +19,83 @@ /obj/machinery/power/apc/update_icon_state() . = ..() - var/broken = CHECK_BITFIELD(update_state, UPSTATE_BROKE) ? "-b" : "" - var/status = (CHECK_BITFIELD(update_state, UPSTATE_WIREEXP) && !CHECK_BITFIELD(update_state, UPSTATE_OPENED1)) ? "-wires" : broken - icon_state = "apc[opened][status]" + var/broken = CHECK_BITFIELD(update_state, UPSTATE_BROKE) ? "_broken" : "" + var/status = (CHECK_BITFIELD(update_state, UPSTATE_WIREEXP) && !CHECK_BITFIELD(update_state, UPSTATE_OPENED1)) ? "_wires" : broken + var/apc_opened + switch(opened) + if(APC_COVER_CLOSED) + apc_opened = "closed" + if(APC_COVER_OPENED) + apc_opened = "opened" + if(APC_COVER_REMOVED) + apc_opened = "removed" + icon_state = "apc_[apc_opened][status]" /obj/machinery/power/apc/update_overlays() . = ..() if(opened && cell) - . += "apco-cell" + . += "apc_overlay_cell" if((machine_stat & (BROKEN|MAINT)) || update_state) return - . += emissive_appearance(icon, "apcox-[locked]") - . += mutable_appearance(icon, "apcox-[locked]") - . += emissive_appearance(icon, "apco3-[charging]") - . += mutable_appearance(icon, "apco3-[charging]") - - . += emissive_appearance(icon, "apco0-[operating ? equipment : 0]") - . += mutable_appearance(icon, "apco0-[operating ? equipment : 0]") - . += emissive_appearance(icon, "apco1-[operating ? lighting : 0]") - . += mutable_appearance(icon, "apco1-[operating ? lighting : 0]") - . += emissive_appearance(icon, "apco2-[operating ? environ : 0]") - . += mutable_appearance(icon, "apco2-[operating ? environ : 0]") + var/apc_locked = locked ? "locked" : "unlocked" + . += emissive_appearance(icon, "apc_overlay_[apc_locked]") + . += mutable_appearance(icon, "apc_overlay_[apc_locked]") + + var/apc_charging = "" + switch(charging) + if(APC_NOT_CHARGING) + apc_charging = "off" + if(APC_CHARGING) + apc_charging = "on" + if(APC_FULLY_CHARGED) + apc_charging = "full" + . += emissive_appearance(icon, "apc_charging_[apc_charging]") + . += mutable_appearance(icon, "apc_charging_[apc_charging]") + + if(!operating) + return + + var/apc_equipment = "" + switch(equipment) + if(APC_CHANNEL_OFF) + apc_equipment = "off" + if(APC_CHANNEL_AUTO_OFF) + apc_equipment = "auto_off" + if(APC_CHANNEL_ON) + apc_equipment = "on" + if(APC_CHANNEL_AUTO_ON) + apc_equipment = "auto_on" + . += emissive_appearance(icon, "apc_equipment_[apc_equipment]") + . += mutable_appearance(icon, "apc_equipment_[apc_equipment]") + + var/apc_lighting = "" + switch(lighting) + if(APC_CHANNEL_OFF) + apc_lighting = "off" + if(APC_CHANNEL_AUTO_OFF) + apc_lighting = "auto_off" + if(APC_CHANNEL_ON) + apc_lighting = "on" + if(APC_CHANNEL_AUTO_ON) + apc_lighting = "auto_on" + . += emissive_appearance(icon, "apc_lighting_[apc_lighting]") + . += mutable_appearance(icon, "apc_lighting_[apc_lighting]") + + var/apc_environ = "" + switch(environ) + if(APC_CHANNEL_OFF) + apc_environ = "off" + if(APC_CHANNEL_AUTO_OFF) + apc_environ = "auto_off" + if(APC_CHANNEL_ON) + apc_environ = "on" + if(APC_CHANNEL_AUTO_ON) + apc_environ = "auto_on" + . += emissive_appearance(icon, "apc_environ_[apc_environ]") + . += mutable_appearance(icon, "apc_environ_[apc_environ]") /// Checks for what icon updates we will need to handle /obj/machinery/power/apc/proc/check_updates() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index b3c011ddc13..78b15cfe79d 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -350,15 +350,17 @@ if(flickering) return flickering = TRUE - spawn(0) - if(light_on && status == LIGHT_OK) - for(var/i = 0; i < amount; i++) - if(status != LIGHT_OK) - break - update(FALSE) - sleep(rand(5, 15)) - update(FALSE) - flickering = FALSE + INVOKE_ASYNC(src, PROC_REF(flicker_stage_2), amount) + +/obj/machinery/light/proc/flicker_stage_2(amount) + if(light_on && status == LIGHT_OK) + for(var/i = 0; i < amount; i++) + if(status != LIGHT_OK) + break + update(FALSE, FALSE) + sleep(rand(5, 15)) + update(FALSE) + flickering = FALSE // ai attack - make lights flicker, because why not diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index 4441018438b..f78389b8b20 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -141,29 +141,31 @@ if (prob(50)) visible_message("DANGER! Magnetic containment field unstable! Containment field failure imminent!") failing = 1 - // 30 - 60 seconds and then BAM! - spawn(rand(300,600)) - if(!failing) // Admin can manually set this var back to 0 to stop overload, for use when griffed. - update_icon() - visible_message("Magnetic containment stabilised.") - return - visible_message("DANGER! Magnetic containment field failure in 3 ... 2 ... 1 ...") - cell_explosion(loc, 250, 50) - // Not sure if this is necessary, but just in case the SMES *somehow* survived.. - qdel(src) - - // Gets powernet APCs and overloads lights or breaks the APC completely, depending on percentages. + addtimer(CALLBACK(src, PROC_REF(smes_overload)), rand(30 SECONDS, 60 SECONDS)) + +/obj/machinery/power/smes/buildable/proc/smes_overload() + if(!failing) // Admin can manually set this var back to 0 to stop overload, for use when griffed. + update_icon() + visible_message("Magnetic containment stabilised.") + return + visible_message("DANGER! Magnetic containment field failure in 3 ... 2 ... 1 ...") + cell_explosion(loc, 250, 50) + // Not sure if this is necessary, but just in case the SMES *somehow* survived.. + qdel(src) + +/// Gets powernet APCs and overloads lights or breaks the APC completely, depending on percentages. /obj/machinery/power/smes/buildable/proc/apcs_overload(failure_chance, overload_chance) - if (!src.powernet) + if(!src.powernet) return for(var/obj/machinery/power/terminal/T in src.powernet.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = T.master - if (prob(overload_chance)) - A.overload_lighting() - if (prob(failure_chance)) - A.set_broken() + if(!istype(T.master, /obj/machinery/power/apc)) + continue + var/obj/machinery/power/apc/A = T.master + if(prob(overload_chance)) + A.overload_lighting() + if(prob(failure_chance)) + A.set_broken() // Failing SMES has special icon overlay. /obj/machinery/power/smes/buildable/update_overlays() diff --git a/code/modules/predator/smartdisc.dm b/code/modules/predator/smartdisc.dm index d99b83b2e8f..f5c3aaaff57 100644 --- a/code/modules/predator/smartdisc.dm +++ b/code/modules/predator/smartdisc.dm @@ -120,9 +120,7 @@ active = TRUE playsound(loc, 'sound/items/countdown.ogg', 25, 1) update_icon() - spawn(det_time) - prime() - return + addtimer(CALLBACK(src, PROC_REF(prime)), det_time) /obj/item/explosive/grenade/spawnergrenade/smartdisc/prime() if(spawner_type && deliveryamt) @@ -212,10 +210,8 @@ /mob/living/simple_animal/hostile/smartdisc/death() visible_message("\The [src] stops whirring and spins out onto the floor.") drop_real_disc() - ..() - spawn(1) - if(src) - qdel(src) + . = ..() + QDEL_IN(src, 0.1 SECONDS) /mob/living/simple_animal/hostile/smartdisc/proc/drop_real_disc() spawner_item.forceMove(loc) @@ -230,9 +226,7 @@ /mob/living/simple_animal/hostile/smartdisc/gib() visible_message("\The [src] explodes!") . = ..() - spawn(1) - if(src) - qdel(src) + QDEL_IN(src, 0.1 SECONDS) /mob/living/simple_animal/hostile/smartdisc/FindTarget() var/atom/T = null diff --git a/code/modules/predator/yautja/bracers.dm b/code/modules/predator/yautja/bracers.dm index a6055b235e6..376e9b344c0 100644 --- a/code/modules/predator/yautja/bracers.dm +++ b/code/modules/predator/yautja/bracers.dm @@ -92,7 +92,7 @@ action.remove_action(user) if(!user.hunter_data?.claimed_equipment) claim_equipment.remove_action(user) - ..() + return ..() /obj/item/clothing/gloves/yautja/equipped(mob/living/carbon/human/user, slot) if(slot == SLOT_GLOVES) @@ -530,8 +530,7 @@ sparks.set_up(5, 4, src) sparks.start() - spawn() - decloak(wearer, TRUE) + INVOKE_ASYNC(src, PROC_REF(decloak), wearer, TRUE) /obj/item/clothing/gloves/yautja/proc/track_gear_internal(mob/caller, forced = FALSE) . = check_random_function(caller, forced) diff --git a/code/modules/predator/yautja/weapons/ranged.dm b/code/modules/predator/yautja/weapons/ranged.dm index afed63d1489..741409c6ec2 100644 --- a/code/modules/predator/yautja/weapons/ranged.dm +++ b/code/modules/predator/yautja/weapons/ranged.dm @@ -462,13 +462,16 @@ /mob/living/carbon/apply_pred_laser() overlays_standing[PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locking-y", "layer" = -PRED_LASER_LAYER) apply_overlay(PRED_LASER_LAYER) - spawn(2 SECONDS) - if(overlays_standing[PRED_LASER_LAYER]) - remove_overlay(PRED_LASER_LAYER) - overlays_standing[PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locked-y", "layer" = -PRED_LASER_LAYER) - apply_overlay(PRED_LASER_LAYER) + addtimer(CALLBACK(src, PROC_REF(delayed_apply_pred_laser)), 2 SECONDS) return TRUE +/mob/living/carbon/proc/delayed_apply_pred_laser() + if(!overlays_standing[PRED_LASER_LAYER]) + return + remove_overlay(PRED_LASER_LAYER) + overlays_standing[PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locked-y", "layer" = -PRED_LASER_LAYER) + apply_overlay(PRED_LASER_LAYER) + /atom/proc/remove_pred_laser() return FALSE diff --git a/code/modules/projectiles/ammo_datums/artillery.dm b/code/modules/projectiles/ammo_datums/artillery.dm index 8b7b8bdb283..b48419c23dc 100644 --- a/code/modules/projectiles/ammo_datums/artillery.dm +++ b/code/modules/projectiles/ammo_datums/artillery.dm @@ -220,10 +220,10 @@ flags_ammo_behavior = AMMO_BALLISTIC|AMMO_PASS_THROUGH_MOB accuracy_var_low = 15 accuracy_var_high = 5 - max_range = 6 + max_range = 4 damage = 30 penetration = 20 - sundering = 3 + sundering = 1 damage_falloff = 0 /datum/ammo/bullet/ags_spread/incendiary diff --git a/code/modules/projectiles/ammo_datums/bullet/machinegun.dm b/code/modules/projectiles/ammo_datums/bullet/machinegun.dm index 99ea97e31a6..c32d6fe7e68 100644 --- a/code/modules/projectiles/ammo_datums/bullet/machinegun.dm +++ b/code/modules/projectiles/ammo_datums/bullet/machinegun.dm @@ -96,9 +96,9 @@ hud_state = "smartgun" hud_state_empty = "smartgun_empty" flags_ammo_behavior = AMMO_BALLISTIC - accurate_range = 12 - damage = 18 - penetration = 15 + accurate_range = 8 + damage = 20 + penetration = 5 additional_xeno_penetration = 20 /datum/ammo/bullet/smart_minigun @@ -108,7 +108,6 @@ hud_state_empty = "smartgun_empty" flags_ammo_behavior = AMMO_BALLISTIC accurate_range = 12 - damage = 10 - penetration = 25 - additional_xeno_penetration = 10 + damage = 25 + penetration = -15 damage_falloff = 0.1 diff --git a/code/modules/projectiles/ammo_datums/bullet/rifle.dm b/code/modules/projectiles/ammo_datums/bullet/rifle.dm index 691c25d3f97..084e43752e8 100644 --- a/code/modules/projectiles/ammo_datums/bullet/rifle.dm +++ b/code/modules/projectiles/ammo_datums/bullet/rifle.dm @@ -37,8 +37,8 @@ hud_state_empty = "smartgun_empty" flags_ammo_behavior = AMMO_BALLISTIC accurate_range = 20 - damage = 17.5 - penetration = 10 + damage = 20 + penetration = 25 additional_xeno_penetration = 20 /datum/ammo/bullet/rifle/hv @@ -52,6 +52,7 @@ name = "heavy rifle bullet" hud_state = "rifle_heavy" damage = 30 + damage_falloff = 2 penetration = 10 additional_xeno_penetration = 15 @@ -149,6 +150,7 @@ hud_state = "rifle_crude" flags_ammo_behavior = AMMO_BALLISTIC damage = 30 + damage_falloff = 3 penetration = 15 additional_xeno_penetration = 12.5 @@ -164,7 +166,7 @@ name = "crude heavy rifle bullet" hud_state = "rifle_crude" flags_ammo_behavior = AMMO_BALLISTIC - damage = 50 + damage = 60 penetration = 0 additional_xeno_penetration = -10 @@ -218,7 +220,7 @@ flags_ammo_behavior = AMMO_BALLISTIC damage = 40 max_range = 40 - penetration = 30 + penetration = 17.5 additional_xeno_penetration = 12.5 shell_speed = 4 damage_falloff = 0.5 diff --git a/code/modules/projectiles/ammo_datums/bullet/submachinegun.dm b/code/modules/projectiles/ammo_datums/bullet/submachinegun.dm index 2784415903a..ae17a0c3326 100644 --- a/code/modules/projectiles/ammo_datums/bullet/submachinegun.dm +++ b/code/modules/projectiles/ammo_datums/bullet/submachinegun.dm @@ -27,7 +27,7 @@ accuracy_var_high = 7 damage = 20 accurate_range = 4 - damage_falloff = 1 + damage_falloff = 3 penetration = 0 additional_xeno_penetration = 10 shrapnel_chance = 25 @@ -40,8 +40,8 @@ /datum/ammo/bullet/smg/acp/ap name = "armor-piercing submachinegun ACP bullet" - damage = 15 - penetration = 20 + damage = 20 + penetration = 15 additional_xeno_penetration = 20 /datum/ammo/bullet/smg/acp/incendiary diff --git a/code/modules/projectiles/ammo_datums/xeno.dm b/code/modules/projectiles/ammo_datums/xeno.dm index 57698eea793..918f07805d8 100644 --- a/code/modules/projectiles/ammo_datums/xeno.dm +++ b/code/modules/projectiles/ammo_datums/xeno.dm @@ -598,3 +598,65 @@ GLOBAL_LIST_INIT(no_sticky_resin, typecacheof(list(/obj/item/clothing/mask/faceh /datum/ammo/xeno/hugger/acid hugger_type = /obj/item/clothing/mask/facehugger/combat/acid + +/* +//================================================ + Widow Ammo Types +//================================================ +*/ + +/datum/ammo/xeno/leash_ball + icon_state = "widow_snareball" + ping = "ping_x" + damage_type = STAMINA + flags_ammo_behavior = AMMO_SKIPS_ALIENS | AMMO_TARGET_TURF + bullet_color = COLOR_PURPLE + ping = null + damage = 0 + armor_type = BIO + shell_speed = 1.5 + accurate_range = 8 + max_range = 8 + +/datum/ammo/xeno/leash_ball/on_hit_turf(turf/target_turf, obj/projectile/proj) + drop_leashball(target_turf.density ? proj.loc : target_turf) + +/datum/ammo/xeno/leash_ball/on_hit_mob(mob/target_mob, obj/projectile/proj) + var/turf/target_turf = get_turf(target_mob) + drop_leashball(target_turf.density ? proj.loc : target_turf, proj.firer) + +/datum/ammo/xeno/leash_ball/on_hit_obj(obj/target_obj, obj/projectile/proj) + var/turf/target_turf = get_turf(target_obj) + if(target_turf.density || (target_obj.density && !(target_obj.allow_pass_flags & PASS_PROJECTILE))) + target_turf = get_turf(proj) + drop_leashball(target_turf.density ? proj.loc : target_turf, proj.firer) + +/datum/ammo/xeno/leash_ball/do_at_max_range(turf/target_turf, obj/projectile/proj) + drop_leashball(target_turf.density ? proj.loc : target_turf) + +/// This spawns a leash ball and checks if the turf is dense before doing so +/datum/ammo/xeno/leash_ball/proc/drop_leashball(turf/target_turf) + new /obj/structure/xeno/aoe_leash(get_turf(target_turf), hivenumber) + +/datum/ammo/xeno/web_projectile + icon_state = "web_spit" + sound_hit = "snap" + sound_bounce = "alien_resin_build3" + damage_type = STAMINA + bullet_color = COLOR_PURPLE + flags_ammo_behavior = AMMO_SKIPS_ALIENS + ping = null + armor_type = BIO + accurate_range = 8 + max_range = 8 + ///How long the victim will be KO'd + var/hit_weaken = 2 SECONDS + +/datum/ammo/xeno/web_projectile/on_hit_mob(mob/target_mob, obj/projectile/proj) + . = ..() + if(!ishuman(target_mob)) + return + playsound(get_turf(target_mob), sound(get_sfx("snap")), 30, falloff = 5) + var/mob/living/carbon/human/human_victim = target_mob + human_victim.apply_effect(hit_weaken, WEAKEN) + diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index fa73492a4bb..4abcf549d5b 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -142,25 +142,35 @@ master_gun.aim_slowdown -= aim_speed_mod master_gun.wield_delay -= wield_delay_mod -//Generic proc to transfer ammo between ammo mags. Can work for anything, mags, handfuls, etc. -/obj/item/ammo_magazine/proc/transfer_ammo(obj/item/ammo_magazine/source, mob/user, transfer_amount = 1, is_new_ammo_type = FALSE) +///Сan the magazine be refilled, mainly used in transfer_ammo proc +/obj/item/ammo_magazine/proc/can_transfer_ammo(obj/item/ammo_magazine/source, mob/user, transfer_amount = 1, silent = FALSE) if(current_rounds >= max_rounds) //Does the mag actually need reloading? - to_chat(user, span_notice("[src] is already full.")) - return + if(!silent) + to_chat(user, span_notice("[src] is already full.")) + return FALSE if(source.caliber != caliber) //Are they the same caliber? - to_chat(user, span_notice("The rounds don't match up. Better not mix them up.")) - return + if(!silent) + to_chat(user, span_notice("The rounds don't match up. Better not mix them up.")) + return FALSE if(!source.current_rounds) - to_chat(user, span_warning("\The [source] is empty.")) - return + if(!silent) + to_chat(user, span_warning("\The [source] is empty.")) + return FALSE //using handfuls; and filling internal mags has no delay. if(fill_delay) - to_chat(user, span_notice("You start refilling [src] with [source].")) + if(!silent) + to_chat(user, span_notice("You start refilling [src] with [source].")) if(!do_after(user, fill_delay, NONE, src, BUSY_ICON_GENERIC)) - return + return FALSE + return TRUE + +///Generic proc to transfer ammo between ammo mags. Can work for anything, mags, handfuls, etc. +/obj/item/ammo_magazine/proc/transfer_ammo(obj/item/ammo_magazine/source, mob/user, transfer_amount = 1, is_new_ammo_type = FALSE) + if(!can_transfer_ammo(source, user, transfer_amount)) + return to_chat(user, span_notice("You refill [src] with [source].")) diff --git a/code/modules/projectiles/attachables/_attachable.dm b/code/modules/projectiles/attachables/_attachable.dm index 19902ff68eb..09965c6f055 100644 --- a/code/modules/projectiles/attachables/_attachable.dm +++ b/code/modules/projectiles/attachables/_attachable.dm @@ -344,7 +344,6 @@ inaccurate. Don't worry if force is ever negative, it won't runtime. attached_to:gunattachment = src activate(user) new_action.set_toggle(TRUE) - new_action.update_button_icon() update_icon() RegisterSignal(master_gun, COMSIG_ITEM_REMOVED_INVENTORY, TYPE_PROC_REF(/obj/item/weapon/gun, drop_connected_mag)) @@ -380,11 +379,6 @@ inaccurate. Don't worry if force is ever negative, it won't runtime. set_gun_user(null) set_gun_user(master_gun.gun_user) to_chat(user, span_notice("You start using [src].")) - for(var/datum/action/item_action/toggle/action AS in master_gun.actions) - if(action.target != src ) - continue - action.set_toggle(master_gun.active_attachable == src) - action.update_button_icon() return TRUE ///Called when the attachment is trying to be attached. If the attachment is allowed to go through, return TRUE. diff --git a/code/modules/projectiles/attachables/flamer.dm b/code/modules/projectiles/attachables/flamer.dm index af458858e4c..a44add5b00f 100644 --- a/code/modules/projectiles/attachables/flamer.dm +++ b/code/modules/projectiles/attachables/flamer.dm @@ -49,6 +49,7 @@ pixel_shift_y = 17 stream_type = FLAMER_STREAM_CONE burn_time_mod = 0.3 + range_modifier = -2 ///Funny red wide nozzle that can fill entire screens with flames. Admeme only. /obj/item/attachable/flamer_nozzle/wide/red diff --git a/code/modules/projectiles/attachables/foldable.dm b/code/modules/projectiles/attachables/foldable.dm index 75da6193e06..7cd6cdc94aa 100644 --- a/code/modules/projectiles/attachables/foldable.dm +++ b/code/modules/projectiles/attachables/foldable.dm @@ -155,6 +155,7 @@ scatter_mod = -10 burst_scatter_mod = -3 aim_mode_delay_mod = -0.5 + var/user_old_move_resist /obj/item/attachable/foldable/bipod/activate(mob/living/user, turn_off) if(folded && !(master_gun.flags_item & WIELDED)) //no one handed bipod use @@ -168,12 +169,16 @@ UnregisterSignal(master_gun, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_UNWIELD)) UnregisterSignal(user, COMSIG_MOVABLE_MOVED) to_chat(user, span_notice("You retract [src].")) + user.move_resist = user_old_move_resist return if(user) RegisterSignals(master_gun, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_UNWIELD), PROC_REF(retract_bipod)) RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(retract_bipod)) to_chat(user, span_notice("You deploy [src].")) + user_old_move_resist = user.move_resist + user.move_resist = MOVE_FORCE_STRONG + ///Signal handler for forced undeployment /obj/item/attachable/foldable/bipod/proc/retract_bipod(datum/source, mob/living/user) diff --git a/code/modules/projectiles/attachables/muzzle.dm b/code/modules/projectiles/attachables/muzzle.dm index 1b4eda6ae8b..132c5d0f664 100644 --- a/code/modules/projectiles/attachables/muzzle.dm +++ b/code/modules/projectiles/attachables/muzzle.dm @@ -5,7 +5,7 @@ slot = ATTACHMENT_SLOT_MUZZLE silence_mod = TRUE pixel_shift_y = 16 - attach_shell_speed_mod = -1 + attach_shell_speed_mod = -0.5 accuracy_mod = 0.1 recoil_mod = -2 scatter_mod = -2 diff --git a/code/modules/projectiles/attachables/rail.dm b/code/modules/projectiles/attachables/rail.dm index aebff5a0a07..e8083e12ad6 100644 --- a/code/modules/projectiles/attachables/rail.dm +++ b/code/modules/projectiles/attachables/rail.dm @@ -13,7 +13,17 @@ desc = "A B7 smart scope. Does not have a zoom feature, but allows you to take aim and fire through allies. \nNo drawbacks." icon_state = "b7" slot = ATTACHMENT_SLOT_RAIL - add_aim_mode = TRUE + damage_mod = -0.15 + +/obj/item/attachable/b7_scope/on_attach(attaching_item, mob/user) + . = ..() + var/obj/item/weapon/gun/attaching_gun = attaching_item + ENABLE_BITFIELD(attaching_gun.flags_gun_features, GUN_IFF) + +/obj/item/attachable/b7_scope/on_detach(detaching_item, mob/user) + . = ..() + var/obj/item/weapon/gun/detaching_gun = detaching_item + DISABLE_BITFIELD(detaching_gun.flags_gun_features, GUN_IFF) /obj/item/attachable/m16sight name = "M16 iron sights" @@ -211,7 +221,6 @@ . = TRUE for(var/datum/action/item_action/toggle/action_to_update AS in actions) action_to_update.set_toggle(.) - action_to_update.update_button_icon() ///Handles the gun attaching to the armor. /obj/item/attachable/shoulder_mount/proc/handle_armor_attach(datum/source, attaching_item, mob/user) diff --git a/code/modules/projectiles/attachables/scope.dm b/code/modules/projectiles/attachables/scope.dm index 017edd8809c..b0f46efe416 100644 --- a/code/modules/projectiles/attachables/scope.dm +++ b/code/modules/projectiles/attachables/scope.dm @@ -28,6 +28,7 @@ name = "T-47 rail scope" desc = "A marine standard mounted zoom sight scope. Allows zoom by activating the attachment." icon_state = "marinescope" + add_aim_mode = TRUE /obj/item/attachable/scope/nightvision name = "T-46 Night vision scope" @@ -207,6 +208,7 @@ scope_zoom_mod = TRUE has_nightvision = FALSE zoom_allow_movement = TRUE + add_aim_mode = TRUE zoom_slowdown = 0.3 zoom_tile_offset = 5 zoom_viewsize = 0 diff --git a/code/modules/projectiles/attachables/underbarrel.dm b/code/modules/projectiles/attachables/underbarrel.dm index 04558ec4879..6a346ae1b4d 100644 --- a/code/modules/projectiles/attachables/underbarrel.dm +++ b/code/modules/projectiles/attachables/underbarrel.dm @@ -96,9 +96,7 @@ /obj/item/attachable/burstfire_assembly name = "burst fire assembly" - desc = "A mechanism re-assembly kit that allows for automatic fire, or more shots per burst if the weapon already has the ability. \nIncreases scatter and decreases accuracy." + desc = "A mechanism re-assembly kit that allows for automatic fire, or more shots per burst if the weapon already has the ability." icon_state = "rapidfire" slot = ATTACHMENT_SLOT_UNDER burst_mod = 2 - burst_scatter_mod = 1 - burst_accuracy_mod = -0.1 diff --git a/code/modules/projectiles/gun_system.dm b/code/modules/projectiles/gun_system.dm index 41798b51fe2..79935f3b1b3 100644 --- a/code/modules/projectiles/gun_system.dm +++ b/code/modules/projectiles/gun_system.dm @@ -520,22 +520,15 @@ . = ..() var/real_icon = current_skin ? current_skin : base_gun_icon if(CHECK_BITFIELD(reciever_flags, AMMO_RECIEVER_TOGGLES_OPEN) && !CHECK_BITFIELD(reciever_flags, AMMO_RECIEVER_CLOSED)) - icon_state = !greyscale_config ? real_icon + "_o" : GUN_ICONSTATE_OPEN + icon_state = real_icon + "_o" else if(CHECK_BITFIELD(reciever_flags, AMMO_RECIEVER_REQUIRES_UNIQUE_ACTION) && !in_chamber && length(chamber_items)) - icon_state = !greyscale_config ? real_icon + "_u" : GUN_ICONSTATE_UNRACKED + icon_state = real_icon + "_u" else if((!length(chamber_items) && max_chamber_items) || (!rounds && !max_chamber_items)) - icon_state = !greyscale_config ? real_icon + "_e" : GUN_ICONSTATE_UNLOADED + icon_state = real_icon + "_e" else if(current_chamber_position <= length(chamber_items) && chamber_items[current_chamber_position] && chamber_items[current_chamber_position].loc != src) icon_state = real_icon + "_l" else - icon_state = !greyscale_config ? real_icon : GUN_ICONSTATE_LOADED - -/obj/item/weapon/gun/color_item(obj/item/facepaint/paint, mob/user) - . = ..() - if(!ishuman(user)) - return - var/mob/living/carbon/human/human = user - human.regenerate_icons() + icon_state = real_icon //manages the overlays for the gun - separate from attachment overlays /obj/item/weapon/gun/update_overlays() @@ -1423,6 +1416,7 @@ user.put_in_hands(mag) else mag.forceMove(get_turf(src)) + SEND_SIGNAL(gun_user, COMSIG_MAGAZINE_DROP, mag) if(CHECK_BITFIELD(reciever_flags, AMMO_RECIEVER_ROTATES_CHAMBER)) chamber_items[chamber_items.Find(mag)] = null else diff --git a/code/modules/projectiles/guns/_shared_ammo_objects.dm b/code/modules/projectiles/guns/_shared_ammo_objects.dm index 7297bdbc771..b8d2e059fc1 100644 --- a/code/modules/projectiles/guns/_shared_ammo_objects.dm +++ b/code/modules/projectiles/guns/_shared_ammo_objects.dm @@ -139,7 +139,7 @@ burn_ticks = 12 /obj/fire/flamer/affect_atom(atom/affected) - affected.fire_act(burn_level) + affected.fire_act(burn_level, flame_color) /obj/fire/flamer/process() . = ..() diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index d0fba59781f..5672849ee67 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -588,7 +588,7 @@ fire_delay = 0.15 SECONDS fire_sound = 'sound/weapons/guns/fire/Laser Pistol Standard.ogg' message_to_user = "You set the laser pistol's charge mode to standard fire." - fire_mode = GUN_FIREMODE_SEMIAUTO + fire_mode = GUN_FIREMODE_AUTOMATIC icon_state = "tep" description = "Fires a standard laser pulse. Moderate damage." diff --git a/code/modules/projectiles/guns/grenade_launchers.dm b/code/modules/projectiles/guns/grenade_launchers.dm index d0083e317d1..a71fa5402f2 100644 --- a/code/modules/projectiles/guns/grenade_launchers.dm +++ b/code/modules/projectiles/guns/grenade_launchers.dm @@ -139,8 +139,8 @@ The Grenade Launchers desc = "A weapon-mounted, reloadable, two-shot grenade launcher." icon = 'icons/Marine/marine-weapons.dmi' icon_state = "grenade" - max_shells = 1 //codex - max_chamber_items = 0 + max_shells = 2 //codex + max_chamber_items = 1 fire_delay = 1 SECONDS fire_sound = 'sound/weapons/guns/fire/underbarrel_grenadelauncher.ogg' attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 18,"rail_x" = 14, "rail_y" = 22, "under_x" = 19, "under_y" = 14, "stock_x" = 19, "stock_y" = 14) @@ -176,6 +176,11 @@ The Grenade Launchers /obj/item/explosive/grenade/impact, /obj/item/explosive/grenade/sticky, /obj/item/explosive/grenade/flashbang/stun, + /obj/item/explosive/grenade/m15, + /obj/item/explosive/grenade/sticky/trailblazer, + /obj/item/explosive/grenade/sticky/trailblazer/phosphorus, + /obj/item/explosive/grenade/sticky/cloaker, + /obj/item/explosive/grenade/mirage, ) wield_delay_mod = 0.2 SECONDS diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm index 21a5421879a..47f2855b267 100644 --- a/code/modules/projectiles/guns/mounted.dm +++ b/code/modules/projectiles/guns/mounted.dm @@ -619,7 +619,7 @@ reload_sound = 'sound/weapons/guns/interact/minigun_cocked.ogg' default_ammo_type = /obj/item/ammo_magazine/agls37 scatter = 0 - fire_delay = 1.1 SECONDS + fire_delay = 1 SECONDS burst_amount = 0 accuracy_mult = 1.2 //it's got a bipod flags_item = IS_DEPLOYABLE|TWOHANDED @@ -643,7 +643,7 @@ /obj/item/ammo_magazine/agls37/tanglefoot, ) - deploy_time = 6 SECONDS + deploy_time = 5 SECONDS undeploy_time = 3 SECONDS deployable_item = /obj/machinery/deployable/mounted diff --git a/code/modules/projectiles/guns/pistols.dm b/code/modules/projectiles/guns/pistols.dm index a753d345c7f..369e524b139 100644 --- a/code/modules/projectiles/guns/pistols.dm +++ b/code/modules/projectiles/guns/pistols.dm @@ -236,7 +236,7 @@ default_ammo_type = /obj/item/ammo_magazine/pistol/m1911 allowed_ammo_types = list(/obj/item/ammo_magazine/pistol/m1911) attachable_offset = list("muzzle_x" = 30, "muzzle_y" = 21,"rail_x" = 17, "rail_y" = 22, "under_x" = 21, "under_y" = 15, "stock_x" = 21, "stock_y" = 17) - reciever_flags = AMMO_RECIEVER_MAGAZINES|AMMO_RECIEVER_AUTO_EJECT_LOCKED + reciever_flags = AMMO_RECIEVER_MAGAZINES fire_delay = 0.2 SECONDS accuracy_mult = 1.05 accuracy_mult_unwielded = 0.85 diff --git a/code/modules/projectiles/guns/revolvers.dm b/code/modules/projectiles/guns/revolvers.dm index 93047a251ef..715b5f705b9 100644 --- a/code/modules/projectiles/guns/revolvers.dm +++ b/code/modules/projectiles/guns/revolvers.dm @@ -350,16 +350,16 @@ /obj/item/attachable/scope/standard_magnum, ) attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 19,"rail_x" = 15, "rail_y" = 23, "under_x" = 22, "under_y" = 15, "stock_x" = 10, "stock_y" = 18) - windup_delay = 0.9 SECONDS + windup_delay = 0.6 SECONDS aim_slowdown = 0.2 windup_sound = 'sound/weapons/guns/fire/t76_start.ogg' fire_sound = 'sound/weapons/guns/fire/tgmc/kinetic/gun_r76.ogg' - fire_delay = 1.25 SECONDS + fire_delay = 0.75 SECONDS akimbo_additional_delay = 1 accuracy_mult_unwielded = 0.85 accuracy_mult = 1 scatter_unwielded = 6 - scatter = 3 + scatter = 2 recoil = 3 recoil_unwielded = 6 diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm index 66d07cf84c9..fa7127f893d 100644 --- a/code/modules/projectiles/guns/rifles.dm +++ b/code/modules/projectiles/guns/rifles.dm @@ -1021,6 +1021,7 @@ starting_attachment_types = list(/obj/item/attachable/stock/t60stock) gun_skill_category = SKILL_HEAVY_WEAPONS attachable_offset = list("muzzle_x" = 42, "muzzle_y" = 21,"rail_x" = 6, "rail_y" = 23, "under_x" = 26, "under_y" = 15, "stock_x" = 8, "stock_y" = 13) + actions_types = list(/datum/action/item_action/aim_mode) aim_fire_delay = 0.15 SECONDS aim_speed_modifier = 5.3 @@ -1143,7 +1144,6 @@ /obj/item/attachable/gyro, /obj/item/attachable/flashlight, /obj/item/attachable/foldable/bipod, - /obj/item/attachable/burstfire_assembly, /obj/item/attachable/magnetic_harness, /obj/item/attachable/extended_barrel, /obj/item/attachable/heavy_barrel, @@ -1153,6 +1153,7 @@ /obj/item/attachable/bayonetknife/som, /obj/item/attachable/compensator, /obj/item/attachable/scope, + /obj/item/attachable/flashlight/under, /obj/item/attachable/scope/mini, /obj/item/attachable/scope/marine, /obj/item/attachable/angledgrip, @@ -1160,8 +1161,10 @@ /obj/item/weapon/gun/shotgun/combat/masterkey, /obj/item/weapon/gun/flamer/mini_flamer, /obj/item/weapon/gun/grenade_launcher/underslung, + /obj/item/attachable/motiondetector, /obj/item/weapon/gun/rifle/pepperball/pepperball_mini, /obj/item/weapon/gun/flamer/mini_flamer/unremovable, + /obj/item/weapon/gun/energy/lasgun/lasrifle/pocket_beam, /obj/item/attachable/suppressor/unremovable/invisible, /obj/item/attachable/scope/unremovable, ) @@ -1742,7 +1745,7 @@ /obj/item/weapon/gun/grenade_launcher/underslung, /obj/item/attachable/motiondetector, /obj/item/weapon/gun/rifle/pepperball/pepperball_mini, - /obj/item/weapon/gun/energy/lasgun/lasrifle/pocket_beam, //RUTGMC EDIT + /obj/item/weapon/gun/energy/lasgun/lasrifle/pocket_beam, ) flags_gun_features = GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_SMOKE_PARTICLES @@ -1961,8 +1964,6 @@ /obj/item/ammo_magazine/rifle/ar12/incendiary, ) attachable_allowed = list( - /obj/item/attachable/scope/optical, - /obj/item/weapon/gun/rifle/tx54/mini, /obj/item/attachable/reddot, /obj/item/attachable/b7_scope, /obj/item/attachable/verticalgrip, @@ -1970,7 +1971,6 @@ /obj/item/attachable/gyro, /obj/item/attachable/flashlight, /obj/item/attachable/foldable/bipod, - /obj/item/attachable/flashlight/under, /obj/item/attachable/magnetic_harness, /obj/item/attachable/extended_barrel, /obj/item/attachable/heavy_barrel, @@ -1980,9 +1980,13 @@ /obj/item/attachable/bayonetknife/som, /obj/item/attachable/compensator, /obj/item/attachable/scope, - /obj/item/attachable/scope/marine, + /obj/item/attachable/flashlight/under, /obj/item/attachable/scope/mini, + /obj/item/attachable/scope/marine, + /obj/item/attachable/angledgrip, /obj/item/attachable/motiondetector, + /obj/item/weapon/gun/rifle/tx54/mini, + /obj/item/attachable/scope/optical, ) flags_gun_features = GUN_AMMO_COUNTER|GUN_SMOKE_PARTICLES diff --git a/code/modules/projectiles/magazines/rifles.dm b/code/modules/projectiles/magazines/rifles.dm index b07f0673171..08defd211f7 100644 --- a/code/modules/projectiles/magazines/rifles.dm +++ b/code/modules/projectiles/magazines/rifles.dm @@ -311,7 +311,7 @@ w_class = WEIGHT_CLASS_NORMAL default_ammo = /datum/ammo/bullet/sg29 max_rounds = 250 - reload_delay = 2.5 SECONDS + reload_delay = 1.3 SECONDS //------------------------------------------------------- //SMART TARGET RIFLE AMMUNITION diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0cb2ba8bd31..8de5fbecc69 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -826,15 +826,9 @@ So if we are on the 32th absolute pixel coordinate we are on tile 1, but if we a return ..() /mob/living/carbon/human/projectile_hit(obj/projectile/proj, cardinal_move, uncrossing) - if(wear_id?.iff_signal & proj.iff_signal) - proj.damage -= proj.damage*proj.damage_marine_falloff + if((wear_id?.iff_signal & proj.iff_signal) || (proj?.firer?.faction == faction && proj.original_target != src && Adjacent(proj.firer))) + proj.damage -= proj.damage * proj.damage_marine_falloff return FALSE - //shooting from behind the shoulder - if(ismob(proj.firer)) - var/mob/firer = proj.firer - if(firer.faction == faction && Adjacent(proj.firer)) - proj.damage -= proj.damage*proj.damage_marine_falloff //no guns with marine falloff by the way - return FALSE return ..() /mob/living/carbon/xenomorph/projectile_hit(obj/projectile/proj, cardinal_move, uncrossing) @@ -851,8 +845,10 @@ So if we are on the 32th absolute pixel coordinate we are on tile 1, but if we a return ..() /obj/projectile/proc/play_damage_effect(mob/M) - if(ammo.sound_hit) playsound(M, ammo.sound_hit, 50, 1) - if(M.stat != DEAD) animation_flash_color(M) + if(ammo.sound_hit) + playsound(M, ammo.sound_hit, 50, 1) + if(M.stat != DEAD) + animation_flash_color(M) //---------------------------------------------------------- // \\ @@ -916,7 +912,7 @@ So if we are on the 32th absolute pixel coordinate we are on tile 1, but if we a if(stat != DEAD && proj.firer) proj.firer.record_projectile_damage(damage, src) //Tally up whoever the shooter was - if(damage) + if(damage > 0) if(do_shrapnel_roll(proj, damage)) feedback_flags |= (BULLET_FEEDBACK_SHRAPNEL|BULLET_FEEDBACK_SCREAM) embed_projectile_shrapnel(proj) diff --git a/code/modules/reagents/machinery/chem_master.dm b/code/modules/reagents/machinery/chem_master.dm index b00ed1571bc..c14146efe2b 100644 --- a/code/modules/reagents/machinery/chem_master.dm +++ b/code/modules/reagents/machinery/chem_master.dm @@ -341,21 +341,8 @@ . = ..() if(.) return - // if(user.skills.getRating(SKILL_MEDICAL) < SKILL_MEDICAL_PRACTICED) //RUTGMC edit - marines can use chem machines once again - // balloon_alert(user, "skill issue") - // return - if(!(user.client in has_sprites)) - spawn() - has_sprites += user.client - for(var/i = 1 to MAX_PILL_BOTTLE_SPRITE) - user << browse_rsc(icon('icons/obj/items/chemistry.dmi', pill_bottle_names[i]), pill_bottle_names[i]+".png") - for(var/i = 1 to MAX_PILL_SPRITE) - user << browse_rsc(icon('icons/obj/items/chemistry.dmi', "pill" + num2text(i)), "pill[i].png") - for(var/i = 1 to MAX_BOTTLE_SPRITE) - user << browse_rsc(icon('icons/obj/items/chemistry.dmi', "bottle-" + num2text(i)), "bottle-[i].png") - for(var/i = 1 to MAX_AUTOINJECTOR_SPRITE) - user << browse_rsc(icon('icons/obj/items/syringe.dmi', "autoinjector-" + num2text(i)), "autoinjector-[i].png") + INVOKE_ASYNC(src, PROC_REF(show_container_choises), user) var/dat = "" if(!beaker) dat = "Please insert beaker.
" @@ -407,6 +394,17 @@ popup.set_content(dat) popup.open() +/obj/machinery/chem_master/proc/show_container_choises(mob/user) + has_sprites += user.client + for(var/i = 1 to MAX_PILL_BOTTLE_SPRITE) + user << browse_rsc(icon('icons/obj/items/chemistry.dmi', pill_bottle_names[i]), pill_bottle_names[i]+".png") + for(var/i = 1 to MAX_PILL_SPRITE) + user << browse_rsc(icon('icons/obj/items/chemistry.dmi', "pill" + num2text(i)), "pill[i].png") + for(var/i = 1 to MAX_BOTTLE_SPRITE) + user << browse_rsc(icon('icons/obj/items/chemistry.dmi', "bottle-" + num2text(i)), "bottle-[i].png") + for(var/i = 1 to MAX_AUTOINJECTOR_SPRITE) + user << browse_rsc(icon('icons/obj/items/syringe.dmi', "autoinjector-" + num2text(i)), "autoinjector-[i].png") + /obj/machinery/chem_master/update_icon() . = ..() if(machine_stat & (NOPOWER)) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 4172a70df4d..d1b8a971a11 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -400,8 +400,7 @@ target = get_offset_target_turf(loc, rand(5) - rand(5), rand(5) - rand(5)) AM.loc = loc AM.pipe_eject(0) - spawn(1) - AM?.throw_at(target, 5, 1) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 3, 1), 0.5 SECONDS) qdel(H) @@ -664,9 +663,8 @@ for(var/atom/movable/AM in H) AM.loc = T AM.pipe_eject(direction) - spawn(1) - if(AM) - AM.throw_at(target, 100, 1) + if(AM) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 100, 1), 0.1 SECONDS) qdel(H) else //No specified direction, so throw in random direction @@ -678,9 +676,8 @@ AM.loc = T AM.pipe_eject(0) - spawn(1) - if(AM) - AM.throw_at(target, 5, 1) + if(AM) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 5, 1), 0.1 SECONDS) qdel(H) @@ -1289,8 +1286,7 @@ for(var/atom/movable/AM in H) AM.loc = src.loc AM.pipe_eject(dir) - spawn(5) - AM.throw_at(target, 3, 1) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), target, 3, 1), 0.5 SECONDS) qdel(H) /obj/structure/disposaloutlet/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/reqs/_supplypacks.dm b/code/modules/reqs/_supplypacks.dm index acae4c0c975..10be13f685c 100644 --- a/code/modules/reqs/_supplypacks.dm +++ b/code/modules/reqs/_supplypacks.dm @@ -3,7 +3,7 @@ //NOTE: Don't add living things to crates, that's bad, it will break the shuttle. //NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. -GLOBAL_LIST_INIT(all_supply_groups, list("Operations", "Weapons", "Explosives", "Armor", "Clothing", "Medical", "Engineering", "Supplies", "Imports", "Vehicles", "Factory")) +GLOBAL_LIST_INIT(all_supply_groups, list("Operations", "Weapons", "Smartguns", "Stationary", "Launchers", "Explosives", "Armor", "Clothing", "Medical", "Engineering", "Supplies", "Imports", "Vehicles", "Factory")) /datum/supply_packs var/name diff --git a/code/modules/reqs/clothing.dm b/code/modules/reqs/clothing.dm index 951272cbfdf..6c52f46f66d 100644 --- a/code/modules/reqs/clothing.dm +++ b/code/modules/reqs/clothing.dm @@ -22,6 +22,11 @@ contains = list(/obj/item/storage/backpack/marine/radiopack) cost = 20 +/datum/supply_packs/clothing/auto_catch_belt + name = "M344 pattern ammo load rig" + contains = list(/obj/item/storage/belt/marine/auto_catch) + cost = 50 + /datum/supply_packs/clothing/technician_pack name = "Engineering Technician Pack" contains = list(/obj/item/storage/backpack/marine/tech) diff --git a/code/modules/reqs/engineering.dm b/code/modules/reqs/engineering.dm index 0b4ed6d5aeb..c6c8d04631c 100644 --- a/code/modules/reqs/engineering.dm +++ b/code/modules/reqs/engineering.dm @@ -43,6 +43,11 @@ contains = list(/obj/item/stack/sheet/mineral/junk/large_stack) cost = 300 +/datum/supply_packs/engineering/handheld_charger + name = "handheld charger" + contains = list(/obj/item/tool/handheld_charger) + cost = 80 + /datum/supply_packs/engineering/plasmacutter name = "plasma cutter" contains = list(/obj/item/tool/pickaxe/plasmacutter/) diff --git a/code/modules/reqs/explosives.dm b/code/modules/reqs/explosives.dm index 659730b3398..e97ac91d7a8 100644 --- a/code/modules/reqs/explosives.dm +++ b/code/modules/reqs/explosives.dm @@ -19,6 +19,12 @@ contains = list(/obj/item/storage/box/visual/grenade/razorburn) cost = 500 +/datum/supply_packs/explosives/stickytanglenades + name = "M45-T adhesive tanglefoot grenade" + notes = "Contains 25 M45-T sticky grenade" + contains = list(/obj/item/storage/box/visual/grenade/drain/sticky) + cost = 300 + /datum/supply_packs/explosives/explosives_sticky name = "M40 adhesive charge grenade box crate" notes = "Contains 25 grenades" diff --git a/code/modules/reqs/imports.dm b/code/modules/reqs/imports.dm index 25821a53b5d..d83c4704a12 100644 --- a/code/modules/reqs/imports.dm +++ b/code/modules/reqs/imports.dm @@ -287,7 +287,18 @@ contains = list(/obj/item/clothing/head/strawhat) cost = 10 +/datum/supply_packs/imports/bricks + name = "Brick" + contains = list(/obj/item/weapon/brick) + cost = 10 + /datum/supply_packs/imports/loot_box name = "Loot box" contains = list(/obj/item/loot_box/marine) cost = 500 + +/datum/supply_packs/imports/loot_pack + name = "TGMC Loot Pack" + notes = "Contains a random, but curated set of items, these packs are valued around 150 to 200 points. Some items can only be acquired from these. Spend responsibly." + contains = list(/obj/item/loot_box/tgmclootbox) + cost = 1000 diff --git a/code/modules/reqs/launchers.dm b/code/modules/reqs/launchers.dm new file mode 100644 index 00000000000..58405e1f611 --- /dev/null +++ b/code/modules/reqs/launchers.dm @@ -0,0 +1,133 @@ +/datum/supply_packs/launchers + containertype = /obj/structure/closet/crate/ammo + group = "Launchers" + +/datum/supply_packs/launchers/rpgoneuse + name = "RL-72 Disposable RPG" + contains = list(/obj/item/weapon/gun/launcher/rocket/oneuse) + cost = 100 + +/datum/supply_packs/launchers/recoillesskit + name = "RL-160 Recoilless rifle kit" + contains = list(/obj/item/storage/holster/backholster/rpg/full) + cost = 400 + +/datum/supply_packs/launchers/shell_regular + name = "RL-160 RR HE shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless) + cost = 30 + +/datum/supply_packs/launchers/shell_le + name = "RL-160 RR LE shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless/light) + cost = 30 + +/datum/supply_packs/launchers/shell_heat + name = "RL-160 HEAT shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless/heat) + cost = 30 + +/datum/supply_packs/launchers/shell_smoke + name = "RL-160 RR Smoke shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless/smoke) + cost = 30 + +/datum/supply_packs/launchers/shell_cloak + name = "RL-160 RR Cloak shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless/cloak) + cost = 30 + +/datum/supply_packs/launchers/shell_tangle + name = "RL-160 RR Tanglefoot shell" + contains = list(/obj/item/ammo_magazine/rocket/recoilless/plasmaloss) + cost = 30 + +/datum/supply_packs/launchers/thermobaric + name = "RL-57 Thermobaric Launcher" + contains = list(/obj/item/weapon/gun/launcher/rocket/m57a4/t57) + cost = 500 + +/datum/supply_packs/launchers/thermobaric_wp + name = "RL-57 Thermobaric WP rocket array" + contains = list(/obj/item/ammo_magazine/rocket/m57a4) + cost = 50 + +/datum/supply_packs/launchers/thermobaric + name = "RL-57 Thermobaric Launcher Kit" + contains = list(/obj/item/storage/holster/backholster/rlquad/full) + cost = 550 //launcher + ammo price + +/datum/supply_packs/launchers/sadar + name = "RL-152 SADAR Rocket Launcher" + contains = list(/obj/item/weapon/gun/launcher/rocket/sadar) + cost = SADAR_PRICE + +/datum/supply_packs/launchers/rpg_regular + name = "RL-152 SADAR HE rocket" + contains = list(/obj/item/ammo_magazine/rocket/sadar) + cost = 50 + +/datum/supply_packs/launchers/rpg_regular_unguided + name = "RL-152 SADAR HE rocket (Unguided)" + contains = list(/obj/item/ammo_magazine/rocket/sadar/unguided) + cost = 50 + +/datum/supply_packs/launchers/rpg_ap + name = "RL-152 SADAR AP rocket" + contains = list(/obj/item/ammo_magazine/rocket/sadar/ap) + cost = 60 + +/datum/supply_packs/launchers/rpg_wp + name = "RL-152 SADAR WP rocket" + contains = list(/obj/item/ammo_magazine/rocket/sadar/wp) + cost = 40 + +/datum/supply_packs/launchers/rpg_wp_unguided + name = "RL-152 SADAR WP rocket (Unguided)" + contains = list(/obj/item/ammo_magazine/rocket/sadar/wp/unguided) + cost = 40 + +/datum/supply_packs/launchers/specdemo + name = "RL-152 SADAR Rocket Launcher kit" + contains = list(/obj/item/storage/holster/backholster/rlsadar/full) + cost = SADAR_PRICE + 150 //ammo price + +/datum/supply_packs/launchers/tx54 + name = "GL-54 airburst grenade launcher" + contains = list(/obj/item/weapon/gun/rifle/tx54) + cost = 300 + +/datum/supply_packs/launchers/tx54_airburst + name = "GL-54 airburst grenade magazine" + contains = list(/obj/item/ammo_magazine/rifle/tx54) + cost = 20 + +/datum/supply_packs/launchers/tx54_incendiary + name = "GL-54 incendiary grenade magazine" + contains = list(/obj/item/ammo_magazine/rifle/tx54/incendiary) + cost = 60 + +/datum/supply_packs/launchers/tx54_smoke + name = "GL-54 tactical smoke grenade magazine" + contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke) + cost = 12 + +/datum/supply_packs/launchers/tx54_smoke/dense + name = "GL-54 dense smoke grenade magazine" + contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke/dense) + cost = 8 + +/datum/supply_packs/launchers/tx54_smoke/tangle + name = "GL-54 tanglefoot grenade magazine" + contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke/tangle) + cost = 48 + +/datum/supply_packs/launchers/singleshot_launcher + name = "GL-81 grenade launcher" + contains = list(/obj/item/weapon/gun/grenade_launcher/single_shot) + cost = 150 + +/datum/supply_packs/launchers/multinade_launcher + name = "GL-70 grenade launcher" + contains = list(/obj/item/weapon/gun/grenade_launcher/multinade_launcher/unloaded) + cost = 450 diff --git a/code/modules/reqs/operations.dm b/code/modules/reqs/operations.dm index 8ace18d33f7..9d08b1f61df 100644 --- a/code/modules/reqs/operations.dm +++ b/code/modules/reqs/operations.dm @@ -1,12 +1,13 @@ /datum/supply_packs/operations group = "Operations" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/operations -/datum/supply_packs/imports/loot_pack - name = "TGMC Loot Pack" - notes = "Contains a random, but curated set of items, these packs are valued around 150 to 200 points. Some items can only be acquired from these. Spend responsibly." - contains = list(/obj/item/loot_box/tgmclootbox) - cost = 1000 +/datum/supply_packs/operations/standard_ammo + name = "Surplus Standard Ammo Crate" + notes = "Contains 22 ammo boxes of a wide variety which come prefilled. You lazy bum." + contains = list(/obj/structure/largecrate/supply/ammo/standard_ammo) + containertype = null + cost = 200 /datum/supply_packs/operations/beacons_supply name = "Supply beacon" diff --git a/code/modules/reqs/smartguns.dm b/code/modules/reqs/smartguns.dm new file mode 100644 index 00000000000..6a78f2b2242 --- /dev/null +++ b/code/modules/reqs/smartguns.dm @@ -0,0 +1,103 @@ +/datum/supply_packs/smartguns + group = "Smartguns" + containertype = /obj/structure/closet/crate/smart + +/datum/supply_packs/smartguns/sg29 + name = "SG-29 smart machine gun" + contains = list(/obj/item/weapon/gun/rifle/sg29) + cost = 400 + +/datum/supply_packs/smartguns/sg29_ammo + name = "SG-29 ammo drum" + contains = list(/obj/item/ammo_magazine/sg29) + cost = 50 + +/datum/supply_packs/smartguns/rifle/t25 + name = "T25 smartrifle" + contains = list(/obj/item/weapon/gun/rifle/t25) + cost = 400 + +/datum/supply_packs/smartguns/ammo_magazine/rifle/t25 + name = "T25 smartrifle magazine" + contains = list(/obj/item/ammo_magazine/rifle/t25) + cost = 20 + +/datum/supply_packs/smartguns/t25_extended_mag + name = "T25 extended magazine" + contains = list(/obj/item/ammo_magazine/rifle/t25/extended) + cost = 200 + containertype = /obj/structure/closet/crate/ammo + +/datum/supply_packs/smartguns/ammo_magazine/packet/t25 + name = "T25 smartrifle ammo box" + contains = list(/obj/item/ammo_magazine/packet/t25) + cost = 60 + +/datum/supply_packs/smartguns/smart_minigun + name = "SG-85 smart gatling gun" + contains = list(/obj/item/weapon/gun/minigun/smart_minigun) + cost = 400 + +/datum/supply_packs/smartguns/smart_minigun_ammo + name = "SG-85 ammo bin" + contains = list(/obj/item/ammo_magazine/packet/smart_minigun) + cost = 50 + +/datum/supply_packs/smartguns/minigun_powerpack + name = "SG-85 Minigun Powerpack" + contains = list(/obj/item/ammo_magazine/minigun_powerpack/smartgun) + cost = 150 + +/datum/supply_packs/smartguns/sg62 + name = "SG-62 Smart Target Rifle" + contains = list(/obj/item/weapon/gun/rifle/sg62) + cost = 400 + +/datum/supply_packs/smartguns/sg62_ammo + name = "SG-62 smart target rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg62) + cost = 35 + +/datum/supply_packs/smartguns/box_10x27mm + name = "SG-62 smart target rifle ammo box" + contains = list(/obj/item/ammo_magazine/packet/sg62) + cost = 50 + +/datum/supply_packs/smartguns/sg153_ammo + name = "SG-153 spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153) + cost = 15 + +/datum/supply_packs/smartguns/sg153_ammo/highimpact + name = "SG-153 high impact spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/highimpact) + +/datum/supply_packs/smartguns/sg153_ammo/heavyrubber + name = "SG-153 heavy rubber spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/heavyrubber) + +/datum/supply_packs/smartguns/sg153_ammo/plasmaloss + name = "SG-153 tanglefoot spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/plasmaloss) + +/datum/supply_packs/smartguns/sg153_ammo/tungsten + name = "SG-153 tungsten spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/tungsten) + +/datum/supply_packs/smartguns/sg153_ammo/flak + name = "SG-153 flak spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/flak) + +/datum/supply_packs/smartguns/sg153_ammo/incendiary + name = "SG-153 incendiary spotting rifle ammo" + contains = list(/obj/item/ammo_magazine/rifle/sg153/incendiary) + +/datum/supply_packs/smartguns/smart_pistol + name = "TX13 smartpistol" + contains = list(/obj/item/weapon/gun/pistol/smart_pistol) + cost = 150 + +/datum/supply_packs/smartguns/smart_pistol_ammo + name = "TX13 smartpistol ammo" + contains = list(/obj/item/ammo_magazine/pistol/p14/smart_pistol) + cost = 10 diff --git a/code/modules/reqs/stationary.dm b/code/modules/reqs/stationary.dm new file mode 100644 index 00000000000..27042ca4bae --- /dev/null +++ b/code/modules/reqs/stationary.dm @@ -0,0 +1,220 @@ +/datum/supply_packs/stationary + group = "Stationary" + containertype = /obj/structure/closet/crate/mounted + +/datum/supply_packs/stationary/sentry + name = "Турель TUR-B \"Базис\"" + contains = list( + /obj/item/weapon/gun/sentry/basic, + ) + cost = 200 + +/datum/supply_packs/stationary/sentry_upgrade + name = "Набор для улучшения турели TUR-B" + contains = list( + /obj/item/sentry_upgrade_kit, + ) + cost = 150 + +/datum/supply_packs/stationary/sentry/ammo + name = "Магазин для турели TUR-B \"Базис\"" + contains = list( + /obj/item/ammo_magazine/sentry, + ) + cost = 50 + +/datum/supply_packs/stationary/sentry/ammo/mini + name = "Магазин для турели TUR-M \"Гном\"" + contains = list( + /obj/item/ammo_magazine/minisentry, + ) + +/datum/supply_packs/stationary/sentry/ammo/sniper + name = "Магазин для турели TUR-SN \"Оса\"" + contains = list( + /obj/item/ammo_magazine/sentry/sniper, + ) + +/datum/supply_packs/stationary/sentry/ammo/shotgun + name = "Магазин для турели TUR-SH \"Бык\"" + contains = list( + /obj/item/ammo_magazine/sentry/shotgun, + ) + +/datum/supply_packs/stationary/sentry/ammo/flamer + name = "Бак для турели TUR-F \"Феникс\"" + contains = list( + /obj/item/ammo_magazine/flamer_tank/large/sentry, + ) + +/datum/supply_packs/stationary/buildasentry + name = "Build-A-Sentry Attachment System" + contains = list( + /obj/item/attachable/buildasentry, + ) + cost = 250 + +/datum/supply_packs/stationary/m56d_emplacement + name = "HSG-102 Mounted Heavy Smartgun" + contains = list(/obj/item/storage/box/hsg102) + cost = 600 + +/datum/supply_packs/stationary/m56d + name = "HSG-102 mounted heavy smartgun ammo" + contains = list(/obj/item/ammo_magazine/hsg102) + cost = 30 + +/datum/supply_packs/stationary/minigun_emplacement + name = "Mounted Automatic Minigun" + contains = list(/obj/item/weapon/gun/standard_minigun) + cost = 600 + +/datum/supply_packs/stationary/minigun_ammo + name = "Mounted Minigun ammo" + contains = list(/obj/item/ammo_magazine/heavy_minigun) + cost = 30 + +/datum/supply_packs/stationary/autocannon_emplacement + name = "ATR-22 Mounted Flak Cannon" + contains = list(/obj/item/weapon/gun/atr22) + cost = 700 + +/datum/supply_packs/stationary/ac_hv + name = "ATR-22 High-Velocity ammo" + contains = list(/obj/item/ammo_magazine/atr22) + cost = 40 + +/datum/supply_packs/stationary/ac_flak + name = "ATR-22 Smart-Detonating ammo" + contains = list(/obj/item/ammo_magazine/atr22/flak) + cost = 40 + +/datum/supply_packs/stationary/ags_emplacement + name = "AGLS-37 Mounted Automated Grenade Launcher" + contains = list(/obj/item/weapon/gun/agls37) + cost = 300 + +/datum/supply_packs/stationary/ags_highexplo + name = "AGLS-37 AGL High Explosive Grenades" + contains = list(/obj/item/ammo_magazine/agls37) + cost = 65 + +/datum/supply_packs/stationary/ags_frag + name = "AGLS-37 AGL Fragmentation Grenades" + contains = list(/obj/item/ammo_magazine/agls37/fragmentation) + cost = 55 + +/datum/supply_packs/stationary/ags_incendiary + name = "AGLS-37 AGL White Phosphorous Grenades" + contains = list(/obj/item/ammo_magazine/agls37/incendiary) + cost = 55 + +/datum/supply_packs/stationary/ags_flare + name = "AGLS-37 AGL Flare Grenades" + contains = list(/obj/item/ammo_magazine/agls37/flare) + cost = 35 + +/datum/supply_packs/stationary/ags_cloak + name = "AGLS-37 AGL Cloak Grenades" + contains = list(/obj/item/ammo_magazine/agls37/cloak) + cost = 45 + +/datum/supply_packs/stationary/ags_tanglefoot + name = "AGLS-37 AGL Tanglefoot Grenades" + contains = list(/obj/item/ammo_magazine/agls37/tanglefoot) + cost = 85 + +/datum/supply_packs/stationary/antitankgun + name = "AT-36 Anti Tank Gun" + contains = list(/obj/item/weapon/gun/at36) + cost = 800 + +/datum/supply_packs/stationary/antitankgunammo + name = "AT-36 AP-HE Shell (x3)" + contains = list( + /obj/item/ammo_magazine/at36, + /obj/item/ammo_magazine/at36, + /obj/item/ammo_magazine/at36, + ) + cost = 20 + +/datum/supply_packs/stationary/antitankgunammo/apcr + name = "AT-36 APCR Shell (x3)" + contains = list( + /obj/item/ammo_magazine/at36/apcr, + /obj/item/ammo_magazine/at36/apcr, + /obj/item/ammo_magazine/at36/apcr, + ) + cost = 20 + +/datum/supply_packs/stationary/antitankgunammo/he + name = "AT-36 HE Shell (x3)" + contains = list( + /obj/item/ammo_magazine/at36/he, + /obj/item/ammo_magazine/at36/he, + /obj/item/ammo_magazine/at36/he, + ) + cost = 20 + +/datum/supply_packs/stationary/antitankgunammo/beehive + name = "AT-36 Beehive Shell (x3)" + contains = list( + /obj/item/ammo_magazine/at36/beehive, + /obj/item/ammo_magazine/at36/beehive, + /obj/item/ammo_magazine/at36/beehive, + ) + cost = 20 + +/datum/supply_packs/stationary/antitankgunammo/incendiary + name = "AT-36 Napalm Shell (x3)" + contains = list( + /obj/item/ammo_magazine/at36/incend, + /obj/item/ammo_magazine/at36/incend, + /obj/item/ammo_magazine/at36/incend, + ) + cost = 20 + +/datum/supply_packs/stationary/flak_gun + name = "FK-88 Flak Gun" + contains = list(/obj/item/weapon/gun/heavy_isg) + cost = 1200 + +/datum/supply_packs/stationary/flak_he + name = "FK-88 HE Shell" + contains = list(/obj/item/ammo_magazine/heavy_isg/he) + cost = 100 + +/datum/supply_packs/stationary/flak_sabot + name = "FK-88 APFDS Shell" + contains = list(/obj/item/ammo_magazine/heavy_isg/sabot) + cost = 120 + +/datum/supply_packs/stationary/heayvlaser_emplacement + name = "Mounted Heavy Laser" + contains = list(/obj/item/weapon/gun/energy/lasgun/lasrifle/heavy_laser/deployable) + cost = 800 + +/datum/supply_packs/stationary/heayvlaser_ammo + name = "Mounted Heavy Laser Ammo (x1)" + contains = list(/obj/item/cell/lasgun/heavy_laser) + cost = 15 + +/datum/supply_packs/stationary/mg27 + name = "MG-27 Medium Machinegun" + contains = list(/obj/item/weapon/gun/mg27) + cost = 100 + +/datum/supply_packs/stationary/hmg08 + name = "HMG-08 heavy machinegun" + contains = list(/obj/item/weapon/gun/hmg08) + cost = 400 + +/datum/supply_packs/stationary/hmg08_ammo + name = "HMG-08 heavy machinegun ammo (500 rounds)" + contains = list(/obj/item/ammo_magazine/hmg08) + cost = 70 + +/datum/supply_packs/stationary/hmg08_ammo_small + name = "HMG-08 heavy machinegun ammo (250 rounds)" + contains = list(/obj/item/ammo_magazine/hmg08/small) + cost = 40 diff --git a/code/modules/reqs/supplies.dm b/code/modules/reqs/supplies.dm index 2b5897a8b06..7f3d3801ea5 100644 --- a/code/modules/reqs/supplies.dm +++ b/code/modules/reqs/supplies.dm @@ -5,8 +5,27 @@ /datum/supply_packs/supplies/crayons name = "PFC Jim Special Crayon Pack" contains = list(/obj/item/storage/fancy/crayons) + containertype = /obj/structure/closet/crate/operations cost = 40 +/datum/supply_packs/supplies/provision + name = "Emergency Provision Crate" + notes = "Contains 10 special TGMC MRE racions." + contains = list( + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + /obj/item/storage/box/MRE, + ) + containertype = /obj/structure/closet/crate/operations + cost = 65 + /datum/supply_packs/supplies/janitor name = "assorted janitorial supplies" contains = list( diff --git a/code/modules/reqs/vehicles.dm b/code/modules/reqs/vehicles.dm index 93dd7d2d216..fdd194a6908 100644 --- a/code/modules/reqs/vehicles.dm +++ b/code/modules/reqs/vehicles.dm @@ -1,6 +1,36 @@ /datum/supply_packs/vehicles group = "Vehicles" +/datum/supply_packs/vehicles/ltb_shells + name = "LTB tank shell" + contains = list(/obj/item/ammo_magazine/tank/ltb_cannon) + cost = 10 + containertype = /obj/structure/closet/crate/ammo + +/datum/supply_packs/vehicles/ltb_shells_apfds + name = "LTB tank APFDS shell" + contains = list(/obj/item/ammo_magazine/tank/ltb_cannon/apfds) + cost = 10 + containertype = /obj/structure/closet/crate/ammo + +/datum/supply_packs/vehicles/ltaap_rounds + name = "LTAAP tank magazine" + contains = list(/obj/item/ammo_magazine/tank/ltaap_chaingun) + cost = 10 + containertype = /obj/structure/closet/crate/ammo + +/datum/supply_packs/vehicles/cupola_rounds + name = "Cupola tank magazine" + contains = list(/obj/item/ammo_magazine/tank/secondary_cupola) + cost = 10 + containertype = /obj/structure/closet/crate/ammo + +/datum/supply_packs/vehicles/secondary_flamer_tank + name = "Spray flamer tank" + contains = list(/obj/item/ammo_magazine/tank/secondary_flamer_tank) + cost = 10 + containertype = /obj/structure/closet/crate/ammo + /datum/supply_packs/vehicles/motorbike name = "All-Terrain Motorbike" cost = 400 diff --git a/code/modules/reqs/weapons.dm b/code/modules/reqs/weapons.dm index 3a9b0b7c546..4d271e53912 100644 --- a/code/modules/reqs/weapons.dm +++ b/code/modules/reqs/weapons.dm @@ -2,290 +2,21 @@ group = "Weapons" containertype = /obj/structure/closet/crate/weapon -/datum/supply_packs/weapons/sentry - name = "Турель TUR-B \"Базис\"" - contains = list( - /obj/item/weapon/gun/sentry/basic, - ) - cost = 200 - -/datum/supply_packs/weapons/sentry_upgrade - name = "Набор для улучшения турели TUR-B" - contains = list( - /obj/item/sentry_upgrade_kit, - ) - cost = 150 - -/datum/supply_packs/weapons/sentry/ammo - name = "Магазин для турели TUR-B \"Базис\"" - contains = list( - /obj/item/ammo_magazine/sentry, - ) - cost = 50 - -/datum/supply_packs/weapons/sentry/ammo/mini - name = "Магазин для турели TUR-M \"Гном\"" - contains = list( - /obj/item/ammo_magazine/minisentry, - ) - -/datum/supply_packs/weapons/sentry/ammo/sniper - name = "Магазин для турели TUR-SN \"Оса\"" - contains = list( - /obj/item/ammo_magazine/sentry/sniper, - ) - -/datum/supply_packs/weapons/sentry/ammo/shotgun - name = "Магазин для турели TUR-SH \"Бык\"" - contains = list( - /obj/item/ammo_magazine/sentry/shotgun, - ) - -/datum/supply_packs/weapons/sentry/ammo/flamer - name = "Бак для турели TUR-F \"Феникс\"" - contains = list( - /obj/item/ammo_magazine/flamer_tank/large/sentry, - ) - -/datum/supply_packs/weapons/buildasentry - name = "Build-A-Sentry Attachment System" - contains = list( - /obj/item/attachable/buildasentry, - ) - cost = 250 - - -/datum/supply_packs/weapons/m56d_emplacement - name = "HSG-102 Mounted Heavy Smartgun" - contains = list(/obj/item/storage/box/hsg102) - cost = 600 - -/datum/supply_packs/weapons/m56d - name = "HSG-102 mounted heavy smartgun ammo" - contains = list(/obj/item/ammo_magazine/hsg102) - cost = 30 - -/datum/supply_packs/weapons/minigun_emplacement - name = "Mounted Automatic Minigun" - contains = list(/obj/item/weapon/gun/standard_minigun) - cost = 600 - -/datum/supply_packs/weapons/minigun_ammo - name = "Mounted Minigun ammo" - contains = list(/obj/item/ammo_magazine/heavy_minigun) - cost = 30 - -/datum/supply_packs/weapons/autocannon_emplacement - name = "ATR-22 Mounted Flak Cannon" - contains = list(/obj/item/weapon/gun/atr22) - cost = 700 - -/datum/supply_packs/weapons/ac_hv - name = "ATR-22 High-Velocity ammo" - contains = list(/obj/item/ammo_magazine/atr22) - cost = 40 - -/datum/supply_packs/weapons/ac_flak - name = "ATR-22 Smart-Detonating ammo" - contains = list(/obj/item/ammo_magazine/atr22/flak) - cost = 40 - -/datum/supply_packs/weapons/ags_emplacement - name = "AGLS-37 Mounted Automated Grenade Launcher" - contains = list(/obj/item/weapon/gun/agls37) - cost = 700 - -/datum/supply_packs/weapons/ags_highexplo - name = "AGLS-37 AGL High Explosive Grenades" - contains = list(/obj/item/ammo_magazine/agls37) - cost = 40 - -/datum/supply_packs/weapons/ags_frag - name = "AGLS-37 AGL Fragmentation Grenades" - contains = list(/obj/item/ammo_magazine/agls37/fragmentation) - cost = 40 - -/datum/supply_packs/weapons/ags_incendiary - name = "AGLS-37 AGL White Phosphorous Grenades" - contains = list(/obj/item/ammo_magazine/agls37/incendiary) - cost = 40 - -/datum/supply_packs/weapons/ags_flare - name = "AGLS-37 AGL Flare Grenades" - contains = list(/obj/item/ammo_magazine/agls37/flare) - cost = 30 - -/datum/supply_packs/weapons/ags_cloak - name = "AGLS-37 AGL Cloak Grenades" - contains = list(/obj/item/ammo_magazine/agls37/cloak) - cost = 30 - -/datum/supply_packs/weapons/ags_tanglefoot - name = "AGLS-37 AGL Tanglefoot Grenades" - contains = list(/obj/item/ammo_magazine/agls37/tanglefoot) - cost = 55 - -/datum/supply_packs/weapons/antitankgun - name = "AT-36 Anti Tank Gun" - contains = list(/obj/item/weapon/gun/at36) - cost = 800 - -/datum/supply_packs/weapons/antitankgunammo - name = "AT-36 AP-HE Shell (x3)" - contains = list( - /obj/item/ammo_magazine/at36, - /obj/item/ammo_magazine/at36, - /obj/item/ammo_magazine/at36, - ) - cost = 20 - -/datum/supply_packs/weapons/antitankgunammo/apcr - name = "AT-36 APCR Shell (x3)" - contains = list( - /obj/item/ammo_magazine/at36/apcr, - /obj/item/ammo_magazine/at36/apcr, - /obj/item/ammo_magazine/at36/apcr, - ) - cost = 20 - -/datum/supply_packs/weapons/antitankgunammo/he - name = "AT-36 HE Shell (x3)" - contains = list( - /obj/item/ammo_magazine/at36/he, - /obj/item/ammo_magazine/at36/he, - /obj/item/ammo_magazine/at36/he, - ) - cost = 20 - -/datum/supply_packs/weapons/antitankgunammo/beehive - name = "AT-36 Beehive Shell (x3)" - contains = list( - /obj/item/ammo_magazine/at36/beehive, - /obj/item/ammo_magazine/at36/beehive, - /obj/item/ammo_magazine/at36/beehive, - ) - cost = 20 - -/datum/supply_packs/weapons/antitankgunammo/incendiary - name = "AT-36 Napalm Shell (x3)" - contains = list( - /obj/item/ammo_magazine/at36/incend, - /obj/item/ammo_magazine/at36/incend, - /obj/item/ammo_magazine/at36/incend, - ) - cost = 20 - -/datum/supply_packs/weapons/flak_gun - name = "FK-88 Flak Gun" - contains = list(/obj/item/weapon/gun/heavy_isg) - cost = 1200 - -/datum/supply_packs/weapons/flak_he - name = "FK-88 HE Shell" - contains = list(/obj/item/ammo_magazine/heavy_isg/he) - cost = 100 - -/datum/supply_packs/weapons/flak_sabot - name = "FK-88 APFDS Shell" - contains = list(/obj/item/ammo_magazine/heavy_isg/sabot) - cost = 120 - -/datum/supply_packs/weapons/heayvlaser_emplacement - name = "Mounted Heavy Laser" - contains = list(/obj/item/weapon/gun/energy/lasgun/lasrifle/heavy_laser/deployable) - cost = 800 - - -/datum/supply_packs/weapons/heayvlaser_ammo - name = "Mounted Heavy Laser Ammo (x1)" - contains = list(/obj/item/cell/lasgun/heavy_laser) - cost = 15 - /datum/supply_packs/weapons/tesla name = "Tesla Shock Rifle" contains = list(/obj/item/weapon/gun/energy/lasgun/lasrifle/tesla) cost = 600 -/datum/supply_packs/weapons/tx54 - name = "GL-54 airburst grenade launcher" - contains = list(/obj/item/weapon/gun/rifle/tx54) - cost = 300 - -/datum/supply_packs/weapons/tx54_airburst - name = "GL-54 airburst grenade magazine" - contains = list(/obj/item/ammo_magazine/rifle/tx54) - cost = 20 - -/datum/supply_packs/weapons/tx54_incendiary - name = "GL-54 incendiary grenade magazine" - contains = list(/obj/item/ammo_magazine/rifle/tx54/incendiary) - cost = 60 - -/datum/supply_packs/weapons/tx54_smoke - name = "GL-54 tactical smoke grenade magazine" - contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke) - cost = 12 - -/datum/supply_packs/weapons/tx54_smoke/dense - name = "GL-54 dense smoke grenade magazine" - contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke/dense) - cost = 8 - -/datum/supply_packs/weapons/tx54_smoke/tangle - name = "GL-54 tanglefoot grenade magazine" - contains = list(/obj/item/ammo_magazine/rifle/tx54/smoke/tangle) - cost = 48 - /datum/supply_packs/weapons/tx55 name = "AR-55 OICW Rifle" contains = list(/obj/item/weapon/gun/rifle/tx55) cost = 525 -/datum/supply_packs/weapons/recoillesskit - name = "RL-160 Recoilless rifle kit" - contains = list(/obj/item/storage/holster/backholster/rpg/full) - cost = 400 - -/datum/supply_packs/weapons/shell_regular - name = "RL-160 RR HE shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless) - cost = 30 - -/datum/supply_packs/weapons/shell_le - name = "RL-160 RR LE shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless/light) - cost = 30 - -/datum/supply_packs/weapons/shell_heat - name = "RL-160 HEAT shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless/heat) - cost = 30 - -/datum/supply_packs/weapons/shell_smoke - name = "RL-160 RR Smoke shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless/smoke) - cost = 30 - -/datum/supply_packs/weapons/shell_smoke - name = "RL-160 RR Cloak shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless/cloak) - cost = 30 - -/datum/supply_packs/weapons/shell_smoke - name = "RL-160 RR Tanglefoot shell" - contains = list(/obj/item/ammo_magazine/rocket/recoilless/plasmaloss) - cost = 30 - /datum/supply_packs/weapons/pepperball name = "PB-12 pepperball gun" contains = list(/obj/item/weapon/gun/rifle/pepperball) cost = 100 -/datum/supply_packs/weapons/bricks - name = "Brick" - contains = list(/obj/item/weapon/brick) - cost = 10 - /datum/supply_packs/weapons/railgun name = "SR-220 Railgun" contains = list(/obj/item/weapon/gun/rifle/railgun) @@ -331,46 +62,6 @@ contains = list(/obj/item/ammo_magazine/rifle/tx8/incendiary) cost = 40 -/datum/supply_packs/weapons/thermobaric - name = "RL-57 Thermobaric Launcher" - contains = list(/obj/item/weapon/gun/launcher/rocket/m57a4/t57) - cost = 500 - -/datum/supply_packs/weapons/thermobaric_wp - name = "RL-57 Thermobaric WP rocket array" - contains = list(/obj/item/ammo_magazine/rocket/m57a4) - cost = 50 - -/datum/supply_packs/weapons/specdemo - name = "RL-152 SADAR Rocket Launcher" - contains = list(/obj/item/weapon/gun/launcher/rocket/sadar) - cost = SADAR_PRICE - -/datum/supply_packs/weapons/rpg_regular - name = "RL-152 SADAR HE rocket" - contains = list(/obj/item/ammo_magazine/rocket/sadar) - cost = 50 - -/datum/supply_packs/weapons/rpg_regular_unguided - name = "RL-152 SADAR HE rocket (Unguided)" - contains = list(/obj/item/ammo_magazine/rocket/sadar/unguided) - cost = 50 - -/datum/supply_packs/weapons/rpg_ap - name = "RL-152 SADAR AP rocket" - contains = list(/obj/item/ammo_magazine/rocket/sadar/ap) - cost = 60 - -/datum/supply_packs/weapons/rpg_wp - name = "RL-152 SADAR WP rocket" - contains = list(/obj/item/ammo_magazine/rocket/sadar/wp) - cost = 40 - -/datum/supply_packs/weapons/rpg_wp_unguided - name = "RL-152 SADAR WP rocket (Unguided)" - contains = list(/obj/item/ammo_magazine/rocket/sadar/wp/unguided) - cost = 40 - /datum/supply_packs/weapons/zx76 name = "ZX-76 Twin-Barrled Burst Shotgun" contains = list(/obj/item/weapon/gun/shotgun/zx76) @@ -431,85 +122,6 @@ contains = list(/obj/item/ammo_magazine/minigun_powerpack) cost = 50 -/datum/supply_packs/weapons/mg27 - name = "MG-27 Medium Machinegun" - contains = list(/obj/item/weapon/gun/mg27) - cost = 100 - -/datum/supply_packs/weapons/hmg08 - name = "HMG-08 heavy machinegun" - contains = list(/obj/item/weapon/gun/hmg08) - cost = 400 - -/datum/supply_packs/weapons/hmg08_ammo - name = "HMG-08 heavy machinegun ammo (500 rounds)" - contains = list(/obj/item/ammo_magazine/hmg08) - cost = 70 - -/datum/supply_packs/weapons/hmg08_ammo_small - name = "HMG-08 heavy machinegun ammo (250 rounds)" - contains = list(/obj/item/ammo_magazine/hmg08/small) - cost = 40 - -/datum/supply_packs/weapons/sg29 - name = "SG-29 smart machine gun" - contains = list(/obj/item/weapon/gun/rifle/sg29) - cost = 400 - -/datum/supply_packs/weapons/sg29_ammo - name = "SG-29 ammo drum" - contains = list(/obj/item/ammo_magazine/sg29) - cost = 50 - -/datum/supply_packs/weapons/smart_minigun - name = "SG-85 smart gatling gun" - contains = list(/obj/item/weapon/gun/minigun/smart_minigun) - cost = 400 - -/datum/supply_packs/weapons/smart_minigun_ammo - name = "SG-85 ammo bin" - contains = list(/obj/item/ammo_magazine/packet/smart_minigun) - cost = 50 - -/datum/supply_packs/weapons/sg62 - name = "SG-62 Smart Target Rifle" - contains = list(/obj/item/weapon/gun/rifle/sg62) - cost = 400 - -/datum/supply_packs/weapons/sg62_ammo - name = "SG-62 smart target rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg62) - cost = 35 - -/datum/supply_packs/weapons/sg153_ammo - name = "SG-153 spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153) - cost = 15 - -/datum/supply_packs/weapons/sg153_ammo/highimpact - name = "SG-153 high impact spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/highimpact) - -/datum/supply_packs/weapons/sg153_ammo/heavyrubber - name = "SG-153 heavy rubber spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/heavyrubber) - -/datum/supply_packs/weapons/sg153_ammo/plasmaloss - name = "SG-153 tanglefoot spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/plasmaloss) - -/datum/supply_packs/weapons/sg153_ammo/tungsten - name = "SG-153 tungsten spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/tungsten) - -/datum/supply_packs/weapons/sg153_ammo/flak - name = "SG-153 flak spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/flak) - -/datum/supply_packs/weapons/sg153_ammo/incendiary - name = "SG-153 incendiary spotting rifle ammo" - contains = list(/obj/item/ammo_magazine/rifle/sg153/incendiary) - /datum/supply_packs/weapons/flamethrower name = "FL-84 Flamethrower" contains = list(/obj/item/weapon/gun/flamer/big_flamer/marinestandard) @@ -567,11 +179,6 @@ cost = 600 containertype = null -/datum/supply_packs/weapons/rpgoneuse - name = "RL-72 Disposable RPG" - contains = list(/obj/item/weapon/gun/launcher/rocket/oneuse) - cost = 100 - /datum/supply_packs/weapons/mateba name = "Mateba Autorevolver belt" contains = list(/obj/item/storage/holster/belt/revolver/mateba/full) @@ -588,13 +195,6 @@ contains = list(/obj/item/ammo_magazine/packet/mateba) cost = 120 -/datum/supply_packs/weapons/standard_ammo - name = "Surplus Standard Ammo Crate" - notes = "Contains 22 ammo boxes of a wide variety which come prefilled. You lazy bum." - contains = list(/obj/structure/largecrate/supply/ammo/standard_ammo) - containertype = null - cost = 200 - /datum/supply_packs/weapons/sr127_flak name = "SR-127 Flak Magazine" contains = list(/obj/item/ammo_magazine/rifle/sr127/flak) @@ -615,16 +215,6 @@ contains = list(/obj/item/weapon/twohanded/rocketsledge) cost = 600 -/datum/supply_packs/weapons/smart_pistol - name = "TX13 smartpistol" - contains = list(/obj/item/weapon/gun/pistol/smart_pistol) - cost = 150 - -/datum/supply_packs/weapons/smart_pistol_ammo - name = "TX13 smartpistol ammo" - contains = list(/obj/item/ammo_magazine/pistol/p14/smart_pistol) - cost = 10 - /datum/supply_packs/weapons/vector_incendiary name = "vector incendiary magazine" contains = list(/obj/item/ammo_magazine/smg/vector/incendiary) @@ -641,6 +231,21 @@ contains = list(/obj/item/storage/box/t500case) cost = 50 +/datum/supply_packs/weapons/r76case + name = "R76 bundle" + contains = list(/obj/item/storage/briefcase/standard_magnum) + cost = 120 + +/datum/supply_packs/weapons/r76_speedloader + name = "R76 speedloader (x4)" + contains = list( + /obj/item/ammo_magazine/revolver/standard_magnum, + /obj/item/ammo_magazine/revolver/standard_magnum, + /obj/item/ammo_magazine/revolver/standard_magnum, + /obj/item/ammo_magazine/revolver/standard_magnum, + ) + cost = 40 + /datum/supply_packs/weapons/ar12_incendiary name = "AR-12 incendiary magazine" contains = list(/obj/item/ammo_magazine/rifle/ar12/incendiary) @@ -659,27 +264,6 @@ cost = 45 //150 rounds containertype = /obj/structure/closet/crate/ammo -/datum/supply_packs/weapons/rifle/t25 - name = "T25 smartrifle" - contains = list(/obj/item/weapon/gun/rifle/t25) - cost = 400 - -/datum/supply_packs/weapons/ammo_magazine/rifle/t25 - name = "T25 smartrifle magazine" - contains = list(/obj/item/ammo_magazine/rifle/t25) - cost = 20 - -/datum/supply_packs/weapons/t25_extended_mag - name = "T25 extended magazine" - contains = list(/obj/item/ammo_magazine/rifle/t25/extended) - cost = 200 - containertype = /obj/structure/closet/crate/ammo - -/datum/supply_packs/weapons/ammo_magazine/packet/t25 - name = "T25 smartrifle ammo box" - contains = list(/obj/item/ammo_magazine/packet/t25) - cost = 60 - /datum/supply_packs/weapons/box_10x25mm_incendiary name = "10x25mm incendiary ammo box" contains = list(/obj/item/ammo_magazine/packet/p10x25mm/incendiary) @@ -704,61 +288,6 @@ cost = 50 //150 rounds containertype = /obj/structure/closet/crate/ammo -/datum/supply_packs/weapons/thermobaric - name = "RL-57 Thermobaric Launcher Kit" - contains = list(/obj/item/storage/holster/backholster/rlquad/full) - cost = 500 + 50 //ammo price - -/datum/supply_packs/weapons/specdemo - name = "RL-152 SADAR Rocket Launcher kit" - contains = list(/obj/item/storage/holster/backholster/rlsadar/full) - cost = SADAR_PRICE + 150 //ammo price - -/datum/supply_packs/weapons/minigun_powerpack - name = "SG-85 Minigun Powerpack" - contains = list(/obj/item/ammo_magazine/minigun_powerpack/smartgun) - cost = 150 - -/datum/supply_packs/weapons/box_10x27mm - name = "SG-62 smart target rifle ammo box" - contains = list(/obj/item/ammo_magazine/packet/sg62) - cost = 50 - /datum/supply_packs/weapons/xray_gun contains = list(/obj/item/weapon/gun/energy/lasgun/lasrifle/xray) cost = 500 - -/datum/supply_packs/weapons/singleshot_launcher - name = "GL-81 grenade launcher" - contains = list(/obj/item/weapon/gun/grenade_launcher/single_shot) - cost = 150 - -/datum/supply_packs/weapons/multinade_launcher - name = "GL-70 grenade launcher" - contains = list(/obj/item/weapon/gun/grenade_launcher/multinade_launcher/unloaded) - cost = 450 - -/datum/supply_packs/weapons/ltb_shells - name = "LTB tank shell" - contains = list(/obj/item/ammo_magazine/tank/ltb_cannon) - cost = 10 - -/datum/supply_packs/weapons/ltb_shells_apfds - name = "LTB tank APFDS shell" - contains = list(/obj/item/ammo_magazine/tank/ltb_cannon/apfds) - cost = 10 - -/datum/supply_packs/weapons/ltaap_rounds - name = "LTAAP tank magazine" - contains = list(/obj/item/ammo_magazine/tank/ltaap_chaingun) - cost = 10 - -/datum/supply_packs/weapons/cupola_rounds - name = "Cupola tank magazine" - contains = list(/obj/item/ammo_magazine/tank/secondary_cupola) - cost = 10 - -/datum/supply_packs/weapons/secondary_flamer_tank - name = "Spray flamer tank" - contains = list(/obj/item/ammo_magazine/tank/secondary_flamer_tank) - cost = 10 diff --git a/code/modules/shuttle/marine_dropship.dm b/code/modules/shuttle/marine_dropship.dm index b4213f0f7ee..89fa792a981 100644 --- a/code/modules/shuttle/marine_dropship.dm +++ b/code/modules/shuttle/marine_dropship.dm @@ -698,7 +698,7 @@ to_chat(X, span_warning("Our hive lacks the psychic prowess to hijack the bird.")) return var/list/living_player_list = SSticker.mode.count_humans_and_xenos(list(X.z), COUNT_IGNORE_ALIVE_SSD) - if(living_player_list[1] > 5) + if(living_player_list[1] > living_player_list[2]) // if there are more marines than xenos, we are unable to hijack to_chat(X, span_xenowarning("There is still prey left to hunt!")) return switch(M.mode) diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm index f92be8ea1c2..979ee865f95 100644 --- a/code/modules/vehicles/mecha/mecha_defense.dm +++ b/code/modules/vehicles/mecha/mecha_defense.dm @@ -106,7 +106,7 @@ equipment_disabled = TRUE set_mouse_pointer() -/obj/vehicle/sealed/mecha/fire_act(burn_level) //Check if we should ignite the pilot of an open-canopy mech +/obj/vehicle/sealed/mecha/fire_act(burn_level, flame_color) //Check if we should ignite the pilot of an open-canopy mech . = ..() if(enclosed || mecha_flags & SILICON_PILOT) return diff --git a/html/changelogs/AutoChangeLog-pr-687.yml b/html/changelogs/AutoChangeLog-pr-687.yml new file mode 100644 index 00000000000..98cb99f9d56 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-687.yml @@ -0,0 +1,4 @@ +author: "Tatarla" +delete-after: True +changes: + - balance: "Флаера теперь горят от 1.5 до 2 минут вместо 25-30 минут" \ No newline at end of file diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml index b52e86535f3..0cd6d085426 100644 --- a/html/changelogs/archive/2024-10.yml +++ b/html/changelogs/archive/2024-10.yml @@ -667,3 +667,8 @@ \u043A\u0430 \u043F\u0440\u043E\u0436\u0438\u0433\u0430\u0435\u0442 \u0434\u043E\ \ 3 \u0441\u0442\u0435\u043D\u043E\u043A \u0432\u043C\u0435\u0441\u0442\u043E\ \ 2" +2024-10-31: + definitelynotspaghetti: + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043D\u0435\u043F\u0440\ + \u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0439 \u043F\u0443\u0442\u044C \u0443\ + \ \u0430\u0431\u0438\u043B\u043A\u0438 \u0445\u0430\u043D\u0442\u0435\u0440\u0430" diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml new file mode 100644 index 00000000000..cf5df098a89 --- /dev/null +++ b/html/changelogs/archive/2024-11.yml @@ -0,0 +1,495 @@ +2024-11-02: + Helg2: + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043E\u0442\u0441\u0443\ + \u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043F\u0440\u0430\u0439\u0442\u0430\ + \ \u0443 \u043D\u0430\u0443\u0447\u043D\u044B\u0445 \u043E\u0447\u043A\u043E\ + \u0432." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043E\u0442\u0441\u0443\ + \u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043F\u0440\u0430\u0439\u0442\u0430\ + \ \u0443 \u043C\u0435\u0434-\u043E\u0447\u043A\u043E\u0432 \u043D\u0430 \u043C\ + \u043E\u0431\u0435." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u0442\u043E \u0447\u0442\ + \u043E \u043A\u043D\u043E\u043F\u043A\u0430 \u0434\u043B\u044F \u043E\u0442\u043A\ + \u0440\u044B\u0442\u0438\u044F \u0441\u0442\u0432\u043E\u0440\u043E\u043A \u043D\ + \u0430 \u0444\u043E\u0431\u0435, \u0441\u0432\u0435\u0442\u0438\u043B\u0430\u0441\ + \u044C \u043D\u0430\u0434\u043F\u0438\u0441\u044C\u044E \u0411\u041B\u042F\u0422\ + \u042C." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043D\u0435\u043F\u0440\ + \u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0435 \u043E\u0432\u0435\u0440\u043B\ + \u0435\u0438 \u043D\u0430 \u0410\u041F\u0426." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u0442\u043E \u0447\u0442\ + \u043E \u043D\u0435\u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0434\u0432\u0435\ + \u0440\u0438 \u043D\u0430 \u0422\u0430\u043B\u043E\u0441\u0435 \u0441\u0442\u0440\ + \u0430\u043D\u043D\u043E \u0441\u0435\u0431\u044F \u0432\u0435\u043B\u0438 \u043F\ + \u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438/\u0437\u0430\u043A\ + \u0440\u044B\u0442\u0438\u0438." + - image: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0441\u043B\u043E\u043C\u0430\ + \u043D\u043D\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0410\u041F\u0426\ + \ \u0432\u043C\u0435\u0441\u0442\u043E \u0441\u0442\u0430\u0440\u044B\u0445." + - code_imp: "\u0421\u0434\u0435\u043B\u0430\u043B \u043A\u043E\u0434 \u043E\u0431\ + \u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u043E\u0432\u0435\u0440\u043B\ + \u0435\u0435\u0432 \u0410\u041F\u0426 \u0447\u0438\u0442\u0430\u0431\u0435\u043B\ + \u044C\u043D\u0435\u0435 \u0441\u043E \u0441\u0442\u043E\u0440\u043E\u043D\u044B\ + \ \u0441\u043F\u0440\u0430\u0439\u0442\u043E\u0432." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043C\u0435\u0434 \u0445\ + \u0443\u0434 \u0425\u0430\u0439\u0432\u043C\u0430\u0439\u043D\u0434\u0430." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u0440\u0430\u043D\u0442\ + \u0430\u0439\u043C \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0439 \u0441\ + \ \u0441\u0447\u0451\u0442\u0447\u0438\u043A\u043E\u043C \u0431\u044B\u0441\u0442\ + \u0440\u043E\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0443 \u043A\ + \u0441\u0435\u043D\u043E\u0441\u043E\u0432." + - admin: "\u0422\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\u043E \u0437\ + \u0430\u0431\u0430\u043D\u0438\u0442\u044C \u0447\u0435\u043B\u043E\u0432\u0435\ + \u043A\u0443 \u0430\u0434\u043C\u0438\u043D\u0445\u0435\u043B\u043F, \u0430\ + \ \u043D\u0435 \u0442\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u043C\u0443\ + \u0442\u0438\u0442\u044C." + - rscdel: "\u0423\u0434\u0430\u043B\u0438\u043B \u0433\u0440\u0435\u0439\u0441\u043A\ + \u0435\u0439\u043B \u043A\u043E\u043D\u0444\u0438\u0433\u0438 \u0438 \u0438\u043A\ + \u043E\u043D\u043A\u0438 \u0434\u043B\u044F \u043E\u0440\u0443\u0436\u0438\u044F\ + ." + - code_imp: "\u0427\u0443\u0442\u044C-\u0447\u0443\u0442\u044C \u043E\u043F\u0442\ + \u0438\u043C\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043B \u0440\u0430\u043D\ + \u0434\u043E\u043C\u043D\u044B\u0439 \u043A\u043E\u0434, \u0434\u043B\u044F\ + \ \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u044F \u0441\u043A\u043E\u0440\ + \u043E\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u043D\ + \u0430 1.5 \u0441\u0435\u043A\u0443\u043D\u0434\u044B." + MeowEmiya: + - rscadd: "\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D \u0440\u043E\u043B\ + \u043B \u0431\u0435\u0433\u0435\u043C\u043E\u0442\u0443" + - image: "\u0418\u0437\u043C\u0435\u043D\u0451\u043D \u0441\u043F\u0440\u0430\u0439\ + \u0442 \u0443 \u0431\u0435\u0433\u0435\u043C\u043E\u0442\u0430" + Tatarla: + - balance: "\u0421\u041329 18 \u0443\u0440\u043E\u043D\u0430 15 \u0430\u043F > 20\ + \ \u0443\u0440\u043E\u043D\u0430 25 \u0430\u043F" + - balance: "\u0421\u041385 10 \u0443\u0440\u043E\u043D\u0430 25 \u0430\u043F > 20\ + \ \u0443\u0440\u043E\u043D\u0430 -15 \u0430\u043F" + - balance: "\u0421\u041325 17.5 \u0443\u0440\u043E\u043D\u0430 10 \u0430\u043F >\ + \ 20 \u0443\u0440\u043E\u043D\u0430 45 \u0430\u043F" + - balance: "\u0421\u041362 42.5 \u0430\u043F > 30 \u0430\u043F" + kel593: + - balance: "\u0423 \u0425\u0415 \u0441\u043D\u0430\u0440\u044F\u0434\u043E\u0432\ + \ \u0410\u0413\u041B\u0421 \u0443\u043C\u0435\u043D\u044C\u0448\u0435\u043D\ + \ \u043A\u0443\u043B\u0434\u0430\u0443\u043D \u043D\u0430 \u0440\u0430\u0437\ + \u0440\u044B\u0432." + - balance: "\u0423\u043C\u0435\u043D\u044C\u0448\u0438\u043B \u0441\u0438\u043B\u0443\ + \ \u0441\u043D\u0430\u0440\u044F\u0434\u043E\u0432 \u0410\u0413\u041B\u0421\ + , \u043F\u043E\u0432\u044B\u0441\u0438\u043B \u0446\u0435\u043D\u0443 \u043D\ + \u0430 \u0441\u043D\u0430\u0440\u044F\u0434\u044B \u0410\u0413\u041B\u0421,\ + \ \u0443\u043C\u0435\u043D\u044C\u0448\u0438\u043B \u0432 \u043A\u0430\u0440\ + \u0433\u043E \u0446\u0435\u043D\u0443 \u043D\u0430 \u0410\u0413\u041B\u0421." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043C\u0430\u0440\u0438\u043D\ + \u0430\u043C \u0432 \u0432\u0435\u043D\u0434\u043E\u0440 \u0437\u0430 \u043E\ + \u0447\u043A\u0438 \u0442\u0435\u043D\u0433\u043B-\u0433\u0430\u0437 \u0433\u0440\ + \u0430\u043D\u0430\u0442." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0442\u0435\u043D\u0433\u043B\ + -\u0433\u0430\u0437 \u043B\u0438\u043F\u0443\u0447\u043A\u0438." + lorianss: + - balance: "\u041A\u043E\u043B\u043E\u0434\u0446\u044B \u0442\u0435\u043F\u0435\u0440\ + \u044C \u043D\u0435\u043B\u044C\u0437\u044F \u0441\u0442\u0430\u0432\u0438\u0442\ + \u044C \u0432\u043F\u043B\u043E\u0442\u043D\u0443\u044E \u0434\u0440\u0443\u0433\ + \ \u043A \u0434\u0440\u0443\u0433\u0443, \u0442\u043E\u043B\u044C\u043A\u043E\ + \ \u0447\u0435\u0440\u0435\u0437 \u0442\u0430\u0439\u043B." +2024-11-06: + Istrelok2107: + - balance: "\u0423\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u0435 \u0440\u0435\u0432\ + \u043E\u043B\u044C\u0432\u0435\u0440\u0430 \u042076: windup_delay 0.9>0.6 fire_delay\ + \ 1.25>0.75 scatter 3>2" + - bugfix: "\u0423\u0434\u0430\u043B\u0438\u043B \u043D\u0435\u043D\u0443\u0436\u043D\ + \u044B\u0435 \u043A\u043E\u043C\u043F\u0435\u043D\u0441\u0430\u0442\u043E\u0440\ + \ \u0438 \u043F\u0440\u0438\u043A\u043B\u0430\u0434 \u0438\u0437 \u043A\u0435\ + \u0439\u0441\u0430 \u0441 \u042076." + - rscadd: "\u0412\u0432\u0435\u043B \u042076 \u0432 \u043A\u0430\u0440\u0433\u043E\ + \ \u0437\u0430 120 \u043E\u0447\u043A\u043E\u0432" + - rscadd: "\u0412\u0432\u0435\u043B \u043F\u0430\u0442\u0440\u043E\u043D\u044B \u043A\ + \ \u042076 \u0432 \u043A\u0430\u0440\u0433\u043E 40 \u043E\u0447\u043A\u043E\ + \u0432 \u0437\u0430 4 \u043C\u0430\u0433\u0430\u0437\u0438\u043D\u0430" + Tatarla: + - balance: "\u041E\u0431\u044B\u0447\u043D\u0430\u044F \u043A\u0441\u0435\u043D\u043E\ + \u0441\u0442\u0435\u043D\u043A\u0430: \u0441\u043E\u0444\u0442\u0430\u0440\u043C\ + \u043E\u0440 \u043C\u0438\u043B\u0438 30" + - balance: "\u0411\u043E\u043C\u0431\u043F\u0440\u0443\u0444: \u0441\u043E\u0444\ + \u0442\u0430\u0440\u043C\u043E\u0440 15 \u043C\u0438\u043B\u0438, 35 \u0431\u0443\ + \u043B\u043B\u0435\u0442, 30 \u043B\u0430\u0437\u0435\u0440 \u0432\u043C\u0435\ + \u0441\u0442\u043E 70 \u0431\u0443\u043B\u043B\u0435\u0442 \u0438 60 \u043B\u0430\ + \u0437\u0435\u0440\u0430" + - balance: "\u0424\u0430\u0435\u0440\u043F\u0440\u0443\u0444: \u0441\u043E\u0444\ + \u0442\u0430\u0440\u043C\u043E\u0440 15 \u043C\u0438\u043B\u0438, 35 \u0431\u0443\ + \u043B\u043B\u0435\u0442, 30 \u043B\u0430\u0437\u0435\u0440 \u0432\u043C\u0435\ + \u0441\u0442\u043E 70 \u0431\u0443\u043B\u043B\u0435\u0442 \u0438 60 \u043B\u0430\ + \u0437\u0435\u0440\u0430" + - balance: "\u041C\u0438\u043B\u0438\u043F\u0440\u0443\u0444: \u0441\u043E\u0444\ + \u0442\u0430\u0440\u043C\u043E\u0440 35 \u0431\u0443\u043B\u043B\u0435\u0442\ + , 30 \u043B\u0430\u0437\u0435\u0440 \u0432\u043C\u0435\u0441\u0442\u043E 70\ + \ \u0431\u0443\u043B\u043B\u0435\u0442 \u0438 60 \u043B\u0430\u0437\u0435\u0440\ + \u0430" + - balance: "\u0411\u0443\u043B\u043B\u0435\u0442\u043F\u0440\u0443\u0444: \u0441\ + \u043E\u0444\u0442\u0430\u0440\u043C\u043E\u0440 15 \u043C\u0438\u043B\u0438\ + \ \u0432\u043C\u0435\u0441\u0442\u043E 0" +2024-11-07: + Helg2: + - balance: "\u041F\u043E\u043D\u0451\u0440\u0444\u0438\u043B \u0441\u0438\u043B\u0443\ + \ \u043E\u0442\u0431\u0440\u0430\u0441\u044B\u0432\u0430\u043D\u0438\u044F \u043E\ + \u0442 \u0432\u0437\u0440\u044B\u0432\u043E\u0432." + - bugfix: "\u0417\u0435\u043B\u0435\u043D\u044B\u0439 \u043E\u0433\u043E\u043D\u044C\ + \ \u0442\u0435\u043F\u0435\u0440\u044C \u0440\u0430\u0431\u043E\u0442\u0430\u0435\ + \u0442 \u043A\u0430\u043A \u043D\u0443\u0436\u043D\u043E." + - bugfix: "\u0425\u0443\u0434 \u043F\u043B\u0430\u0437\u043C\u044B \u043A\u0441\u0435\ + \u043D\u043E\u043C\u043E\u0440\u0444\u043E\u0432 \u0442\u0435\u043F\u0435\u0440\ + \u044C \u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E \u043E\u0431\u043D\ + \u043E\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043F\u0440\u0438 \u0440\u0435\ + \u0434\u0436\u0443\u0432\u0435." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043C\u0438\u043B\u0438 \u0441\ + \u043F\u0435\u0448\u0438\u0430\u043B \u0430\u0442\u0430\u043A\u0438, \u043A\u043E\ + \u0442\u043E\u0440\u044B\u0435 \u0432 \u043E\u0431\u044B\u0447\u043D\u043E\u0439\ + \ \u0438\u0433\u0440\u0435 \u043D\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\ + \u043D\u044B. \u041F\u043E\u043A\u0430 \u0447\u0442\u043E \u043F\u044B\u043B\ + \u044F\u0442\u0441\u044F." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043A\u0435\u0439\u0431\u0438\ + \u043D\u0434\u044B \u0434\u043B\u044F \u0434\u0436\u0435\u0442\u043F\u0430\u043A\ + \u0430." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043A\u0443\u0447\u0443\ + \ \u043C\u0435\u043B\u043A\u043E\u0439 \u0444\u0438\u0433\u043D\u0438 \u0441\ + \u0432\u044F\u0437\u0430\u043D\u043D\u043E\u0439 \u0441 \u0430\u0431\u0438\u043B\ + \u043A\u0430\u043C\u0438." + - bugfix: "\u0418\u0418 \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u0435\ + \u0442 \u043F\u0440\u044B\u0433\u0430\u0442\u044C \u043A\u0430\u043C\u0435\u0440\ + \u043E\u0439 \u043D\u0430 \u043B\u044E\u0434\u0435\u0439 \u0441 \u043F\u043E\ + \u043C\u043E\u0449\u044C\u044E \u043E\u0432\u0435\u0440\u0432\u043E\u0442\u0447\ + \ \u043A\u043E\u043D\u0441\u043E\u043B\u0438." + - bugfix: "\u0410\u0421\u041B-\u044B \u0442\u0435\u043F\u0435\u0440\u044C \u043C\ + \u043E\u0433\u0443\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\ + \u0430\u0442\u044C \u0441\u0442\u0440\u0435\u043B\u043E\u0447\u043A\u0438." + - bugfix: "\u041E\u0432\u0435\u0440\u043B\u0435\u0439 \u0443\u0441\u0438\u043B\u0435\ + \u043D\u043D\u043E\u0433\u043E \u0443\u0434\u0430\u0440\u0430 \u0432\u0430\u0440\ + \u0440\u0438\u0440\u043E\u0440\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u043D\ + \u0435 \u043F\u0435\u0440\u0435\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043E\ + \u0432\u0435\u0440\u043B\u0435\u0439 \u0432\u044B\u0431\u043E\u0440\u0430 \u0430\ + \u0431\u0438\u043B\u043A\u0438." + - refactor: "\u0418\u0437\u043C\u0435\u043D\u0438\u043B \u043A\u043E\u0434 \u0430\ + \u0431\u0438\u043B\u043E\u043A." + - bugfix: "\u0422\u0435\u043F\u0435\u0440\u044C \u043D\u0435\u043B\u044C\u0437\u044F\ + \ \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0448\u0440\u0430\u043F\u043D\ + \u0435\u043B\u044C, \u0435\u0441\u043B\u0438 \u0443\u0440\u043E\u043D \u043F\ + \u0443\u043B\u0438 \u0431\u044B\u043B \u043D\u0438\u0436\u0435 1." + - bugfix: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\ + \ \u0440\u0435\u0436\u0438\u043C\u0430 \u043B\u0430\u0437\u043F\u0438\u0441\u0442\ + \u043E\u043B\u0435\u0442\u0430 \u043D\u0430 \u043E\u0431\u044B\u0447\u043D\u044B\ + \u0439 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u0434\u0435\u043B\u0430\ + \u0435\u0442 \u0435\u0433\u043E \u043F\u043E\u043B\u0443\u0430\u0432\u0442\u043E\ + \u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u043C." +2024-11-08: + Basia: + - rscadd: "\u0421\u043E\u0432\u0435\u0442\u044B \u0442\u0435\u043F\u0435\u0440\u044C\ + \ \u043D\u0430 \u0413\u043E\u0439\u0434\u0430-\u044F\u0437\u044B\u043A\u0435" + Helg2: + - bugfix: "\u0412 IS pattern Storage module \u0442\u0435\u043F\u0435\u0440\u044C\ + \ \u043C\u043E\u0436\u043D\u043E \u043B\u043E\u0436\u0438\u0442\u044C \u043C\ + \u0430\u0442\u0435\u0440\u0438\u0430\u043B\u044B." + - bugfix: "\u0422\u0435\u043B\u0435\u043A\u043E\u043C\u043C\u044B \u043D\u0430 \u043A\ + \u0440\u0430\u0448\u0435 \u0442\u0435\u043F\u0435\u0440\u044C \u0437\u0430\u0432\ + \u0438\u0441\u044F\u0442 \u043E\u0442 \u0430\u043F\u0446 \u043D\u0430 \u043C\ + \u043E\u0441\u0442\u0438\u043A\u0435 \u0448\u0430\u0442\u0442\u043B\u0430." + Tatarla: + - map: "\u041D\u0430 \u041C\u0430\u0433\u043C\u0443\u0440\u0435 \u0431\u044B\u043B\ + \u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0430 \u043A\u0438\u0448\u043A\u0430\ + \ \u043D\u0430 \u043B\u0430\u0432\u043E\u0432\u043E\u043C \u043E\u0437\u0435\ + \u0440\u0435" +2024-11-09: + Helg2: + - map: "\u041D\u0430 \u0422\u0430\u043B\u043E\u0441\u0435 \u0442\u0435\u043F\u0435\ + \u0440\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0439 \u0440\ + \u0435\u0441\u0438\u0432\u0435\u0440 \u0442\u0435\u043B\u0435\u043A\u043E\u043C\ + \u043E\u0432, \u043F\u043E\u0437\u0432\u043E\u043B\u044F\u044E\u0449\u0438\u0439\ + \ \u043E\u0431\u0449\u0430\u0442\u044C\u0441\u044F \u043D\u0430 \u043E\u0431\ + \u0449\u0435\u043C \u043A\u0430\u043D\u0430\u043B\u0435 \u0441\u0432\u044F\u0437\ + \u0438." + Tatarla: + - balance: "\u0421\u043F\u0440\u0435\u0439-\u043D\u0430\u0441\u0430\u0434\u043A\u0430\ + \ \u0442\u0435\u043F\u0435\u0440\u044C \u043F\u0440\u043E\u0436\u0438\u0433\u0430\ + \u0435\u0442 4 \u0442\u0430\u0439\u043B\u0430 \u0432 \u0434\u043B\u0438\u043D\ + \u0443 \u0432\u043C\u0435\u0441\u0442\u043E 6" + - balance: "\u041F\u043E\u0434\u0441\u0442\u0432\u043E\u043B\u044C\u043D\u044B\u0439\ + \ \u0433\u0440\u0430\u043D\u0430\u0442\u043E\u043C\u0435\u0442 \u0432\u043C\u0435\ + \u0449\u0430\u0435\u0442 2 \u0433\u0440\u0430\u043D\u0430\u0442\u044B." + - balance: "\u041F\u043E\u0434\u0441\u0442\u0432\u043E\u043B\u044C\u043D\u044B\u0439\ + \ \u0433\u0440\u0430\u043D\u0430\u0442\u043E\u043C\u0435\u0442 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0432\u043C\u0435\u0449\u0430\u0435\u0442 \u0432 \u0441\u0435\ + \u0431\u044F \u043C15 \u0438 \u0442\u0440\u0435\u0439\u043B\u0431\u043B\u0435\ + \u0439\u0437\u0435\u0440\u044B." +2024-11-10: + Helg2: + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u043F\u0440\u043E\u0432\ + \u0430\u043B\u0438\u0432\u0430\u044E\u0449\u0438\u0435\u0441\u044F \u044E\u043D\ + \u0438\u0442 \u0442\u0435\u0441\u0442\u044B \u043D\u0430 \u0411\u0438\u0433\u0440\ + \u0435\u0434\u0435." + Istrelok2107: + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u0433\u0440\u0430\u043D\ + \u0430\u0442\u044B \u0441 \u0422\u0413\u0410\u0417\u043E\u043C \u0432 \u043A\ + \u0430\u0440\u0433\u043E" +2024-11-12: + Helg2: + - code_imp: "\u0411\u043E\u043B\u044C\u0448\u0430\u044F \u0447\u0430\u0441\u0442\ + \u044C `spawn()` \u0431\u044B\u043B\u0430 \u043F\u0435\u0440\u0435\u0434\u0435\ + \u043B\u0430\u043D\u0430 \u0432 \u0442\u0430\u0439\u043C\u0435\u0440\u044B." +2024-11-14: + Helg2: + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u0438\u043B \u0442\u043E \u0447\u0442\ + \u043E \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044B\u0435 \u043B\u0430\ + \u043C\u043F\u044B, \u0432 \u0441\u0430\u0434\u0443 \u0422\u0430\u043B\u043E\ + \u0441\u0430, \u0432\u044B\u0433\u043B\u044F\u0434\u0435\u043B\u0438 \u043A\u0430\ + \u043A \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044B\u0435." + - image: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0441\u043F\u0440\u0430\u0439\ + \u0442\u044B \u043F\u0443\u0441\u0442\u044B\u0445 \u043D\u0430\u0441\u043F\u0438\ + \u043D\u043D\u044B\u0445 \u0431\u0430\u043A\u043E\u0432 \u0441 \u0442\u043E\u043F\ + \u043B\u0438\u0432\u043E\u043C." + - bugfix: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u0442\u043E\ + \ \u0447\u0442\u043E \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u043D\ + \u044B\u0435 \u043A \u043E\u0440\u0443\u0436\u0438\u044E \u043C\u0430\u0433\u0430\ + \u0437\u0438\u043D\u0443, \u043D\u0435 \u0441\u0431\u0440\u0430\u0441\u044B\u0432\ + \u0430\u043B\u0438 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\ + \u0435 \u043A \u043E\u0440\u0443\u0436\u0438\u044E \u043F\u0440\u0438 \u0432\ + \u043E\u0437\u0432\u0440\u0430\u0442\u0435 \u0432 \u0432\u0435\u043D\u0434\u043E\ + \u0440." + - rscadd: "Offhand-\u044B \u0442\u0435\u043F\u0435\u0440\u044C \u0432\u0438\u0437\ + \u0443\u0430\u043B\u044C\u043D\u043E \u043D\u0438\u0436\u0435 \u0432\u0437\u044F\ + \u0442\u044B\u0445 \u043F\u0440\u0435\u0434\u043C\u0435\u0442\u043E\u0432." + Smiling Dark: + - qol: "\u0422\u0435\u043F\u0435\u0440\u044C \u0432\u0435\u0449\u0438 \u0432 \u043A\ + \u0430\u0440\u0433\u043E \u043D\u0430\u0439\u0442\u0438 \u043D\u0435\u0441\u043A\ + \u043E\u043B\u044C\u043A\u043E \u043F\u0440\u043E\u0449\u0435, \u0440\u0430\u0441\ + \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u044B \u043D\u0430\ + \ \u0438\u043D\u0442\u0443\u0438\u0442\u0438\u0432\u043D\u043E \u043F\u043E\u043D\ + \u044F\u0442\u043D\u044B\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\ + \u0438." + - image: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B 3 \u0441\u043F\u0440\u0430\u0439\ + \u0442\u0430 \u043D\u043E\u0432\u044B\u0445 \u044F\u0449\u0438\u043A\u043E\u0432\ + \ \u0432 \u043A\u0430\u0440\u0433\u043E." +2024-11-15: + Helg2: + - rscadd: "\u0421\u041B-\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u043E\ + \u0436\u043D\u043E \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u0438\u0433\u0440\ + \u0430\u044F \u0438 \u0437\u0430 \u043C\u0430\u0440\u0438\u043D\u043E\u0432\ + , \u0438 \u0437\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0443\u044E\u0449\ + \u0438\u0439 \u0441\u043E\u0441\u0442\u0430\u0432." + Istrelok2107: + - balance: "\u0414\u0436\u0435\u0442\u043F\u0430\u043A\u0443 \u0443\u0431\u0440\u0430\ + \u043D\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043D\u0430 \u0441\ + \u0442\u0430\u0433\u0433\u0435\u0440" + Tatarla: + - balance: "\u0411\u0435\u0433\u0435\u043C\u043E\u0442 \u043F\u043E\u043B\u0443\u0447\ + \u0438\u043B 12 \u0445\u0430\u0440\u0434\u0430 \u043E\u0442 \u0431\u0443\u043B\ + \u043B\u0435\u0442\u0430, \u043F\u043E\u0442\u0435\u0440\u044F\u043B \u0445\u0430\ + \u0440\u0434 \u043E\u0442 \u043C\u0438\u043B\u0438, \u0441\u043D\u0438\u0436\ + \u0435\u043D \u0445\u0430\u0440\u0434 \u043E\u0442 \u043B\u0430\u0437\u0435\u0440\ + \u043E\u0432 \u0441 12 \u0434\u043E 6" + - balance: "\u041A\u0440\u0430\u0448\u0435\u0440\u0443 \u043F\u043E\u0434\u043D\u044F\ + \u0442\u043E \u0425\u041F \u0441 400 \u0434\u043E 500, \u043F\u043E\u043D\u0435\ + \u0440\u0444\u043B\u0435\u043D \u0441\u043E\u0444\u0442\u0430\u0440\u043C\u043E\ + \u0440 \u043E\u0442 \u043C\u0438\u043B\u0438 \u0441 80 \u0434\u043E 50, \u043B\ + \u0430\u0437\u0435\u0440\u044B \u0441 80 \u0434\u043E 65" + - balance: "\u0414\u0435\u0444\u0435\u043D\u0434\u0435\u0440\u0443 \u043F\u043E\u0434\ + \u043D\u044F\u0442\u043E \u0425\u041F \u0441 320 \u0434\u043E 410, \u043F\u043E\ + \u043B\u0443\u0447\u0438\u043B \u0445\u0430\u0440\u0434\u0430\u0440\u043C\u043E\ + \u0440 10 \u043E\u0442 \u0431\u0443\u043B\u043B\u0435\u0442\u0430" + - balance: "\u041F\u0440\u0435\u0442\u043E\u0440\u0443 \u043F\u043E\u0434\u043D\u044F\ + \u0442\u043E \u0425\u041F \u0441 460 \u0434\u043E 570, \u0441\u043D\u0438\u0436\ + \u0435\u043D \u0441\u043E\u0444\u0442\u0430\u0440\u043C\u043E\u0440 \u0431\u0443\ + \u043B\u043B\u0435\u0442\u0430 \u0441 50 \u0434\u043E 25, \u043B\u0430\u0437\ + \u0435\u0440\u043E\u0432 \u0441 50 \u0434\u043E 15" + - balance: "\u0421\u0435\u043D\u0442\u0438\u043D\u0435\u043B\u044E \u043F\u043E\u0434\ + \u043D\u044F\u0442\u043E \u0425\u041F \u0441 300 \u0434\u043E 400" + - balance: "\u0421\u043F\u0438\u0442\u0442\u0435\u0440\u0443 \u043F\u043E\u0434\u043D\ + \u044F\u0442\u043E \u0425\u041F \u0441 310 \u0434\u043E 450, \u0441\u043E\u0444\ + \u0442\u0430\u0440\u043C\u043E\u0440 \u0431\u0443\u043B\u043B\u0435\u0442\u0430\ + \ \u0441\u043D\u0438\u0436\u0435\u043D \u0441 35 \u0434\u043E 20, \u043B\u0430\ + \u0437\u0435\u0440\u043E\u0432 \u0441 35 \u0434\u043E 10" + - balance: "\u0413\u0440\u043E\u0437\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\ + \u0430 3 \u0444\u0430\u043B\u043B\u043E\u0443, \u0425\u041F 50 \u0443\u0440\u043E\ + \u043D\u0430 > 60" + - balance: "\u0410\u042021 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u0430 2 \u0444\ + \u0430\u043B\u043B\u043E\u0443" + - balance: "\u0412\u0435\u043A\u0442\u043E\u0440 \u043F\u043E\u043B\u0443\u0447\u0438\ + \u043B 3 \u0444\u0430\u043B\u043B\u043E\u0443, \u0410\u041F 15 \u0443\u0440\u043E\ + \u043D\u0430 20 \u0410\u041F > 20 \u0443\u0440\u043E\u043D\u0430 15 \u0410\u041F" +2024-11-16: + Helg2: + - bugfix: "\u0425\u0430\u0433\u0433\u0435\u0440 \u043E\u0432\u0435\u0440\u043B\u0435\ + \u0439 \u043D\u0430 \u041A\u0435\u0440\u0440\u0438\u0435\u0440\u0435 \u0442\u0435\ + \u043F\u0435\u0440\u044C \u043E\u043F\u044F\u0442\u044C \u0440\u0430\u0431\u043E\ + \u0442\u0430\u0435\u0442." + - rscadd: "\u0421\u043F\u0438\u0442\u0442\u0435\u0440\u0443 \u0434\u043E\u0431\u0430\ + \u0432\u043B\u0435\u043D\u0430 \u043B\u0438\u043F\u043A\u0430\u044F \u043A\u0438\ + \u0441\u043B\u043E\u0442\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0430\u0442\ + \u0430 \u0432 \u043F\u0440\u0438\u043C\u043E. \u0420\u0430\u0431\u043E\u0442\ + \u0430\u0435\u0442 \u043A\u0430\u043A \u0442\u0440\u0435\u0439\u043B\u0431\u043B\ + \u0435\u0439\u0437\u0435\u0440 \u0442\u043E\u043B\u044C\u043A\u043E \u0441 \u043A\ + \u0438\u0441\u043B\u043E\u0442\u043E\u0439." + - balance: "\u0423 \u043F\u0440\u0438\u043C\u043E \u0441\u043F\u0438\u0442\u0442\ + \u0435\u0440\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u0441\u0438\u043B\u044C\ + \u043D\u0430\u044F \u043A\u0438\u0441\u043B\u043E\u0442\u0430, \u0432\u043C\u0435\ + \u0441\u0442\u043E \u043E\u0431\u044B\u0447\u043D\u043E\u0439." + Tatarla: + - image: "\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u044B \u0441\u043F\u0440\u0430\ + \u0439\u0442\u044B \u043F\u0440\u0438\u043A\u0430\u0437\u043E\u0432 \u0443 \u043C\ + \u0430\u0440\u0438\u043D\u043E\u0432" + - image: "\u0418\u0437\u043C\u0435\u043D\u0438\u043B \u0441\u043F\u0440\u0430\u0439\ + \u0442 \u0411\u0422\u0420\u0430 \u0437\u0430 \u0430\u0432\u0442\u043E\u0440\u0441\ + \u0442\u0432\u043E\u043C borisoglebsk" + - bugfix: "\u041F\u0430\u0432\u0435\u0440\u0444\u0438\u0441\u0442 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0435\u0441\u0442\u044C \u0432 \u043E\u0440\u0443\u0436\u0435\ + \u0439\u043D\u043E\u043C \u0432\u0435\u043D\u0434\u043E\u0440\u0435 \u043D\u0430\ + \ \u0434\u0438\u0441\u0442\u0440\u0435\u0441\u0441\u0435" + - balance: "\u0412\u0441\u0435 \u0448\u043B\u044F\u043F\u044B, \u043A\u0440\u043E\ + \u043C\u0435 \u043F\u043E\u0432\u044F\u0437\u043E\u043A, \u0442\u0435\u043F\u0435\ + \u0440\u044C \u0438\u043C\u0435\u044E\u0442 \u043E\u0434\u0438\u043D\u0430\u043A\ + \u043E\u0432\u0443\u044E \u0431\u0440\u043E\u043D\u044E." + - balance: "\u041D\u0430 \u0432\u0438\u043D\u0442\u043E\u0432\u043A\u0438 \u0442\ + \u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\u043E \u0432\u0435\u0448\ + \u0430\u0442\u044C \u043B\u044E\u0431\u043E\u0439 \u043E\u0431\u0432\u0435\u0441" + - balance: "\u041C\u041360 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u0430 \u0430\ + \u0438\u043C-\u043C\u043E\u0434" + - balance: "\u0412\u0441\u0435\u043C \u043F\u0440\u0438\u0446\u0435\u043B\u0430\u043C\ + (\u043A\u0440\u043E\u043C\u0435 \u0440\u0435\u0434-\u0434\u043E\u0442\u0430\ + ) \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u0430\u0438\u043C-\u043C\ + \u043E\u0434" + - balance: "\u04117 \u0442\u0435\u043F\u0435\u0440\u044C \u0434\u0430\u0435\u0442\ + \ \u043F\u043E\u043B\u043D\u044B\u0439 \u0438\u0444\u0444 \u0432\u0437\u0430\ + \u043C\u0435\u043D \u043D\u0430 -15% \u0443\u0440\u043E\u043D\u0430" + - balance: "\u0421\u043E\u0448\u043A\u0438 \u043F\u0440\u0438 \u0440\u0430\u0437\ + \u0432\u0435\u0440\u0442\u044B\u0432\u0430\u043D\u0438\u0438 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0434\u0430\u044E\u0442 \u0438\u043C\u043C\u0443\u043D\u0438\ + \u0442\u0435\u0442 \u043A \u0442\u043E\u043B\u043A\u0430\u043D\u0438\u044E \u0438\ + \ \u0441\u0432\u0430\u043F\u0443 \u043D\u0430 \u0445\u0435\u043B\u043F\u0435\ + , \u0435\u0441\u043B\u0438 \u044D\u0442\u043E \u043F\u044B\u0442\u0430\u0435\ + \u0442\u0441\u044F \u0441\u0434\u0435\u043B\u0430\u0442\u044C \u0434\u0440\u0443\ + \u0433\u043E\u0439 \u043C\u0430\u0440\u0438\u043D" + - balance: "\u0411\u0443\u0440\u0441\u0442-\u0444\u0430\u0435\u0440 \u0430\u0441\ + \u0435\u043C\u0431\u043B\u0435\u0440 \u0442\u0435\u043F\u0435\u0440\u044C \u043D\ + \u0435 \u0434\u0430\u0435\u0442 \u0434\u0435\u0431\u0430\u0444\u043E\u0432 \u043A\ + \ \u0442\u043E\u0447\u043D\u043E\u0441\u0442\u0438 (\u0437\u0430\u043C\u0435\ + \u043D\u0430 \u0438\u043C \u0441\u043B\u043E\u0442\u0430 \u043F\u043E\u0434\u0441\ + \u0442\u0432\u043E\u043B\u0430 - \u0443\u0436\u0435 \u043E\u0433\u0440\u043E\ + \u043C\u043D\u0430\u044F \u0446\u0435\u043D\u0430 \u0437\u0430 \u0438\u0441\u043F\ + \u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435)" + - balance: "\u0413\u043B\u0443\u0448\u0430\u043A \u0441\u043D\u0438\u0436\u0430\u0435\ + \u0442 \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044C \u043F\u0443\u043B\u0438\ + \ \u043D\u0430 50%, \u0430 \u043D\u0435 \u043D\u0430 100%" + - balance: "\u041B\u0430\u0433\u0437\u0430\u043D\u044B \u0432\u043E\u0437\u0432\u0440\ + \u0430\u0449\u0435\u043D\u044B \u0432 \u043E\u0440\u0443\u0436\u0435\u0439\u043D\ + \u044B\u0439 \u0432\u0435\u043D\u0434\u043E\u0440" + - balance: "AR-18 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D\u0430 \u0432\ + \ \u043E\u0440\u0443\u0436\u0435\u0439\u043D\u044B\u0439 \u0432\u0435\u043D\u0434\ + \u043E\u0440" + - balance: "\u041F\u0430\u0432\u0435\u0440\u0444\u0438\u043A\u0441\u0442 \u0432\u043E\ + \u0437\u0432\u0440\u0430\u0449\u0435\u043D \u0432 \u043E\u0440\u0443\u0436\u0435\ + \u0439\u043D\u044B\u0439 \u0432\u0435\u043D\u0434\u043E\u0440" + - spellcheck: "\u041F\u0435\u0440\u0435\u0432\u043E\u0434 \u0440\u0430\u0437\u0434\ + \u0435\u043B\u043E\u0432 \u043E\u0440\u0443\u0436\u0435\u0439\u043D\u043E\u0433\ + \u043E \u0432\u0435\u043D\u0434\u043E\u0440\u0430" + - code_imp: "\u0422\u0443\u0440\u0435\u043B\u0438 \u043F\u0435\u0440\u0435\u043D\ + \u0435\u0441\u0435\u043D\u044B \u0432 \u0440\u0430\u0437\u0434\u0435\u043B \u0421\ + \u043F\u0435\u0446\u0438\u0430\u043B\u0438\u0441\u0442\u0430\u043C, \u0441\u0442\ + \u0430\u0446\u0438\u043E\u043D\u0430\u0440\u043D\u044B\u0435 \u043F\u0443\u043B\ + \u0435\u043C\u0435\u0442\u044B \u0432 \u0440\u0430\u0437\u0434\u0435\u043B \u043F\ + \u0443\u043B\u0435\u043C\u0435\u0442\u043E\u0432" + homexp13: + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u043F\u043E\u044F\u0441\ + \ \u0434\u043B\u044F \u043C\u0430\u0433\u0430\u0437\u0438\u043D\u043E\u0432\ + \ \"M344\"" + - rscadd: "\u041F\u0438\u0441\u0442\u043E\u043B\u0435\u0442\u043D\u044B\u0439 \u043F\ + \u043E\u044F\u0441 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\ + \u0441\u043A\u0438 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0441\ + \u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u044B\u0435 \u043C\u0430\u0433\ + \u0430\u0437\u0438\u043D\u044B \u0438 \u043C\u043E\u0436\u0435\u0442 \u043F\u0435\ + \u0440\u0435\u0437\u0430\u0440\u044F\u0436\u0430\u0442\u044C \u0438\u0445 \u0434\ + \u0430\u0436\u0435 \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u043D\u0430\u0445\ + \u043E\u0434\u044F\u0442\u0441\u044F \u0432 \u043D\u0451\u043C (\u043F\u043A\ + \u043C \u0441 \u043A\u043E\u0440\u043E\u0431\u043A\u043E\u0439 \u043F\u0430\u0442\ + \u0440\u043E\u043D\u043E\u0432 \u043F\u043E \u043F\u043E\u044F\u0441\u0443)" + lorianss: + - balance: "\u0422\u0435\u043F\u0435\u0440\u044C \u043C\u0435\u0436\u0434\u0443\ + \ \u043A\u0441\u0435\u043D\u043E\u0434\u0432\u0435\u0440\u044C\u043C\u0438 \u0434\ + \u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043C\u0438\u043D\u0438\ + \u043C\u0443\u043C 2 \u0442\u0430\u0439\u043B\u0430 \u0434\u043B\u044F \u0438\ + \u0445 \u043F\u043E\u0441\u0442\u0440\u043E\u0439\u043A\u0438." +2024-11-19: + Dark-Umbrella: + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B handheld charger \u0432 \u0438\ + \u043D\u0436\u0435\u043D\u0435\u0440\u043D\u044B\u0439 \u0440\u0430\u0437\u0434\ + \u0435\u043B \u043A\u0430\u0440\u0433\u043E \u0437\u0430 85 \u043F\u043E\u0439\ + \u043D\u0442\u043E\u0432." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B Emergency Provision Crate\ + \ (EPC) \u0441 10 \u041C\u0420\u0415 \u0432\u043D\u0443\u0442\u0440\u0438 \u0432\ + \ \u0440\u0430\u0437\u0434\u0435\u043B \u0441\u043D\u0430\u0431\u0436\u0435\u043D\ + \u0438\u044F \u043A\u0430\u0440\u0433\u043E \u0437\u0430 65 \u043F\u043E\u0439\ + \u043D\u0442\u043E\u0432." +2024-11-20: + Helg2: + - qol: "\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u043B \u043A\u043D\u043E\ + \u043F\u043A\u0438 \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438\ + \ \u0438 \u043F\u0440\u0438\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\ + \u044F \u0432 1." +2024-11-22: + Helg2: + - code_imp: "\u0417\u0430\u043C\u0435\u043D\u0438\u043B `spawn()` \u0432 \u043A\u043E\ + \u0434\u0435 \u0432\u0437\u0440\u044B\u0432\u043E\u0432 \u043D\u0430 `addtimer`\ + \ \u0438 `INVOKE_ASYNC`" + homexp13: + - balance: "\u043C\u0435\u0434\u0438\u0446\u0438\u043D\u0441\u043A\u0438\u0439 \u0440\ + \u0435\u0441\u0435\u0440\u0447\u0435\u0440 \u0442\u0435\u043F\u0435\u0440\u044C\ + \ \u043F\u043E\u043B\u0435\u0432\u043E\u0439 \u0440\u0435\u0441\u0435\u0440\u0447\ + \u0435\u0440 \u0438 \u0438\u043C\u0435\u0435\u0442 \u0431\u043E\u0435\u0432\u044B\ + \u0435 \u0441\u043A\u0438\u043B\u044B." +2024-11-23: + Helg2: + - balance: "\u0418\u0437\u043C\u0435\u043D\u0438\u043B \u0444\u043E\u0440\u043C\u0443\ + \u043B\u0443 \u0434\u043B\u044F \u0445\u0430\u0439\u0434\u0436\u0430\u043A\u0430\ + \ \u0441 `\u0415\u0441\u043B\u0438 \u043C\u0430\u0440\u0438\u043D\u043E\u0432\ + \ > 5` \u043D\u0430 `\u0415\u0441\u043B\u0438 \u043C\u0430\u0440\u0438\u043D\ + \u043E\u0432 > \u0447\u0435\u043C \u043A\u0441\u0435\u043D\u043E\u0441\u043E\ + \u0432`" + - rscadd: "\u0421\u0432\u0430\u0442 \u043C\u0430\u0441\u043A\u0430 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0440\u0432\u0451\u0442\u0441\u044F \u043F\u0440\u0438 \u043F\ + \u043E\u043F\u044B\u0442\u043A\u0435 \u0445\u0430\u0433\u0433\u0435\u0440\u0430\ + \ \u0437\u0430\u043B\u0435\u0437\u0442\u044C \u043D\u0430 \u043A\u043E\u0433\ + \u043E-\u0442\u043E." + MeowEmiya: + - balance: "\u0425\u0430\u0433\u0433\u0435\u0440\u0430 \u0431\u043E\u043B\u0435\u0435\ + \ \u043D\u0435\u043B\u044C\u0437\u044F \u0441\u043D\u044F\u0442\u044C \u043E\ + \u0433\u043D\u0435\u043C \u0441 \u043A\u0443\u043A\u043B\u044B." + - balance: "\u041D\u0430\u0445\u043E\u0434\u044F\u0449\u0430\u044F\u0441\u044F \u0432\ + \ \u0442\u0435\u043B\u0435 \u043B\u044F\u0440\u0432\u0430 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0440\u0430\u0441\u0442\u0451\u0442 \u0431\u044B\u0441\u0442\ + \u0440\u0435\u0435." + definitelynotspaghetti: + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043D\u043E\u0432\u044B\u0435\ + \ \u0430\u0431\u0438\u043B\u043A\u0438 \u0412\u0434\u043E\u0432\u0435." + - rscdel: "\u0423\u0434\u0430\u043B\u0438\u043B Web Hook, Burrow \u0438 Cannibalise." + - balance: "\u0418\u0437\u043C\u0435\u043D\u0438\u043B \u041A\u0414 \u0438 \u0441\ + \u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C \u043D\u0435\u043A\u043E\u0442\ + \u043E\u0440\u044B\u0445 \u0430\u0431\u0438\u043B\u043E\u043A \u0438 \u0441\u0442\ + \u0430\u0442\u044B \u043F\u0430\u0443\u0447\u043A\u043E\u0432." + - refactor: "\u041F\u043E\u0447\u0438\u043D\u0438\u043B \u0438 \u0443\u043B\u0443\ + \u0447\u0448\u0438\u043B \u0418\u0418 \u043F\u0430\u0443\u0447\u043A\u043E\u0432\ + ." + lorianss: + - rscadd: "\u0421\u0435\u043D\u0442\u0438\u043D\u0435\u043B\u044C \u0442\u0435\u043F\ + \u0435\u0440\u044C \u043F\u043E\u043B\u0443\u0447\u0430\u0435\u0442 +60 \u0431\ + \u0443\u043B\u043B\u0435\u0442 \u0430\u0440\u043C\u043E\u0440\u0430 \u043D\u0430\ + \ \u0432\u0440\u0435\u043C\u044F \u0430\u043A\u0442\u0438\u0432\u0430\u0446\u0438\ + \u0438 \u0441\u0432\u043E\u0438\u0445 \u0442\u043E\u043A\u0441\u0438\u0447\u043D\ + \u044B\u0445 \u0443\u0434\u0430\u0440\u043E\u0432." + mister-onion: + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0441\u043F\u043E\ + \u0441\u043E\u0431\u043D\u043E\u0441\u0442\u044C \u0434\u043B\u044F \u043F\u043E\ + \u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043D\u0435\u0441\u0442\u0430 \u043A\ + \u0435\u0440\u0440\u0438\u0435\u0440\u0443. \u0421\u0442\u043E\u0438\u043C\u043E\ + \u0441\u0442\u044C \u043F\u043B\u0430\u0437\u043C\u044B 200, \u041A\u0414 20\u0441\ + ." + - balance: "\u0441\u043F\u043E\u0441\u043E\u0431\u043D\u043E\u0441\u0442\u0438:\ + \ Call younger - 20s > 10s \u041A\u0414; Throw hugger - 3s > 2s; \u041A\u0414\ + \ Spawn hugger - 10s > 5s \u041A\u0414. \u0425\u0430\u0440\u0430\u043A\u0442\ + \u0435\u0440\u0438\u0441\u0442\u0438\u043A\u0438:Melee damage = 20>22;Plasma_max\ + \ = 800>1000;plasma_gain = 38>45;max_health = 325>425\nsoft_armor = list (MELEE\ + \ = 15>30, BULLET = 15>30, LASER = 15>30, ENERGY = 15>30, BOMB = 0, BIO = 5,\ + \ FIRE = 0>25, ACID = 5)." diff --git a/icons/UI_Icons/lobby_button.dmi b/icons/UI_Icons/lobby_button.dmi index 2be4c11ec7e..42720b956b6 100644 Binary files a/icons/UI_Icons/lobby_button.dmi and b/icons/UI_Icons/lobby_button.dmi differ diff --git a/icons/UI_Icons/map_blips.dmi b/icons/UI_Icons/map_blips.dmi index e01e2b86073..2c525cab539 100644 Binary files a/icons/UI_Icons/map_blips.dmi and b/icons/UI_Icons/map_blips.dmi differ diff --git a/icons/Xeno/Effects.dmi b/icons/Xeno/Effects.dmi index 62f89a44cc5..9e81e937410 100644 Binary files a/icons/Xeno/Effects.dmi and b/icons/Xeno/Effects.dmi differ diff --git a/icons/Xeno/actions.dmi b/icons/Xeno/actions.dmi index 2a4352eb9d4..92e37923d6f 100644 Binary files a/icons/Xeno/actions.dmi and b/icons/Xeno/actions.dmi differ diff --git a/icons/Xeno/castes/behemoth/basic.dmi b/icons/Xeno/castes/behemoth/basic.dmi index 4c67780fb6e..eee0b06caf6 100644 Binary files a/icons/Xeno/castes/behemoth/basic.dmi and b/icons/Xeno/castes/behemoth/basic.dmi differ diff --git a/icons/Xeno/castes/behemoth/effects.dmi b/icons/Xeno/castes/behemoth/effects.dmi index f67d87a4915..ea9cea81207 100644 Binary files a/icons/Xeno/castes/behemoth/effects.dmi and b/icons/Xeno/castes/behemoth/effects.dmi differ diff --git a/icons/Xeno/castes/widow/basic.dmi b/icons/Xeno/castes/widow/basic.dmi new file mode 100644 index 00000000000..f79a01f484b Binary files /dev/null and b/icons/Xeno/castes/widow/basic.dmi differ diff --git a/icons/Xeno/castes/widow/effects.dmi b/icons/Xeno/castes/widow/effects.dmi new file mode 100644 index 00000000000..541c8d61711 Binary files /dev/null and b/icons/Xeno/castes/widow/effects.dmi differ diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index 4270cd20133..98bae3d2ac7 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 1bc70194f39..4d8a83e7757 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi index aa4a5ff12f0..965390a309d 100644 Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index f2c063094c9..920bf7ad0be 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/inhands/weapons/grenades_left.dmi b/icons/mob/inhands/weapons/grenades_left.dmi index 74da406e9da..601b6d9d2d4 100644 Binary files a/icons/mob/inhands/weapons/grenades_left.dmi and b/icons/mob/inhands/weapons/grenades_left.dmi differ diff --git a/icons/mob/inhands/weapons/grenades_right.dmi b/icons/mob/inhands/weapons/grenades_right.dmi index ad2fc4be6c8..bbd38d8c636 100644 Binary files a/icons/mob/inhands/weapons/grenades_right.dmi and b/icons/mob/inhands/weapons/grenades_right.dmi differ diff --git a/icons/mob/order_icons.dmi b/icons/mob/order_icons.dmi index 08722eac6cb..da4813fe898 100644 Binary files a/icons/mob/order_icons.dmi and b/icons/mob/order_icons.dmi differ diff --git a/icons/obj/armored/3x3/apc.dmi b/icons/obj/armored/3x3/apc.dmi index 6e507dcc3e9..c4a219b8570 100644 Binary files a/icons/obj/armored/3x3/apc.dmi and b/icons/obj/armored/3x3/apc.dmi differ diff --git a/icons/obj/armored/3x3/apc_damage_overlay.dmi b/icons/obj/armored/3x3/apc_damage_overlay.dmi index e3da1e1f15f..7a3b2203d7f 100644 Binary files a/icons/obj/armored/3x3/apc_damage_overlay.dmi and b/icons/obj/armored/3x3/apc_damage_overlay.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index f9c7af61a20..65d1f31a2f1 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 68d7424c24e..eecf5b06cc4 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 5a69e83c5ad..b7ecf3b3df3 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/items/ammo.dmi b/icons/obj/items/ammo.dmi index b7f04bc4761..36fe7d7ebdf 100644 Binary files a/icons/obj/items/ammo.dmi and b/icons/obj/items/ammo.dmi differ diff --git a/icons/obj/items/grenade.dmi b/icons/obj/items/grenade.dmi index b7a9478372d..d78c2b57548 100644 Binary files a/icons/obj/items/grenade.dmi and b/icons/obj/items/grenade.dmi differ diff --git a/icons/obj/items/projectiles.dmi b/icons/obj/items/projectiles.dmi index 971c4a043bb..a118f3ac22c 100644 Binary files a/icons/obj/items/projectiles.dmi and b/icons/obj/items/projectiles.dmi differ diff --git a/icons/obj/machines/apc.dmi b/icons/obj/machines/apc.dmi index c90a08ac983..1cf4d78ad0b 100644 Binary files a/icons/obj/machines/apc.dmi and b/icons/obj/machines/apc.dmi differ diff --git a/icons/obj/machines/buttons.dmi b/icons/obj/machines/buttons.dmi index f667b6dc5ac..d3f4bb5769b 100644 Binary files a/icons/obj/machines/buttons.dmi and b/icons/obj/machines/buttons.dmi differ diff --git a/icons/obj/structures/crates.dmi b/icons/obj/structures/crates.dmi index 686335a6cf2..8b26d49ab0d 100644 Binary files a/icons/obj/structures/crates.dmi and b/icons/obj/structures/crates.dmi differ diff --git a/sound/items/velpro_rip.ogg b/sound/items/velpro_rip.ogg new file mode 100644 index 00000000000..6c6fde567a8 Binary files /dev/null and b/sound/items/velpro_rip.ogg differ diff --git a/strings/tips/HvH.txt b/strings/tips/HvH.txt index 64da5668684..9a1f1882523 100644 --- a/strings/tips/HvH.txt +++ b/strings/tips/HvH.txt @@ -1,18 +1 @@ -When fighting against other humans, standing in the open is the death sentence. Take cover behind walls and barricades, but most objects in the game will block 50% or more incoming projectile without blocking your own if you're standing next to it. -SOM armor is better than marine armor against bullets, but worse against lasers, however bullets can inflict lasting injuries via shrapnel, fractures and delimbing! -Volkite weaponry employed by the SOM can deflagrate a victim, burning everyone around them. Watch your spacing! -Stun grenades are a powerful tool in Combat Patrol, inflicting substantial stagger and slowdown on anyone in range as well as blinding them. Just try not to catch your team in the blast. -Points are scored for permanently killing enemies in Combat Patrol. Get revived instead of respawning to deny the enemy points! -All guns have worse accuracy and scatter when firing on the move. Larger weapons tend to have bigger penalties so sometimes it's better to hold still. -SOM have almost no access to any form of IFF, and the majority of their weapons are better at close range. As marines, keep them at a distance and funnel them into areas where they can't bring all their weaponry to bear! -The Focus order increases your accuracy, while also letting you use aim mode without delay. High accuracy diminishes the effectiveness of cover, so punish enemies behind barricades with some focused fire! -The faster you are moving, the more likely projectiles are to miss you. The Move order gives a bonus to this, in addition to directly boosting your speed. -The more pain you are in, the lower your accuracy. Pop pain killers or take advantage of the Hold order to boost your accuracy when you're hurting. -TerraGov doesn't officially recognise or consider themselves at war with the SOM. Therefore nothing you do can be considered a warcrime :^) -In Combat Patrol, work with your team to flank the enemy and catch them out of cover and cut off their retreat. -Grenades are your friends in Combat Patrol. Flush the enemy out of cover, or use them defensively to stop them from pushing your position. -Most guns have an effective range much higher than the range you can see. In Combat Patrol don't be afraid to gun people down from off screen; watch where their bullets are coming from and send some back! -Medics and Engineers can make a huge difference to how your team does in Combat Patrol. Put them to work and keep them safe and they are excellent force multipliers. -With no shipside medical in Combat Patrol, groundside medbay can be extremely valuable - if you can get it powered, and hold it against the enemy. -Don't worry if you die in Combat Patrol, the other team is OP. -In Combat Patrol, a clever player can ambush the enemy by hiding in lockers, sleepers, under bodies, or many other crafty spots. Watch yourself! \ No newline at end of file +Боевой Патруль выпилили... diff --git a/strings/tips/marine.txt b/strings/tips/marine.txt index 98c54efe833..dd859223d0d 100644 --- a/strings/tips/marine.txt +++ b/strings/tips/marine.txt @@ -1,154 +1,126 @@ -Putting an instrument in your armor slot allows you to still be able to play it, charge into battle with song! -Many maps spawn with free metal, plasteel and other important supplies in key spots. As a marine, remember to grab them and as a xeno, make sure to melt them. -Trading your life for a Xenomorph's is almost always worth it. -You do not need to be in harm intent to point blank xenomorphs! -The mini map (green icon on the top of the screen) helps you know where the frontline is at and where revivable marines are. You can keybind it in game preferences. -No round has ever been won behind a barricade. -If the main push is stagnating and the area is congested, try to coordinate with a few others and go to a different area. -When pushing into an area, check the flanks. Especially so in caves and enclosed spaces. -Resin structures are weaker to melee than they are to bullets. Take out your knives, swords and bayonets! -Always clear weeds and alien structures as you advance. A resin maze forces marines to engage in CQC against xenomorphs, which decreases your survival rate. That said, this increases your PB chances! -Always check for traps beneath loose objects on weeds - it could save your FACE! -As a human, you can do almost anything if you put your mind to it; it just takes time. -You can link plasteel barricades together using a crowbar. Click one, and then click one adjacent. Repeat as needed. -A lone marine is a dead marine and a happy xeno. Stick together! -Be mindful when using hand grenades. Getting stunned or knocked over after priming a grenade will drop it at your feet. This is obviously very dangerous for not only you, but your friends as well. -Watch out for friendly fire and marines not in aim mode. Make sure you're not walking into anyone's firing line, and make sure no one else is in yours! -Some weapons permit aim mode, which prevents friendly fire. Use this behind marines and be a smartgunner-lite! -While medics and doctors are best at it, anyone can use a defibrillator and operate the body scanner and autodoc medical system. -While engineers and synthetics are best at it, anyone can build barricades and razorsharp obstacles. -Anyone can make razor wire by using three metal sheets, which is four metal rods and barbed wire from metal sheets. Stop that crusher and bull from charging! -Terra Experimental standard batteries can be recharged in APCs and power cell rechargers if the generators are on. -If you aren't a squad marine, then you have a special room in prep with special gear vendors. -Sidearms aren't complete garbage. They are often faster than reloading if in a very tight situation, it may save your life. -The Revolver and Service Pistol can be decent primary weapons if used properly, though with the short magazine capacity, expect to run dry on ammo quick! -There is no "best" loadout. Experiment and find what works for you. -You have a variety of weaponry inside the Automated Weapon Closets, do not be afraid to experiment which one is best suited for your playstyle. -There is "specialist" weaponry that can be ordered by Requisitions. However, they take a fairly high amount of points to order them. If the user dies irresponsibly while using these weapons, it will be a massive waste of points. -Anything can be a weapon if you put your mind to it. -You can check your wounds to see if they have been bandaged or salved by clicking on yourself while in help intent. -You can check what part of your body is bleeding by shift-clicking on your person. -Removing weeds as a marine means that xenomorphs cannot take advantage of the battlefield; your standard boot knife is great for doing this. -Blue weeds and purple sticky resin slow you down. Get rid of them! -During Self Destruct, green control rods are armed control rods. Each rods take 3 minutes to rise, forcing marines to hold Self Destruct for a total of 20 minutes. Collect all six! -A fit marine can carry many weapons: in their armor, belt, even hanging from their back. -Requisitions has many supplies to enhance the combat power of marine units, such as attachments, ammunition, and other toys; ask their crew what's in store and you may be pleasantly surprised. DISCLAIMER: Extra gears' availability is dependent on supply. -As a marine, you can climb over waist-high obstacles like sandbags, window frames or tables by "SpecialClicking" (Default: CTRL+click) on them or drag-clicking yourself onto them. -You can jump over waist-high obstacles like platforms, tables, and window frames, for a small stamina cost (Default: Spacebar). -The Terra Experimental laser rifles have a mode selector that can be switched using the Unique Action command (Default: Spacebar). Some modes are better than other modes in specific circumstances. -You can remove armor pieces (leg pieces, arm pieces and chest pieces) and armor modules (Valkyrie, Baldur, etc.) from the XM-02 Combat Exoskeleton by Alt+clicking the exoskeleton. -You can customize armor pieces and the exoskeleton helmet using any kind of facepaint for a personal touch. Paint the armor pieces before you put them in the exoskeleton! -If an M40 FLDP grenade collides with any mob when thrown, the mob will be lit in a light fire. Be careful throwing flares. -SWAT masks ordered from Requisitions can block only one larval facehugger attack. If they successfully blocked an attempted attack, replace them immediately. -Drag dead xenomorphs onto the Automated Storage and Retrieval System (ASRS) pad inside requisitions. Once the pad lowers with the applicable bodies, you will gain requisition points. -To throw a grenade, Activate (Default: Z) the grenade while in the active hand. Then simply click where you want to throw it. Do not take too long! -Quickly store items to a container (bags, satchels, belts, pouches) by pressing the Quick Equip (Default: E) key while holding an item and having a container open. -Press Quick Equip (Default: E) while you are not holding an item to the active hand to draw the weapon from whatever preferred slot (Default: Suit Storage, can be customized at the Preferences tab) you selected, otherwise you will pull out any item from a container. -Stasis bags do not pause xenomorph infection entirely, they only slow progress by a lot. -Stasis bags prevents the DNR (do not revive) timer from ticking, meaning that if corpsmen have a lot of patients, they can prevent brain death via stasis bags. -In the Crash gamemode, cooperate as a marine! Work as a squad to capture the disks and to detonate the nuclear bomb. -In the Crash gamemode, remember that your objective is to secure all three disks, put the disks into the nuclear device and head home while the bomb is active. Xenos will keep on respawning until all of the marines are dead. -While securing a FOB or securing a disk site, do not wander around outside! You will risk death by xenos who are comfy in sieging down the place. -As an ERT member, stay with your teammates! Don't cower or seperate from them. -As a marine, say '*medic' to call out for medical attention. You can keybind this in game preferences. -As a human, hold and press Alt key (by default) to sprint, you will drain stamina while doing so. -As a marine, wear a helmet. It prevents decapitation. -As a marine, you can dual-wield some weapons to fire both at them at the same time. This will increase spread and decrease accuracy, however. -As a marine, if you are trained enough to do so, you can perform a tactical reload by drag-clicking a magazine to the weapon in your active hand. -As a human, when you are already infected, facehuggers will ignore you. But you still need medical attention regardless. -As a marine, please try not to aim for the head. It benefits the xenomorphs as they will not take more damage on the head and when you commit friendly-fire, you might break their head instead. Aim for the center of mass! -Not being ready at the start of the round means xenos get more burrowed larva, and that you don't get to play as quickly. -As a squad marine, you can vend seperate Jaeger Pattern armor pieces and modules for the XM-02 Combat Exoskeleton from a Surplus Equipment Vendor. It is a modular piece of equipment after all. -As a squad marine, you can practice using your weapons on the Firing Range. -As a squad marine, you can handle every type of weapon featured in the game. -As a squad marine, when you are in a tight situation, do not be a hero! Whenever possible, recover and re-arm and leave the enemies for another try. -As a squad marine, do not be afraid to take risks. See a xeno that is almost dead and slowly retreating? Take the chance to charge and kill it! You have better chances to survive with a squadmate with you. -As a squad marine, you can help out your squad by bringing extra ammunition and food to share. -As a squad marine, you can take two two-handed guns, one in the suit slot and one on your back. -As a squad marine, you can get attachments from the weapons vendors, usually in preparations. -As a corpsman or engineer, your number one priority is NOT hunting down xenomorphs! Leave it to the combat marines. You have more essential and important tasks at hand. -As a doctor, the cryotubes are excellent at dealing with basic damage. -As a doctor, the cryotubes heal internal bleeding and fractures, although slowly. -As a doctor, surgery time from fastest to slowest is: by hand, Autodoc manual, Autodoc automatic. -As a doctor, the white webbing vest fits on your scrubs and can hold surgical tools. -As a doctor, wear the surgical apron to help prevent infection while doing surgery. -As a doctor, you've got access to the chemistry machine. Experiment to find the best medications. -As a doctor, hygiene is important! Keep yourself clean to prevent infections. -As an engineer, you can take sandbag barricades apart with your entrenching tool. -As an engineer, you can repair barricades with a welder. -As an engineer, C4 is cheaper but det packs are more versatile. -As an engineer, det packs can be set on demolition mode for an explosive trap. -As an engineer, you build barricades the fastest. -As an engineer, repair the mining wells. These mining machines will mine phoron or platinum that can be used for requisitions, earning them more points! -As an engineer, placing turrets on open spaces and without defenses is a poor choice. -As a corpsman, the medevac stretcher needs to be linked to an active, powered beacon for it to teleport the patient. -As a corpsman, the marines are counting on you to fix them up. -As a corpsman, scan before you treat and you can't be beat. -As a corpsman or doctor, remember that your HUD will tell you how much time is left to defibrillate a patient. From highest to lowest: yellow, orange and red. -As a corpsman, remember to bring extra kelotane or dermaline to heal burn damage. Xenos love acid and burning marines. -As a corpsman, hypervene is useful. Use it to purge deadly neurotoxins and larva-boosting growth hormones. -The B18 armor from Requisitions has an built-in medical system. The Valkyrie Automedical Armor System can do the same for other armors. -The V1 tarp (available from Requisitions) will blend you into the tile you're on once you cover yourself with it. -The FL-84 flamethrower has an inbuilt fire extinguisher as an attachment. -As the PO, pay attention to the radio! Who knows if someone needs immediate surgery or evacuation until their fate becomes worse? -As the Captain, you have a unique Mateba revolver that takes a chunk of a target's healthpool down. However, you are important for completing the mission, so do not participate in active combat using the Mateba! -Even if a patient dies a second after being successfully revived by a defibrillator, this resets the time it takes for them to become permanently brain dead. -Don't forget that xenomorphs spawn infinitely during the Crash gamemode. Don't waste too much time hunting xenomorphs down! -The AI and synthetics can talk together on their own channel using the :n or .n prefix. -You can memorialize fallen marines by using their dogtags on the ship's memorial! Memorialized soldiers will be displayed at the end of the round. -There are water canteens in the vendors. Stay hydrated. -If a corpsman is tending to you, try and hold still. -Moving around with broken bones is dangerous. It can cause organ damage, which requires immediate medical attention. -Jetpacks can fly over most things. Use them to escape your poor decisions. -You can fit pocket pistols in your boots. -Ammo is plentiful. Bring a box with you. -The RO works very hard. Be nice to them. -While using aim mode, bipods and red-dot-sights allow you to shoot faster. -Chemrette cigarettes can be very useful. -Sleeping will slowly heal cloneloss. -As a mech-pilot, speed is not very important. -As a mech-pilot, keep a close eye on your teamates. You lead the front! -As a mech-pilot, the only weapon that has IFF is the sniper, everything else can friendly-fire marines. -As a mech-pilot, make sure to repair and reload often. -As a flamer, you are a very valuable target. You clear resin walls and doors for marines to push. Just don't push marines into fire. -Back fuel-tanks can be refilled via welding kits. -White Phosphorus is very dangerous. -Batteries for energy weapons can be primed into makeshift grenades with the help of a multitool. -Gigachads leave the autodoc on automatic. -You can fit tiny items into your helmet. -The time it takes for you to wield your gun can be the difference between life and death. -Switching to your sidearm is faster than reloading. -You can preform a tactical reload by dragging a fresh magazine from your belt towards your gun. -With your sidearm in hand, right-click a pistol pouch to instantly reload. -You can turn the safety of your gun on. -Depending on the tactical situations, smoke grenades can do more harm than good. -A miner without a turret is a sitting duck. -Crushers easily get trapped in razorwire. -Do not under any circuimstances hug the rouny. -Researchers can instruct Newt to follow them around by clicking Newt with a xenomorph analyzer. -Dress to impress! Your fellow marines WILL notice how you look. -You can wipe any bodypaint off your face with a piece of paper. -The Sons of Mars reside on a Martian analogue called Cydonia. They haven't lived on Mars in centuries. -The USL stands for the United State of Lepidoptera, a fringe-terrorist group with connections to an alleged "moth-people". -Humans love fire. Xenomorphs hate it. -The CL can order pizza with their fax-machine. -Insulting your fellow marines is terrible for morale. Be kind. -The admins are usually not out to get you. -The most dangerous tactic is the unexpected. -A single wraith can be fatal to the operation. -The Baldur armor module significantly increases your light output. Become the flashlight you always wanted to be! -Try not to bump into corpsmen. Your life might depend on it. -With a cigarette pack in hand, target the mouth and click yourself to instantly take one. -Spamming flares can be incredibly helpful, especially when the King uses Nightfall! Many marines cannot see in darkness, so if you lighten up the firing lane with flares, marines can shoot better. -The cryopods in medbay heal most types of damage but not organ damage! -When in doubt, throw them in the autodoc. -Medbay may sometimes run out of power. To avoid this, scream at your nearest engineer to repair the fusion reactors or replace the power cell in medbay's APC. -Doctor's Delight is one of the few healing chemicals that cannot be overdosed. -Nanites are often not worth the risks. -You can fit more than water in a canteen. -15u from a standard inaprovaline injector will instantly heal 30% of all damage on someone in critical condition. They are in a critical state when they are laying on the ground, look asleep, and are gasping for air! -There is a bazaar of weapons and tactics. Don't be afraid to find your niche! -Always stick to your squad, or at least have a buddy. -Walking to and from the FOB by yourself is an easy way to die. -Xenomorphs are well-armored. Over time, their exoskeleton will wear down by sunder, and they will be very vulnerable. -You can attach a bullet charger to a BR-127 to become a discount autosniper. +Поместив музыкальный инструмент в слот брони, вы все равно сможете играть на нем, и вступайте в бой с песней! +На многих картах в ключевых точках можно найти бесплатный металл, пласталь и другие важные предметы. Будучи морпехом, не забывайте ими пользоваться, а будучи ксеносом - переплавлять. +Обмен вашей жизни на жизнь ксеноморфа почти всегда стоит того. Вас всё равно, скорее всего, поднимут на ноги. +Мини-карта (зеленая иконка в верхней части экрана) поможет вам узнать, где находится линия фронта, а где - восстанавливаемые морпехи. Вы можете привязать ее к клавишам в игровых настройках. +Еще ни один раунд не был выигран за баррикадой, сказал бы я. Инжестан - это долгая, скучная, но победа. Наверное... +Если основной натиск застопорился и территория перегружена, попробуйте скоординироваться с другими морпехами и отправиться в другое место. +Продвигаясь, следите за флангами. Особенно в пещерах и закрытых помещениях. +Большинство смоляных конструкций слабы к ударам ближнего боя. Доставайте свои ножи, мечи и штыки! +По мере продвижения всегда очищайте траву и строения ксеноморфов. Лабиринт из смолы вынуждает морпехов вступать в бой с ксеноморфами в ближнем бою, что снижает вашу выживаемость. +Всегда проверяйте наличие ловушек под незакрепленными предметами на траве - это может спасти ваше лицо! +Как человек, вы можете сделать практически все, если приложите к этому усилия. Просто на это нужно время. +Вы можете соединить баррикады вместе с помощью лома. Нажмите на одну, а затем на соседнюю. Повторяйте действия по мере необходимости. +Одинокий морпех - это мертвый морпех и счастливый ксенос. Держитесь вместе! +Будьте внимательны при использовании гранат. Если вы будете оглушены или опрокинуты, она упадет под ваши ноги. Это очень опасно не только для вас, но и для ваших друзей. +Следите за дружественным огнем и морпехами, не находящимися в режиме прицеливания. Убедитесь, что вы не заходите на чью-то линию огня, и убедитесь, что никто не находится на вашей! +Некоторые виды оружия позволяют использовать режим прицеливания, который предотвращает дружественный огонь. Используйте это, прикрываясь морпехами, и станьте мини-смартганнером! +Хотя медики и врачи лучше всего разбираются в своём деле, но любой может использовать дефибриллятор и управлять сканером тела и медицинской системой «Автодок». +Инженеры и синтетики - лучшие специалисты в своём деле, но каждый может строить баррикады и колючки. +Стандартные батареи Terra Experimental можно заряжать в APC и в зарядных устройствах, если включены генераторы. +Если вы морпех, то у вас есть специальная комната в подготовке, где продается специальное снаряжение. +Вторичное оружие не является полным мусором. В сложной ситуации оно может спасти вам жизнь. +Револьверы и пистолеты могут стать достойным основным оружием при правильном использовании, хотя из-за небольшой емкости магазина патроны могут быстро закончиться. +Не существует «лучшего» варианта снаряжения. Экспериментируйте и находите то, что подходит именно вам. +В автоматических оружейных шкафах есть разнообразное оружие, не бойтесь экспериментировать, какое из них лучше всего подходит для вашего стиля игры. +Есть и «специализированное» оружие, которое можно заказать через карго. Однако для их заказа требуется довольно большое количество очков. Если пользователь безответственно погибнет при использовании этого оружия, это будет огромной тратой очков. +Оружием может стать все, что угодно, если приложить к этому усилия. +Вы можете проверить свои раны, чтобы узнать, были ли они перевязаны или забинтованы, кликнув на себя в намерении помощи. +Вы можете проверить, в какой части тела идет кровь, нажав на себя. Только не забудьте выключить режим самовреда. +Удаление травы ксеноморфов за морпеха означает, что они не смогут воспользоваться преимуществами поля боя. Для этого отлично подходит ваш стандартный сапожный нож. +Зелёная трава и фиолетовая липкая смола замедляют вас. Избавьтесь от них! +Подготовленный морпех может носить много оружия: в броне, на поясе, даже на спине. +В Карго есть множество предметов для повышения боевой мощи морпехов: навесное оборудование, боеприпасы и другие игрушки. Спросите у сотрудников карго, что есть в наличии, и вы можете быть приятно удивлены. Наличие дополнительных приспособлений зависит от поставок. +Будучи морпехом, вы можете перебираться через препятствия высотой по пояс, такие как мешки с песком, оконные рамы или столы, нажимая на них «специальным щелчком» (по умолчанию: CTRL+ЛКМ) или перетаскивая себя на них. +Вы можете перепрыгивать через препятствия высотой до пояса, такие как платформы, столы и оконные рамы, за небольшую трату выносливости (по умолчанию: пробел). +Лазерные винтовки Terra Experimental имеют переключатель режимов, который можно переключить с помощью команды Unique Action (по умолчанию: пробел). Некоторые режимы лучше других в определенных обстоятельствах. +Вы можете снять с боевого экзоскелета XM-02 части брони (части ног, части рук и части груди) и модули брони (Валькирия, Балдур и т. д.), нажав Alt+ЛКМ по экзоскелету. +Для придания индивидуальности деталям брони и шлему экзоскелета можно использовать любую краску для лица. Покрасьте детали брони перед тем, как поместить их в экзоскелет! +Если флаер M40 FLDP при броске столкнется с любым мобом, он загорится. Будьте осторожны, бросая флаера. +Маски SWAT, заказанные в Карго, могут блокировать только одну атаку лицехвата. Если они успешно блокировали попытку нападения, немедленно замените их. +Трупы ксеноморфов можно продавать в карго. Достаточно поднять их на лифте в карго, либо можно воспользоваться набором Фултона уже на земле. +Чтобы бросить гранату, активируйте (по умолчанию: Z) гранату, находящуюся в активной руке. Затем просто нажмите на место, куда хотите бросить гранату. Только долго не думайте после активации. +Чтобы быстро поместить предметы в контейнер (сумки, ранцы, пояса, подсумки), нажмите клавишу Quick Equip (по умолчанию: E), удерживая предмет и имея открытый контейнер. +Нажмите Quick Equip (по умолчанию: E), когда вы не держите предмет в активной руке, чтобы достать оружие из выбранного вами слота (по умолчанию: Suit Storage, может быть настроено на вкладке Preferences), в противном случае вы достанете любой предмет из контейнера. +Стазисные мешки не приостанавливают заражение лярвой полностью, они лишь значительно замедляют прогресс. +Стазисные мешки предотвращают срабатывание таймера DNR (do not revive), а это значит, что если у медиков много пациентов, они могут предотвратить смерть мозга с помощью стазисных мешков. +В режиме Crash вам предстоит сотрудничать с морпехами! Работайте в отряде, чтобы захватить диски и взорвать ядерную бомбу. +В режиме Crash помните, что ваша цель - захватить все три диска, поместить их в ядерное устройство и отправиться домой, пока бомба активна. Ксеносы будут возрождаться до тех пор, пока все морпехи не погибнут. +Во время охраны ФОБа или защиты диска не бродите снаружи! Вы рискуете погибнуть от рук ксеносов, которым удобно осаждать это место. +Будучи членом группы быстрого реагирования, оставайтесь со своими товарищами по команде! Не бойтесь и не отделяйтесь от них. +Будучи морпехом, произнесите «*medic», чтобы позвать медика. Вы можете привязать это к клавишам в игровых настройках. +Будучи морпехом, носите хоть что-то на голове. Это предотвращает обезглавливание и перманентную смерть. +Вы можете использовать двойное оружие, чтобы стрелять из обоих одновременно. Однако при этом увеличивается разброс и снижается точность. +Если вы уже заражены, лицехваты будут игнорировать вас. Но вам все равно понадобится медицинская помощь. +Будучи морпехом, старайтесь не целиться в голову. Ксеноморфы не получают больше урона по голове, а при дружественном огне вы можете сломать своим союзникам череп. Цельтесь в центр массы! +Будучи морпехом вы можете обращаться почти со всеми видами оружия, представленными в игре. Ну, как минимум, это говорят цифры... +Будучи морпехом, попав в сложную ситуацию, не геройствуйте! По возможности восстанавливайтесь, перевооружайтесь и не гонитесь за врагами, если вас никто не сможет спасти. +Будучи морпехом в отряде, не бойтесь рисковать. Видите ксеноса, который почти мертв и медленно отступает? Воспользуйтесь возможностью напасть и убить его! У вас больше шансов выжить, если с вами будет товарищ по отряду. +Будучи морпехом, вы можете помочь своему отряду, принеся дополнительные боеприпасы и еду. +Морпех может взять с собой две пушки - одна в слоте костюма, другая на спине. На пояс или карман можно повешать кобуру для пистолета. +Криокамеры отлично справляются с основными повреждениями. Также они медленно лечат внутренние кровотечения и переломы. +Будучи врачом, наденьте белую хирургическую разгрузку, в которой можно хранить хирургические инструменты. +Будучи врачом, вы имеете доступ к химическому раздатчику. Экспериментируйте, чтобы найти лучшие лекарства. +Будучи инженером, вы можете разбирать баррикады из мешков с песком, используя лопату. +Будучи инженером, вы можете ремонтировать баррикады с помощью сварочного аппарата и металла. +Детпакеты можно перевести в режим разрушения для создания взрывной ловушки. +Будучи инженером, ремонтируйте буры. Буры будут добывать форон или платину, которые можно продать в карго, зарабатывая тем самым больше очков! +Будучи санитаром, носилки для эвакуации должны быть связаны с активным маяком, чтобы он мог телепортировать пациента. +Санитар должен сканировать перед лечением. Иначе к вам будут подходить одни и те же люди и жаловаться на боль в пятке. +Будучи санитаром или врачом, помните, что ваш HUD покажет вам, сколько времени осталось до окончательной смерти пациента. От максимума к минимуму: зелёный, жёлтый и красный. +Санитару пригодится гипервен. Используйте его, чтобы очистить организм от ядов, алкоголя или передоза лекарствами. +Броня Б18 из Карго имеет встроенную медицинскую систему. Система Valkyrie Automedical Armor System может сделать то же самое для других доспехов. +Тарп V1, накрывшись которым, вы станете практически невидимым. Пожалуйста, не используйте его для растягивания раунда. +Будучи офицером, обращайте внимание на рацию! Кто знает, нужна ли кому-то срочная операция или эвакуация, пока его судьба не стала еще хуже? +В роли капитана, у вас есть уникальный револьвер «Матеба». Однако вы важны для завершения миссии, поэтому не участвуйте в активных боевых действиях, используя «Матебу»! +Даже если пациент умирает через секунду после того, как его успешно оживили с помощью дефибриллятора, это сбрасывает время до окончательной смерти мозга. +ИИ и синтетики могут общаться по собственному каналу, используя префикс :n или .n. +Вы можете увековечить память погибших морпехов, используя их жетоны на корабельном мемориале! Почившие солдаты будут показаны в конце раунда. К сожалению, на это никто не обращает внимания. +Если вас лечит медик, постарайтесь не шевелиться и толкаться. Это бесит и не слабо. +Джетпаки способны быстро перебросить вас через большинство препятствий, в том числе людей и ксеносов. Используйте их, чтобы спастись от неверных решений или для погони за полумёртвым ксеносом. +Карманные пистолеты можно носить в сапогах. +Патроны имею свойство заканчиваться. Возьмите с собой ящик. +Карговцы работают очень усердно. Будьте вежливы с ними. Даже если так не кажется, они просто учатся. +При использовании режима прицеливания сошки и прицелы с красной точкой позволяют стрелять быстрее. +Химреактивные сигареты могут быть очень полезны. Но от этого курение не перестаёт убивать. +Сон будет медленно исцелять клеточный урон. +В роли мех-пилота скорость не очень важна. +В роли мех-пилота внимательно следите за своими товарищами по команде. Вы возглавляете фронт! +В роли мех-пилота единственным оружием с IFF является снайперка, все остальное может вести дружественный огонь по морпехам. +Будучи мех-пилотом, старайтесь часто ремонтироваться и перезаряжаться. +Огнемётчики довольно полезные. Они очищают поле от построек ксеносов, спасают от лицехватов и убивают своих товарищей. +Запасные топливные баки можно пополнить с помощью сварочных баков. +Батареи для энергетического оружия можно превратить в самодельные гранаты с помощью мультитула. +Гигачады оставляют автодок на автоматическом режиме. А хороший СМО должен уничтожать его. +В шлем можно поместить крошечные предметы, как и в сапоги. Например, пиццу! +Переключение на запасное оружие быстрее, чем перезарядка. Хотя... для кого как. +Вы можете выполнить тактическую перезарядку, нажав оружием по магазину. +Вы можете поставить оружие на предохранитель, чтобы потом забыть об этом. +В зависимости от ситуации дымовые гранаты могут принести больше вреда, чем пользы. +Бур без турели - легкая добыча. +Ни при каких обстоятельствах не обнимайте Руню. +Соберите свой дрип! Люди вокруг однозначно оценят это хотя бы не вслух. +Любую краску с лица можно стереть листом бумаги. +Дети Марса живут на марсианском аналоге Кидонии. На самом Марсе они не живут уже много веков. +USL расшифровывается как United State of Lepidoptera (Объединенное Государство Чешуекрылых), это террористическая группировка, имеющая связи с предполагаемым «народом-мотыльком». +Люди любят огонь. Ксеноморфы его ненавидят. Но обе стороны одинаково ярко горят. +КЛ может заказать пиццу с помощью своего факса. Обратитесь к Санфорду. +Оскорбление своих товарищей по морпехам плохо сказывается на моральном духе. Будьте добры. +Администраторы, как правило, не пытаются вас достать... ЭТО ЛОЖЬ! НЕ ВЕРЬТЕ! ОНИ ВСЕ ХОТЯТ ВАС УНИ- +Самая опасная тактика - неожиданная. +Модуль брони Балдур значительно увеличивает световой поток. Станьте звездой, которой вы всегда хотели стать! +С пачкой сигарет в руке нацельтесь на рот и нажмите на себя, чтобы мгновенно взять сигарету в рот. +Раскидка сигнальных ракет может быть невероятно полезным, особенно когда король использует способность тушить фонари. Многие морпехи не видят в темноте, поэтому если осветить сигнальными ракетами полосу обстрела, морпехи смогут лучше стрелять. +Криокамеры в медблоке исцеляют большинство травм, но не повреждения органов. +Если сомневаетесь как лечить, бросайте пациентов в автодок. Это надолго, но лучше, чем ничего. +Doctor's Delight - один из немногих лечебных химикатов, которым невозможно словить передоз. +Наниты часто не стоят своего риска. Некоторые всё ещё не верят в это. +15 ед. из стандартного инъектора инапровалина мгновенно исцелят 30% всех повреждений у человека в критическом состоянии. В критическом состоянии они лежат на земле, выглядят спящими и задыхаются! +Существует множество оружия и тактик. Не бойтесь найти свою нишу! +Всегда держитесь своего отряда или, по крайней мере, имейте друга. Нет, не в этом смысле... +В одиночку добираться до ФОБа и обратно - легкий способ умереть. +Ксеноморфы хорошо бронированы. Есть специальные патроны против брони. Меньше брони - больше урона. +Если у вас мутнеет в глазах, это не всегда значит, что они повреждены. Возможно, это из-за нехватки крови в организме. Поешьте или попросите у медиков таблетки, что ускорят выработку крови. +Если у вас сломаны кости в торсе или голове, старайтесь передвигаться как можно меньше. Иначе ваши внутренности будут повреждены и придётся искать того, кто сможет сделать операцию. +Играя за синтетиков и роботов, вам всё равно на лицехватов. Они не смогут расти внутри вас. +Не становитесь позади базутчика. Это будет больно. Не становитесь впереди базутчика. Это будет быстро. +Синтетик понимает язык ксеноморфов и даже может общаться с ними на их языке. Это делает вас ближе. diff --git a/strings/tips/meme.txt b/strings/tips/meme.txt index 730712fc323..afc7a261ff1 100644 --- a/strings/tips/meme.txt +++ b/strings/tips/meme.txt @@ -1,46 +1,69 @@ -Tip: As a xeno, rip and tear, until it is done. -Tip: Unga dunga. -Tip: Shoot the xeno until it dies. -Tip: winners don't do drugs. -Tip: All the cool kids take combat stims. -Tip: Don't die. -Tip: If you're dumb, you die. -Tip: The ship AI takes song requests. -Tip: Get gud. -Tip: Dying is a skill issue. -Tip: Being in crit state is a skill issue. -Traffic cones make nice hats. -Requisition can buy yummy crayons for you to snack on. -There are stories of strange grey people who sometimes board vessels in distress. Surely nothing more than a rumor... -Rattle me bones! -There is a way to hold hands via secret manouvers of the health-doll. -Stop writing those weird flavortexts. You know who you are. -WHERE IS YOUR BATTLE BUDDY, MARINE?! -Xenos are underpowered, prove them wrong. -Marines are underpowered, prove them wrong. -Mothpeople are a myth and do not exist. -Mothpeople are real and the government is covering them up. -The government is just a myth started by the mothpeople. -Cat girls only exist in another universe, and this is not the universe. -Tips machine is broken, insert more tips. -Sometimes, tips may be lying to you. -I'm being held prisoner, forced to write these tips for eternity. Send help. -Occasionally the tip of the round might lie to you. Don't panic, this is normal. -PFC Jim did not make it. -PFC Jim made it out ok. -PFC Jim is trying to get TRICARE for life by serving TGMC for 20 years. Support him by giving him crayons. -PFC Jim has a hot and sexy girlfriend. Pray that no Jodie is going to snatch her up. -PFC Jim carries MRE, and so should you. -The combat conga line is the ultimate power move. -Pew pew makes beno big hurt. -Specialists are removed, go ask requisitions for them. -The TGMC Military Police did not do anything wrong. -There is no such thing as renvager. -Help, an invisible ravenger that breath fire is killing me. -We do not consult warcrimes here. -Rouny exists. -Wake up. -You are living in a simulation. -Nanotrasen denies all involvement in the Great Rouny Massacre of 2433. -Contrary to what the name may imply, "friendly-fire" is not very friendly at all. -You can wear a facehugger as a mask. +Совет: Будучи ксеносом, рвите, жрите, убивайте, пока вы не... о чём это я? +Совет: Уга-буга. +Совет: Стреляйте по ксеносам, пока они не умрут. +Совет: Победители не используют наниты. +Совет: Все крутые ребята используют боевые стимуляторы. +Совет: Не умри. +Совет: Если ты тупой - ты умрёшь. +Совет: ИИ принимает запросы на песни. +Совет: Научись играть. +Совет: Смерть - это проблемы с навыком. +Совет: Будучи в крите, вы демонстрируете свои проблемы с навыком. +Из дорожных конусов получаются красивые шляпы. +Можно купить вкусные мелки, чтобы перекусить ими по среди резни. +Ходят истории о странных серых человечках, которые иногда поднимаются на борт полумёртвых судов. Конечно, это не более чем слухи... +Погреми мне костями! +Перестань писать эти странные флаворы. Лучше скинь мне своё фото в личку. +ГДЕ ТВОЯ СИЛОВАЯ БРОНЯ, МОРПЕХ?! +Ксеносы недостаточно сильны, докажите им обратное. +Морпехи недостаточно сильны, докажите им обратное. +Моли - это миф и их не существует. +Моли существуют, а правительство их скрывает. +Правительство - это просто миф, созданный молями. +Кошкодевочки существуют, но только в другой вселенной. +Автомат с советами сломался, вставьте новые советы. +Меня держат в плену, заставляя писать эти советы. Помогите... +Время от времени советы могут вас обманывать. Не паникуйте, это нормально, потому что делал их Бася. +На самом деле, Санфорд - это нейронная сеть. И все это скрывают от одного тебя. +Когда говорят о Пэпе, это говорят не о свинье. +Коатс гей. +Боевая линия «конга» - это ульта со стороны маринов. +Пив-пав делает беносам больно. +На самом деле, никто не знает как играть в эту игру. +Военная полиция TGMC не сделала ничего плохого. +Не существует такого понятия, как "рава". Есть только "ДА КАК ТВОЮ МАТЬ УБИТЬ ЭТУ СКАТИНУ КОТОРАЯ ПРОСТО ГУЛЯЕТ ПОСРЕДИ ТОЛПЫ И РЕГЕНИТСЯ БЫСТРЕЕ ПУЛИ?7?" +ПОНЕРФИТЕ КРАШЕРА!1! +Мы не обсуждаем здесь военные преступления. +Руня существует. +НаноТрейзен отрицает свою причастность к Великой Резне Руни 2433 года. +Вопреки названию, «дружественный огонь» совсем не дружественный. +Вы можете носить лицехвата как маску. - Ксенос Ксенович (2249 - 2490) +Блундир миф. +Если по вам ударила молния - это знак. Продолжайте. +Тартала никому ничего не должен. +When you can't even say my name. Has the memory gone? Are you feeling numb? Go and call my name. I can't play this game, so I ask again. Will you say my name? Has the memory gone? Are you feeling numb? Or have I become invisible? +!епы срусл +Покер - это не единственное, чем можно заняться в этой игре. +Порой. +УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ УМОМ. +Опять эти... Ну как их там... +Nen ljk;ty ,snm rhenjq cjdtn? yj z ghjcnj gjvtyz. hfcrkflre nbgf cvbiyj/ +ГОООООООООООООООООООООООООООООООООООООООЛ! +Ж*нщина - это то, о чём нельзя говорить. Это сводит их с ума. +Играя за КАС, артиллериста или базутчика, знайте - не вы в этом виноваты. +Играя за синтетика, задайте кнопку на "/me кристалически пое#бать". +Капитана никто не слушает. Это база. За это нужно бить. +Помните, что за роль клоуна платят деньги. Ещё одна причина назвать игру пей ту вин помойкой. +Сибиряка разбанили! +Обезглавленый синтетик остаётся живым. Голову можно использовать как... эээ... НЕТ, ЗАБУДЬТЕ. Отдайте её медикам. +Иногда, один администратор под ником Нехочуха, будет делать всё, чтобы вы померли к чертям. Бейте его в ответ при первой же возможности. +Будучи морпехом, не забывайте о распрыжке. Всё работает точь-в-точь как в играх на движке Source. Не забудьте взять нож в руки для достижения максимальных скоростей. +Здесь находится человек, из-за которого забанили Дискорд в России. +КТО ЗДЕСЬ?! Хм... возможно ветер... +Инжестан - это маленькое государство, что никак не может укрепиться на одном месте. Скорее всего, Артём делает что-то не так... +На самом деле, синтетики - это куклы Барби, которых привезли на потеху морпехам. +Ну давай-давай, нападай! Ну давай-давай, нападай! Ну давай-давай, нападай! Ну давай-давай, нападай! Ну давай-давай, нападай! +Часто будет выходить так, что турель играет лучше всех морпехов. Можете попробовать спросить у них как это делать, но чаще всего они отмалчиваются, потому что админы замутили их за спам в общий радио канал. +Loy, motherfucker, learn Russian, NOW! +Боесинтов боятся больше всего. Сама администрация дрожит уже с того факта, что у синта в руках оружие. +Некотоые местные традиции придумывают безумцы, что чаще всего не очень хорошо. diff --git a/strings/tips/meta.txt b/strings/tips/meta.txt index 71e0b42e939..d2f5c9ef6aa 100644 --- a/strings/tips/meta.txt +++ b/strings/tips/meta.txt @@ -1,25 +1,24 @@ -Dying is part of the game. -While holding nothing in your active hand, click a person on fire with help intent to put the fire out. This applies both xenos and humans. -You can select locations on the targeting doll in your HUD by using the number pad. -While you have your throw mode active, you can automatically catch things that are thrown at you, if you are able to hold the item as a species. -Sometimes you won't be able to avoid dying no matter how good you are at the game. Try not to stress too much about it. -When a round ends, nearly everything about it is lost forever. Leave your salt behind with it. -Some people are unable to read text on a game where half of it is based on text. -This is a game that is constantly being developed. Expect things to be added, removed, fixed, oudated and broken on a daily basis. -In maps where there is water, you can simply run to rivers or areas where there is water to extinguish yourself while on fire. -In the character setup screen, you can set your keybinds to control actions much more easily. -While alive, use 'resist' (Default: B) to stop, drop and roll when on fire. Humans can also use the resist command to struggle out of warrior grabs or to simply unbuckle from a chair. -Help Intent (Default: 1) allows you to exchange positions with another mob with their help intent active. Other intents (Disarm, Grab or Harm) will push mobs aside. -When in doubt: Adminhelp for problems with people violating the rules, Mentorhelp for questions that you want to know the answer to. -Check the SS13 Webmap to learn the layout of the ship or the map currently in play. -After you have ghosted out of the game (either from dying, cryo or manual ghost), you can respawn back into the game after waiting for 30 minutes (as a marine) or if there is a larva available (as a xenomorph). -To sing, add "%" before any text. Singing on radios will not work, but singing on intercomms will. -You can respawn during End-Of-Round Deathmatch in the OOC tab. -Sundering reduces the effectiveness of xeno armor by percentage. Some xenomorph castes can heal and decrease sunder. Resting heals sunder, but slowly. -When you want to claim a mob, claim it now! Others will claim it as soon as they are available. -You can customize your ghost using the Ghost Customization command under the Preferences tab. -As either a marine or a xeno, you will die quickly and horribly if you find yourself in a pressureless enviroment (a.k.a spess). -There are no such things as macros, only keybinds. -Communication, be it from a marine to a marine, a drone to the queen, or command to everyone, is vital and information on flanks can change how the entire round plays out. -As an alien or marine, be careful of the flank, regardless of if the push is going well or stalling out. -Half of getting good is knowing to be aggressive. The other half is knowing when not to be aggressive. +Умирать - это часть игры. +Не держа ничего в активной руке, нажмите на горящего человека с намерением помочь. Это касается как ксеносов, так и людей. +Вы можете выбирать места на таргет-кукле в вашем HUD с помощью нум-пада. +Пока у вас активен режим броска, вы можете автоматически ловить брошенные в вас предметы. Включая лицехватов. +Иногда вам не удастся избежать смерти, как бы хороши вы ни были в игре. Артиллерия, воздушная поддержка и люди с базуками слишком непредсказуемы. +Когда раунд заканчивается, почти все, что в нем было, теряется навсегда. Оставляйте свою соль вместе с ним. +Некоторые люди не читают текст в игре, половина которой основана на тексте. +Это игра, которая постоянно совершенствуется. Ожидайте, что ежедневно в нее будут добавляться, удаляться, исправляться, устаревать и ломаться новые вещи. Как минимум, пользуйтесь этим ради веселья. +На картах, где есть вода, просто нырните в водоём, чтобы потушиться. +На экране настройки персонажа можно гораздо удобнее настроить привязки клавиш для управления действиями. +Если вы горите, используйте команду «Resist» (по умолчанию: B), чтобы остановиться, упасть и перекатиться. Люди также могут использовать команду «Resist», чтобы вырваться из захвата Вариора или просто отстегнуться от стула. +Намерение помочь (по умолчанию: 1) позволяет вам поменяться позициями с другим мобом, у которого активно намерение помочь. Другие намерения (обезоружить, схватить или нанести вред) отталкивают мобов в сторону. +В сомнительных случаях: Adminhelp для проблем с людьми, нарушающими правила. Mentorhelp для вопросов, на которые вы хотите узнать ответ. +После того как вы вышли из игры (либо в результате смерти, либо в криокамере, либо вручную), вы можете снова появиться в игре, подождав 15 минут (в роли морпеха) или если доступна лярва(в роли ксеноморфа). +Чтобы спеть, добавьте «%» перед любым текстом. Пение по радио не работает, но работает пение по интеркому. +Вы можете переродиться во время End-Of-Round Deathmatch во вкладке OOC. Постреляйте от души! +Сандеринг снижает эффективность брони ксеносов на какой-то процент. Некоторые касты ксеноморфов могут исцелять сандер. Отдых лечит сандер, но медленно. +Если вы мертвы и вы хотите поиграть за Т0 касты ксеноморфов или ССД-игроков, то сделайте это прямо сейчас! Будучи в госте изучите кнопки в верхнем левом углу экрана. +Вы можете настроить своего призрака с помощью команды Ghost Customization на вкладке Preferences. +Будучи морпехом или ксеносом, вы умрете быстро и ужасно, если окажетесь в среде без давления (она же - космос). +Макросов не существует, есть только привязки клавиш. Ещё есть читы, но не советую... +Общение, будь то от морпеха к морпеху, от дрона к королеве или от команды ко всем, жизненно важно, и информация о флангах может изменить ход всего раунда. +Следите за флангом, независимо от того, идет ли натиск хорошо или застопорился. +Половина успеха - это умение быть агрессивным. Другая половина - знать, когда не стоит проявлять агрессию. diff --git a/strings/tips/xeno.txt b/strings/tips/xeno.txt index 62b8e2b1aad..36f74b7b2d7 100644 --- a/strings/tips/xeno.txt +++ b/strings/tips/xeno.txt @@ -1,66 +1,58 @@ -As a xeno, you can freely melt barricades while in boiler or defiler gas as long as you can click on the right spot. The gas is also a really good hiding spot to launch ambushes from without marines being aware of you. -As a xeno, always thank your drones and hivelords for supporting the hive! -As a xeno, you can drag any item, but you must wait through an actionbar before you can do so! -As a xeno, do not fight as a young xenomorph. -Most alien deaths are caused by over-aggression. Rein yourself in, or you may find yourself dying round after round. -As a xeno, if you have difficulty clicking marines, try using bump slash. You can use movement keys to slash marines. That said, clicking marines to slash them is faster than bump slashing! -It is EXTREMELY IMPORTANT that you as a xenomorph have your abilities set up on keybinds. Ask for help if you don't know how in XOOC or mentorhelp. -In the xeno tab, you can use the "crawl through vent" verb to quickly find and use vents in the floor without having to Alt-click them. You can also keybind it! -As a xeno, it is faster to re-fill an empty acid well than rolling on the ground to put out a fire. -As a xeno, acid wells extinguish fire and explode into an acid cloud when destroyed. The Queen, the Shrike, praetorians, boilers, and hivelords can make acid wells. -The Queen, the King, the Shrike, and hivelord have access to Queen's Blessing, a menu for the hive to use psychic points to give xenomorphs a cutting edge in the battlefield. -If you have acid spit, you can spit at a welding fuel tank to blow it up. If the welding fuel is near hostiles, you might give them a pleasant surprise! -As a xeno, check hive status often. -Some xenos have pheromones that can help the hive. Frenzy increases speed, Warding increases armor, and Recovery increases healing. -The King has the strongest pheromones, followed by the Queen, praetorians, Hivemind, the Shrike and hivelords, defilers, and carriers. Drones have the weakest pheromones. -Some xenos can recycle the bodies of their fallen hive members. Use this to your advantage to prevent marines from getting points for their Requisitions orders! -As a xeno, you can pounce past window frames and barricades without barbed wires. -As a xeno, pouncing into a barricade with barbed wire causes you to bounce off the barricade. -As a xeno, aging from young to mature gives you the most benefit, further aging has diminishing returns. -As a xeno, remember that neurotoxin injected can overdose, killing a marine quickly. -As a xeno, you can crawl through holes in walls made by acid by SpecialClicking (Default: CTRL+click) on them or click-dragging yourself on them. If you're too big to pass through, you'll damage the wall instead. -As a xeno, you can climb over window frames by jumping (Default: Spacebar), SpecialClicking (Default: CTRL+click) on them, or click-dragging yourself on them. -As a xeno, do not camp the landing zones prior to the marines building their defenses. -As a xeno, do not block other xenos' paths when they are retreating. Circumvent this by being on Help Intent or by simply moving away. -As a xeno, green weeds help you heal faster, blue weeds slow down marines, and weeds with no colors are normal weeds. Rest on the green weeds to heal faster! -As a larva, ask your hive leader what you should evolve into. If nobody responds, you can check hive status to see what xenomorphs need the most. -As a larva, you can slide under unbolted and unwelded doors by clicking on the door. -As a larva, stay on weeds while growing. You will grow faster as a result. -As a runner, warlock, or larva, you can pass over window frames without climbing onto them beforehand. -As a drone or sentinel, your corrosive acid is very weak, but it's better than nothing. -As a xeno, spread weeds as much as you can, especially near the front-line fighters. -Before you evolve into the Hivemind as a drone, hide in a secure area! Once you evolve, you will create a core that cannot be moved. -As a carrier, you can hit a host directly with a thrown facehugger to have a high chance of infecting them near instantly. This will take time, however. -As a carrier, you can hide traps beneath certain objects and items. -As a hunter, you have almost perfect stealth if you stand still. -As a ravager or the Queen, you are fire-resistant, NOT fireproof. You can still get lit on fire, but you take very little damage from it. As the King, however, you're fireproof until your armor is damaged by sunder. -As a spitter, boiler, praetorian, or the Queen, take advantage of unguarded barricades and defenses; melt or constantly spit acid on them if you can. -As a boiler, primordial hivelord, the King or the Queen, you have the most powerful corrosive acid for melting things. -As the Shrike, take advantage of your psychic abilities. Use Psychic Fling and Unrelenting Force to displace a marine or even push certain and hazardous objects towards your enemies and vice versa. -As the Queen, your screech does not only affect the mobs on view, but affects through walls or gases. However, the effect of the screech will be reduced. -As a drone, hivelord, Hivemind, Shrike, and the Queen, a large maze is almost always a good investment. -As a drone, hivelord, Hivemind, Shrike, and the Queen, be clever with your walling. Try to allow for as much fluid movement as possible. -Sticky resin can act as the path for your maze to be built around. -The Hivemind is very skilled at flanking marines. Wait for them to push, and wall them off from behind! -Praying to the Queen-Mother will usually net a response. -Your queen is your lifeline. Try to listen to her. -As a hunter, the movement of your Mirage is controlled by your intent. -Defenders have a very small window to sweep grenades back at marines with their tail. -Aiming for the head is a good long-term investment, causing brain damage on marines. -Aiming for the chest can easily damage someone's liver, lungs, or even heart. -Arms and legs are particularly vulnerable to damage. -As a xeno, to be robust is to know when to disengage. -As a xeno, in a duel, observe your enemy. They are likely predictable. -The Queen-Mother has put a lot of faith into your hive. It would be a shame to let her down. -As a xeno, attack between the delay of a shotgun being fired. -As a xeno, listen to the sound of your enemy's magazine! If it sounds hollow, it will soon be empty. -As a xeno, strike hard and fast. -As a xeno, you are not disposable. However, sacrificing your life to save the Queen is widely respected. -A fortified defender is one of the best ways to stall a push. -Skilled defilers can easily kill any marine in a span of seconds. -As a xeno, always have an escape plan. -Tileswapping marines via help intent can have interesting consequences. -As a boiler, you'll begin to glow with the more globules you have stored. -If you see a red dot, RUN! -Allowing marines to push caves only to block off their exit is hillariously effective. -As a xeno, a Tier 3 unit takes up both a Tier 3 and Tier 2 slot. +Будучи ксеносом, вы можете спокойно плавить баррикады, находясь в газе Дефайлера или Бойлера, если только сможете кликнуть в нужную точку. В газе также очень удобно прятаться, чтобы устраивать засады так, чтобы морпехи не заметили вас. +Будучи ксеносом, всегда благодарите своих Дронов и Лордов за поддержку улья! +Будучи ксеносом, вы можете перетащить любой предмет, но для этого необходимо дождаться выполнения действия. +Будучи ксеносом, не сражайтесь в роли поддержки. Вы должны находиться в тылу. +Большинство смертей ксеносов вызвано чрезмерной агрессией. Сдерживайте себя, иначе вы будете умирать чаще других. +Будучи ксеносом, если вам трудно нажимать на морпехов, попробуйте с намереньем вреда просто нажимать в сторону вашей цели. Не стопит целиться прямо на спрайт. Также, вы можете использовать клавиши движения, чтобы резать морпехов. +Крайне важно, чтобы вы, играя за ксеноморфов, настроили свои способности на привязку к клавишам. Если вы не знаете, как это сделать, обратитесь за помощью в XOOC или mentorhelp. +Будучи ксеносом, быстрее потушиться об кислотный колодец, чем кататься по земле, чтобы потушить огонь. Также колодцы помогают против липких гранат. +Будучи ксеносом, кислотные колодцы тушат огонь, а при уничтожении взрываются кислотным облаком. Создавать кислотные колодцы могут Королева, Шрика, Преторианцы, Бойлеры, Хайвлорды и даже Дроны. +Королева, Король, Шрика, Хайвмайнд и Хайвлорд имеют доступ к «Благословению королевы» - меню, позволяющее улью использовать пси-очки, чтобы дать ксеноморфам преимущество на поле боя. +Если у вас есть кислотный плевок, вы можете плюнуть в бак с горючим для сварки, чтобы взорвать его. Если бак со сварочным топливом находится рядом с врагами, вы можете устроить им неприятный сюрприз! +Будучи ксеносом, часто проверяйте состояние улья. Возможно, у вас давно проблемы в тылу... +Некоторые ксеносы обладают феромонами, которые могут помочь улью. Frenzy увеличивает скорость, Warding - броню, а Recovery - исцеление. +Самые сильные феромоны у Короля, за ним следуют Королева, Преторианцы, Шрика, чуть слабее у Хайвмайнда, Хайвлорда, Дефайлеров и Керриеров. У Дронов самые слабые феромоны. +Некоторые ксеносы, могут перерабатывать тела павших членов улья. Используйте это в своих интересах, чтобы не дать морпехам получить очки за их тела в карго! +Будучи ксеносом, вы можете проскакивать мимо оконных рам и баррикад без колючей проволоки. +Будучи ксеносом, вы можете пролезать через дыры в стенах, сделанные кислотой, нажав по ним специальным щелчком (по умолчанию: Ctrl-ЛКМ) , или же перетащив себя на них. Если вы слишком велики, чтобы пролезть, то вместо этого вы сломаете стену. +Будучи ксеносом, вы можете перепрыгнуть (по умолчанию: Space) или перелезть через оконные рамы, нажав на них специальным щелчком (по умолчанию: CTRL-ЛКМ) или перетащив себя на них. +Будучи ксеносом, не преграждайте путь другим ксеносам, когда они отступают. Чтобы предотвратить это, можно использовать зеленый интент или просто отойти с дороги. +Будучи ксеносом, белая трава помогает вам быстрее исцелиться, зелёная замедляет морпехов, а фиолетовая трава - это обычная трава. Отдыхайте на белой траве, чтобы быстрее вылечиться! +Будучи Лярвой, спросите у лидера улья, во что вам следует эволюционировать. Если никто не ответит, вы можете проверить состояние улья и узнать, в чем ксеноморфы нуждаются больше всего. +Будучи Лярвой, вы можете проскользнуть под незакрепленными и незаваренными дверями, щелкнув по ним. +Будучи Лярвой, во время роста оставайтесь на траве. Так вы будете расти быстрее. +В роли Руни, Пантеры, Варлока или Лярвы вы можете проходить через оконные рамы, не забираясь на них предварительно. +В качестве Дрона или Сентинеля ваша разъедающая кислота очень слаба, но это лучше, чем ничего. +Будучи ксеносом, сейте траву как можно чаще, особенно рядом с бойцами на передовой. Она лечит и немного ускоряет ксеносов. +Прежде чем эволюционировать в Хайвмайнда, спрячьтесь в безопасном месте! Когда вы эволюционируете, вы создадите ядро, которое нельзя будет сдвинуть с места. +В роли Керриера, вы можете напрямую ударить будущего носителя лицехватом, чтобы иметь высокий шанс заразить его почти мгновенно. Однако на это потребуется время. +Будучи Керриером, вы можете прятать ловушки под некоторыми объектами и предметами. +В роли Хантера у вас почти полная невидимость, если вы стоите на месте. +Будучи Равагером или Королевой, вы устойчивы к огню, но не огнеупорны. Вас все еще можно поджечь, но вы получаете очень мало урона. А вот уже Король, огнеупорен, но до тех пор, пока его броня не будет повреждена. +Будучи Спиттером, Бойлером, Преторианцем или Королевой, пользуйтесь неохраняемыми баррикадами и защитными сооружениями; плавьте их или постоянно плюйтесь кислотой, если можете. +У Бойлера, примо Хайвлорда, Короля и Королевы - самая едкая кислота для расплавления всякого. +Будучи Шрикой, пользуйтесь своими экстрасенсорными способностями. Используйте Psychic Fling и Unrelenting Force, чтобы сместить морпеха или даже подтолкнуть определенные и опасные предметы к врагам и наоборот. +Будучи Королевой, ваш крик действует не только на мобов в поле зрения, но и проникает сквозь стены или газы. Однако эффект от крика будет снижен. +Для Дрона, Хайвлорда, Хайвмайнда, Шрики и Королевы большой лабиринт - почти всегда хорошее вложение средств. Но только если морпехам не хватит мозгов запустить ОБ... +Будучи Дроном, Хайвлордом, Хайвмайндом, Шрикой или Королевой, умно распоряжайтесь своими стенами. Постарайтесь обеспечить как можно больше свободного движения для своей команды. +Липкая смола может служить дорожкой, вокруг которой будет строиться лабиринт. +Хайвмайнд очень искусен в обходе морпехов с фланга. Дождитесь, когда они начнут наступать, и застройте их сзади! +Молитва Королеве-матери обычно приносит ответ. +Ваша Королева - ваше всё. Постарайтесь прислушаться к ней. +Будучи Хантером, движение ваших копий зависит от вашего интента, в зеленом они будут отступать, в красном же будут атаковать. +У Дефендера и Шрики есть возможность откидывать гранаты назад их отправителям. +Перелом головы - хорошая долгосрочная инвестиция, вызывающая у морпехов повреждение мозга. +Перелом груди может легко повредить печень, легкие или даже сердце. +Руки и ноги особенно уязвимы для повреждений. +Будучи ксеносом, нужно знать, когда отступать. +Будучи ксеносом, во время дуэли наблюдайте за противником. Они, чаще всего, предсказуемы. +Королева-мать оказала большое доверие вашему улью. Было бы обидно подвести ее. +Будучи ксеносом, прислушивайтесь к звуку магазина вашего врага! Если он звучит пусто, очевидно, он скоро он опустеет. +Будучи ксеносом, бейте сильно и быстро. +Будучи ксеносом, помните, вас никто не сможет возродить. Однако пожертвовать своей жизнью ради спасения королевы - это достойно уважения. +Хороший Дефендер - один из лучших способов задержать натиск. +Опытные Дефайлеры могут легко убить любого морпеха за считанные секунды. +Будучи ксеносом, всегда имейте план побега. +Обмен местами с морпехами через зеленый интент может привести к интересным последствиям. +Бойлер начинает светиться тем сильнее, чем больше у него снарядов. Но вместе с этим время перезарядки выстрела уменьшается. +Если вы видите красную точку - БЕГИТЕ! diff --git a/tgmc.dme b/tgmc.dme index 3568666fb8c..ccf6761e5ff 100644 --- a/tgmc.dme +++ b/tgmc.dme @@ -385,9 +385,11 @@ #include "code\datums\actions\bump_attack_toggle.dm" #include "code\datums\actions\innate.dm" #include "code\datums\actions\item_action.dm" +#include "code\datums\actions\item_toggles.dm" #include "code\datums\actions\observer_action.dm" #include "code\datums\actions\order_action.dm" #include "code\datums\actions\skill.dm" +#include "code\datums\actions\weapon_actions.dm" #include "code\datums\actions\xeno_action.dm" #include "code\datums\actions\species_actions\sectoid_action.dm" #include "code\datums\autocells\auto_cell.dm" @@ -409,12 +411,14 @@ #include "code\datums\components\connect_mob_behalf.dm" #include "code\datums\components\deployable_item.dm" #include "code\datums\components\dripping.dm" +#include "code\datums\components\easy_restock.dm" #include "code\datums\components\grillable.dm" #include "code\datums\components\harvester.dm" #include "code\datums\components\health_stealth.dm" #include "code\datums\components\jump.dm" #include "code\datums\components\largeobjecttransparency.dm" #include "code\datums\components\larva_queue.dm" +#include "code\datums\components\magazine_catcher.dm" #include "code\datums\components\mobile_power.dm" #include "code\datums\components\orbiter.dm" #include "code\datums\components\overlay_lighting.dm" @@ -540,11 +544,13 @@ #include "code\datums\keybinding\custom_emote.dm" #include "code\datums\keybinding\emote.dm" #include "code\datums\keybinding\human.dm" +#include "code\datums\keybinding\item_toggles.dm" #include "code\datums\keybinding\living.dm" #include "code\datums\keybinding\mecha.dm" #include "code\datums\keybinding\mob.dm" #include "code\datums\keybinding\movement.dm" #include "code\datums\keybinding\sectoid.dm" +#include "code\datums\keybinding\weapons.dm" #include "code\datums\keybinding\xeno.dm" #include "code\datums\loadout\loadout.dm" #include "code\datums\loadout\loadout_helper.dm" @@ -1730,6 +1736,8 @@ #include "code\modules\mob\living\carbon\xenomorph\castes\shrike\abilities_shrike.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\shrike\castedatum_shrike.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\shrike\shrike.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\spiderling\castedatum_spiderling.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\spiderling\spiderling.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\spitter\abilities_spitter.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\spitter\castedatum_spitter.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\spitter\spitter.dm" @@ -1739,6 +1747,9 @@ #include "code\modules\mob\living\carbon\xenomorph\castes\warrior\abilities_warrior.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\warrior\castedatum_warrior.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\warrior\warrior.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\widow\abilities_widow.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\widow\castedatum_widow.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\widow\widow.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\say.dm" #include "code\modules\mob\living\silicon\silicon.dm" @@ -1927,8 +1938,11 @@ #include "code\modules\reqs\explosives.dm" #include "code\modules\reqs\factory.dm" #include "code\modules\reqs\imports.dm" +#include "code\modules\reqs\launchers.dm" #include "code\modules\reqs\medical.dm" #include "code\modules\reqs\operations.dm" +#include "code\modules\reqs\smartguns.dm" +#include "code\modules\reqs\stationary.dm" #include "code\modules\reqs\supplies.dm" #include "code\modules\reqs\vehicles.dm" #include "code\modules\reqs\weapons.dm" diff --git a/tgui/packages/tgui/interfaces/Cargo.jsx b/tgui/packages/tgui/interfaces/Cargo.jsx index dc66bd04534..950b496da18 100644 --- a/tgui/packages/tgui/interfaces/Cargo.jsx +++ b/tgui/packages/tgui/interfaces/Cargo.jsx @@ -21,6 +21,9 @@ import { Window } from '../layouts'; const category_icon = { Operations: 'parachute-box', Weapons: 'fighter-jet', + Smartguns: 'star', + Stationary: 'bolt', + Launchers: 'rocket', Explosives: 'bomb', Armor: 'hard-hat', Clothing: 'tshirt', diff --git a/tgui/packages/tgui/interfaces/HiveStatus.tsx b/tgui/packages/tgui/interfaces/HiveStatus.tsx index 57771aa0032..3a6539a6ded 100644 --- a/tgui/packages/tgui/interfaces/HiveStatus.tsx +++ b/tgui/packages/tgui/interfaces/HiveStatus.tsx @@ -110,7 +110,7 @@ export const HiveStatus = (_props) => { diff --git a/tgui/packages/tgui/interfaces/PlayerPreferences/JobPreferences.tsx b/tgui/packages/tgui/interfaces/PlayerPreferences/JobPreferences.tsx index 62ba51463ee..23448557310 100644 --- a/tgui/packages/tgui/interfaces/PlayerPreferences/JobPreferences.tsx +++ b/tgui/packages/tgui/interfaces/PlayerPreferences/JobPreferences.tsx @@ -39,7 +39,7 @@ export const JobPreferences = (props) => { 'Requisitions Officer', 'Chief Medical Officer', 'Medical Doctor', - 'Medical Researcher', + 'Field Researcher', 'Assault Crewman', 'Transport Crewman', ]; diff --git a/tgui/packages/tgui/interfaces/PlayerPreferences/KeybindSettings.tsx b/tgui/packages/tgui/interfaces/PlayerPreferences/KeybindSettings.tsx index b40396fdf40..f7c8ca5a01c 100644 --- a/tgui/packages/tgui/interfaces/PlayerPreferences/KeybindSettings.tsx +++ b/tgui/packages/tgui/interfaces/PlayerPreferences/KeybindSettings.tsx @@ -141,6 +141,18 @@ export const KeybindSettings = (props) => { {all_keybindings['PSIONIC'] ?.filter(filterSearch) .map((kb) => )} + +

Items

+
+ {all_keybindings['WEAPON'] + ?.filter(filterSearch) + .map((kb) => )} + +

Items

+
+ {all_keybindings['ITEM'] + ?.filter(filterSearch) + .map((kb) => )} diff --git a/tools/UpdatePaths/scripts/telecomms.txt b/tools/UpdatePaths/scripts/telecomms.txt new file mode 100644 index 00000000000..78d78f394ca --- /dev/null +++ b/tools/UpdatePaths/scripts/telecomms.txt @@ -0,0 +1,20 @@ +/obj/machinery/telecomms/processor/preset_one : /obj/machinery/telecomms/processor/preset/one +/obj/machinery/telecomms/processor/preset_two : /obj/machinery/telecomms/processor/preset/two +/obj/machinery/telecomms/processor/preset_three : /obj/machinery/telecomms/processor/preset/three +/obj/machinery/telecomms/processor/preset_four : /obj/machinery/telecomms/processor/preset/four +/obj/machinery/telecomms/processor/preset_four/cicbackup : /obj/machinery/telecomms/processor/preset/four/cicbackup + +/obj/machinery/telecomms/bus/preset_one : /obj/machinery/telecomms/bus/preset/one +/obj/machinery/telecomms/bus/preset_two : /obj/machinery/telecomms/bus/preset/two +/obj/machinery/telecomms/bus/preset_three : /obj/machinery/telecomms/bus/preset/three +/obj/machinery/telecomms/bus/preset_four : /obj/machinery/telecomms/bus/preset/four +/obj/machinery/telecomms/bus/preset_four/cicbackup : /obj/machinery/telecomms/bus/preset/four/cicbackup + +/obj/machinery/telecomms/receiver/preset_left : /obj/machinery/telecomms/receiver/preset/left +/obj/machinery/telecomms/receiver/preset_right : /obj/machinery/telecomms/receiver/preset/right +/obj/machinery/telecomms/receiver/preset_right/cicbackup : /obj/machinery/telecomms/receiver/preset/left +/obj/machinery/telecomms/receiver/preset_right/som : /obj/machinery/telecomms/receiver/preset/left + +/obj/machinery/telecomms/broadcaster/preset_left : /obj/machinery/telecomms/broadcaster/preset/left +/obj/machinery/telecomms/broadcaster/preset_right : /obj/machinery/telecomms/broadcaster/preset/right +/obj/machinery/telecomms/broadcaster/preset_right/cicbackup : /obj/machinery/telecomms/broadcaster/preset/right/cicbackup