diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 345e490962..1af5ec21f6 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -24601,8 +24601,7 @@ dir = 4 }, /obj/machinery/posialert{ - pixel_x = 29; - pixel_y = -4 + pixel_x = 32 }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index d2392c04e2..50654d4eb3 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -49217,8 +49217,7 @@ dir = 4 }, /obj/machinery/posialert{ - pixel_x = -31; - pixel_y = -2 + pixel_x = -32 }, /turf/open/floor/plasteel/dark/side{ dir = 8 diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 9f0150241e..2714ee2166 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -61508,9 +61508,6 @@ dir = 4 }, /obj/effect/turf_decal/bot, -/obj/machinery/posialert{ - pixel_y = -31 - }, /turf/open/floor/plasteel, /area/science/robotics/lab) "dIO" = ( @@ -61537,12 +61534,12 @@ /obj/machinery/computer/operating{ dir = 1 }, -/obj/machinery/newscaster{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/posialert{ + pixel_y = -32 + }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "dIR" = ( diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 38e124f9f0..94eba129cc 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -37000,6 +37000,9 @@ /obj/item/assembly/flash/handheld, /obj/item/assembly/flash/handheld, /obj/item/assembly/flash/handheld, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bhC" = ( @@ -43733,7 +43736,7 @@ }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 @@ -84930,7 +84933,7 @@ /obj/item/reagent_containers/food/drinks/bottle/grenadine, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 @@ -85014,56 +85017,56 @@ /obj/item/reagent_containers/food/drinks/bottle/wine, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 6c2502e628..3f60c8a105 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -6052,9 +6052,6 @@ /obj/effect/turf_decal/trimline/white/filled/corner{ dir = 1 }, -/obj/machinery/posialert{ - pixel_y = 27 - }, /turf/open/floor/plasteel, /area/science/robotics/lab) "amD" = ( @@ -7942,6 +7939,9 @@ /obj/structure/table, /obj/item/stack/cable_coil/random, /obj/machinery/camera/autoname, +/obj/machinery/posialert{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/science/robotics/lab) "apy" = ( @@ -13523,7 +13523,7 @@ }, /mob/living/simple_animal/pet/gondola{ desc = "The last known gondola for lightyears, it is your duty to keep them safe from the filthy yellowed hands of the greytide."; - loot = list(/obj/effect/decal/cleanable/blood/gibs, /obj/item/stack/sheet/animalhide/gondola = 1); + loot = list(/obj/effect/decal/cleanable/blood/gibs,/obj/item/stack/sheet/animalhide/gondola=1); name = "Filbert" }, /turf/open/floor/plasteel/dark, @@ -38035,7 +38035,7 @@ dir = 5 }, /obj/machinery/vending/medical{ - products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, /obj/item/sensor_device = 4, /obj/item/pinpointer/crew = 2, /obj/item/reagent_containers/medspray/sterilizine = 1, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/insulin = 10, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/storage/hypospraykit/fire = 2, /obj/item/storage/hypospraykit/toxin = 2, /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5, /obj/item/storage/briefcase/medical = 2, /obj/item/stack/sticky_tape/surgical = 3, /obj/item/healthanalyzer/wound = 4, /obj/item/stack/medical/ointment = 2, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/bone_gel = 4) + products = list(/obj/item/reagent_containers/syringe=12,/obj/item/reagent_containers/dropper=3,/obj/item/healthanalyzer=4,/obj/item/sensor_device=4,/obj/item/pinpointer/crew=2,/obj/item/reagent_containers/medspray/sterilizine=1,/obj/item/stack/medical/gauze=8,/obj/item/reagent_containers/pill/patch/styptic=5,/obj/item/reagent_containers/medspray/styptic=2,/obj/item/reagent_containers/pill/patch/silver_sulf=5,/obj/item/reagent_containers/medspray/silver_sulf=2,/obj/item/reagent_containers/pill/insulin=10,/obj/item/reagent_containers/pill/salbutamol=2,/obj/item/reagent_containers/glass/bottle/charcoal=4,/obj/item/reagent_containers/glass/bottle/epinephrine=4,/obj/item/reagent_containers/glass/bottle/salglu_solution=3,/obj/item/reagent_containers/glass/bottle/morphine=4,/obj/item/reagent_containers/glass/bottle/toxin=3,/obj/item/reagent_containers/syringe/antiviral=6,/obj/item/storage/hypospraykit/fire=2,/obj/item/storage/hypospraykit/toxin=2,/obj/item/storage/hypospraykit/o2=2,/obj/item/storage/hypospraykit/brute=2,/obj/item/storage/hypospraykit/enlarge=2,/obj/item/reagent_containers/glass/bottle/vial/small=5,/obj/item/storage/briefcase/medical=2,/obj/item/stack/sticky_tape/surgical=3,/obj/item/healthanalyzer/wound=4,/obj/item/stack/medical/ointment=2,/obj/item/stack/medical/suture=2,/obj/item/stack/medical/bone_gel=4) }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -46039,7 +46039,7 @@ "bXK" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/machinery/vending/medical{ - products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, /obj/item/sensor_device = 4, /obj/item/pinpointer/crew = 2, /obj/item/reagent_containers/medspray/sterilizine = 1, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/insulin = 10, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/storage/hypospraykit/fire = 2, /obj/item/storage/hypospraykit/toxin = 2, /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5, /obj/item/storage/briefcase/medical = 2, /obj/item/stack/sticky_tape/surgical = 3, /obj/item/healthanalyzer/wound = 4, /obj/item/stack/medical/ointment = 2, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/bone_gel = 4) + products = list(/obj/item/reagent_containers/syringe=12,/obj/item/reagent_containers/dropper=3,/obj/item/healthanalyzer=4,/obj/item/sensor_device=4,/obj/item/pinpointer/crew=2,/obj/item/reagent_containers/medspray/sterilizine=1,/obj/item/stack/medical/gauze=8,/obj/item/reagent_containers/pill/patch/styptic=5,/obj/item/reagent_containers/medspray/styptic=2,/obj/item/reagent_containers/pill/patch/silver_sulf=5,/obj/item/reagent_containers/medspray/silver_sulf=2,/obj/item/reagent_containers/pill/insulin=10,/obj/item/reagent_containers/pill/salbutamol=2,/obj/item/reagent_containers/glass/bottle/charcoal=4,/obj/item/reagent_containers/glass/bottle/epinephrine=4,/obj/item/reagent_containers/glass/bottle/salglu_solution=3,/obj/item/reagent_containers/glass/bottle/morphine=4,/obj/item/reagent_containers/glass/bottle/toxin=3,/obj/item/reagent_containers/syringe/antiviral=6,/obj/item/storage/hypospraykit/fire=2,/obj/item/storage/hypospraykit/toxin=2,/obj/item/storage/hypospraykit/o2=2,/obj/item/storage/hypospraykit/brute=2,/obj/item/storage/hypospraykit/enlarge=2,/obj/item/reagent_containers/glass/bottle/vial/small=5,/obj/item/storage/briefcase/medical=2,/obj/item/stack/sticky_tape/surgical=3,/obj/item/healthanalyzer/wound=4,/obj/item/stack/medical/ointment=2,/obj/item/stack/medical/suture=2,/obj/item/stack/medical/bone_gel=4) }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -62235,7 +62235,7 @@ /area/engineering/break_room) "cUI" = ( /obj/machinery/vending/engineering{ - products = list(/obj/item/clothing/under/rank/engineering/engineer = 4, /obj/item/clothing/shoes/sneakers/orange = 4, /obj/item/clothing/head/hardhat = 4, /obj/item/storage/belt/utility = 4, /obj/item/clothing/glasses/meson/engine = 4, /obj/item/clothing/gloves/color/yellow = 2, /obj/item/screwdriver = 12, /obj/item/crowbar = 12, /obj/item/wirecutters = 12, /obj/item/multitool = 12, /obj/item/wrench = 12, /obj/item/t_scanner = 12, /obj/item/stock_parts/cell = 8, /obj/item/weldingtool = 8, /obj/item/clothing/head/welding = 8, /obj/item/light/tube = 10, /obj/item/clothing/suit/fire = 4, /obj/item/stock_parts/scanning_module = 5, /obj/item/stock_parts/micro_laser = 5, /obj/item/stock_parts/matter_bin = 5, /obj/item/stock_parts/manipulator = 5) + products = list(/obj/item/clothing/under/rank/engineering/engineer=4,/obj/item/clothing/shoes/sneakers/orange=4,/obj/item/clothing/head/hardhat=4,/obj/item/storage/belt/utility=4,/obj/item/clothing/glasses/meson/engine=4,/obj/item/clothing/gloves/color/yellow=2,/obj/item/screwdriver=12,/obj/item/crowbar=12,/obj/item/wirecutters=12,/obj/item/multitool=12,/obj/item/wrench=12,/obj/item/t_scanner=12,/obj/item/stock_parts/cell=8,/obj/item/weldingtool=8,/obj/item/clothing/head/welding=8,/obj/item/light/tube=10,/obj/item/clothing/suit/fire=4,/obj/item/stock_parts/scanning_module=5,/obj/item/stock_parts/micro_laser=5,/obj/item/stock_parts/matter_bin=5,/obj/item/stock_parts/manipulator=5) }, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -70229,7 +70229,7 @@ }, /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/sillycup/smallcarton{ - list_reagents = list(/datum/reagent/consumable/milk = 20); + list_reagents = list(/datum/reagent/consumable/milk=20); name = "small milk carton"; pixel_x = -8; pixel_y = 5 diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 792f51bc73..e632a77747 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -1702,7 +1702,7 @@ name = "3maintenance loot spawner" }, /obj/effect/spawner/lootdrop/armory_contraband{ - loot = list(/obj/item/gun/ballistic/automatic/pistol = 5, /obj/item/gun/ballistic/shotgun/automatic/combat = 5, /obj/item/gun/ballistic/revolver/mateba, /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/storage/box/syndie_kit/throwing_weapons = 3) + loot = list(/obj/item/gun/ballistic/automatic/pistol=5,/obj/item/gun/ballistic/shotgun/automatic/combat=5,/obj/item/gun/ballistic/revolver/mateba,/obj/item/gun/ballistic/automatic/pistol/deagle,/obj/item/storage/box/syndie_kit/throwing_weapons=3) }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -37381,9 +37381,6 @@ network = list("ss13","rd") }, /obj/effect/turf_decal/delivery, -/obj/machinery/posialert{ - pixel_y = 24 - }, /turf/open/floor/plasteel, /area/science/robotics/lab) "cDh" = ( @@ -40950,6 +40947,9 @@ /obj/item/cautery{ pixel_y = 15 }, +/obj/machinery/posialert{ + pixel_y = -32 + }, /turf/open/floor/plasteel/white/corner{ dir = 4 }, @@ -57273,7 +57273,7 @@ "iqV" = ( /obj/structure/table/wood/poker, /obj/effect/spawner/lootdrop{ - loot = list(/obj/item/gun/ballistic/revolver/russian = 5, /obj/item/storage/box/syndie_kit/throwing_weapons, /obj/item/toy/cards/deck/syndicate = 2); + loot = list(/obj/item/gun/ballistic/revolver/russian=5,/obj/item/storage/box/syndie_kit/throwing_weapons,/obj/item/toy/cards/deck/syndicate=2); name = "gambling valuables spawner" }, /turf/open/floor/wood, diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 28c0e21264..1c42b077f8 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -27989,6 +27989,9 @@ dir = 1 }, /obj/effect/turf_decal/bot, +/obj/machinery/posialert{ + pixel_y = 32 + }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bae" = ( diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 458e6aca93..318e72a0d4 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -15742,7 +15742,7 @@ /area/service/cafeteria/lunchroom) "aNb" = ( /obj/machinery/vending/sustenance{ - contraband = list(/obj/item/kitchen/knife = 6, /obj/item/reagent_containers/food/drinks/coffee = 12); + contraband = list(/obj/item/kitchen/knife=6,/obj/item/reagent_containers/food/drinks/coffee=12); desc = "A vending machine which vends food."; product_ads = "Sufficiently healthy." }, @@ -26309,9 +26309,6 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/posialert{ - pixel_y = 26 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "blM" = ( @@ -29634,6 +29631,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bsX" = ( @@ -38803,7 +38803,7 @@ input_tag = "mix_in"; name = "Gas Mix Tank Control"; output_tag = "mix_in"; - sensors = list("mix_sensor" = "Tank") + sensors = list("mix_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -40292,7 +40292,7 @@ input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; - sensors = list("n2o_sensor" = "Tank") + sensors = list("n2o_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -41681,7 +41681,7 @@ input_tag = "tox_in"; name = "Plasma Supply Control"; output_tag = "tox_out"; - sensors = list("tox_sensor" = "Tank") + sensors = list("tox_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ diff --git a/_maps/map_files/Snaxi/Snaxi.dmm b/_maps/map_files/Snaxi/Snaxi.dmm index 7e68f53cdd..53e34ba320 100644 --- a/_maps/map_files/Snaxi/Snaxi.dmm +++ b/_maps/map_files/Snaxi/Snaxi.dmm @@ -9515,6 +9515,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "axr" = ( @@ -36875,7 +36878,7 @@ /area/engineering/secure_construction) "qzP" = ( /obj/machinery/vending/dinnerware{ - contraband = list(/obj/item/kitchen/rollingpin = 2, /obj/item/kitchen/knife/butcher = 2, /obj/item/reagent_containers/food/condiment/flour = 4) + contraband = list(/obj/item/kitchen/rollingpin=2,/obj/item/kitchen/knife/butcher=2,/obj/item/reagent_containers/food/condiment/flour=4) }, /turf/open/floor/plasteel/freezer, /area/service/kitchen) @@ -44912,7 +44915,7 @@ dir = 8 }, /obj/effect/spawner/lootdrop/armory_contraband{ - loot = list(/obj/item/gun/ballistic/automatic/pistol = 5, /obj/item/gun/ballistic/shotgun/automatic/combat = 5, /obj/item/gun/ballistic/revolver/mateba, /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/storage/box/syndie_kit/throwing_weapons = 3) + loot = list(/obj/item/gun/ballistic/automatic/pistol=5,/obj/item/gun/ballistic/shotgun/automatic/combat=5,/obj/item/gun/ballistic/revolver/mateba,/obj/item/gun/ballistic/automatic/pistol/deagle,/obj/item/storage/box/syndie_kit/throwing_weapons=3) }, /obj/effect/spawner/lootdrop/maintenance{ lootcount = 3; diff --git a/auxmos.dll b/auxmos.dll index 6178d9c2a5..5e1b5dc374 100644 Binary files a/auxmos.dll and b/auxmos.dll differ diff --git a/auxmos.pdb b/auxmos.pdb index 788e2fa52e..48ecb28850 100644 Binary files a/auxmos.pdb and b/auxmos.pdb differ diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 6266dcc6d3..c585a822ea 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -152,6 +152,10 @@ #define ATMOS_PASS_PROC -1 //ask CanAtmosPass() #define ATMOS_PASS_DENSITY -2 //just check density +// Adjacency flags +#define ATMOS_ADJACENT_ANY (1<<0) +#define ATMOS_ADJACENT_FIRELOCK (1<<1) + #define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) #define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) ) @@ -323,14 +327,6 @@ #define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ - -#ifdef TESTING -GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) -#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 } -#else -#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1 -#endif - //If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks #define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs)) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index a6d411a8dd..6dae40ce07 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -206,6 +206,19 @@ ///Time to spend without clicking on other things required for your shots to become accurate. #define GUN_AIMING_TIME (2 SECONDS) +//Autofire component +/// Compatible firemode is in the gun. Wait until it's held in the user hands. +#define AUTOFIRE_STAT_IDLE (1<<0) +/// Gun is active and in the user hands. Wait until user does a valid click. +#define AUTOFIRE_STAT_ALERT (1<<1) +/// Gun is shooting. +#define AUTOFIRE_STAT_FIRING (1<<2) + +#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown" + #define COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS (1<<0) +#define COMSIG_AUTOFIRE_SHOT "autofire_shot" + #define COMPONENT_AUTOFIRE_SHOT_SUCCESS (1<<0) + //Object/Item sharpness #define SHARP_NONE 0 #define SHARP_EDGED 1 @@ -261,3 +274,4 @@ * a "inefficiently" prefix will be added to the message. */ #define FEEBLE_ATTACK_MSG_THRESHOLD 0.5 + diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 9de0dbe7c5..7a54b8482d 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -321,6 +321,12 @@ ///from base of mob/AltClickOn(): (atom/A) #define COMSIG_MOB_ALTCLICKON "mob_altclickon" +//Gun signals +///When a gun is switched to automatic fire mode +#define COMSIG_GUN_AUTOFIRE_SELECTED "gun_autofire_selected" +///When a gun is switched off of automatic fire mode +#define COMSIG_GUN_AUTOFIRE_DESELECTED "gun_autofire_deselected" + // Lighting: ///from base of [atom/proc/set_light]: (l_range, l_power, l_color, l_on) #define COMSIG_ATOM_SET_LIGHT "atom_set_light" @@ -348,12 +354,22 @@ #define COMSIG_ATOM_UPDATE_LIGHT_FLAGS "atom_update_light_flags" // /client signals -#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client) #define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client) #define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) #define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view) #define COMSIG_MOB_CLIENT_MOUSEMOVE "mob_client_mousemove" //from base of /client/MouseMove(): (object, location, control, params) +///sent when a mob/login() finishes: (client) +#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" +//from base of client/MouseDown(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDOWN "client_mousedown" +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEUP "client_mouseup" + #define COMPONENT_CLIENT_MOUSEUP_INTERCEPT (1<<0) +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDRAG "client_mousedrag" + + // /mob/living signals #define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) diff --git a/code/__DEFINES/gun.dm b/code/__DEFINES/gun.dm new file mode 100644 index 0000000000..05ce5118a3 --- /dev/null +++ b/code/__DEFINES/gun.dm @@ -0,0 +1,3 @@ +#define SELECT_SEMI_AUTOMATIC 1 +#define SELECT_BURST_SHOT 2 +#define SELECT_FULLY_AUTOMATIC 3 diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 128f9120c6..88cba1c449 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -4,3 +4,6 @@ #define HUD_STYLE_NOHUD 3 //No hud (for screenshots) #define HUD_VERSIONS 3 //Used in show_hud(); Please ensure this is the same as the maximum index. + +#define ui_borg_pda_send "CENTER+5:21,SOUTH:5" // To the right of the alert panel +#define ui_borg_pda_log "CENTER+6:21,SOUTH:5" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 4c70c24e9c..19cb08de54 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -395,6 +395,23 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define BEAT_SLOW 2 #define BEAT_NONE 0 +//Mouse buttons pressed/held/released +#define RIGHT_CLICK "right" +#define MIDDLE_CLICK "middle" +#define LEFT_CLICK "left" + +//Keys held down during the mouse action +#define CTRL_CLICK "ctrl" +#define ALT_CLICK "alt" +#define SHIFT_CLICK "shift" + +//Pixel coordinates within the icon, in the icon's coordinate space +#define ICON_X "icon-x" +#define ICON_Y "icon-y" + +//Pixel coordinates in screen_loc format ("[tile_x]:[pixel_x],[tile_y]:[pixel_y]") +#define SCREEN_LOC "screen-loc" + //https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity #define MOUSE_OPACITY_TRANSPARENT 0 #define MOUSE_OPACITY_ICON 1 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 428784e953..73b2dd3006 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -673,6 +673,27 @@ Turf and target are separate in case you want to teleport some distance from a t if(final_x || final_y) return locate(final_x, final_y, T.z) +///Returns a turf based on text inputs, original turf and viewing client +/proc/parse_caught_click_modifiers(list/modifiers, turf/origin, client/viewing_client) + if(!modifiers) + return null + + var/screen_loc = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",") + var/list/actual_view = getviewsize(viewing_client ? viewing_client.view : world.view) + var/click_turf_x = splittext(screen_loc[1], ":") + var/click_turf_y = splittext(screen_loc[2], ":") + var/click_turf_z = origin.z + + var/click_turf_px = text2num(click_turf_x[2]) + var/click_turf_py = text2num(click_turf_y[2]) + click_turf_x = origin.x + text2num(click_turf_x[1]) - round(actual_view[1] / 2) - 1 + click_turf_y = origin.y + text2num(click_turf_y[1]) - round(actual_view[2] / 2) - 1 + + var/turf/click_turf = locate(clamp(click_turf_x, 1, world.maxx), clamp(click_turf_y, 1, world.maxy), click_turf_z) + LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * world.icon_size)]") + LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * world.icon_size)]") + return click_turf + //Finds the distance between two atoms, in pixels //centered = FALSE counts from turf edge to edge //centered = TRUE counts from turf center to turf center diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index 58c182036d..a698706f1a 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -23,23 +23,31 @@ SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user) return - -/client/MouseDown(object, location, control, params) - if (mouse_down_icon) +/client/MouseDown(datum/object, location, control, params) + if(!control) + return + if(QDELETED(object)) //Yep, you can click on qdeleted things before they have time to nullspace. Fun. + return + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params) + if(mouse_down_icon) mouse_pointer_icon = mouse_down_icon var/delay = mob.CanMobAutoclick(object, location, params) if(delay) selected_target[1] = object selected_target[2] = params while(selected_target[1]) - Click(selected_target[1], location, control, selected_target[2], TRUE) + Click(selected_target[1], location, control, selected_target[2]) sleep(delay) active_mousedown_item = mob.canMobMousedown(object, location, params) if(active_mousedown_item) active_mousedown_item.onMouseDown(object, location, params, mob) /client/MouseUp(object, location, control, params) - if (mouse_up_icon) + if(!control) + return + if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT) + click_intercept_time = world.time + if(mouse_up_icon) mouse_pointer_icon = mouse_up_icon selected_target[1] = null if(active_mousedown_item) @@ -74,9 +82,6 @@ /obj/item/proc/onMouseUp(object, location, params, mob) return -/obj/item/gun/CanItemAutoclick(object, location, params) - . = automatic - /atom/proc/IsAutoclickable() . = 1 @@ -110,6 +115,7 @@ selected_target[2] = params if(active_mousedown_item) active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob) + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params) /obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) return diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 03ad1b1821..e20bae87d7 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -342,3 +342,43 @@ if(.) return robot.modularInterface?.interact(robot) + +//borg pda +/datum/hud/robot/New(mob/owner) + . = ..() + + var/atom/movable/screen/using + + //PDA message + using = new /atom/movable/screen/robot/pda_msg_send + using.screen_loc = ui_borg_pda_send + using.hud = src + static_inventory += using + + //PDA log + using = new /atom/movable/screen/robot/pda_msg_show + using.screen_loc = ui_borg_pda_log + using.hud = src + static_inventory += using + +/atom/movable/screen/robot/pda_msg_send + name = "PDA - Send Message" + icon = 'icons/mob/screen_ai.dmi' + icon_state = "pda_send" + +/atom/movable/screen/robot/pda_msg_send/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.cmd_send_pdamesg(usr) + +/atom/movable/screen/robot/pda_msg_show + name = "PDA - Show Message Log" + icon = 'icons/mob/screen_ai.dmi' + icon_state = "pda_receive" + +/atom/movable/screen/robot/pda_msg_show/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.cmd_show_message_log(usr) diff --git a/code/controllers/subsystem/adjacent_air.dm b/code/controllers/subsystem/adjacent_air.dm deleted file mode 100644 index 99ee587826..0000000000 --- a/code/controllers/subsystem/adjacent_air.dm +++ /dev/null @@ -1,39 +0,0 @@ -SUBSYSTEM_DEF(adjacent_air) - name = "Atmos Adjacency" - flags = SS_BACKGROUND - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - wait = 10 - priority = FIRE_PRIORITY_ATMOS_ADJACENCY - var/list/queue = list() - -/datum/controller/subsystem/adjacent_air/stat_entry(msg) -#ifdef TESTING - msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]" -#else - msg = "P:[length(queue)]" -#endif - return ..() - -/datum/controller/subsystem/adjacent_air/Initialize() - while(length(queue)) - fire(mc_check = FALSE) - return ..() - -/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE) - if(SSair.thread_running()) - pause() - return - - var/list/queue = src.queue - - while (length(queue)) - var/turf/currT = queue[1] - queue.Cut(1,2) - - currT.ImmediateCalculateAdjacentTurfs() - - if(mc_check) - if(MC_TICK_CHECK) - break - else - CHECK_TICK diff --git a/code/datums/action.dm b/code/datums/action.dm index ac8c909bd2..304aa47baa 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -23,6 +23,8 @@ var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon var/button_icon_state = "default" //And this is the state for the action icon var/mob/owner + ///List of all mobs that are viewing our action button -> A unique movable for them to view. + var/list/viewers = list() /datum/action/New(Target) link_to(Target) @@ -121,6 +123,11 @@ return FALSE return TRUE +/datum/action/proc/UpdateButtons(status_only, force) + for(var/datum/hud/hud in viewers) + var/atom/movable/screen/movable/button = viewers[hud] + UpdateButtonIcon(button, status_only, force) + /datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE) if(!button) return @@ -217,6 +224,8 @@ name = "Toggle Hood" /datum/action/item_action/toggle_firemode + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "fireselect_no" name = "Toggle Firemode" /datum/action/item_action/rcl_col diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm new file mode 100644 index 0000000000..4b9c25db91 --- /dev/null +++ b/code/datums/components/fullauto.dm @@ -0,0 +1,278 @@ +#define AUTOFIRE_MOUSEUP 0 +#define AUTOFIRE_MOUSEDOWN 1 + +/datum/component/automatic_fire + var/client/clicker + var/mob/living/shooter + var/atom/target + var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves). + var/autofire_stat = AUTOFIRE_STAT_IDLE + var/mouse_parameters + var/autofire_shot_delay = 0.3 SECONDS //Time between individual shots. + var/mouse_status = AUTOFIRE_MOUSEUP //This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar. + + COOLDOWN_DECLARE(next_shot_cd) + +/datum/component/automatic_fire/Initialize(_autofire_shot_delay) + . = ..() + if(!isgun(parent)) + return COMPONENT_INCOMPATIBLE + var/obj/item/gun = parent + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/wake_up) + RegisterSignal(parent, COMSIG_GUN_AUTOFIRE_SELECTED, .proc/wake_up) + RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED), .proc/autofire_off) + if(_autofire_shot_delay) + autofire_shot_delay = _autofire_shot_delay + if(ismob(gun.loc)) + var/mob/user = gun.loc + wake_up(src, user) + + +/datum/component/automatic_fire/Destroy() + UnregisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED)) + autofire_off() + return ..() + +/datum/component/automatic_fire/process(delta_time) + if(!(autofire_stat & AUTOFIRE_STAT_FIRING)) + STOP_PROCESSING(SSprojectiles, src) + return + + if(!COOLDOWN_FINISHED(src, next_shot_cd)) + return + + process_shot() + +/datum/component/automatic_fire/proc/wake_up(datum/source, mob/user, slot) + SIGNAL_HANDLER + + if(autofire_stat & (AUTOFIRE_STAT_ALERT)) + return //We've updated the firemode. No need for more. + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() //Let's stop shooting to avoid issues. + return + + var/obj/item/gun/G = parent + + if(iscarbon(user)) + var/mob/living/carbon/shooter = user + if(shooter.is_holding(parent) && G.fire_select == SELECT_FULLY_AUTOMATIC) + autofire_on(shooter.client) + else + autofire_off() + +// There is a gun and there is a user wielding it. The component now waits for the mouse click. +/datum/component/automatic_fire/proc/autofire_on(client/usercli) + SIGNAL_HANDLER + if(autofire_stat & (AUTOFIRE_STAT_ALERT|AUTOFIRE_STAT_FIRING)) + return + autofire_stat = AUTOFIRE_STAT_ALERT + clicker = usercli + shooter = clicker.mob + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDOWN, .proc/on_mouse_down) + RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT, .proc/autofire_off) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN) + parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, /obj/item/gun/.proc/autofire_bypass_check) + parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, /obj/item/gun/.proc/do_autofire) + + +/datum/component/automatic_fire/proc/autofire_off(datum/source) + SIGNAL_HANDLER + if(autofire_stat & (AUTOFIRE_STAT_IDLE)) + return + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() + + autofire_stat = AUTOFIRE_STAT_IDLE + + if(!QDELETED(clicker)) + UnregisterSignal(clicker, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG)) + mouse_status = AUTOFIRE_MOUSEUP //In regards to the component there's no click anymore to care about. + clicker = null + RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN, .proc/on_client_login) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT) + shooter = null + parent.UnregisterSignal(parent, COMSIG_AUTOFIRE_SHOT) + parent.UnregisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN) + +/datum/component/automatic_fire/proc/on_client_login(mob/source) + SIGNAL_HANDLER + if(!source.client) + return + if(source.is_holding(parent)) + autofire_on(source.client) + +/datum/component/automatic_fire/proc/on_mouse_down(client/source, atom/_target, turf/location, control, params) + var/list/modifiers = params2list(params) //If they're shift+clicking, for example, let's not have them accidentally shoot. + + if(LAZYACCESS(modifiers, SHIFT_CLICK)) + return + if(LAZYACCESS(modifiers, CTRL_CLICK)) + return + if(LAZYACCESS(modifiers, MIDDLE_CLICK)) + return + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + return + if(LAZYACCESS(modifiers, ALT_CLICK)) + return + if(source.mob.in_throw_mode) + return + if(!isturf(source.mob.loc)) //No firing inside lockers and stuff. + return + if(get_dist(source.mob, _target) < 2) //Adjacent clicking. + return + + if(isnull(location)) //Clicking on a screen object. + if(_target.plane != CLICKCATCHER_PLANE) //The clickcatcher is a special case. We want the click to trigger then, under it. + return //If we click and drag on our worn backpack, for example, we want it to open instead. + _target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source) + if(!_target) + CRASH("Failed to get the turf under clickcatcher") + + if(SEND_SIGNAL(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, source, _target, location, control, params) & COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS) + return + + source.click_intercept_time = world.time //From this point onwards Click() will no longer be triggered. + + if(autofire_stat & (AUTOFIRE_STAT_IDLE)) + CRASH("on_mouse_down() called with [autofire_stat] autofire_stat") + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() //This can happen if we click and hold and then alt+tab, printscreen or other such action. MouseUp won't be called then and it will keep autofiring. + + target = _target + target_loc = get_turf(target) + mouse_parameters = params + start_autofiring() + + +//Dakka-dakka +/datum/component/automatic_fire/proc/start_autofiring() + if(autofire_stat == AUTOFIRE_STAT_FIRING) + return //Already pew-pewing. + autofire_stat = AUTOFIRE_STAT_FIRING + + clicker.mouse_override_icon = 'icons/effects/mouse_pointers/weapon_pointer.dmi' + clicker.mouse_pointer_icon = clicker.mouse_override_icon + + if(mouse_status == AUTOFIRE_MOUSEUP) //See mouse_status definition for the reason for this. + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEUP, .proc/on_mouse_up) + mouse_status = AUTOFIRE_MOUSEDOWN + + RegisterSignal(shooter, COMSIG_MOB_SWAP_HANDS, .proc/stop_autofiring) + + if(isgun(parent)) + var/obj/item/gun/shoota = parent + if(!shoota.on_autofire_start(shooter)) //This is needed because the minigun has a do_after before firing and signals are async. + stop_autofiring() + return + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return //Things may have changed while on_autofire_start() was being processed, due to do_after's sleep. + + if(!process_shot()) //First shot is processed instantly. + return //If it fails, such as when the gun is empty, then there's no need to schedule a second shot. + + START_PROCESSING(SSprojectiles, src) + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG, .proc/on_mouse_drag) + + +/datum/component/automatic_fire/proc/on_mouse_up(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEUP) + mouse_status = AUTOFIRE_MOUSEUP + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() + return COMPONENT_CLIENT_MOUSEUP_INTERCEPT + + +/datum/component/automatic_fire/proc/stop_autofiring(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + switch(autofire_stat) + if(AUTOFIRE_STAT_IDLE, AUTOFIRE_STAT_ALERT) + return + STOP_PROCESSING(SSprojectiles, src) + autofire_stat = AUTOFIRE_STAT_ALERT + if(clicker) + clicker.mouse_override_icon = null + clicker.mouse_pointer_icon = clicker.mouse_override_icon + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_SWAP_HANDS) + target = null + target_loc = null + mouse_parameters = null + +/datum/component/automatic_fire/proc/on_mouse_drag(client/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + SIGNAL_HANDLER + if(isnull(over_location)) //This happens when the mouse is over an inventory or screen object, or on entering deep darkness, for example. + var/list/modifiers = params2list(params) + var/new_target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source) + mouse_parameters = params + if(!new_target) + if(QDELETED(target)) //No new target acquired, and old one was deleted, get us out of here. + stop_autofiring() + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]. Old target was incidentally QDELETED.") + target = get_turf(target) //If previous target wasn't a turf, let's turn it into one to avoid locking onto a potentially moving target. + target_loc = target + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]") + target = new_target + target_loc = new_target + return + target = over_object + target_loc = get_turf(over_object) + mouse_parameters = params + + +/datum/component/automatic_fire/proc/process_shot() + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return + if(QDELETED(target) || get_turf(target) != target_loc) //Target moved or got destroyed since we last aimed. + target = target_loc //So we keep firing on the emptied tile until we move our mouse and find a new target. + if(get_dist(shooter, target) <= 0) + target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. + target_loc = target + else if(!in_view_range(shooter, target)) + stop_autofiring() //Elvis has left the building. + return FALSE + shooter.face_atom(target) + COOLDOWN_START(src, next_shot_cd, autofire_shot_delay) + if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) + return TRUE + stop_autofiring() + return FALSE + +// Gun procs. + +/obj/item/gun/proc/on_autofire_start(mob/living/shooter) + if(!can_shoot(shooter) || !can_trigger_gun(shooter) || semicd) + return FALSE + var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index()) + if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand)) + to_chat(shooter, "You need two hands to fire [src]!") + return FALSE + return TRUE + + +/obj/item/gun/proc/autofire_bypass_check(datum/source, client/clicker, atom/target, turf/location, control, params) + SIGNAL_HANDLER + if(clicker.mob.get_active_held_item() != src) + return COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS + + +/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params) + SIGNAL_HANDLER_DOES_SLEEP + if(!can_shoot()) + shoot_with_empty_chamber(shooter) + return NONE + var/obj/item/gun/akimbo_gun = shooter.get_inactive_held_item() + var/bonus_spread = 0 + if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM) + if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter)) + bonus_spread = dual_wield_spread + addtimer(CALLBACK(akimbo_gun, /obj/item/gun.proc/process_fire, target, shooter, TRUE, params, null, bonus_spread), 1) + process_fire(target, shooter, TRUE, params, null, bonus_spread) + return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting. + +#undef AUTOFIRE_MOUSEUP +#undef AUTOFIRE_MOUSEDOWN diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index b6de6c300a..c14b7b1d0a 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -86,6 +86,9 @@ return FALSE return TRUE +/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE) + return ..() && (length(dead_players) + length(list_observers) >= required_applicants) + /datum/dynamic_ruleset/midround/from_ghosts/execute() var/list/possible_candidates = list() possible_candidates.Add(dead_players) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index c0866ce165..2a0dbd316a 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -34,6 +34,8 @@ /obj/machinery/door/firedoor/Initialize(mapload) . = ..() CalculateAffectingAreas() + UpdateAdjacencyFlags() + /obj/machinery/door/firedoor/examine(mob/user) . = ..() @@ -53,6 +55,20 @@ var/area/A = I LAZYADD(A.firedoors, src) +/obj/machinery/door/firedoor/proc/UpdateAdjacencyFlags() + var/turf/T = get_turf(src) + if(flags_1 & ON_BORDER_1) + for(var/t in T.atmos_adjacent_turfs) + if(get_dir(loc, t) == dir) + var/turf/open/T2 = t + T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK + T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK + else + for(var/t in T.atmos_adjacent_turfs) + var/turf/open/T2 = t + T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK + T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK + /obj/machinery/door/firedoor/closed icon_state = "door_closed" opacity = TRUE diff --git a/code/game/machinery/posi_alert.dm b/code/game/machinery/posi_alert.dm new file mode 100644 index 0000000000..a2a67f22f9 --- /dev/null +++ b/code/game/machinery/posi_alert.dm @@ -0,0 +1,55 @@ +/obj/machinery/posialert + name = "automated positronic alert console" + desc = "A console that will ping when a positronic personality is available for download." + icon = 'icons/obj/machines/terminals.dmi' + icon_state = "posialert" + var/inuse = FALSE + var/online = TRUE + + var/obj/item/radio/radio + var/radio_key = /obj/item/encryptionkey/headset_sci + var/science_channel = "Science" + +/obj/machinery/posialert/Initialize(mapload, ndir, building) + . = ..() + radio = new(src) + radio.keyslot = new radio_key + radio.listening = 0 + radio.recalculateChannels() + if(building) + setDir(ndir) + pixel_x = (dir & 3)? 0 : (dir == 4 ? -32 : 32) + pixel_y = (dir & 3)? (dir ==1 ? -32 : 32) : 0 + + +/obj/machinery/posialert/Destroy() + QDEL_NULL(radio) + return ..() + +/obj/item/wallframe/posialert + name = "automated positronic alert console frame" + desc = "Used to build positronic alert consoles, just secure to the wall." + icon_state = "newscaster" + custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000) + result_path = /obj/machinery/posialert + +/obj/machinery/posialert/attack_hand(mob/living/user) + online = !online + to_chat(user, "You turn the posi-alert system [online ? "on" : "off"]!") + return + +/obj/machinery/posialert/attack_ghost(mob/user) + . = ..() + if(!online) + return + if(inuse) + return + inuse = TRUE + flick("posialertflash",src) + visible_message("There are positronic personalities available!") + radio.talk_into(src, "There are positronic personalities available!", science_channel) + playsound(loc, 'sound/machines/ping.ogg', 50) + addtimer(CALLBACK(src, .proc/liftcooldown), 300) + +/obj/machinery/posialert/proc/liftcooldown() + inuse = FALSE diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 7fb1dd0065..5ff7bbc714 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1232,6 +1232,51 @@ GLOBAL_LIST_EMPTY(PDAs) continue . += P +//borg pda stuff +/mob/living/silicon/robot/proc/cmd_send_pdamesg(mob/user) + var/list/plist = list() + var/list/namecounts = list() + + if(aiPDA.toff) + to_chat(user, "Turn on your receiver in order to send messages.") + return + + for (var/obj/item/pda/P in get_viewable_pdas()) + if (P == src) + continue + else if (P == aiPDA) + continue + + plist[avoid_assoc_duplicate_keys(P.owner, namecounts)] = P + + var/c = input(user, "Please select a PDA") as null|anything in sortList(plist) + + if (!c) + return + + var/selected = plist[c] + + if(aicamera.stored.len) + var/add_photo = input(user,"Do you want to attach a photo?","Photo","No") as null|anything in list("Yes","No") + if(add_photo=="Yes") + var/datum/picture/Pic = aicamera.selectpicture(user) + aiPDA.picture = Pic + + if(incapacitated()) + return + + aiPDA.create_message(src, selected) + + +/mob/living/silicon/robot/proc/cmd_show_message_log(mob/user) + if(incapacitated()) + return + if(!isnull(aiPDA)) + var/HTML = "AI PDA Message Log[aiPDA.tnote]" + user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") + else + to_chat(user, "You do not have a PDA. You should make an issue report about this.") + #undef PDA_SCANNER_NONE #undef PDA_SCANNER_MEDICAL #undef PDA_SCANNER_FORENSICS diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index ce5305f7dc..3a3ffd7ea1 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -5,6 +5,7 @@ item_state = "walkietalkie" desc = "A basic handheld radio that communicates with local telecommunication networks." dog_fashion = /datum/dog_fashion/back + var/list/extra_channels = list() //Allows indivudal channels, used for borgs flags_1 = CONDUCT_1 | HEAR_1 slot_flags = ITEM_SLOT_BELT @@ -69,6 +70,11 @@ if(keyslot.independent) independent = TRUE + if(extra_channels) + for(var/ch_name in extra_channels) + if(!(ch_name in channels)) + channels[ch_name] = extra_channels[ch_name] + for(var/ch_name in channels) secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name]) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 0b39a83e7e..a49b373be6 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -215,7 +215,6 @@ as performing this in action() will cause the upgrade to end up in the borg inst C.icon_state = initial(icon_state) for(var/obj/item/ammo_casing/energy/plasma/weak/L in C.ammo_type) L.projectile_type = initial(L.projectile_type) - /obj/item/borg/upgrade/tboh name = "janitor cyborg trash bag of holding" desc = "A trash bag of holding replacement for the janiborg's standard trash bag." diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index a62fc70917..7502d4b2f0 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( if(turf_type) var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags) - CALCULATE_ADJACENT_TURFS(newT) + newT.ImmediateCalculateAdjacentTurfs() /turf/proc/copyTurf(turf/T) if(T.type != type) @@ -285,10 +285,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( //If you modify this function, ensure it works correctly with lateloaded map templates. /turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf() levelupdate() - if(flags & CHANGETURF_RECALC_ADJACENT) - ImmediateCalculateAdjacentTurfs() - else - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() //update firedoor adjacency var/list/turfs_to_check = get_adjacent_open_turfs(src) | src diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index dc44ac728f..549e244669 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(station_turfs) add_overlay(/obj/effect/fullbright) if(requires_activation) - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() if (light_power && light_range) update_light() @@ -111,7 +111,7 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/proc/set_temperature() /turf/proc/Initalize_Atmos(times_fired) - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() /turf/Destroy(force) . = QDEL_HINT_IWILLGC diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm index 8d063825f1..033ea6d871 100644 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ b/code/modules/atmospherics/environmental/LINDA_system.dm @@ -40,21 +40,19 @@ return FALSE /turf/proc/ImmediateCalculateAdjacentTurfs() - if(SSair.thread_running()) - CALCULATE_ADJACENT_TURFS(src) - return var/canpass = CANATMOSPASS(src, src) var/canvpass = CANVERTICALATMOSPASS(src, src) for(var/direction in GLOB.cardinals_multiz) var/turf/T = get_step_multiz(src, direction) if(!istype(T)) continue - var/opp_dir = REVERSE_DIR(direction) if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs) - atmos_adjacent_turfs[T] = direction - T.atmos_adjacent_turfs[src] = opp_dir + atmos_adjacent_turfs[T] = ATMOS_ADJACENT_ANY + T.atmos_adjacent_turfs[src] = ATMOS_ADJACENT_ANY + for(var/obj/machinery/door/firedoor/FD in T) + FD.UpdateAdjacencyFlags() else if (atmos_adjacent_turfs) atmos_adjacent_turfs -= T @@ -65,7 +63,8 @@ T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1) UNSETEMPTY(atmos_adjacent_turfs) src.atmos_adjacent_turfs = atmos_adjacent_turfs - set_sleeping(blocks_air) + for(var/obj/machinery/door/firedoor/FD in src) + FD.UpdateAdjacencyFlags() __update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf())) /turf/proc/set_sleeping(should_sleep) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 56820d2836..d7fb2e8b5a 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -280,7 +280,11 @@ we use a hook instead parse_gas_string(model.initial_gas_mix) return 1 +/datum/gas_mixture/proc/__auxtools_parse_gas_string(gas_string) + /datum/gas_mixture/parse_gas_string(gas_string) + return __auxtools_parse_gas_string(gas_string) + /* gas_string = SSair.preprocess_gas_string(gas_string) var/list/gas = params2list(gas_string) @@ -295,6 +299,7 @@ we use a hook instead set_moles(id, text2num(gas[id])) archive() return 1 + */ /* /datum/gas_mixture/react(datum/holder) . = NO_REACTION diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm index e4060de1a2..557061e5a6 100644 --- a/code/modules/cargo/centcom_podlauncher.dm +++ b/code/modules/cargo/centcom_podlauncher.dm @@ -567,7 +567,8 @@ else if(picking_dropoff_turf) holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed - holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released) + holder.mouse_override_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released) + holder.mouse_pointer_icon = holder.mouse_override_icon holder.click_intercept = src //Create a click_intercept so we know where the user is clicking else var/mob/holder_mob = holder.mob diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 294fdcc30b..c1399ce646 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -22,6 +22,8 @@ ///Contains admin info. Null if client is not an admin. var/datum/admins/holder = null var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc + ///Time when the click was intercepted + var/click_intercept_time = 0 var/AI_Interact = 0 var/jobbancache = null //Used to cache this client's jobbans to save on DB queries @@ -78,6 +80,8 @@ //These two vars are used to make a special mouse cursor, with a unique icon for clicking var/mouse_up_icon = null var/mouse_down_icon = null + ///used to override the mouse cursor so it doesnt get reset + var/mouse_override_icon = null var/ip_intel = "Disabled" diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index a268eac90a..24f792afa3 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -876,6 +876,16 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( return last_activity = world.time last_click = world.time + //fullauto stuff + /* + if(!control) + return + */ + if(click_intercept_time) + if(click_intercept_time >= world.time) + click_intercept_time = 0 //Reset and return. Next click should work, but not this one. + return + click_intercept_time = 0 //Just reset. Let's not keep re-checking forever. var/list/L = params2list(params) if(L["drag"]) diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index 738d10665a..d69b9da768 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list( if(toupdate.len) for(var/turf/T1 in toupdate) - CALCULATE_ADJACENT_TURFS(T1) + T1.ImmediateCalculateAdjacentTurfs() return copiedobjs diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 7e0b996fff..f48aaf3df2 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -132,7 +132,7 @@ . = list() var/mob/living/carbon/human/H var/obj/item/card/id/C - if(ishuman(user)) + if(ishuman(user) || iscyborg(user)) H = user C = H.get_idcard(TRUE) if(C) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 19847d9bdc..2392ee03e0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -4,6 +4,7 @@ icon = 'icons/mob/robots.dmi' icon_state = "robot" bubble_icon = "robot" + var/obj/item/pda/ai/aiPDA /mob/living/silicon/robot/get_cell() return cell @@ -27,6 +28,12 @@ inv2 = new /atom/movable/screen/robot/module2() inv3 = new /atom/movable/screen/robot/module3() + if(!shell) + aiPDA = new/obj/item/pda/ai(src) + aiPDA.owner = real_name + aiPDA.ownjob = "Cyborg" + aiPDA.name = real_name + " (" + aiPDA.ownjob + ")" + previous_health = health if(ispath(cell)) @@ -968,6 +975,9 @@ notify_ai(RENAME, oldname, newname) if(!QDELETED(builtInCamera)) builtInCamera.c_tag = real_name + if(aiPDA && !shell) + aiPDA.owner = newname + aiPDA.name = newname + " (" + aiPDA.ownjob + ")" custom_name = newname diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 50463b436c..5b49af9a20 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -16,6 +16,7 @@ var/list/modules = list() //holds all the usable modules var/list/added_modules = list() //modules not inherient to the robot module, are kept when the module changes var/list/storages = list() + var/list/added_channels = list() //Borg radio stuffs var/cyborg_base_icon = "robot" //produces the icon for the borg and, if no special_light_key is set, the lights var/special_light_key //if we want specific lights, use this instead of copying lights in the dmi @@ -263,6 +264,8 @@ R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine/dogborg else R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine + R.radio.extra_channels = RM.added_channels + R.radio.recalculateChannels() R.maxHealth = borghealth R.health = min(borghealth, R.health) qdel(src) @@ -349,6 +352,7 @@ /obj/item/robot_module/medical name = "Medical" + added_channels = list(RADIO_CHANNEL_MEDICAL = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -467,6 +471,7 @@ /obj/item/robot_module/engineering name = "Engineering" + added_channels = list(RADIO_CHANNEL_ENGINEERING = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/borg/sight/meson, @@ -587,6 +592,7 @@ /obj/item/robot_module/security name = "Security" + added_channels = list(RADIO_CHANNEL_SECURITY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -695,6 +701,7 @@ /obj/item/robot_module/peacekeeper name = "Peacekeeper" + added_channels = list(RADIO_CHANNEL_SECURITY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -787,6 +794,7 @@ /obj/item/robot_module/clown name = "Clown" + added_channels = list(RADIO_CHANNEL_SERVICE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -819,6 +827,7 @@ /obj/item/robot_module/butler name = "Service" + added_channels = list(RADIO_CHANNEL_SERVICE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -968,6 +977,7 @@ /obj/item/robot_module/miner name = "Miner" + added_channels = list(RADIO_CHANNEL_SUPPLY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -1064,6 +1074,7 @@ /obj/item/robot_module/syndicate name = "Syndicate Assault" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -1094,6 +1105,7 @@ /obj/item/robot_module/syndicate_medical name = "Syndicate Medical" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -1126,6 +1138,7 @@ /obj/item/robot_module/saboteur name = "Syndicate Saboteur" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/borg/sight/thermal, diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index be10567790..63021287e5 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -912,6 +912,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if (!client) return client.mouse_pointer_icon = initial(client.mouse_pointer_icon) + // Consider using mouse override icon or snapping this section. if(pull_cursor_icon && client.keys_held["Ctrl"]) client.mouse_pointer_icon = pull_cursor_icon else if(throw_cursor_icon && in_throw_mode != 0) @@ -920,10 +921,13 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) client.mouse_pointer_icon = combat_cursor_icon else if(examine_cursor_icon && client.keys_held["Shift"]) //mouse shit is hardcoded, make this non hard-coded once we make mouse modifiers bindable client.mouse_pointer_icon = examine_cursor_icon - else if (ismecha(loc)) - var/obj/vehicle/sealed/mecha/M = loc - if(M.mouse_pointer) - client.mouse_pointer_icon = M.mouse_pointer + // + else if(istype(loc, /obj/vehicle/sealed)) + var/obj/vehicle/sealed/mecha/E = loc + if(E.mouse_pointer) + client.mouse_pointer_icon = E.mouse_pointer + if(client.mouse_override_icon) + client.mouse_pointer_icon = client.mouse_override_icon /mob/proc/is_literate() return 0 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index f7f5b335c5..cb02a440b8 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -952,7 +952,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) playsound(T, 'sound/effects/supermatter.ogg', 50, 1) T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ "You hear a loud crack as you are washed with a wave of heat.") - CALCULATE_ADJACENT_TURFS(T) + T.ImmediateCalculateAdjacentTurfs() //Do not blow up our internal radio /obj/machinery/power/supermatter_crystal/contents_explosion(severity, target, origin) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 7f1f43efc3..236143dc43 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -22,6 +22,7 @@ var/ranged_attack_speed = CLICK_CD_RANGE var/melee_attack_speed = CLICK_CD_MELEE + var/gun_flags = NONE var/fire_sound = "gunshot" var/suppressed = null //whether or not a message is displayed when fired var/can_suppress = FALSE @@ -32,6 +33,7 @@ trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers var/sawn_desc = null //description change if weapon is sawn-off var/sawn_off = FALSE + var/firing_burst = 0 //Prevent the weapon from firing again while already firing /// can we be put into a turret var/can_turret = TRUE @@ -57,6 +59,8 @@ var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0. var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once. var/inaccuracy_modifier = 1 + var/semicd = 0 //cooldown handler + var/dual_wield_spread = 24 //additional spread when dual wielding lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' @@ -87,27 +91,64 @@ var/zoom_out_amt = 0 var/datum/action/item_action/toggle_scope_zoom/azoom + //Firemodes + var/datum/action/item_action/toggle_firemode/firemode_action + /// Current fire selection, can choose between burst, single, and full auto. + var/fire_select = SELECT_SEMI_AUTOMATIC + var/fire_select_index = 1 + /// What modes does this weapon have? Put SELECT_FULLY_AUTOMATIC in here to enable fully automatic behaviours. + var/list/fire_select_modes = list(SELECT_SEMI_AUTOMATIC) + /// if i`1t has an icon for a selector switch indicating current firemode. + var/selector_switch_icon = FALSE + var/dualwield_spread_mult = 1 //dualwield spread multiplier /// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun. var/projectile_damage_multiplier = 1 - var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds - /// directional recoil multiplier var/dir_recoil_amp = 10 +/obj/item/gun/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_firemode)) + fire_select() + else if(istype(action, /datum/action/item_action/toggle_scope_zoom)) + zoom(user, user.dir) + else if(istype(action, alight)) + toggle_gunlight() + else + ..() + /obj/item/gun/Initialize(mapload) . = ..() - if(no_pin_required) - pin = null - else if(pin) + if(pin) pin = new pin(src) + if(gun_light) - alight = new (src) + alight = new(src) + if(zoomable) azoom = new (src) + if(burst_size > 1 && !(SELECT_BURST_SHOT in fire_select_modes)) + fire_select_modes.Add(SELECT_BURST_SHOT) + else if(burst_size <= 1 && (SELECT_BURST_SHOT in fire_select_modes)) + fire_select_modes.Remove(SELECT_BURST_SHOT) + + burst_size = 1 + + sortList(fire_select_modes, /proc/cmp_numeric_asc) + + if(fire_select_modes.len > 1) + firemode_action = new(src) + firemode_action.button_icon_state = "fireselect_[fire_select]" + firemode_action.UpdateButtonIcon() + +/obj/item/gun/ComponentInitialize() + . = ..() + if(SELECT_FULLY_AUTOMATIC in fire_select_modes) + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/gun/Destroy() if(pin) QDEL_NULL(pin) @@ -117,6 +158,10 @@ QDEL_NULL(bayonet) if(chambered) QDEL_NULL(chambered) + if(azoom) + QDEL_NULL(azoom) + if(firemode_action) + QDEL_NULL(firemode_action) return ..() /obj/item/gun/examine(mob/user) @@ -142,6 +187,41 @@ else if(can_bayonet) . += "It has a bayonet lug on it." +/obj/item/gun/proc/fire_select() + var/mob/living/carbon/human/user = usr + + var/max_mode = fire_select_modes.len + + if(max_mode <= 1) + to_chat(user, "[src] is not capable of switching firemodes!") + return + + fire_select_index = 1 + fire_select_index % max_mode //Magic math to cycle through this shit! + + fire_select = fire_select_modes[fire_select_index] + + switch(fire_select) + if(SELECT_SEMI_AUTOMATIC) + burst_size = 1 + fire_delay = 0 + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user) + to_chat(user, "You switch [src] to semi-automatic.") + if(SELECT_BURST_SHOT) + burst_size = initial(burst_size) + fire_delay = initial(fire_delay) + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user) + to_chat(user, "You switch [src] to [burst_size]-round burst.") + if(SELECT_FULLY_AUTOMATIC) + burst_size = 1 + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_SELECTED, user) + to_chat(user, "You switch [src] to automatic.") + + playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) + update_appearance() + firemode_action.button_icon_state = "fireselect_[fire_select]" + firemode_action.UpdateButtonIcon() + return TRUE + /obj/item/gun/equipped(mob/living/user, slot) . = ..() if(zoomed && user.get_active_held_item() != src) @@ -567,12 +647,6 @@ gun_light = new_light -/obj/item/gun/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_scope_zoom)) - zoom(user, user.dir) - else if(istype(action, alight)) - toggle_gunlight() - /obj/item/gun/proc/toggle_gunlight() if(!gun_light) return diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 4b871d59b2..4d08520246 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -5,8 +5,8 @@ var/automatic_burst_overlay = TRUE can_suppress = TRUE burst_size = 3 - burst_shot_delay = 2 - actions_types = list(/datum/action/item_action/toggle_firemode) + fire_delay = 2 + fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC) /obj/item/gun/ballistic/automatic/proto name = "\improper Nanotrasen Saber SMG" @@ -15,6 +15,7 @@ fire_sound = "sound/weapons/gunshot_smg_alt.ogg" mag_type = /obj/item/ammo_box/magazine/smgm9mm pin = null + burst_size = 1 /obj/item/gun/ballistic/automatic/proto/unrestricted pin = /obj/item/firing_pin @@ -55,34 +56,6 @@ else to_chat(user, "You cannot seem to get \the [src] out of your hands!") -/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_firemode)) - burst_select() - else - return ..() - -/obj/item/gun/ballistic/automatic/proc/burst_select() - var/mob/living/carbon/human/user = usr - select = !select - if(!select) - disable_burst() - to_chat(user, "You switch to semi-automatic.") - else - enable_burst() - to_chat(user, "You switch to [burst_size]-rnd burst.") - - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/gun/ballistic/automatic/proc/enable_burst() - burst_size = initial(burst_size) - -/obj/item/gun/ballistic/automatic/proc/disable_burst() - burst_size = 1 - /obj/item/gun/ballistic/automatic/can_shoot() return get_ammo() @@ -136,18 +109,10 @@ knife_y_offset = 12 automatic_burst_overlay = FALSE -/obj/item/gun/ballistic/automatic/wt550/enable_burst() - . = ..() - spread = 15 - /obj/item/gun/ballistic/automatic/wt550/afterattack() . = ..() empty_alarm() -/obj/item/gun/ballistic/automatic/wt550/disable_burst() - . = ..() - spread = 0 - /obj/item/gun/ballistic/automatic/wt550/update_icon_state() icon_state = "wt550[magazine ? "-[CEILING(((get_ammo(FALSE) / magazine.max_ammo) * 20) /4, 1)*4]" : "-0"]" //Sprites only support up to 20. @@ -211,6 +176,7 @@ /obj/item/gun/ballistic/automatic/m90/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "" : "-e"]" +/* /obj/item/gun/ballistic/automatic/m90/burst_select() var/mob/living/carbon/human/user = usr switch(select) @@ -228,6 +194,7 @@ playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_icon() return +*/ /obj/item/gun/ballistic/automatic/tommygun name = "\improper Thompson SMG" @@ -304,14 +271,17 @@ slot_flags = 0 mag_type = /obj/item/ammo_box/magazine/mm712x82 weapon_weight = WEAPON_HEAVY - var/cover_open = FALSE can_suppress = FALSE - burst_size = 3 - burst_shot_delay = 1 + burst_size = 1 + actions_types = list() spread = 7 pin = /obj/item/firing_pin/implant/pindicate - automatic_burst_overlay = FALSE + var/cover_open = FALSE +/obj/item/gun/ballistic/automatic/l6_saw/Initialize() + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) /obj/item/gun/ballistic/automatic/l6_saw/unrestricted pin = /obj/item/firing_pin diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index c53366c4f5..10a6eea89d 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -39,7 +39,7 @@ mag_type = /obj/item/ammo_box/magazine/m75 burst_size = 1 fire_delay = 0 - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) casing_ejector = FALSE /obj/item/gun/ballistic/automatic/gyropistol/update_icon_state() diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 98b654aadb..bd6f203882 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -7,7 +7,7 @@ can_suppress = TRUE burst_size = 1 fire_delay = 0 - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) automatic_burst_overlay = FALSE /obj/item/gun/ballistic/automatic/pistol/no_mag @@ -104,7 +104,7 @@ mag_type = /obj/item/ammo_box/magazine/pistolm9mm burst_size = 3 fire_delay = 2 - actions_types = list(/datum/action/item_action/toggle_firemode) + fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC) /obj/item/gun/ballistic/automatic/pistol/stickman name = "flat gun" @@ -137,7 +137,7 @@ burst_size = 1 can_suppress = FALSE w_class = WEIGHT_CLASS_NORMAL - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) fire_sound = 'sound/weapons/noscope.ogg' spread = 20 //damn thing has no rifling. automatic_burst_overlay = FALSE diff --git a/code/modules/projectiles/guns/energy/laser_gatling.dm b/code/modules/projectiles/guns/energy/laser_gatling.dm index 16a977515c..65d525b638 100644 --- a/code/modules/projectiles/guns/energy/laser_gatling.dm +++ b/code/modules/projectiles/guns/energy/laser_gatling.dm @@ -101,8 +101,6 @@ slot_flags = null w_class = WEIGHT_CLASS_HUGE custom_materials = null - automatic = 0.5 - fire_delay = 2 ammo_type = list( /obj/item/ammo_casing/energy/laser ) diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm index 0fdef4819e..84d98fe1e3 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm @@ -75,6 +75,14 @@ build_path = /obj/item/wallframe/newscaster category = list("initial", "Construction") +/datum/design/posialert + name = "Posialert Frame" + id = "posialert_frame" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 14000, /datum/material/glass = 8000) + build_path = /obj/item/wallframe/posialert + category = list("initial", "Construction") + /datum/design/status_display_frame name = "Status Display Frame" id = "status_display_frame" diff --git a/dependencies.sh b/dependencies.sh index 7943782996..e0df827a2a 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -21,7 +21,7 @@ export SPACEMAN_DMM_VERSION=suite-1.7 export PYTHON_VERSION=3.7.9 # Auxmos git tag -export AUXMOS_VERSION=v1.1.1 +export AUXMOS_VERSION=v2.1.0 # Extools git tag export EXTOOLS_VERSION=v0.0.7 diff --git a/html/changelogs/archive/2022-09.yml b/html/changelogs/archive/2022-09.yml index 1cb1de1497..792c158035 100644 --- a/html/changelogs/archive/2022-09.yml +++ b/html/changelogs/archive/2022-09.yml @@ -46,7 +46,25 @@ 2022-09-19: Putnam3145: - code_imp: Auxmos updated to 2.0.0 -2022-09-22: +2022-09-23: shellspeed1: - rscadd: Massively buffs talking by adding 3 new speech verbs improving the ability of everyone to scream at each other. +2022-09-24: + Putnam3145: + - bugfix: Added a check to from-ghosts midrounds making them not able to roll if + there are no ghosts + shellspeed1: + - rscadd: full auto is now available for some weapons. + - rscadd: All automatic weapons now come with a firemode selector switch. + - rscadd: You can now take people hostage with a gun by using it on someone with + the grab intent on. + - bugfix: cyborg mining point card now works again. + - rscadd: Added the posialert console, now ghosts can complain at the roboticist + for not making posibrains. + - rscadd: Borgs now receive access to the comms associated with their department + by default! + zeroisthebiggay, retlaw34 (https://github.com/retlaw34), any%, tetrazeta, zxaber(https://github.com/zxaber): + - imageadd: Restyles the hud + - imageadd: The Airlock Shock Indicator seen when using a Diagnostics Hud has a + new sprite. diff --git a/icons/effects/mouse_pointers/weapon_pointer.dmi b/icons/effects/mouse_pointers/weapon_pointer.dmi new file mode 100644 index 0000000000..b5070062c0 Binary files /dev/null and b/icons/effects/mouse_pointers/weapon_pointer.dmi differ diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi index 10627cf66d..2eb92f4a45 100644 Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 32741d958b..fa71351bec 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/obj/machines/terminals.dmi b/icons/obj/machines/terminals.dmi new file mode 100644 index 0000000000..e504b35abb Binary files /dev/null and b/icons/obj/machines/terminals.dmi differ diff --git a/modular_sand/code/game/machinery/posialert.dm b/modular_sand/code/game/machinery/posialert.dm deleted file mode 100644 index 2ca1eeb7cf..0000000000 --- a/modular_sand/code/game/machinery/posialert.dm +++ /dev/null @@ -1,19 +0,0 @@ -/obj/machinery/posialert - name = "automated positronic alert console" - desc = "A console that will ping when a positronic personality is available for download." - icon = 'modular_sand/icons/obj/machines/terminals.dmi' - icon_state = "posialert" - var/inuse = FALSE - -/obj/machinery/posialert/attack_ghost(mob/user) - . = ..() - if(inuse) - return - inuse = TRUE - flick("posialertflash",src) - visible_message("There are positronic personalities available!", runechat_popup = TRUE) - playsound(loc, 'sound/machines/ping.ogg', 50) - addtimer(CALLBACK(src, /obj/machinery/posialert.proc/liftcooldown), 30 SECONDS) - -/obj/machinery/posialert/proc/liftcooldown() - inuse = FALSE diff --git a/modular_sand/icons/obj/machines/terminals.dmi b/modular_sand/icons/obj/machines/terminals.dmi deleted file mode 100644 index 36b60fb04e..0000000000 Binary files a/modular_sand/icons/obj/machines/terminals.dmi and /dev/null differ diff --git a/tgstation.dme b/tgstation.dme index 778cb37190..a4404da092 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -56,6 +56,7 @@ #include "code\__DEFINES\fantasy_affixes.dm" #include "code\__DEFINES\food.dm" #include "code\__DEFINES\footsteps.dm" +#include "code\__DEFINES\gun.dm" #include "code\__DEFINES\hud.dm" #include "code\__DEFINES\instruments.dm" #include "code\__DEFINES\integrated_electronics.dm" @@ -371,7 +372,6 @@ #include "code\controllers\configuration\entries\vote.dm" #include "code\controllers\subsystem\achievements.dm" #include "code\controllers\subsystem\activity.dm" -#include "code\controllers\subsystem\adjacent_air.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" #include "code\controllers\subsystem\atoms.dm" @@ -554,6 +554,7 @@ #include "code\datums\components\field_of_vision.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\fried.dm" +#include "code\datums\components\fullauto.dm" #include "code\datums\components\gps.dm" #include "code\datums\components\honkspam.dm" #include "code\datums\components\identification.dm" @@ -942,6 +943,7 @@ #include "code\game\machinery\mass_driver.dm" #include "code\game\machinery\navbeacon.dm" #include "code\game\machinery\PDApainter.dm" +#include "code\game\machinery\posi_alert.dm" #include "code\game\machinery\prisonlabor.dm" #include "code\game\machinery\quantum_pad.dm" #include "code\game\machinery\recharger.dm" @@ -3949,7 +3951,6 @@ #include "modular_sand\code\game\machinery\autodoc.dm" #include "modular_sand\code\game\machinery\cryopod.dm" #include "modular_sand\code\game\machinery\cryptominers.dm" -#include "modular_sand\code\game\machinery\posialert.dm" #include "modular_sand\code\game\machinery\Sleeper.dm" #include "modular_sand\code\game\machinery\computer\arcade\tetris.dm" #include "modular_sand\code\game\machinery\pipe\construction.dm"