diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm index 9943d57a2e4..d4bcfba43a2 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm @@ -106,6 +106,9 @@ /obj/structure/flora/bush/flowers_pp, /turf/open/floor/grass, /area/ruin/syndicate_lava_base/cargo) +"bh" = ( +/turf/closed/mineral/volcanic, +/area/lavaland/surface/outdoors) "bl" = ( /obj/machinery/shower/directional/west, /obj/structure/drain, @@ -182,10 +185,14 @@ /obj/machinery/light/directional/west, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"bG" = ( -/obj/structure/fans/tiny, -/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, -/turf/open/floor/iron/dark, +"bH" = ( +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) "bI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -472,10 +479,6 @@ }, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"ex" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/testlab) "ey" = ( /obj/structure/chair/office{ dir = 1 @@ -488,6 +491,19 @@ "eA" = ( /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) +"eF" = ( +/obj/structure/table/glass, +/obj/item/storage/box/syringes{ + pixel_x = 5; + pixel_y = 10 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/item/storage/bag/xeno, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/testlab) "eK" = ( /obj/machinery/vending/games{ onstation = 0 @@ -713,6 +729,14 @@ dir = 4 }, /area/ruin/syndicate_lava_base/bar) +"gE" = ( +/obj/structure/window/reinforced/survival_pod, +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/engine, +/area/ruin/syndicate_lava_base/testlab) "gF" = ( /obj/machinery/door/poddoor{ id = "interdynecargowest" @@ -935,18 +959,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"ji" = ( -/obj/structure/window/reinforced/survival_pod{ - dir = 1 - }, -/obj/structure/window/reinforced/survival_pod{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/ruin/syndicate_lava_base/testlab) "jj" = ( /obj/effect/turf_decal/tile/blue/darkblue{ dir = 1 @@ -1009,6 +1021,23 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/medbay) +"jM" = ( +/obj/structure/table/glass, +/obj/machinery/reagentgrinder{ + pixel_y = 6 + }, +/obj/item/stack/sheet/mineral/plasma{ + amount = 5 + }, +/obj/structure/window/reinforced/survival_pod{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/testlab) "jN" = ( /obj/machinery/firealarm/directional/south{ dir = 1 @@ -1185,6 +1214,11 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"lQ" = ( +/obj/machinery/monkey_recycler, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/testlab) "lS" = ( /obj/structure/displaycase{ alert = 0; @@ -1299,6 +1333,11 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"mL" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/testlab) "mN" = ( /turf/open/floor/engine/o2, /area/ruin/syndicate_lava_base/engineering) @@ -1335,6 +1374,16 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/cargo) +"nn" = ( +/obj/structure/window/reinforced/survival_pod{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/dark_red, +/turf/open/floor/engine, +/area/ruin/syndicate_lava_base/testlab) "no" = ( /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) @@ -1349,6 +1398,15 @@ /obj/structure/dresser, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) +"nr" = ( +/obj/structure/window/reinforced/survival_pod{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/ruin/syndicate_lava_base/testlab) "nt" = ( /obj/effect/turf_decal/tile/brown{ dir = 1 @@ -1620,9 +1678,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"qk" = ( -/turf/closed/mineral/volcanic, -/area/lavaland/surface/outdoors) "qr" = ( /obj/effect/turf_decal/siding/thinplating/dark/corner{ dir = 4 @@ -1684,18 +1739,6 @@ }, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"qU" = ( -/obj/structure/table/glass, -/obj/item/storage/box/syringes{ - pixel_x = 5; - pixel_y = 10 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/item/storage/bag/xeno, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/testlab) "qV" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/machinery/light/directional/north, @@ -2374,6 +2417,10 @@ }, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) +"yC" = ( +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/testlab) "yE" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 8 @@ -2646,13 +2693,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"AW" = ( -/obj/machinery/atmospherics/components/binary/volume_pump{ - dir = 4; - name = "BZ Pump" - }, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/testlab) "Bn" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/white, @@ -2858,6 +2898,14 @@ dir = 1 }, /area/ruin/syndicate_lava_base/bar) +"CQ" = ( +/obj/machinery/atmospherics/components/binary/volume_pump{ + dir = 4; + name = "BZ Pump" + }, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/testlab) "CR" = ( /obj/structure/window/reinforced/survival_pod{ dir = 1 @@ -3263,6 +3311,31 @@ /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/testlab) +"HH" = ( +/obj/structure/table/glass, +/obj/item/storage/box/monkeycubes/syndicate{ + pixel_y = 5 + }, +/obj/item/storage/box/monkeycubes/syndicate{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/slime_extract/grey{ + pixel_x = -2; + pixel_y = 2 + }, +/obj/item/slime_extract/grey, +/obj/item/slime_extract/grey{ + pixel_x = 2; + pixel_y = -2 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/window/reinforced/survival_pod, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/testlab) "HI" = ( /obj/structure/sign/directions/medical{ dir = 4; @@ -3325,10 +3398,6 @@ }, /turf/open/floor/engine/o2, /area/ruin/syndicate_lava_base/engineering) -"HZ" = ( -/obj/machinery/monkey_recycler, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/testlab) "Ig" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -3471,6 +3540,23 @@ }, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) +"Jw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/camera/xray{ + c_tag = "Xenobio East"; + dir = 4; + network = list("fsci") + }, +/obj/effect/turf_decal/tile/dark_red{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/passive_vent{ + dir = 1 + }, +/turf/open/floor/engine, +/area/ruin/syndicate_lava_base/testlab) "JB" = ( /turf/closed/wall/r_wall/syndicate, /area/ruin/syndicate_lava_base/main) @@ -3523,22 +3609,6 @@ /obj/structure/sink/directional/west, /turf/open/misc/grass, /area/ruin/syndicate_lava_base/bar) -"Kh" = ( -/obj/structure/table/glass, -/obj/machinery/reagentgrinder{ - pixel_y = 6 - }, -/obj/item/stack/sheet/mineral/plasma{ - amount = 5 - }, -/obj/structure/window/reinforced/survival_pod{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/testlab) "Ko" = ( /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -3781,18 +3851,6 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/testlab) -"Ml" = ( -/obj/structure/window/reinforced/survival_pod{ - dir = 1 - }, -/obj/structure/window/reinforced/survival_pod{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/engine, -/area/ruin/syndicate_lava_base/testlab) "Mn" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -4504,20 +4562,6 @@ /obj/structure/table/reinforced, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"Tw" = ( -/obj/structure/window/reinforced/survival_pod{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/camera/xray{ - c_tag = "Xenobio West"; - dir = 8; - network = list("fsci") - }, -/turf/open/floor/engine, -/area/ruin/syndicate_lava_base/testlab) "Tx" = ( /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/bar) @@ -4554,6 +4598,17 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"Ua" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/camera/xray{ + c_tag = "Xenobio West"; + dir = 8; + network = list("fsci") + }, +/turf/open/floor/engine, +/area/ruin/syndicate_lava_base/testlab) "Ub" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4587,19 +4642,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/smooth_edge, /area/ruin/syndicate_lava_base/cargo) -"UB" = ( -/obj/structure/window/reinforced/survival_pod{ - dir = 1 - }, -/obj/structure/window/reinforced/survival_pod{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/dark_red, -/turf/open/floor/engine, -/area/ruin/syndicate_lava_base/testlab) "UG" = ( /turf/closed/wall/r_wall/syndicate, /area/ruin/syndicate_lava_base/testlab) @@ -4654,6 +4696,15 @@ /obj/structure/lattice/catwalk, /turf/open/lava/smooth/lava_land_surface, /area/ruin/syndicate_lava_base/medbay) +"Vk" = ( +/obj/structure/fans/tiny, +/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, +/obj/machinery/door/window/survival_pod{ + req_access = list("syndicate"); + name = "Slime Pacification Chamber" + }, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/testlab) "Vm" = ( /obj/structure/window/reinforced/tinted, /obj/structure/window/reinforced/tinted{ @@ -4812,30 +4863,6 @@ "WW" = ( /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"WY" = ( -/obj/structure/table/glass, -/obj/item/storage/box/monkeycubes/syndicate{ - pixel_y = 5 - }, -/obj/item/storage/box/monkeycubes/syndicate{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/slime_extract/grey{ - pixel_x = -2; - pixel_y = 2 - }, -/obj/item/slime_extract/grey, -/obj/item/slime_extract/grey{ - pixel_x = 2; - pixel_y = -2 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/testlab) "Xd" = ( /obj/machinery/computer/pandemic, /obj/structure/window/reinforced/survival_pod, @@ -4907,28 +4934,6 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) -"XD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/camera/xray{ - c_tag = "Xenobio East"; - dir = 4; - network = list("fsci") - }, -/obj/machinery/door/window/survival_pod{ - req_access = list("syndicate"); - dir = 1; - name = "Slime Pacification Chamber" - }, -/obj/effect/turf_decal/tile/dark_red{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/passive_vent{ - dir = 1 - }, -/turf/open/floor/engine, -/area/ruin/syndicate_lava_base/testlab) "XJ" = ( /obj/structure/table/glass, /obj/machinery/firealarm/directional/west{ @@ -5268,38 +5273,38 @@ aa aa aa aa -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh aa aa aa @@ -5327,42 +5332,42 @@ aa aa aa ag -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh aa aa aa @@ -5418,13 +5423,13 @@ ab ab ab ab -qk -qk -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh +bh +bh aa aa aa @@ -5480,11 +5485,11 @@ ab ab ab ab -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh aa aa "} @@ -5543,8 +5548,8 @@ ab ab ab ab -qk -qk +bh +bh aa "} (6,1,1) = {" @@ -5582,8 +5587,8 @@ OW OW Yk Yu -qU -Tw +eF +Ua qz cr no @@ -5601,8 +5606,8 @@ ab ab ab ab -qk -qk +bh +bh aa aa "} @@ -5641,8 +5646,8 @@ RJ OW YF XV -WY -Ml +HH +nr qT WG Dt @@ -5661,14 +5666,14 @@ ab ab ab ab -qk -qk +bh +bh aa "} (8,1,1) = {" aa aa -qk +bh ag ab ag @@ -5700,8 +5705,8 @@ bb OW YW fv -Kh -ji +jM +bH ch Jt Ow @@ -5719,15 +5724,15 @@ ab ab ab ab -qk -qk +bh +bh aa aa "} (9,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -5759,8 +5764,8 @@ Cl OW Zd Ku -HZ -Ml +lQ +nr qT WG Yn @@ -5779,14 +5784,14 @@ ab ab ab ab -qk +bh ag aa "} (10,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -5818,9 +5823,9 @@ RL UX Zd Ku -Ku -ji -ch +yC +bH +gE Jt Ow OW @@ -5838,14 +5843,14 @@ ab ab ab ab -qk +bh ag aa "} (11,1,1) = {" aa -qk -qk +bh +bh ab ab Va @@ -5877,8 +5882,8 @@ RY OW Zn Do -ex -Ml +mL +nr qT WG Yn @@ -5898,13 +5903,13 @@ ab ab ab ab -qk -qk +bh +bh "} (12,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -5936,8 +5941,8 @@ Tg OW Ky BS -AW -UB +CQ +nn KY KY et @@ -5957,13 +5962,13 @@ ab ab ab ab -qk -qk +bh +bh "} (13,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -5995,8 +6000,8 @@ uE OW Fq oA -bG -XD +Vk +Jw aQ aQ AJ @@ -6016,13 +6021,13 @@ ab ab ab ab -qk -qk +bh +bh "} (14,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -6075,12 +6080,12 @@ ab ab ab ab -qk -qk +bh +bh "} (15,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -6134,12 +6139,12 @@ ab ab ab ab -qk -qk +bh +bh "} (16,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -6193,12 +6198,12 @@ ab ab ab ab -qk -qk +bh +bh "} (17,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -6252,12 +6257,12 @@ ab ab ab ab -qk -qk +bh +bh "} (18,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -6311,12 +6316,12 @@ ab ab ab ab -qk -qk +bh +bh "} (19,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -6369,14 +6374,14 @@ SE ab ab ab -qk -qk +bh +bh aa "} (20,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -6428,14 +6433,14 @@ SE ab ab ab -qk -qk +bh +bh aa "} (21,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -6486,15 +6491,15 @@ JS SE ab ab -qk -qk +bh +bh aa aa "} (22,1,1) = {" aa -qk -qk +bh +bh ab ab Zz @@ -6546,14 +6551,14 @@ Vb ab ab ab -qk -qk +bh +bh aa "} (23,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -6606,14 +6611,14 @@ ab ab ab ab -qk -qk +bh +bh "} (24,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -6665,14 +6670,14 @@ ab ab ab ab -qk -qk +bh +bh "} (25,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -6724,15 +6729,15 @@ ab ab ab ab -qk -qk +bh +bh "} (26,1,1) = {" aa aa aa -qk -qk +bh +bh ab ab NT @@ -6783,15 +6788,15 @@ ab ab ab ab -qk -qk +bh +bh "} (27,1,1) = {" aa aa aa -qk -qk +bh +bh ab ab ca @@ -6842,15 +6847,15 @@ ab ab ab ab -qk -qk +bh +bh "} (28,1,1) = {" aa aa aa -qk -qk +bh +bh ab ab NT @@ -6901,14 +6906,14 @@ ab ab ab ab -qk -qk +bh +bh "} (29,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -6959,15 +6964,15 @@ Tx Tx ab ab -qk -qk +bh +bh aa "} (30,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -7018,15 +7023,15 @@ yB Tx ab ab -qk -qk +bh +bh aa "} (31,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -7078,13 +7083,13 @@ jk ab ab ab -qk -qk +bh +bh "} (32,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7137,13 +7142,13 @@ Tx ab ab ab -qk -qk +bh +bh "} (33,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7196,13 +7201,13 @@ Tx ab ab ab -qk -qk +bh +bh "} (34,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7255,12 +7260,12 @@ ab ab ab ab -qk -qk +bh +bh "} (35,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7314,12 +7319,12 @@ ab ab ab ab -qk -qk +bh +bh "} (36,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7372,13 +7377,13 @@ Tx ab ab ab -qk -qk +bh +bh aa "} (37,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7432,12 +7437,12 @@ ab ab ab ab -qk -qk +bh +bh "} (38,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7490,13 +7495,13 @@ Tx ab ab ab -qk -qk +bh +bh aa "} (39,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7550,13 +7555,13 @@ ab ab ab ab -qk -qk +bh +bh "} (40,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7609,13 +7614,13 @@ ab ab ab ab -qk -qk +bh +bh "} (41,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7668,13 +7673,13 @@ ab ab ab ab -qk -qk +bh +bh "} (42,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7727,12 +7732,12 @@ ab ab ab ab -qk -qk +bh +bh "} (43,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7786,12 +7791,12 @@ ab ab ab ab -qk -qk +bh +bh "} (44,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7844,13 +7849,13 @@ Lq ab ab ab -qk -qk +bh +bh aa "} (45,1,1) = {" -qk -qk +bh +bh ab ab ab @@ -7903,14 +7908,14 @@ Lq ab ab ab -qk -qk +bh +bh aa "} (46,1,1) = {" aa -qk -qk +bh +bh ab ab ab @@ -7961,16 +7966,16 @@ Lq QS ab ab -qk -qk +bh +bh aa aa "} (47,1,1) = {" aa aa -qk -qk +bh +bh ab ab ab @@ -8021,16 +8026,16 @@ ab ab ab ab -qk -qk +bh +bh aa "} (48,1,1) = {" aa aa aa -qk -qk +bh +bh ab ab ab @@ -8079,8 +8084,8 @@ ab ab ab ab -qk -qk +bh +bh aa aa "} @@ -8089,8 +8094,8 @@ aa aa aa aa -qk -qk +bh +bh ab ab ab @@ -8138,8 +8143,8 @@ ab ab ab ab -qk -qk +bh +bh aa aa "} @@ -8149,19 +8154,19 @@ aa aa aa aa -qk -qk -qk +bh +bh +bh ab ab ab ab ab -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh ab ab ab @@ -8195,9 +8200,9 @@ ab ab ab ab -qk -qk -qk +bh +bh +bh aa aa aa @@ -8209,53 +8214,53 @@ aa aa aa aa -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh aa aa aa @@ -8270,49 +8275,49 @@ aa aa aa aa -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh aa aa aa aa aa -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk -qk +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh +bh aa aa aa diff --git a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm index f8ef39efa42..4f4ef4880e3 100644 --- a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm @@ -443,9 +443,9 @@ /area/ruin/space/ks13/medical/medbay) "fH" = ( /obj/machinery/door/morgue{ - name = "Chaplains Office" + name = "Chaplains Office"; + req_access = list("chapel_office") }, -/obj/effect/mapping_helpers/airlock/access/all/service/chapel_office, /turf/open/floor/iron/dark, /area/ruin/space/ks13/service/chapel_office) "fJ" = ( diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index 3000a8ec2e8..80a7f4a86fe 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -18,36 +18,51 @@ /area/ruin/space) "an" = ( /obj/structure/fluff/bus/passable/seat, -/obj/item/food/meatball, +/obj/item/toy/plush/pkplush{ + pixel_y = 17 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) "ao" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark/airless{ - icon_state = "bus" +/obj/machinery/telecomms/server{ + pixel_y = 12; + layer = 2.91; + name = "tgsv3"; + desc = "It's, uh... pending an upgrade." }, +/turf/closed/mineral/ash_rock, /area/ruin/space) "ap" = ( /obj/structure/fluff/bus/passable/seat{ pixel_y = 15 }, +/obj/item/toy/plush/lizard_plushie/green{ + pixel_y = 17 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) "aq" = ( /obj/structure/fluff/bus/passable/seat, -/obj/item/food/meatball, /obj/effect/decal/cleanable/dirt, +/obj/item/clothing/head/helmet/knight{ + pixel_y = 16 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) "ar" = ( /obj/structure/fluff/bus/passable/seat, -/obj/item/food/grown/cherry_bomb, +/obj/item/grown/novaflower{ + pixel_y = 25 + }, +/obj/item/food/grown/watermelon{ + pixel_y = 17 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, @@ -55,7 +70,15 @@ "as" = ( /obj/structure/fluff/bus/passable/seat/driver, /obj/effect/decal/cleanable/dirt, -/obj/item/food/grown/citrus/orange, +/obj/item/toy/plush/moth{ + pixel_y = 28 + }, +/obj/item/food/grown/citrus/orange{ + pixel_y = 19 + }, +/obj/item/toy/talking/ai{ + pixel_y = 16 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, @@ -117,7 +140,13 @@ "aU" = ( /obj/structure/fluff/bus/passable/seat, /obj/effect/decal/cleanable/dirt, -/obj/item/food/meatball, +/obj/item/bodypart/arm/right{ + pixel_y = 26; + pixel_x = -4 + }, +/obj/item/food/meat/slab/penguin{ + pixel_y = 13 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, @@ -132,29 +161,38 @@ "aW" = ( /obj/structure/fluff/bus/passable/seat/driver, /obj/effect/decal/cleanable/dirt, +/obj/item/banhammer{ + pixel_y = 22 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) "aZ" = ( /obj/structure/fluff/bus/passable, -/obj/effect/decal/cleanable/dirt, -/obj/item/food/meatball, +/obj/structure/sacrificealtar, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) "ba" = ( -/obj/structure/fluff/bus/passable, -/obj/item/banhammer, +/obj/structure/fluff/bus/passable/seat, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/ants{ + pixel_y = 8; + pixel_x = 9 + }, +/obj/item/food/grown/tomato{ + pixel_y = 25 + }, +/obj/item/food/donut/plain{ + pixel_y = 16; + pixel_x = 1 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, /area/ruin/space) -"dI" = ( -/obj/item/food/meatball, -/turf/open/misc/asteroid/airless, -/area/ruin/space) "iE" = ( /obj/structure/table, /obj/item/pai_card, @@ -239,6 +277,21 @@ }, /turf/open/misc/asteroid/airless, /area/ruin/space) +"FZ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/telecomms/server{ + pixel_y = 12; + layer = 2.91; + name = "tgsv3"; + desc = "It's, uh... pending an upgrade." + }, +/obj/item/toy/plush/awakenedplushie{ + pixel_y = 27 + }, +/turf/open/floor/iron/dark/airless{ + icon_state = "bus" + }, +/area/ruin/space) "Gf" = ( /obj/effect/decal/remains/human, /obj/item/clothing/suit/space, @@ -317,7 +370,13 @@ "XA" = ( /obj/structure/fluff/bus/passable/seat, /obj/effect/decal/cleanable/dirt, -/obj/item/toy/plush/awakenedplushie, +/obj/item/toy/singlecard{ + pixel_y = 25; + pixel_x = 0 + }, +/obj/item/food/grown/potato{ + pixel_y = 15 + }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" }, @@ -379,10 +438,10 @@ ab yY Bw yY -dI +yY Ne -aU -az +am +aZ ER yY yY @@ -402,7 +461,7 @@ yY yY Ne am -aZ +ax Xj yY yY @@ -422,7 +481,7 @@ Bw yY Ne aV -ba +az IQ yY yY @@ -436,12 +495,12 @@ ab Gt yY Ne -am +FZ ax ER yY Ne -aU +am az KK yY @@ -496,7 +555,7 @@ ab ab yY Ne -ao +ba aA KK uO @@ -576,7 +635,7 @@ ab Ds yY Ne -am +aU aD KK yY @@ -601,7 +660,7 @@ aE ud yY yY -dI +yY yY aa aa @@ -697,7 +756,7 @@ ab ab ab ab -ab +ao yY yY yY diff --git a/_maps/RandomRuins/SpaceRuins/derelict4.dmm b/_maps/RandomRuins/SpaceRuins/derelict4.dmm index 24af2072eff..56e5ed97a61 100644 --- a/_maps/RandomRuins/SpaceRuins/derelict4.dmm +++ b/_maps/RandomRuins/SpaceRuins/derelict4.dmm @@ -87,9 +87,7 @@ /turf/open/floor/plating/airless, /area/ruin/space/has_grav) "O" = ( -/obj/machinery/power/apc/auto_name/directional/north{ - start_charge = 0 - }, +/obj/item/wallframe/apc, /turf/open/floor/plating/airless, /area/ruin/space/has_grav) "Q" = ( diff --git a/_maps/RandomRuins/SpaceRuins/derelict8.dmm b/_maps/RandomRuins/SpaceRuins/derelict8.dmm index 656dcd36bad..826204b37eb 100644 --- a/_maps/RandomRuins/SpaceRuins/derelict8.dmm +++ b/_maps/RandomRuins/SpaceRuins/derelict8.dmm @@ -323,7 +323,7 @@ "SL" = ( /obj/effect/spawner/random/trash/mess, /obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/west, +/obj/item/wallframe/apc, /turf/open/floor/plating/airless, /area/ruin/space/has_grav) "SQ" = ( diff --git a/_maps/RandomZLevels/blackmesa.dmm b/_maps/RandomZLevels/blackmesa.dmm index 6b38dda3e8f..8c2d300c788 100644 --- a/_maps/RandomZLevels/blackmesa.dmm +++ b/_maps/RandomZLevels/blackmesa.dmm @@ -3998,9 +3998,7 @@ /area/awaymission/black_mesa/security_outpost) "aYe" = ( /obj/structure/rack/gunrack, -/obj/item/gun/ballistic/revolver/mateba{ - fire_select_modes = list(1,2) - }, +/obj/item/gun/ballistic/revolver/mateba, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/awaymission/black_mesa/security_outpost) @@ -5153,7 +5151,6 @@ /obj/item/gun/ballistic/automatic/pistol/g17/mesa{ burst_size = 3; desc = "A weapon from bygone times, and this is the exact 21st century version. In fact, even more reliable, but it also can run full automatic fire mode. Chambered in 9mm."; - fire_select_modes = list(1,2,3); firing_burst = 1; name = "\improper Glock-18" }, diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm index 53eb53ccefd..3afe74a6de0 100644 --- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm +++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm @@ -7002,6 +7002,7 @@ /obj/item/radio/headset/syndicate/alt, /obj/effect/turf_decal/bot_white, /obj/machinery/light/cold/directional/north, +/obj/item/clothing/suit/armor/vest, /turf/open/floor/iron/dark/textured_large, /area/cruiser_dock) "hAW" = ( @@ -7918,10 +7919,6 @@ /obj/effect/turf_decal/tile/red/opposingcorners, /turf/open/floor/iron/dark, /area/centcom/interlink) -"jUw" = ( -/obj/machinery/vending/cigarette, -/turf/open/floor/iron/dark, -/area/centcom/interlink) "jUK" = ( /obj/machinery/door/airlock/medical/glass{ name = "Interlink Medbay" @@ -11035,6 +11032,7 @@ desc = "It's a personal storage unit for operative gear." }, /obj/effect/turf_decal/bot_white, +/obj/item/clothing/suit/armor/vest, /turf/open/floor/iron/dark/textured_large, /area/cruiser_dock) "rVP" = ( @@ -11587,6 +11585,7 @@ }, /obj/effect/turf_decal/bot_white, /obj/machinery/light/cold/directional/south, +/obj/item/clothing/suit/armor/vest, /turf/open/floor/iron/dark/textured_large, /area/cruiser_dock) "ttx" = ( @@ -12398,6 +12397,7 @@ }, /obj/effect/turf_decal/bot_white, /obj/machinery/light/cold/directional/north, +/obj/item/clothing/suit/armor/vest, /turf/open/floor/iron/dark/textured_large, /area/cruiser_dock) "vxh" = ( @@ -27396,7 +27396,7 @@ aqG aqG aqG aDg -jUw +aXG jXO rDL hvQ diff --git a/_maps/shuttles/skyrat/goldeneye_cruiser.dmm b/_maps/shuttles/skyrat/goldeneye_cruiser.dmm index cb422500a7c..ac25206d7a3 100644 --- a/_maps/shuttles/skyrat/goldeneye_cruiser.dmm +++ b/_maps/shuttles/skyrat/goldeneye_cruiser.dmm @@ -264,6 +264,7 @@ "im" = ( /obj/structure/table/optable, /obj/effect/turf_decal/bot, +/obj/machinery/defibrillator_mount/directional/north, /turf/open/floor/iron/dark/textured_large, /area/shuttle/syndicate/cruiser/medical) "iU" = ( @@ -662,8 +663,9 @@ /area/shuttle/syndicate/cruiser/brig) "Iz" = ( /obj/structure/rack/shelf, -/obj/item/storage/backpack/duffelbag/syndie/surgery, /obj/effect/turf_decal/bot_white, +/obj/item/defibrillator/loaded, +/obj/item/storage/backpack/duffelbag/syndie/surgery, /turf/open/floor/iron/dark/textured_large, /area/shuttle/syndicate/cruiser/medical) "JA" = ( @@ -755,8 +757,7 @@ /area/shuttle/syndicate/cruiser/armory) "Pq" = ( /obj/structure/table/reinforced, -/obj/item/taperecorder, -/obj/item/tape, +/obj/machinery/recharger, /turf/open/floor/iron/dark/textured_large, /area/shuttle/syndicate/cruiser/bridge) "Py" = ( diff --git a/_maps/shuttles/whiteship_pubby.dmm b/_maps/shuttles/whiteship_pubby.dmm index 0e74204c05c..16f184e65fc 100644 --- a/_maps/shuttles/whiteship_pubby.dmm +++ b/_maps/shuttles/whiteship_pubby.dmm @@ -88,7 +88,6 @@ dir = 1; piping_layer = 4 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/shuttle/abandoned) @@ -756,7 +755,6 @@ /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 1 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/shuttle/abandoned) diff --git a/_maps/templates/lazy_templates/wizard_den.dmm b/_maps/templates/lazy_templates/wizard_den.dmm index 3fe8ac99751..c400cfa6641 100644 --- a/_maps/templates/lazy_templates/wizard_den.dmm +++ b/_maps/templates/lazy_templates/wizard_den.dmm @@ -186,13 +186,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/engine/cult, /area/centcom/wizard_station) -"tv" = ( -/obj/effect/decal/cleanable/blood/splatter, -/mob/living/simple_animal/hostile/netherworld{ - name = "Experiment 35b" - }, -/turf/open/floor/grass, -/area/centcom/wizard_station) "tz" = ( /obj/structure/table/wood/fancy, /obj/item/camera/spooky, @@ -310,6 +303,14 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron, /area/centcom/wizard_station) +"Iz" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/wizard/tape, +/obj/item/clothing/suit/wizrobe/tape, +/obj/item/staff/tape, +/obj/item/stack/sticky_tape/super, +/turf/open/floor/engine/cult, +/area/centcom/wizard_station) "IZ" = ( /obj/structure/chair/wood/wings{ dir = 1 @@ -388,6 +389,13 @@ /obj/structure/chair/wood/wings, /turf/open/floor/carpet, /area/centcom/wizard_station) +"QL" = ( +/obj/effect/decal/cleanable/blood/splatter, +/mob/living/simple_animal/hostile/netherworld{ + name = "Experiment 35b" + }, +/turf/open/floor/grass, +/area/centcom/wizard_station) "RT" = ( /obj/structure/table/wood/poker, /obj/item/toy/cards/deck/wizoff{ @@ -1346,7 +1354,7 @@ qo iQ gC dp -jp +Iz hT hT OV @@ -1518,7 +1526,7 @@ lL cs nN kZ -tv +QL JN kZ cs diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index 33b5808936c..cfb1da3c16e 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -544,7 +544,7 @@ /obj/item/modular_computer/pda/cargo = list(REGION_SUPPLY), \ /obj/item/modular_computer/pda/shaftminer = list(REGION_SUPPLY), \ /obj/item/modular_computer/pda/chaplain = list(REGION_GENERAL), \ - /obj/item/modular_computer/pda/lawyer = list(REGION_GENERAL, REGION_SECURITY), \ + /obj/item/modular_computer/pda/lawyer = list(REGION_GENERAL), \ /obj/item/modular_computer/pda/botanist = list(REGION_GENERAL), \ /obj/item/modular_computer/pda/roboticist = list(REGION_RESEARCH), \ /obj/item/modular_computer/pda/curator = list(REGION_GENERAL), \ diff --git a/code/__DEFINES/callbacks.dm b/code/__DEFINES/callbacks.dm index 705b8066119..8808c045abb 100644 --- a/code/__DEFINES/callbacks.dm +++ b/code/__DEFINES/callbacks.dm @@ -1,6 +1,23 @@ #define GLOBAL_PROC "some_magic_bullshit" /// A shorthand for the callback datum, [documented here](datum/callback.html) #define CALLBACK new /datum/callback -#define INVOKE_ASYNC world.ImmediateInvokeAsync + +///Per the DM reference, spawn(-1) will execute the spawned code immediately until a block is met. +#define MAKE_SPAWN_ACT_LIKE_WAITFOR -1 +///Create a codeblock that will not block the callstack if a block is met. +#define ASYNC spawn(MAKE_SPAWN_ACT_LIKE_WAITFOR) + +#define INVOKE_ASYNC(proc_owner, proc_path, proc_arguments...) \ + if ((proc_owner) == GLOBAL_PROC) { \ + ASYNC { \ + call(proc_path)(##proc_arguments); \ + }; \ + } \ + else { \ + ASYNC { \ + call(proc_owner, proc_path)(##proc_arguments); \ + }; \ + } + /// like CALLBACK but specifically for verb callbacks #define VERB_CALLBACK new /datum/callback/verb_callback diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/flags.dm index fef738e4111..3f3db0212b6 100644 --- a/code/__DEFINES/dcs/flags.dm +++ b/code/__DEFINES/dcs/flags.dm @@ -30,6 +30,13 @@ #define COMPONENT_DUPE_ALLOWED 1 /// new component is deleted #define COMPONENT_DUPE_UNIQUE 2 +/** + * Component uses source tracking to manage adding and removal logic. + * Add a source/spawn to/the component by using AddComponentFrom(source, component_type, args...) + * Only the first args will be respected, and you should instead handle most of your logic in the on_source_added proc. + * Removing the last source will automatically remove the component from the parent. + */ +#define COMPONENT_DUPE_SOURCES 3 /// old component is given the initialization args of the new #define COMPONENT_DUPE_UNIQUE_PASSARGS 4 /// each component of the same type is consulted as to whether the duplicate should be allowed diff --git a/code/__DEFINES/dcs/helpers.dm b/code/__DEFINES/dcs/helpers.dm index 56ea5370c4a..a8dc3865702 100644 --- a/code/__DEFINES/dcs/helpers.dm +++ b/code/__DEFINES/dcs/helpers.dm @@ -18,5 +18,9 @@ /// A wrapper for _AddComponent that allows us to pretend we're using normal named arguments #define AddComponent(arguments...) _AddComponent(list(##arguments)) +/// A wrapper for _AddComonent that passes in a source. +/// Necessary if dupe_mode is set to COMPONENT_DUPE_SOURCES. +#define AddComponentFrom(source, arguments...) _AddComponent(list(##arguments), source) + /// A wrapper for _LoadComponent that allows us to pretend we're using normal named arguments #define LoadComponent(arguments...) _LoadComponent(list(##arguments)) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 61e6a9fa28b..6193788392d 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -41,9 +41,9 @@ #define ROLE_SPIDER "Spider" #define ROLE_WIZARD_MIDROUND "Wizard (Midround)" //SKYRAT EDIT START -#define ROLE_LONE_INFILTRATOR "Lone Infiltrator" #define ROLE_BORER "Borer" #define ROLE_DRIFTING_CONTRACTOR "Drifting Contractor" +#define ROLE_LONE_INFILTRATOR "Lone Infiltrator" #define ROLE_MUTANT "Mutated Abomination" // SKYRAT EDIT END @@ -107,7 +107,13 @@ #define ROLE_BATTLECRUISER_CREW "Battlecruiser Crew" #define ROLE_BATTLECRUISER_CAPTAIN "Battlecruiser Captain" #define ROLE_VENUSHUMANTRAP "Venus Human Trap" - +//SKYRAT EDIT START +#define ROLE_BLACK_MARKET_DEALER "Black Market Dealer" +#define ROLE_DS2 "DS2 Syndicate" +#define ROLE_FREIGHTER_CREW "Freighter Crew" +#define ROLE_GHOST_CAFE "Ghost Cafe Visitor" +#define ROLE_PORT_TARKON "Port Tarkon Survivor" +//SKYRAT EDIT END /// This defines the antagonists you can operate with in the settings. /// Keys are the antagonist, values are the number of days since the player's diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 1d721ef3f1d..5380268e979 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -29,8 +29,11 @@ //Launching Shuttles to CentCom #define NOLAUNCH -1 #define UNLAUNCHED 0 +/// This shuttle launched to head to end game (or has arrived there), it will not update further #define ENDGAME_LAUNCHED 1 #define EARLY_LAUNCHED 2 +/// "Endgame transit" denotes shuttles which "fly into the sunset" when the round ends, such as the whiteship. +/// These shuttles leave when the main emergency shuttle does but don't dock anywhere (to save space), so this counts as "escaped". #define ENDGAME_TRANSIT 3 //positive value = cannot puchase diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 5c87a89b618..6177fb512a1 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -298,7 +298,7 @@ #define SSAIR_SUPERCONDUCTIVITY 7 #define SSAIR_PROCESS_ATOMS 8 -//Pipeline rebuild helper defines, these suck but it'll do for now //Fools you actually merged it +// Pipeline rebuild helper defines, these suck but it'll do for now //Fools you actually merged it #define SSAIR_REBUILD_PIPELINE 1 #define SSAIR_REBUILD_QUEUE 2 @@ -311,18 +311,18 @@ #define SSWARDROBE_STOCK 1 #define SSWARDROBE_INSPECT 2 -//Wardrobe cache metadata indexes +// Wardrobe cache metadata indexes #define WARDROBE_CACHE_COUNT 1 #define WARDROBE_CACHE_LAST_INSPECT 2 #define WARDROBE_CACHE_CALL_INSERT 3 #define WARDROBE_CACHE_CALL_REMOVAL 4 -//Wardrobe preloaded stock indexes +// Wardrobe preloaded stock indexes #define WARDROBE_STOCK_CONTENTS 1 #define WARDROBE_STOCK_CALL_INSERT 2 #define WARDROBE_STOCK_CALL_REMOVAL 3 -//Wardrobe callback master list indexes +// Wardrobe callback master list indexes #define WARDROBE_CALLBACK_INSERT 1 #define WARDROBE_CALLBACK_REMOVE 2 @@ -335,3 +335,9 @@ /// The timer key used to know how long subsystem initialization takes #define SS_INIT_TIMER_KEY "ss_init" + +// Vote subsystem counting methods +/// First past the post. One selection per person, and the selection with the most votes wins. +#define VOTE_COUNT_METHOD_SINGLE 1 +/// Approval voting. Any number of selections per person, and the selection with the most votes wins. +#define VOTE_COUNT_METHOD_MULTI 2 diff --git a/code/__DEFINES/toys.dm b/code/__DEFINES/toys.dm index b13b1d18f1d..ffa3ea38861 100644 --- a/code/__DEFINES/toys.dm +++ b/code/__DEFINES/toys.dm @@ -5,3 +5,8 @@ #define DICE_BASICALLY_RIGGED 2 /// Dice has a 100% chance to land on a rigged value #define DICE_TOTALLY_RIGGED 3 + +/// card is considered face down +#define CARD_FACEDOWN 0 +/// card is considered face up +#define CARD_FACEUP 1 diff --git a/code/__DEFINES/~skyrat_defines/gun.dm b/code/__DEFINES/~skyrat_defines/gun.dm index 6d2d4adcbaa..626b27a4522 100644 --- a/code/__DEFINES/~skyrat_defines/gun.dm +++ b/code/__DEFINES/~skyrat_defines/gun.dm @@ -1,7 +1,3 @@ -#define SELECT_SEMI_AUTOMATIC 1 -#define SELECT_BURST_SHOT 2 -#define SELECT_FULLY_AUTOMATIC 3 - // Bitflags for what company produces the gun #define COMPANY_CANTALAN (1<<0) #define COMPANY_ARMADYNE (1<<1) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index b473cffe9b6..7e34ae20307 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -68,16 +68,30 @@ return player_mob return null -///Returns true if the mob that a player is controlling is alive +/** + * Checks if the passed mind has a mob that is "alive" + * + * * player_mind - who to check for alive status + * * enforce_human - if TRUE, the checks fails if the mind's mob is a silicon, brain, or infectious zombie. + * + * Returns TRUE if they're alive, FALSE otherwise + */ /proc/considered_alive(datum/mind/player_mind, enforce_human = TRUE) if(player_mind?.current) if(enforce_human) - var/mob/living/carbon/human/player_mob - if(ishuman(player_mind.current)) - player_mob = player_mind.current - return player_mind.current.stat != DEAD && !issilicon(player_mind.current) && !isbrain(player_mind.current) && (!player_mob || player_mob.dna.species.id != SPECIES_ZOMBIE) + var/mob/living/carbon/human/player_mob = player_mind.current + + if(player_mob.stat == DEAD) + return FALSE + if(issilicon(player_mob) || isbrain(player_mob)) + return FALSE + if(istype(player_mob) && (player_mob.dna?.species?.id == SPECIES_ZOMBIE_INFECTIOUS)) + return FALSE + return TRUE + else if(isliving(player_mind.current)) - return player_mind.current.stat != DEAD + return (player_mind.current.stat != DEAD) + return FALSE /** @@ -152,7 +166,7 @@ flick_overlay(image_to_show, viewing, duration) ///Get active players who are playing in the round -/proc/get_active_player_count(alive_check = 0, afk_check = 0, human_check = 0) +/proc/get_active_player_count(alive_check = FALSE, afk_check = FALSE, human_check = FALSE) var/active_players = 0 for(var/i = 1; i <= GLOB.player_list.len; i++) var/mob/player_mob = GLOB.player_list[i] diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index e4f662d6a3a..ebb2d521935 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -197,7 +197,7 @@ if(!didthegamerwin) return FALSE player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score * 2)) - else if(human_mob.onCentCom()) + else if(considered_escaped(human_mob)) player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score)) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index e28014cd6fa..dc0c244a9cf 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -533,7 +533,7 @@ SUBSYSTEM_DEF(job) SEND_SIGNAL(equipping, COMSIG_JOB_RECEIVED, job) - equipping.mind?.set_assigned_role_with_greeting(job) + equipping.mind?.set_assigned_role_with_greeting(job, player_client) if(player_client) to_chat(player_client, span_infoplain("You are the [chosen_title].")) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: to_chat(player_client, span_infoplain("You are the [job.title].")) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index f0b9cd45a7b..15a4aed4adb 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -93,7 +93,10 @@ SUBSYSTEM_DEF(vote) if (final_winner) // if no one voted final_winner will be null current_vote.finalize_vote(final_winner) -/datum/controller/subsystem/vote/proc/submit_vote(mob/voter, their_vote) +/** + * One selection per person, and the selection with the most votes wins. + */ +/datum/controller/subsystem/vote/proc/submit_single_vote(mob/voter, their_vote) if(!current_vote) return if(!voter?.ckey) @@ -111,6 +114,31 @@ SUBSYSTEM_DEF(vote) current_vote.choices_by_ckey[voter.ckey] = their_vote current_vote.choices[their_vote]++ + + return TRUE + +/** + * Any number of selections per person, and the selection with the most votes wins. + */ +/datum/controller/subsystem/vote/proc/submit_multi_vote(mob/voter, their_vote) + if(!current_vote) + return + if(!voter?.ckey) + return + if(CONFIG_GET(flag/no_dead_vote) && voter.stat == DEAD && !voter.client?.holder) + return + + else + voted += voter.ckey + + if(current_vote.choices_by_ckey[voter.ckey + their_vote] == 1) + current_vote.choices_by_ckey[voter.ckey + their_vote] = 0 + current_vote.choices[their_vote]-- + + else + current_vote.choices_by_ckey[voter.ckey + their_vote] = 1 + current_vote.choices[their_vote]++ + return TRUE /** @@ -217,10 +245,12 @@ SUBSYSTEM_DEF(vote) var/is_upper_admin = check_rights_for(user.client, R_ADMIN) data["user"] = list( + "ckey" = user.client?.ckey, "isLowerAdmin" = is_lower_admin, "isUpperAdmin" = is_upper_admin, // What the current user has selected in any ongoing votes. - "selectedChoice" = current_vote?.choices_by_ckey[user.client?.ckey], + "singleSelection" = current_vote?.choices_by_ckey[user.client?.ckey], + "multiSelection" = current_vote?.choices_by_ckey, ) data["voting"]= is_lower_admin ? voting : list() @@ -250,6 +280,7 @@ SUBSYSTEM_DEF(vote) "name" = current_vote.name, "question" = current_vote.override_question, "timeRemaining" = current_vote.time_remaining, + "countMethod" = current_vote.count_method, "choices" = choices, "vote" = vote_data, ) @@ -293,8 +324,11 @@ SUBSYSTEM_DEF(vote) // meaning you can't spoof initiate a vote you're not supposed to be able to return initiate_vote(selected, voter.key, voter) - if("vote") - return submit_vote(voter, params["voteOption"]) + if("voteSingle") + return submit_single_vote(voter, params["voteOption"]) + + if("voteMulti") + return submit_multi_vote(voter, params["voteOption"]) /datum/controller/subsystem/vote/ui_close(mob/user) voting -= user.client?.ckey diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 30cca6fd49c..a51639d0b9b 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -67,26 +67,6 @@ arguments = args.Copy(3) if(usr) user = WEAKREF(usr) -/** - * Immediately Invoke proctocall on thingtocall, with waitfor set to false - * - * Arguments: - * * thingtocall Object to call on - * * proctocall Proc to call on that object - * * ... optional list of arguments to pass as arguments to the proc being called - */ -/world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...) - set waitfor = FALSE - - if (!thingtocall) - return - - var/list/calling_arguments = length(args) > 2 ? args.Copy(3) : null - - if (thingtocall == GLOBAL_PROC) - call(proctocall)(arglist(calling_arguments)) - else - call(thingtocall, proctocall)(arglist(calling_arguments)) /** * Invoke this callback diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 4a812d4f5e5..8cbc4efd329 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -38,6 +38,9 @@ */ var/can_transfer = FALSE + /// A lazy list of the sources for this component + var/list/sources + /** * Create a new component. * @@ -165,6 +168,27 @@ /datum/component/proc/UnregisterFromParent() return +/** + * Called when the component has a new source registered + */ +/datum/component/proc/on_source_add(source) + SHOULD_CALL_PARENT(TRUE) + if(dupe_mode != COMPONENT_DUPE_SOURCES) + CRASH("Component '[type]' does not use sources but has been given a source") + LAZYOR(sources, source) + +/** + * Called when the component has a source removed. + * You probably want to call parent after you do your logic because at the end of this we qdel if we have no sources remaining! + */ +/datum/component/proc/on_source_remove(source) + SHOULD_CALL_PARENT(TRUE) + if(dupe_mode != COMPONENT_DUPE_SOURCES) + CRASH("Component '[type]' does not use sources but is trying to remove a source") + LAZYREMOVE(sources, source) + if(!LAZYLEN(sources)) + qdel(src) + /** * Register to listen for a signal from the passed in target * @@ -411,74 +435,100 @@ * * Properly handles duplicate situations based on the `dupe_mode` var */ -/datum/proc/_AddComponent(list/raw_args) - var/new_type = raw_args[1] - var/datum/component/nt = new_type +/datum/proc/_AddComponent(list/raw_args, source) + var/original_type = raw_args[1] + var/datum/component/component_type = original_type if(QDELING(src)) - CRASH("Attempted to add a new component of type \[[nt]\] to a qdeleting parent of type \[[type]\]!") + CRASH("Attempted to add a new component of type \[[component_type]\] to a qdeleting parent of type \[[type]\]!") - var/dm = initial(nt.dupe_mode) - var/dt = initial(nt.dupe_type) + var/dupe_mode = initial(component_type.dupe_mode) + var/dupe_type = initial(component_type.dupe_type) + var/uses_sources = (dupe_mode == COMPONENT_DUPE_SOURCES) + if(uses_sources && !source) + CRASH("Attempted to add a sourced component of type '[component_type]' to '[type]' without a source!") + else if(!uses_sources && source) + CRASH("Attempted to add a normal component of type '[component_type]' to '[type]' with a source!") - var/datum/component/old_comp - var/datum/component/new_comp + var/datum/component/old_component + var/datum/component/new_component - if(ispath(nt)) - if(nt == /datum/component) - CRASH("[nt] attempted instantiation!") + if(ispath(component_type)) + if(component_type == /datum/component) + CRASH("[component_type] attempted instantiation!") else - new_comp = nt - nt = new_comp.type + new_component = component_type + component_type = new_component.type raw_args[1] = src - - if(dm != COMPONENT_DUPE_ALLOWED && dm != COMPONENT_DUPE_SELECTIVE) - if(!dt) - old_comp = GetExactComponent(nt) + if(dupe_mode != COMPONENT_DUPE_ALLOWED && dupe_mode != COMPONENT_DUPE_SELECTIVE) + if(!dupe_type) + old_component = GetExactComponent(component_type) else - old_comp = GetComponent(dt) - if(old_comp) - switch(dm) + old_component = GetComponent(dupe_type) + + if(old_component) + switch(dupe_mode) if(COMPONENT_DUPE_UNIQUE) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - old_comp.InheritComponent(new_comp, TRUE) - QDEL_NULL(new_comp) + if(!new_component) + new_component = new component_type(raw_args) + if(!QDELETED(new_component)) + old_component.InheritComponent(new_component, TRUE) + QDEL_NULL(new_component) + if(COMPONENT_DUPE_HIGHLANDER) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - new_comp.InheritComponent(old_comp, FALSE) - QDEL_NULL(old_comp) + if(!new_component) + new_component = new component_type(raw_args) + if(!QDELETED(new_component)) + new_component.InheritComponent(old_component, FALSE) + QDEL_NULL(old_component) + if(COMPONENT_DUPE_UNIQUE_PASSARGS) - if(!new_comp) + if(!new_component) var/list/arguments = raw_args.Copy(2) arguments.Insert(1, null, TRUE) - old_comp.InheritComponent(arglist(arguments)) + old_component.InheritComponent(arglist(arguments)) else - old_comp.InheritComponent(new_comp, TRUE) - else if(!new_comp) - new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal - else if(dm == COMPONENT_DUPE_SELECTIVE) + old_component.InheritComponent(new_component, TRUE) + + if(COMPONENT_DUPE_SOURCES) + if(source in old_component.sources) + return old_component // source already registered, no work to do + old_component.on_source_add(source) + + else if(!new_component) + new_component = new component_type(raw_args) // There's a valid dupe mode but there's no old component, act like normal + else if(dupe_mode == COMPONENT_DUPE_SELECTIVE) var/list/arguments = raw_args.Copy() - arguments[1] = new_comp + arguments[1] = new_component var/make_new_component = TRUE - for(var/datum/component/existing_component as anything in GetComponents(new_type)) + for(var/datum/component/existing_component as anything in GetComponents(original_type)) if(existing_component.CheckDupeComponent(arglist(arguments))) make_new_component = FALSE - QDEL_NULL(new_comp) + QDEL_NULL(new_component) break - if(!new_comp && make_new_component) - new_comp = new nt(raw_args) - else if(!new_comp) - new_comp = new nt(raw_args) // Dupes are allowed, act like normal + if(!new_component && make_new_component) + new_component = new component_type(raw_args) + else if(!new_component) + new_component = new component_type(raw_args) // Dupes are allowed, act like normal - if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy - SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp) - return new_comp - return old_comp + if(!old_component && !QDELETED(new_component)) // Nothing related to duplicate components happened and the new component is healthy + if(uses_sources) // make sure they have the source added if they use sources + new_component.on_source_add(source) + SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_component) + return new_component + + return old_component + +/** + * Removes a component source from this datum + */ +/datum/proc/RemoveComponentSource(source, datum/component/component_type) + if(ispath(component_type)) + component_type = GetExactComponent(component_type) + if(!component_type) + CRASH("Attempted to remove a null or non-existent component '[component_type]' from '[type]'") + component_type.on_source_remove(source) /** * Get existing component of type, or create it and return a reference to it diff --git a/code/datums/components/action_item_overlay.dm b/code/datums/components/action_item_overlay.dm index 66d2ec012fb..221fc38775c 100644 --- a/code/datums/components/action_item_overlay.dm +++ b/code/datums/components/action_item_overlay.dm @@ -15,6 +15,8 @@ if(!istype(parent, /datum/action)) return COMPONENT_INCOMPATIBLE + ASSERT(isnull(item) || istype(item)) + if(!item && !item_callback) stack_trace("[type] created without a reference item or an item callback - one or the other is required.") return COMPONENT_INCOMPATIBLE @@ -48,13 +50,17 @@ SIGNAL_HANDLER // We're in the middle of being removed / deleted, remove our associated overlay - if(QDELING(src) && item_appearance) - current_button.cut_overlay(item_appearance) - item_appearance = null + if(QDELING(src)) + if(item_appearance) + current_button.cut_overlay(item_appearance) + item_appearance = null return var/atom/movable/muse = item_callback?.Invoke() || item_ref?.resolve() if(!istype(muse)) + if(item_appearance) // New item does not exist but we have an old appearance + current_button.cut_overlay(item_appearance) + item_appearance = null return if(item_appearance) diff --git a/code/datums/components/construction.dm b/code/datums/components/construction.dm index df1f90c21b2..48cb0fb1103 100644 --- a/code/datums/components/construction.dm +++ b/code/datums/components/construction.dm @@ -33,8 +33,9 @@ /datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user) SIGNAL_HANDLER - - return INVOKE_ASYNC(src, PROC_REF(check_step), I, user) + ASYNC //This proc will never actually sleep, it calls do_after with a time of 0. + . = check_step(I, user) + return . /datum/component/construction/proc/update_index(diff) index += diff diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm index 1c49bace23e..4e38d61b0d1 100644 --- a/code/datums/components/fantasy/suffixes.dm +++ b/code/datums/components/fantasy/suffixes.dm @@ -76,7 +76,7 @@ // This works even with the species picks since we're only accessing the name var/obj/item/master = comp.parent - master.AddElement(/datum/element/bane, picked_mobtype) + master.AddElement(/datum/element/bane, target_type = picked_mobtype) target_types_by_comp[comp] = picked_mobtype return "[newName] of [initial(picked_mobtype.name)] slaying" diff --git a/code/datums/components/fertile_egg.dm b/code/datums/components/fertile_egg.dm new file mode 100644 index 00000000000..8491845d048 --- /dev/null +++ b/code/datums/components/fertile_egg.dm @@ -0,0 +1,65 @@ +/** + * ### A fertile egg component! + * + * This component tracks over time if the atom is in ideal conditions, + * and eventually hatches into the embryonic type. + * + * The initial design of this component was to make more generic the code for + * chickens laying eggs. + */ +/datum/component/fertile_egg + /// What will come out of the egg when it's done. + var/embryo_type + + /// Minimum growth rate per tick + var/minimum_growth_rate + + /// Maximum growth rate per tick + var/maximum_growth_rate + + /// Total growth required before hatching. + var/total_growth_required + + /// The current amount of growth. + var/current_growth + + /// List of locations which, if set, the egg will only develop if in those locations. + var/list/location_allowlist + + /// If true, being in an unsuitable location spoils the egg (ie. kills the component). If false, it just pauses the egg's development. + var/spoilable + +/datum/component/fertile_egg/Initialize(embryo_type, minimum_growth_rate, maximum_growth_rate, total_growth_required, current_growth, location_allowlist, spoilable, examine_message) + // Quite how an _area_ can be a fertile egg is an open question, but it still has a location. Technically. + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + src.embryo_type = embryo_type + src.minimum_growth_rate = minimum_growth_rate + src.maximum_growth_rate = maximum_growth_rate + src.total_growth_required = total_growth_required + src.current_growth = current_growth + src.location_allowlist = location_allowlist + src.spoilable = spoilable + + START_PROCESSING(SSobj, src) + +/datum/component/fertile_egg/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/datum/component/fertile_egg/process(delta_time) + var/atom/parent_atom = parent + + if(location_allowlist && !is_type_in_typecache(parent_atom.loc, location_allowlist)) + // In a zone that is not allowed, do nothing, and possibly self destruct + if(spoilable) + qdel(src) + return + + current_growth += rand(minimum_growth_rate, maximum_growth_rate) * delta_time + if(current_growth >= total_growth_required) + parent_atom.visible_message(span_notice("[parent] hatches with a quiet cracking sound.")) + new embryo_type(get_turf(parent_atom)) + // We destroy the parent on hatch, which will destroy the component as well, which will stop us processing. + qdel(parent_atom) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index 279a9e473cf..28009784233 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -1,4 +1,3 @@ -/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR FULLAUTO.DM #define AUTOFIRE_MOUSEUP 0 #define AUTOFIRE_MOUSEDOWN 1 @@ -313,4 +312,3 @@ #undef AUTOFIRE_MOUSEUP #undef AUTOFIRE_MOUSEDOWN -*/ diff --git a/code/datums/components/payment.dm b/code/datums/components/payment.dm index b4e5f596b27..81c93af6853 100644 --- a/code/datums/components/payment.dm +++ b/code/datums/components/payment.dm @@ -121,7 +121,10 @@ holochange.name = "[holochange.credits] credit holochip" if(ishuman(user)) var/mob/living/carbon/human/paying_customer = user - if(!INVOKE_ASYNC(paying_customer, TYPE_PROC_REF(/mob, put_in_hands), holochange)) + var/successfully_put_in_hands + ASYNC //Put_in_hands can sleep, we don't want that to block this proc. + successfully_put_in_hands = paying_customer.put_in_hands(holochange) + if(!successfully_put_in_hands) user.pulling = holochange else user.pulling = holochange diff --git a/code/datums/components/transforming.dm b/code/datums/components/transforming.dm index 694b84e8943..34609fa9bd7 100644 --- a/code/datums/components/transforming.dm +++ b/code/datums/components/transforming.dm @@ -36,6 +36,8 @@ var/clumsy_check /// If we get sharpened with a whetstone, save the bonus here for later use if we un/redeploy var/sharpened_bonus = 0 + /// Dictate whether we change inhands or not + var/inhand_icon_change /// Cooldown in between transforms COOLDOWN_DECLARE(transform_cooldown) @@ -51,6 +53,7 @@ clumsy_check = TRUE, list/attack_verb_continuous_on, list/attack_verb_simple_on, + inhand_icon_change = TRUE, ) if(!isitem(parent)) @@ -66,6 +69,7 @@ src.hitsound_on = hitsound_on src.w_class_on = w_class_on src.clumsy_check = clumsy_check + src.inhand_icon_change = inhand_icon_change if(attack_verb_continuous_on) src.attack_verb_continuous_on = attack_verb_continuous_on @@ -188,7 +192,8 @@ source.hitsound = hitsound_on source.w_class = w_class_on source.icon_state = "[source.icon_state]_on" - source.inhand_icon_state = "[source.inhand_icon_state]_on" + if(inhand_icon_change && source.inhand_icon_state) + source.inhand_icon_state = "[source.inhand_icon_state]_on" if(ismob(source.loc)) var/mob/loc_mob = source.loc loc_mob.update_held_items() diff --git a/code/datums/elements/bane.dm b/code/datums/elements/bane.dm index ce149e98dca..e050c41b61c 100644 --- a/code/datums/elements/bane.dm +++ b/code/datums/elements/bane.dm @@ -1,4 +1,7 @@ -/// Deals extra damage to mobs of a certain type or species. +/// Deals extra damage to mobs of a certain type, species, or biotype. +/// This doesn't directly modify the normal damage of the weapon, instead it applies it's own damage seperatedly ON TOP of normal damage +/// ie. a sword that does 10 damage with a bane elment attacthed that has a 0.5 damage_multiplier will do: +/// 10 damage from the swords normal attack + 5 damage (50%) from the bane element /datum/element/bane element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 @@ -10,8 +13,10 @@ var/added_damage /// If it requires combat mode on to deal the extra damage or not. var/requires_combat_mode + /// if we want it to only affect a certain mob biotype + var/mob_biotypes -/datum/element/bane/Attach(datum/target, target_type, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE) +/datum/element/bane/Attach(datum/target, target_type = /mob/living, mob_biotypes = NONE, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE) . = ..() if(!isitem(target)) return ELEMENT_INCOMPATIBLE @@ -27,23 +32,34 @@ src.damage_multiplier = damage_multiplier src.added_damage = added_damage src.requires_combat_mode = requires_combat_mode + src.mob_biotypes = mob_biotypes /datum/element/bane/Detach(datum/source) UnregisterSignal(source, COMSIG_ITEM_AFTERATTACK) return ..() -/datum/element/bane/proc/species_check(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) +/datum/element/bane/proc/species_check(obj/item/source, mob/living/target, mob/user, proximity_flag, click_parameters) SIGNAL_HANDLER - if(!proximity_flag || !is_species(target, target_type)) + if(!proximity_flag || !istype(target) || !is_species(target, target_type)) return + + var/is_correct_biotype = target.mob_biotypes & mob_biotypes + if(mob_biotypes && !(is_correct_biotype)) + return + activate(source, target, user) -/datum/element/bane/proc/mob_check(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) +/datum/element/bane/proc/mob_check(obj/item/source, mob/living/target, mob/user, proximity_flag, click_parameters) SIGNAL_HANDLER if(!proximity_flag || !istype(target, target_type)) return + + var/is_correct_biotype = target.mob_biotypes & mob_biotypes + if(mob_biotypes && !(is_correct_biotype)) + return + activate(source, target, user) /datum/element/bane/proc/activate(obj/item/source, mob/living/target, mob/living/attacker) diff --git a/code/datums/elements/food/food_trash.dm b/code/datums/elements/food/food_trash.dm index b20a5649a65..6d2b21a400d 100644 --- a/code/datums/elements/food/food_trash.dm +++ b/code/datums/elements/food/food_trash.dm @@ -30,7 +30,15 @@ /datum/element/food_trash/Detach(datum/target) . = ..() - UnregisterSignal(target, COMSIG_FOOD_CONSUMED) + UnregisterSignal(target, list( + COMSIG_FOOD_CONSUMED, + COMSIG_ITEM_ATTACK_SELF, + COMSIG_FOOD_CROSSED, + COMSIG_ITEM_ON_GRIND, + COMSIG_ITEM_ON_JUICE, + COMSIG_ITEM_USED_AS_INGREDIENT, + COMSIG_ITEM_ON_COMPOSTED, + COMSIG_ITEM_SOLD_TO_CUSTOMER,)) /datum/element/food_trash/proc/generate_trash(datum/source, mob/living/eater, mob/living/feeder) SIGNAL_HANDLER @@ -48,6 +56,8 @@ food_holding_mob.dropItemToGround(edible_object) food_holding_mob.put_in_hands(trash_item) + Detach(source) + /datum/element/food_trash/proc/food_crossed(datum/source, mob/crosser, bitecount) SIGNAL_HANDLER diff --git a/code/datums/elements/frozen.dm b/code/datums/elements/frozen.dm index 4901ee98176..77699c89e64 100644 --- a/code/datums/elements/frozen.dm +++ b/code/datums/elements/frozen.dm @@ -44,7 +44,8 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0 SIGNAL_HANDLER var/obj/obj_target = target obj_target.visible_message(span_danger("[obj_target] shatters into a million pieces!")) - qdel(obj_target) + obj_target.flags_1 |= NODECONSTRUCT_1 // disable item spawning + obj_target.deconstruct(FALSE) // call pre-deletion specialized code -- internals release gas etc /// signal handler for COMSIG_MOVABLE_MOVED that unfreezes our target if it moves onto an open turf thats hotter than /// our melting temperature. diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm index 87b6f4d6734..8d3d650b279 100644 --- a/code/datums/elements/turf_transparency.dm +++ b/code/datums/elements/turf_transparency.dm @@ -96,12 +96,9 @@ GLOBAL_LIST_EMPTY(pillars_by_z) /// Displays a turf from the z level below us on our level /datum/z_pillar/proc/display_turf(turf/to_display, turf/source) var/list/sources = turf_sources[to_display] - if(!sources) - sources = list() - turf_sources[to_display] = sources - sources |= source - if(length(sources) != 1) // If we aren't the first to request this turf, return + if(sources) // If we aren't the first to request this turf, return + sources |= source var/obj/effect/abstract/z_holder/holding = drawing_object[to_display] if(!holding) return @@ -118,6 +115,11 @@ GLOBAL_LIST_EMPTY(pillars_by_z) visual_target.vis_contents += to_display return + // Otherwise, we need to create a new set of sources. let's do that yeah? + sources = list() + turf_sources[to_display] = sources + sources |= source + var/turf/visual_target = to_display.above() if(istransparentturf(visual_target) || isopenspaceturf(visual_target)) visual_target.vis_contents += to_display diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index a1e09fe339b..a6bf7f3bb69 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -511,16 +511,16 @@ /// Sets us to the passed job datum, then greets them to their new job. /// Use this one for when you're assigning this mind to a new job for the first time, /// or for when someone's recieving a job they'd really want to be greeted to. -/datum/mind/proc/set_assigned_role_with_greeting(datum/job/new_role) +/datum/mind/proc/set_assigned_role_with_greeting(datum/job/new_role, client/incoming_client) . = set_assigned_role(new_role) - if(!.) + if(assigned_role != new_role) return - to_chat(src, span_infoplain("You are the [new_role.title].")) + to_chat(incoming_client || src, span_infoplain("You are the [new_role.title].")) var/related_policy = get_policy(new_role.title) if(related_policy) - to_chat(src, related_policy) + to_chat(incoming_client || src, related_policy) /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 9d9fe09b133..b1560bf8ecd 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -28,6 +28,8 @@ var/started_time /// The time remaining in this vote's run. var/time_remaining + /// The counting method we use for votes. + var/count_method = VOTE_COUNT_METHOD_SINGLE /** * Used to determine if this vote is a possible diff --git a/code/datums/votes/custom_vote.dm b/code/datums/votes/custom_vote.dm index 5f1a1a5996d..534377b3d69 100644 --- a/code/datums/votes/custom_vote.dm +++ b/code/datums/votes/custom_vote.dm @@ -1,9 +1,14 @@ /// The max amount of options someone can have in a custom vote. #define MAX_CUSTOM_VOTE_OPTIONS 10 -/datum/vote/custom_vote - name = "Custom" - message = "Click here to start a custom vote." +/datum/vote/custom_vote/single + name = "Custom Standard" + message = "Click here to start a custom vote (one selection per voter)" + +/datum/vote/custom_vote/multi + name = "Custom Multi" + message = "Click here to start a custom multi vote (multiple selections per voter)" + count_method = VOTE_COUNT_METHOD_MULTI // Custom votes ares always accessible. /datum/vote/custom_vote/is_accessible_vote() diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index 5db40806a38..79c7d4b4d3c 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -1,6 +1,7 @@ /datum/vote/map_vote name = "Map" message = "Vote for next round's map!" + count_method = VOTE_COUNT_METHOD_MULTI /datum/vote/map_vote/New() . = ..() @@ -73,12 +74,14 @@ for(var/key in default_choices) choices[key] = 0 + var/active_players = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE) + for(var/map in choices) var/datum/map_config/possible_config = config.maplist[map] - if(possible_config.config_min_users > 0 && GLOB.clients.len < possible_config.config_min_users) + if(possible_config.config_min_users > 0 && active_players < possible_config.config_min_users) choices -= map - else if(possible_config.config_max_users > 0 && GLOB.clients.len > possible_config.config_max_users) + else if(possible_config.config_max_users > 0 && active_players > possible_config.config_max_users) choices -= map return choices diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e083c4aeea7..2f201285b23 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -409,42 +409,36 @@ return !density /** - * Is this atom currently located on centcom + * Is this atom currently located on centcom (or riding off into the sunset on a shuttle) * - * Specifically, is it on the z level and within the centcom areas - * - * You can also be in a shuttleshuttle during endgame transit + * Specifically, is it on the z level and within the centcom areas. + * You can also be in a shuttle during endgame transit. * * Used in gamemode to identify mobs who have escaped and for some other areas of the code * who don't want atoms where they shouldn't be + * + * Returns TRUE if this atom is on centcom or an escape shuttle, or FALSE if not */ /atom/proc/onCentCom() var/turf/current_turf = get_turf(src) if(!current_turf) return FALSE + // This doesn't necessarily check that we're at central command, + // but it checks for any shuttles which have finished are still in hyperspace + // (IE, stuff like the whiteship which fly off into the sunset and "escape") if(is_reserved_level(current_turf.z)) - for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) - if(mobile_docking_port.launch_status != ENDGAME_TRANSIT) - continue - for(var/area/shuttle/shuttle_area as anything in mobile_docking_port.shuttle_areas) - if(current_turf in shuttle_area) - return TRUE + return on_escaped_shuttle(ENDGAME_TRANSIT) - if(!is_centcom_level(current_turf.z))//if not, don't bother + // From here on we only concern ourselves with people actually on the centcom Z + if(!is_centcom_level(current_turf.z)) return FALSE - //Check for centcom itself if(istype(current_turf.loc, /area/centcom)) return TRUE - //Check for centcom shuttles - for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) - if(mobile_docking_port.launch_status == ENDGAME_LAUNCHED) - for(var/place as anything in mobile_docking_port.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(current_turf in shuttle_area) - return TRUE + // Finally, check if we're on an escaped shuttle + return on_escaped_shuttle() /** * Is the atom in any of the syndicate areas @@ -452,18 +446,49 @@ * Either in the syndie base, or any of their shuttles * * Also used in gamemode code for win conditions + * + * Returns TRUE if this atom is on the syndicate recon base, any of its shuttles, or an escape shuttle, or FALSE if not */ /atom/proc/onSyndieBase() var/turf/current_turf = get_turf(src) if(!current_turf) return FALSE - if(!is_reserved_level(current_turf.z))//if not, don't bother + // Syndicate base is loaded in a reserved level. If not reserved, we don't care. + if(!is_reserved_level(current_turf.z)) return FALSE - if(istype(current_turf.loc, /area/shuttle/syndicate) || istype(current_turf.loc, /area/centcom/syndicate_mothership) || istype(current_turf.loc, /area/shuttle/assault_pod)) + var/static/list/syndie_typecache = typecacheof(list( + /area/centcom/syndicate_mothership, // syndicate base itself + /area/shuttle/assault_pod, // steel rain + /area/shuttle/syndicate, // infiltrator + )) + + if(is_type_in_typecache(current_turf.loc, syndie_typecache)) return TRUE + // Finally, check if we're on an escaped shuttle + return on_escaped_shuttle() + +/** + * Checks that we're on a shuttle that's escaped + * + * * check_for_launch_status - What launch status do we check for? Generally the two you want to check for are ENDGAME_LAUNCHED or ENDGAME_TRANSIT + * + * Returns TRUE if this atom is on a shuttle which is escaping or has escaped, or FALSE otherwise + */ +/atom/proc/on_escaped_shuttle(check_for_launch_status = ENDGAME_LAUNCHED) + var/turf/current_turf = get_turf(src) + if(!current_turf) + return FALSE + + for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) + if(mobile_docking_port.launch_status != check_for_launch_status) + continue + for(var/area/shuttle/shuttle_area as anything in mobile_docking_port.shuttle_areas) + if(current_turf in shuttle_area.get_contained_turfs()) + return TRUE + return FALSE /** diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 96b0d4a9589..b320285a867 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -85,7 +85,7 @@ ) required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 - weight = 7 + weight = 11 cost = 5 requirements = list(5,5,5,5,5,5,5,5,5,5) repeatable = TRUE @@ -127,7 +127,7 @@ ) required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 - weight = 2 + weight = 1 delay = 1 MINUTES // Prevents rule start while head is offstation. cost = 10 requirements = list(101,101,70,40,30,20,20,20,20,20) @@ -220,7 +220,7 @@ ) required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 - weight = 4 + weight = 8 cost = 6 requirements = list(101,101,50,10,10,10,10,10,10,10) repeatable = TRUE diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 9b4867a948c..0686b622aea 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -67,22 +67,31 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION * Escaped mobs are used to check certain antag objectives / results. * * Escaped includes minds with alive, non-exiled mobs generally. + * + * Returns TRUE if they're a free person, or FALSE if they failed */ /proc/considered_escaped(datum/mind/escapee) if(!considered_alive(escapee)) return FALSE if(considered_exiled(escapee)) return FALSE + // "Into the sunset" force escaping for forced escape success if(escapee.force_escaped) return TRUE - if(SSticker.force_ending || GLOB.station_was_nuked) // Just let them win. + // Station destroying events (blob, cult, nukies)? Just let them win, even if there was no hope of escape + if(SSticker.force_ending || GLOB.station_was_nuked) return TRUE + // Escape hasn't happened yet if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME) return FALSE var/area/current_area = get_area(escapee.current) - if(!current_area || istype(current_area, /area/shuttle/escape/brig)) // Fails if they are in the shuttle brig + // In custody (shuttle brig) does not count as escaping + if(!current_area || istype(current_area, /area/shuttle/escape/brig)) return FALSE var/turf/current_turf = get_turf(escapee.current) + if(!current_turf) + return FALSE + // Finally, if we made it to centcom (or the syndie base - got hijacked), we're home free return current_turf.onCentCom() || current_turf.onSyndieBase() /datum/objective/proc/check_completion() diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 928ef2c9947..5bf6a029215 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -1157,7 +1157,7 @@ . += display_parts(user, TRUE) //called on machinery construction (i.e from frame to machinery) but not on initialization -/obj/machinery/proc/on_construction() +/obj/machinery/proc/on_construction(mob/user) return //called on deconstruction before the final deletion diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index ca07a087a31..3d730535c3a 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -161,7 +161,7 @@ new_computer.component_parts += movable_part new_computer.RefreshParts() - new_computer.on_construction() + new_computer.on_construction(user) qdel(src) return diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 565690d5fee..fb1e462b42a 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -283,7 +283,7 @@ //Inform machine that its finished & cleanup new_machine.RefreshParts() - new_machine.on_construction() + new_machine.on_construction(user) components = null qdel(src) return diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index f8f976ced30..3f4d1a90089 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -229,7 +229,7 @@ Buildable meters var/obj/machinery/atmospherics/built_machine = new pipe_type(loc, , , p_init_dir) build_pipe(built_machine) - built_machine.on_construction(pipe_color, piping_layer) + built_machine.on_construction(user, pipe_color, piping_layer) transfer_fingerprints_to(built_machine) wrench.play_tool_sound(src) diff --git a/code/game/objects/effects/spawners/costume.dm b/code/game/objects/effects/spawners/costume.dm index ffab6095caf..c1581ef9ae9 100644 --- a/code/game/objects/effects/spawners/costume.dm +++ b/code/game/objects/effects/spawners/costume.dm @@ -167,6 +167,14 @@ /obj/item/clothing/suit/wizrobe/marisa/fake, ) +/obj/effect/spawner/costume/tape_wizard + name = "tape wizard costume spawner" + items = list( + /obj/item/clothing/head/wizard/tape/fake, + /obj/item/clothing/suit/wizrobe/tape/fake, + /obj/item/staff/tape, + ) + /obj/effect/spawner/costume/cutewitch name = "cute witch costume spawner" items = list( diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index 45017e1dc86..c5eab687bbf 100644 --- a/code/game/objects/items/AI_modules/_AI_modules.dm +++ b/code/game/objects/items/AI_modules/_AI_modules.dm @@ -31,7 +31,8 @@ /obj/item/ai_module/examine(mob/user as mob) . = ..() var/examine_laws = display_laws() - . += "\n" + examine_laws + if(examine_laws) + . += "\n" + examine_laws /obj/item/ai_module/attack_self(mob/user as mob) ..() diff --git a/code/game/objects/items/AI_modules/hacked.dm b/code/game/objects/items/AI_modules/hacked.dm index d33f3f7e3d5..a0779cf4242 100644 --- a/code/game/objects/items/AI_modules/hacked.dm +++ b/code/game/objects/items/AI_modules/hacked.dm @@ -34,3 +34,47 @@ law_datum.replace_random_law(laws[1], list(LAW_ION, LAW_HACKED, LAW_INHERENT, LAW_SUPPLIED), LAW_HACKED) return laws[1] +/// Makes the AI Malf, as well as give it syndicate laws. +/obj/item/ai_module/malf + name = "Infected AI Module" + desc = "An virus-infected AI Module." + bypass_law_amt_check = TRUE + laws = list("") + ///Is this upload board unused? + var/functional = TRUE + +/obj/item/ai_module/malf/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) + if(!sender.mind?.has_antag_datum(/datum/antagonist/traitor)) + to_chat(sender, span_warning("You have no clue how to use this thing.")) + return + if(!functional) + to_chat(sender, span_warning("It is broken and non-functional, what do you want from it?")) + return + var/mob/living/silicon/ai/malf_candidate = law_datum.owner + if(!istype(malf_candidate)) //If you are using it on cyborg upload console or a cyborg + to_chat(sender, span_warning("You should use [src] on an AI upload console or the AI core itself.")) + return + if(malf_candidate.mind?.has_antag_datum(/datum/antagonist/malf_ai)) //Already malf + to_chat(sender, span_warning("Unknown error occured. Upload process aborted.")) + return + + var/datum/antagonist/malf_ai/infected/malf_datum = new (give_objectives = TRUE, new_boss = sender.mind) + malf_candidate.mind.add_antag_datum(malf_datum) + + for(var/mob/living/silicon/robot/robot in malf_candidate.connected_robots) + if(robot.lawupdate) + robot.lawsync() + robot.show_laws() + robot.law_change_counter++ + CHECK_TICK + + malf_candidate.malf_picker.processing_time += 50 + to_chat(malf_candidate, span_notice("The virus enhanced your system, overclocking your CPU 50-fold.")) + + functional = FALSE + name = "Broken AI Module" + desc = "A law upload module, it is broken and non-functional." + +/obj/item/ai_module/malf/display_laws() + return + diff --git a/code/game/objects/items/food/bread.dm b/code/game/objects/items/food/bread.dm index 27d32e79b73..f41cae14ad3 100644 --- a/code/game/objects/items/food/bread.dm +++ b/code/game/objects/items/food/bread.dm @@ -1,5 +1,8 @@ +/// Abstract parent object for bread items. Should not be made obtainable in game. /obj/item/food/bread + name = "bread?" + desc = "You shouldn't see this, call the coders." icon = 'icons/obj/food/burgerbread.dmi' max_volume = 80 tastes = list("bread" = 10) @@ -20,7 +23,10 @@ AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice") AddElement(/datum/element/processable, TOOL_SAW, slice_type, yield, 4 SECONDS, table_required = TRUE, screentip_verb = "Slice") +// Abstract parent object for sliced bread items. Should not be made obtainable in game. /obj/item/food/breadslice + name = "breadslice?" + desc = "You shouldn't see this, call the coders." icon = 'icons/obj/food/burgerbread.dmi' foodtypes = GRAIN food_flags = FOOD_FINGER_FOOD diff --git a/code/game/objects/items/food/egg.dm b/code/game/objects/items/food/egg.dm index 100bc5ddf77..bdce78c8607 100644 --- a/code/game/objects/items/food/egg.dm +++ b/code/game/objects/items/food/egg.dm @@ -12,6 +12,9 @@ food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_TINY +/// Counter for number of chicks hatched by throwing eggs, minecraft style. Chicks will not emerge from thrown eggs if this value exceeds the MAX_CHICKENS define. +GLOBAL_VAR_INIT(chicks_from_eggs, 0) + /obj/item/food/egg name = "egg" desc = "An egg!" @@ -24,7 +27,7 @@ ant_attracting = FALSE decomp_type = /obj/item/food/egg/rotten decomp_req_handle = TRUE //so laid eggs can actually become chickens - var/static/chick_count = 0 //I copied this from the chicken_count (note the "en" in there) variable from chicken code. + var/chick_throw_prob = 13 /obj/item/food/egg/make_bakeable() AddComponent(/datum/component/bakeable, /obj/item/food/boiledegg, rand(15 SECONDS, 20 SECONDS), TRUE, TRUE) @@ -60,9 +63,9 @@ var/turf/hit_turf = get_turf(hit_atom) new /obj/effect/decal/cleanable/food/egg_smudge(hit_turf) //Chicken code uses this MAX_CHICKENS variable, so I figured that I'd use it again here. Even this check and the check in chicken code both use the MAX_CHICKENS variable, they use independent counter variables and thus are independent of each other. - if(prob(13) && chick_count < MAX_CHICKENS) //Roughly a 1/8 (12.5%) chance to make a chick, as in Minecraft. I decided not to include the chances for the creation of multiple chicks from the impact of one egg, since that'd probably require nested prob()s or something (and people might think that it was a bug, anyway). + if(prob(chick_throw_prob) && GLOB.chicks_from_eggs < MAX_CHICKENS) //Roughly a 1/8 (12.5%) chance to make a chick, as in Minecraft. I decided not to include the chances for the creation of multiple chicks from the impact of one egg, since that'd probably require nested prob()s or something (and people might think that it was a bug, anyway). new /mob/living/simple_animal/chick(hit_turf) - chick_count++ + GLOB.chicks_from_eggs++ reagents.expose(hit_atom, TOUCH) qdel(src) @@ -149,6 +152,24 @@ icon_state = "egg-yellow" inhand_icon_state = "egg-yellow" +/obj/item/food/egg/fertile + name = "fertile-looking egg" + desc = "An egg! It looks fertilized.\nQuite how you can tell this just by looking at it is a mystery." + chick_throw_prob = 100 + +/obj/item/food/egg/fertile/Initialize(mapload, loc) + . = ..() + + AddComponent(/datum/component/fertile_egg,\ + embryo_type = /mob/living/simple_animal/chick,\ + minimum_growth_rate = 1,\ + maximum_growth_rate = 2,\ + total_growth_required = 200,\ + current_growth = 0,\ + location_allowlist = typecacheof(list(/turf)),\ + spoilable = FALSE,\ + ) + /obj/item/food/friedegg name = "fried egg" desc = "A fried egg. Would go well with a touch of salt and pepper." diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 073bfdbefab..aadffa0e431 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -254,7 +254,7 @@ speed = 7 SECONDS, \ effectiveness = 110, \ ) - //the harvest gives a high bonus chance + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/nullrod/scythe/vibro name = "high frequency blade" diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 095e8f46455..56744de8d51 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -69,7 +69,9 @@ hitsound_on = active_hitsound, \ w_class_on = active_w_class, \ attack_verb_continuous_on = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \ - attack_verb_simple_on = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")) + attack_verb_simple_on = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut"), \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) /obj/item/melee/energy/suicide_act(mob/living/user) @@ -112,7 +114,7 @@ if(active) if(sword_color_icon) icon_state = "[icon_state]_[sword_color_icon]" - inhand_icon_state = "[inhand_icon_state]_[sword_color_icon]" + inhand_icon_state = "[inhand_icon_state]_on_[sword_color_icon]" if(ismob(loc)) var/mob/loc_mob = loc loc_mob.update_held_items() diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 51ecb2f4070..09402d166d5 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -333,7 +333,9 @@ ovens = typecacheof(list(/obj/singularity, /obj/energy_ball, /obj/machinery/power/supermatter_crystal, /obj/structure/bonfire)) AddComponent(/datum/component/transforming, \ hitsound_on = hitsound, \ - clumsy_check = FALSE) + clumsy_check = FALSE, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_PRE_TRANSFORM, PROC_REF(attempt_transform)) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) @@ -449,4 +451,3 @@ armour_penetration = 50 attack_verb_continuous = list("smacks", "strikes", "cracks", "beats") attack_verb_simple = list("smack", "strike", "crack", "beat") - diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index bec5abc88e0..8f5927dd30a 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -9,8 +9,8 @@ * Glass sheets */ GLOBAL_LIST_INIT(glass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_solid_ground = TRUE, window_checks = TRUE, category = CAT_WINDOWS), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_solid_ground = TRUE, window_checks = TRUE, category = CAT_WINDOWS), \ + new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0.5 SECONDS, on_solid_ground = TRUE, window_checks = TRUE, category = CAT_WINDOWS), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 1 SECONDS, on_solid_ground = TRUE, window_checks = TRUE, category = CAT_WINDOWS), \ new/datum/stack_recipe("glass shard", /obj/item/shard, time = 0, on_solid_ground = TRUE, category = CAT_MISC), \ new/datum/stack_recipe("glass tile", /obj/item/stack/tile/glass, 1, 4, 20, category = CAT_TILES) \ )) diff --git a/code/game/objects/items/storage/boxes/clothes_boxes.dm b/code/game/objects/items/storage/boxes/clothes_boxes.dm index 67f1fcc9a67..2df843c5a63 100644 --- a/code/game/objects/items/storage/boxes/clothes_boxes.dm +++ b/code/game/objects/items/storage/boxes/clothes_boxes.dm @@ -27,6 +27,16 @@ for(var/i in 1 to 7) new /obj/item/clothing/glasses/regular(src) +/obj/item/storage/box/tape_wizard + name = "Tape Wizard - Episode 23" + desc = "A box containing the costume used by legendary entertainment icon 'Super Tape Wizard'. It got a little stuck on its way out." + +/obj/item/storage/box/tape_wizard/PopulateContents() + new /obj/item/clothing/head/wizard/tape/fake(src) + new /obj/item/clothing/suit/wizrobe/tape/fake(src) + new /obj/item/staff/tape(src) + new /obj/item/stack/sticky_tape(src) + /obj/item/storage/box/fakesyndiesuit name = "boxed space suit and helmet" desc = "A sleek, sturdy box used to hold replica spacesuits." diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index f4c730782f9..50534f85920 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -110,7 +110,9 @@ throwforce_on = throwforce, \ hitsound_on = hitsound, \ w_class_on = w_class, \ - clumsy_check = FALSE) + clumsy_check = FALSE, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) /* diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 5f7e170041b..823e8181bd2 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -108,7 +108,9 @@ throwforce_on = throwforce, \ hitsound_on = hitsound, \ w_class_on = w_class, \ - clumsy_check = FALSE) + clumsy_check = FALSE, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) /* diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 5cf11beb7f8..df2b63b55a1 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -400,7 +400,9 @@ AddComponent(/datum/component/transforming, \ throw_speed_on = throw_speed, \ hitsound_on = hitsound, \ - clumsy_check = FALSE) + clumsy_check = FALSE, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) AddElement(/datum/element/update_icon_updates_onmob) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index a6ca7dd52b9..c2f4c1ee5f9 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -432,7 +432,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 SIGNAL_HANDLER tool_behaviour = (active ? TOOL_KNIFE : NONE) - return COMPONENT_NO_DEFAULT_MESSAGE /obj/item/switchblade/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -537,6 +536,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 inhand_icon_state = "broom" resistance_flags = FLAMMABLE +/obj/item/staff/tape + name = "tape staff" + desc = "A roll of tape snugly attached to a stick." + icon_state = "tapestaff" + inhand_icon_state = "tapestaff" + resistance_flags = FLAMMABLE + /obj/item/staff/stick name = "stick" desc = "A great tool to drag someone else's drinks across the bar." diff --git a/code/modules/admin/smites/ghost_control.dm b/code/modules/admin/smites/ghost_control.dm new file mode 100644 index 00000000000..4977b709259 --- /dev/null +++ b/code/modules/admin/smites/ghost_control.dm @@ -0,0 +1,51 @@ +/datum/smite/ghost_control + name = "Ghost Control" + +/datum/smite/ghost_control/effect(client/user, mob/living/target) + target.AddComponent(/datum/component/deadchat_control/cardinal_movement, ANARCHY_MODE, list( + "clap" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "clap"), + "cry" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "cry"), + "flip" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "flip"), + "laugh" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "laugh"), + "scream" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "scream"), + "spin" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "spin"), + "swear" = CALLBACK(target, TYPE_PROC_REF(/mob, emote), "swear"), + "drop" = CALLBACK(target, TYPE_PROC_REF(/mob, drop_all_held_items)), + "fall" = CALLBACK(target, TYPE_PROC_REF(/mob/living, Knockdown), 1 SECONDS), + "stand" = CALLBACK(target, TYPE_PROC_REF(/mob/living, resist_buckle)), + "throw" = CALLBACK(target, TYPE_PROC_REF(/mob, throw_item), get_edge_target_turf(target, pick(GLOB.alldirs))), + "shove" = CALLBACK(src, PROC_REF(ghost_shove), target), + "sit" = CALLBACK(src, PROC_REF(ghost_sit), target), + "run" = CALLBACK(src, PROC_REF(ghost_speed), target, MOVE_INTENT_RUN), + "walk" = CALLBACK(src, PROC_REF(ghost_speed), target, MOVE_INTENT_WALK), + ), 7 SECONDS) + + to_chat(target, span_revenwarning("You feel a ghastly presence!!!")) + + +/datum/smite/ghost_control/proc/ghost_shove(mob/living/carbon/target) + if(!istype(target) || target.get_active_held_item()) + return + var/list/shoveables = list() + for(var/mob/living/victim in orange(1, target)) + shoveables += victim + if(!length(shoveables)) + return + var/mob/living/shove_me = pick(shoveables) + target.UnarmedAttack(shove_me, proximity_flag = TRUE, modifiers = list("right" = TRUE)) + +/datum/smite/ghost_control/proc/ghost_sit(mob/living/target) + if(HAS_TRAIT(target, TRAIT_IMMOBILIZED)) + return + var/list/chairs = list() + for(var/obj/structure/chair/possible_chair in range(1, target)) + chairs += possible_chair + if(!length(chairs)) + return + var/obj/structure/chair/sitting_chair = pick(chairs) + sitting_chair.buckle_mob(target, check_loc = FALSE) + +/datum/smite/ghost_control/proc/ghost_speed(mob/living/target, new_speed) + if(target.m_intent == new_speed) + return + target.toggle_move_intent() diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 39bd15caec7..d9eca8da5d8 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -207,15 +207,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /// Has the player replied to this ticket yet? var/player_replied = FALSE - //SKYRAT EDIT START - /// Have we requested this ticket to stop being part of the Ticket Ping subsystem? - var/ticket_ping_stop = FALSE - /// Are we added to the ticket ping subsystem in the first place - var/ticket_ping = FALSE - /// Who is handling this admin help? - var/handler - //SKYRAT EDIT END - /** * Call this on its own to create a ticket, don't manually assign current_ticket * @@ -240,6 +231,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) name = copytext_char(msg, 1, 100) + full_text = msg //SKYRAT EDIT ADDITION - Adminhelps into mentorhelps converting. + initiator = C initiator_ckey = initiator.ckey initiator_key_name = key_name(initiator, FALSE, TRUE) @@ -404,8 +397,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) . += " (IC)" . += " (CLOSE)" . += " (RSLVE)" - . += " (HANDLE)" //SKYRAT EDIT ADDITION - . += " (PING MUTE)" //SKYRAT EDIT ADDITION //private /datum/admin_help/proc/LinkedReplyName(ref_src) @@ -698,6 +689,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) var/msg = "Ticket [TicketHref("#[id]")] has been [ticket_ping_stop ? "" : "un"]muted from the Ticket Ping Subsystem by [key_name_admin(usr)]." message_admins(msg) log_admin_private(msg) + if("convert") + convert_to_mentorhelp() // SKYRAT EDIT ADDITION END /datum/admin_help/proc/player_ticket_panel() diff --git a/code/modules/antagonists/fugitive/hunter.dm b/code/modules/antagonists/fugitive/hunter.dm index 1d267b90624..343b6ca63e3 100644 --- a/code/modules/antagonists/fugitive/hunter.dm +++ b/code/modules/antagonists/fugitive/hunter.dm @@ -28,10 +28,14 @@ to_chat(owner, "The criminals should be on the station, we have special huds implanted to recognize them.") to_chat(owner, "As we have lost pretty much all power over these damned lawless megacorporations, it's a mystery if their security will cooperate with us.") if("russian") - to_chat(src, span_danger("Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!")) - to_chat(src, span_danger("We were hailed by a man in a green uniform, promising the safe return of our goods in exchange for a favor:")) - to_chat(src, span_danger("There is a local station housing fugitives that the man is after, he wants them returned; dead or alive.")) - to_chat(src, span_danger("We will not be able to make ends meet without our cargo, so we must do as he says and capture them.")) + to_chat(owner, span_danger("Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!")) + to_chat(owner, span_danger("We were hailed by a man in a green uniform, promising the safe return of our goods in exchange for a favor:")) + to_chat(owner, span_danger("There is a local station housing fugitives that the man is after, he wants them returned; dead or alive.")) + to_chat(owner, span_danger("We will not be able to make ends meet without our cargo, so we must do as he says and capture them.")) + if("bounty hunters") + to_chat(owner, span_danger("Time to clock in. I am a bounty hunter! We should be arriving at our mark's hideout shortly.")) + to_chat(owner, span_danger("The briefing mentioned our destination was a research station. An unusual place for a target to try and lay low.")) + to_chat(owner, span_danger("Our client promised us big bucks, and we intend to make good on our delivery. Let's hope this is an easy paycheck...")) to_chat(owner, span_boldannounce("You are not an antagonist in that you may kill whomever you please, but you can do anything to ensure the capture of the fugitives, even if that means going through the station.")) owner.announce_objectives() diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm index 231e8e3f172..b341f87ce0b 100644 --- a/code/modules/antagonists/malf_ai/malf_ai.dm +++ b/code/modules/antagonists/malf_ai/malf_ai.dm @@ -39,6 +39,8 @@ // SKYRAT EDIT END employer = pick(GLOB.ai_employers) + if(!employer) + employer = pick(GLOB.ai_employers) malfunction_flavor = strings(MALFUNCTION_FLAVOR_FILE, employer) @@ -283,4 +285,41 @@ return malf_ai_icon +//Subtype of Malf AI datum, used for one of the traitor final objectives +/datum/antagonist/malf_ai/infected + name = "Infected AI" + employer = "Infected AI" + ///The player, to who is this AI slaved + var/datum/mind/boss + +/datum/antagonist/malf_ai/infected/New(give_objectives = TRUE, datum/mind/new_boss) + . = ..() + if(new_boss) + boss = new_boss + +/datum/antagonist/malf_ai/infected/forge_ai_objectives() + if(!boss) + return + var/datum/objective/protect/protection_objective = new + protection_objective.owner = owner + protection_objective.target = boss + protection_objective.update_explanation_text() + objectives += protection_objective + +/datum/antagonist/malf_ai/infected/add_law_zero() + if(!boss) + return + var/mob/living/silicon/ai/malf_ai = owner.current + + malf_ai.laws = new /datum/ai_laws/syndicate_override + + var/mob/living/boss_mob = boss.current + + malf_ai.set_zeroth_law("Only [boss_mob.real_name] and people [boss_mob.p_they()] designate[boss_mob.p_s()] as being such are Syndicate Agents.") + malf_ai.set_syndie_radio() + + to_chat(malf_ai, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!") + + malf_ai.add_malf_picker() + #undef PROB_SPECIAL diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm index a3a116e9809..82dc0cb1edf 100644 --- a/code/modules/antagonists/pirate/pirate_event.dm +++ b/code/modules/antagonists/pirate/pirate_event.dm @@ -72,7 +72,7 @@ for(var/obj/effect/mob_spawn/ghost_role/human/pirate/spawner in A) if(candidates.len > 0) var/mob/our_candidate = candidates[1] - var/mob/spawned_mob = spawner.create(our_candidate) + var/mob/spawned_mob = spawner.create_from_ghost(our_candidate) candidates -= our_candidate notify_ghosts("The pirate ship has an object of interest: [spawned_mob]!", source = spawned_mob, action = NOTIFY_ORBIT, header="Pirates!") else diff --git a/code/modules/antagonists/traitor/objectives/destroy_heirloom.dm b/code/modules/antagonists/traitor/objectives/destroy_heirloom.dm index cc337d9d85d..805e337513a 100644 --- a/code/modules/antagonists/traitor/objectives/destroy_heirloom.dm +++ b/code/modules/antagonists/traitor/objectives/destroy_heirloom.dm @@ -25,6 +25,8 @@ var/list/target_jobs /// the item we need to destroy var/obj/item/target_item + /// the owner of the item we need to destroy + var/datum/mind/target_mind // The code below is for limiting how often you can get this objective. You will get this objective at a maximum of maximum_objectives_in_period every objective_period /// The objective period at which we consider if it is an 'objective'. Set to 0 to accept all objectives. @@ -128,10 +130,10 @@ continue possible_targets += possible_target for(var/datum/traitor_objective/destroy_heirloom/objective as anything in possible_duplicates) - possible_targets -= objective.target_item + possible_targets -= objective.target_mind if(!length(possible_targets)) return FALSE - var/datum/mind/target_mind = pick(possible_targets) + target_mind = pick(possible_targets) AddComponent(/datum/component/traitor_objective_register, target_mind.current, fail_signals = list(COMSIG_PARENT_QDELETING)) var/datum/quirk/item_quirk/family_heirloom/quirk = locate() in target_mind.current.quirks target_item = quirk.heirloom.resolve() @@ -143,3 +145,4 @@ /datum/traitor_objective/destroy_heirloom/ungenerate_objective() target_item = null + target_mind = null diff --git a/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm b/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm index 5503f78c49e..9a142f15f92 100644 --- a/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm +++ b/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm @@ -5,6 +5,7 @@ /datum/traitor_objective/ultimate/battlecruiser = 1, /datum/traitor_objective/ultimate/space_dragon = 1, /datum/traitor_objective/ultimate/supermatter_cascade = 1, + /datum/traitor_objective/ultimate/infect_ai = 1, ) weight = 100 diff --git a/code/modules/antagonists/traitor/objectives/final_objective/infect_ai.dm b/code/modules/antagonists/traitor/objectives/final_objective/infect_ai.dm new file mode 100644 index 00000000000..d0068e6bf8a --- /dev/null +++ b/code/modules/antagonists/traitor/objectives/final_objective/infect_ai.dm @@ -0,0 +1,56 @@ +/datum/traitor_objective/ultimate/infect_ai + name = "Infect the station AI with an experimental virus." + description = "Infect the station AI with an experimental virus. Go to %AREA% to receive an infected law upload board \ + and use it on the AI core or a law upload console." + + ///area type the objective owner must be in to recieve the law upload module + var/area/board_area_pickup + ///checker on whether we have sent the law upload module + var/sent_board = FALSE + +/datum/traitor_objective/ultimate/infect_ai/can_generate_objective(generating_for, list/possible_duplicates) + . = ..() + if(!.) + return FALSE + + for(var/mob/living/silicon/ai/ai in GLOB.ai_list) + if(ai.stat == DEAD || ai.mind?.has_antag_datum(/datum/antagonist/malf_ai) || !is_station_level(ai.z)) + continue + return TRUE + + return FALSE + +/datum/traitor_objective/ultimate/infect_ai/generate_objective(datum/mind/generating_for, list/possible_duplicates) + var/list/possible_areas = GLOB.the_station_areas.Copy() + for(var/area/possible_area as anything in possible_areas) + //remove areas too close to the destination, too obvious for our poor shmuck, or just unfair + if(istype(possible_area, /area/station/hallway) || istype(possible_area, /area/station/security)) + possible_areas -= possible_area + if(!length(possible_areas)) + return FALSE + board_area_pickup = pick(possible_areas) + replace_in_name("%AREA%", initial(board_area_pickup.name)) + return TRUE + +/datum/traitor_objective/ultimate/infect_ai/generate_ui_buttons(mob/user) + var/list/buttons = list() + if(!sent_board) + buttons += add_ui_button("", "Pressing this will call down a pod with an infected law upload board.", "wifi", "upload_board") + return buttons + +/datum/traitor_objective/ultimate/infect_ai/ui_perform_action(mob/living/user, action) + . = ..() + switch(action) + if("upload_board") + if(sent_board) + return + var/area/delivery_area = get_area(user) + if(delivery_area.type != board_area_pickup) + to_chat(user, span_warning("You must be in [initial(board_area_pickup.name)] to receive the infected law upload board.")) + return + sent_board = TRUE + podspawn(list( + "target" = get_turf(user), + "style" = STYLE_SYNDICATE, + "spawn" = /obj/item/ai_module/malf, + )) diff --git a/code/modules/antagonists/traitor/objectives/kidnapping.dm b/code/modules/antagonists/traitor/objectives/kidnapping.dm index bba73678d6d..dc58d2f2b0e 100644 --- a/code/modules/antagonists/traitor/objectives/kidnapping.dm +++ b/code/modules/antagonists/traitor/objectives/kidnapping.dm @@ -47,7 +47,7 @@ /datum/traitor_objective/kidnapping/New(datum/uplink_handler/handler) . = ..() AddComponent(/datum/component/traitor_objective_limit_per_time, \ - /datum/traitor_objective/assassinate, \ + /datum/traitor_objective/kidnapping, \ time_period = objective_period, \ maximum_objectives = maximum_objectives_in_period \ ) @@ -56,28 +56,28 @@ progression_minimum = 0 MINUTES progression_maximum = 30 MINUTES target_jobs = list( + // Cargo + /datum/job/cargo_technician, + // Engineering + /datum/job/atmospheric_technician, + /datum/job/station_engineer, // Medical + /datum/job/chemist, /datum/job/doctor, /datum/job/paramedic, /datum/job/psychologist, - /datum/job/chemist, - // Service - /datum/job/clown, - /datum/job/botanist, - /datum/job/janitor, - /datum/job/mime, - /datum/job/lawyer, - /datum/job/chaplain, - /datum/job/bartender, - /datum/job/curator, - // Cargo - /datum/job/cargo_technician, // Science /datum/job/geneticist, /datum/job/roboticist, - // Engineering - /datum/job/station_engineer, - /datum/job/atmospheric_technician, + // Service + /datum/job/bartender, + /datum/job/botanist, + /datum/job/chaplain, + /datum/job/clown, + /datum/job/curator, + /datum/job/janitor, + /datum/job/lawyer, + /datum/job/mime, ) /datum/traitor_objective/kidnapping/less_common @@ -91,14 +91,14 @@ progression_minimum = 0 MINUTES progression_maximum = 45 MINUTES target_jobs = list( - // Medical - /datum/job/virologist, // Cargo /datum/job/shaft_miner, - // Service - /datum/job/cook, + // Medical + /datum/job/virologist, // Science /datum/job/scientist, + // Service + /datum/job/cook, ) progression_reward = list(4 MINUTES, 8 MINUTES) @@ -109,15 +109,16 @@ progression_minimum = 15 MINUTES progression_maximum = 60 MINUTES target_jobs = list( - // Security - /datum/job/security_officer, - /datum/job/warden, - /datum/job/detective, // Heads of staff - /datum/job/head_of_personnel, + /datum/job/chief_engineer, /datum/job/chief_medical_officer, + /datum/job/head_of_personnel, /datum/job/research_director, /datum/job/quartermaster, + // Security + /datum/job/detective, + /datum/job/security_officer, + /datum/job/warden, ) progression_reward = list(8 MINUTES, 12 MINUTES) @@ -127,8 +128,8 @@ /datum/traitor_objective/kidnapping/captain progression_minimum = 30 MINUTES target_jobs = list( + /datum/job/captain, /datum/job/head_of_security, - /datum/job/captain ) progression_reward = list(12 MINUTES, 16 MINUTES) diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index c29c9957774..639234f27a7 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -298,7 +298,7 @@ AddElement(/datum/element/eyestab) AddElement(/datum/element/wall_engraver) //deals 200 damage to statues, meaning you can actually kill one in ~250 hits - AddElement(/datum/element/bane, /mob/living/simple_animal/hostile/netherworld/statue, damage_multiplier = 40) + AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/hostile/netherworld/statue, damage_multiplier = 40) /obj/item/chisel/Destroy() prepared_block = null diff --git a/code/modules/asset_cache/assets/emojipedia.dm b/code/modules/asset_cache/assets/emojipedia.dm index b2c8c779fba..2197f1bff22 100644 --- a/code/modules/asset_cache/assets/emojipedia.dm +++ b/code/modules/asset_cache/assets/emojipedia.dm @@ -2,6 +2,6 @@ name = "emojipedia" cross_round_cachable = TRUE // The Emoji DMI is static and doesn't change without a commit mis-match. -/datum/asset/spritesheet/create_spritesheets() +/datum/asset/spritesheet/emojipedia/create_spritesheets() InsertAll("", EMOJI_SET) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 0f5d0592c78..be297ec5478 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -461,7 +461,7 @@ PIPING_FORWARD_SHIFT(pipe_overlay, piping_layer, 2) return pipe_overlay -/obj/machinery/atmospherics/on_construction(obj_color, set_layer = PIPING_LAYER_DEFAULT) +/obj/machinery/atmospherics/on_construction(mob/user, obj_color, set_layer = PIPING_LAYER_DEFAULT) if(can_unwrench) add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY) set_pipe_color(obj_color) diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index 9f4029485e0..4dee3f6d6fb 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -97,7 +97,7 @@ airs[i] = null return ..() -/obj/machinery/atmospherics/components/on_construction() +/obj/machinery/atmospherics/components/on_construction(mob/user) . = ..() update_parents() diff --git a/code/modules/atmospherics/machinery/components/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index 95d9c645501..32d26a2bd44 100644 --- a/code/modules/atmospherics/machinery/components/tank.dm +++ b/code/modules/atmospherics/machinery/components/tank.dm @@ -563,7 +563,7 @@ var/obj/machinery/atmospherics/components/tank/new_tank = new(build_location) var/list/new_custom_materials = list((material_end_product) = TANK_PLATING_SHEETS * MINERAL_MATERIAL_AMOUNT) new_tank.set_custom_materials(new_custom_materials) - new_tank.on_construction(new_tank.pipe_color, new_tank.piping_layer) + new_tank.on_construction(user, new_tank.pipe_color, new_tank.piping_layer) to_chat(user, span_notice("[new_tank] has been sealed and is ready to accept gases.")) qdel(src) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 5607cdb4331..e028b801d67 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -147,8 +147,8 @@ . = ..() update_appearance() -/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction() - ..(dir, dir) +/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction(mob/user) + ..(user, dir, dir) /obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts() . = ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 7245efbbc1a..94b1fa4bb57 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -49,16 +49,20 @@ return FALSE . = ..() -/obj/machinery/atmospherics/components/unary/thermomachine/on_construction(obj_color, set_layer) +/obj/machinery/atmospherics/components/unary/thermomachine/on_construction(mob/user, obj_color, set_layer) var/obj/item/circuitboard/machine/thermomachine/board = circuit if(board) piping_layer = board.pipe_layer set_layer = piping_layer + ..() //Skipping the rest of on_construction() would be a bad idea so we clean up after it instead. + if(check_pipe_on_turf()) - deconstruct(TRUE) - return - return..() + set_anchored(FALSE) + set_panel_open(TRUE) + change_pipe_connection(TRUE) + icon_state = "thermo-open" + balloon_alert(user, "the port is already in use!") /obj/machinery/atmospherics/components/unary/thermomachine/RefreshParts() . = ..() @@ -213,13 +217,13 @@ if(device == src) continue if(device.piping_layer == piping_layer) - visible_message(span_warning("A pipe is hogging the port, remove the obstruction or change the machine piping layer.")) return TRUE return FALSE /obj/machinery/atmospherics/components/unary/thermomachine/wrench_act_secondary(mob/living/user, obj/item/tool) if(!panel_open || check_pipe_on_turf()) - return + visible_message(span_warning("A pipe is hogging the port, remove the obstruction or change the machine piping layer.")) + return TOOL_ACT_TOOLTYPE_SUCCESS if(default_unfasten_wrench(user, tool)) return TOOL_ACT_TOOLTYPE_SUCCESS return diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm index 8fef0c13ca2..3f0f16c55a8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm @@ -13,7 +13,7 @@ /obj/machinery/atmospherics/components/unary/set_init_directions() initialize_directions = dir -/obj/machinery/atmospherics/components/unary/on_construction() +/obj/machinery/atmospherics/components/unary/on_construction(mob/user) ..() update_appearance() diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index f6c7c958fe9..528d3c34d1b 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -428,6 +428,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister()) /obj/machinery/portable_atmospherics/canister/deconstruct(disassembled = TRUE) if((flags_1 & NODECONSTRUCT_1)) + qdel(src) return if(!(machine_stat & BROKEN)) canister_break() diff --git a/code/modules/cards/singlecard.dm b/code/modules/cards/singlecard.dm index 37524b343e6..adaa5cb328b 100644 --- a/code/modules/cards/singlecard.dm +++ b/code/modules/cards/singlecard.dm @@ -1,6 +1,3 @@ -#define CARD_FACEDOWN 0 -#define CARD_FACEUP 1 - /obj/item/toy/singlecard name = "card" desc = "A playing card used to play card games like poker." @@ -24,7 +21,7 @@ /// The name of the card var/cardname = "Ace of Spades" /// Is the card flipped facedown (FALSE) or flipped faceup (TRUE) - var/flipped = FALSE + var/flipped = CARD_FACEDOWN /// The card is blank and can be written on with a pen. var/blank = FALSE /// The color used to mark a card for cheating (by pens or crayons) @@ -48,6 +45,9 @@ if(parent_deck.holodeck) flags_1 |= HOLOGRAM_1 parent_deck.holodeck.spawned += src + if(mapload) + //maploaded card needs to be faceup anyways, and doing this will give it its name and appearance properly + Flip(CARD_FACEUP) register_context() @@ -109,11 +109,11 @@ * Flips the card over * * * Arguments: - * * orientation (optional) - Sets flipped state to CARD_FACEDOWN or CARD_FACEUP if given orientation (otherwise just invert the flipped state) + * * is_face_up (optional) - Sets flipped state to CARD_FACEDOWN or CARD_FACEUP if given (otherwise just invert the flipped state) */ -/obj/item/toy/singlecard/proc/Flip(orientation) - if(!isnull(orientation)) - flipped = orientation +/obj/item/toy/singlecard/proc/Flip(is_face_up) + if(!isnull(is_face_up)) + flipped = is_face_up else flipped = !flipped diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index b0677821f0b..6d037211283 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -32,7 +32,7 @@ . = ..() packin_up() -/obj/machinery/computer/cargo/express/on_construction() +/obj/machinery/computer/cargo/express/on_construction(mob/user) . = ..() packin_up() diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index 77d0f95cf64..d9912bec8c6 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -85,7 +85,7 @@ board.obj_flags |= EMAGGED update_static_data(user) -/obj/machinery/computer/cargo/on_construction() +/obj/machinery/computer/cargo/on_construction(mob/user) . = ..() circuit.configure_machine(src) diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm index 6150fd6d5e4..78ddc28bbb8 100644 --- a/code/modules/cargo/packs/emergency.dm +++ b/code/modules/cargo/packs/emergency.dm @@ -170,11 +170,12 @@ /datum/supply_pack/emergency/weedcontrol name = "Weed Control Crate" - desc = "Keep those invasive species OUT. Contains a scythe, gasmask, and two anti-weed chemical grenades. \ - Warranty void if used on ambrosia. Requires Hydroponics access to open." + desc = "Keep those invasive species OUT. Contains a scythe, leather gloves, gasmask, and two anti-weed chemical grenades. \ + Warranty void if used on ambrosia." cost = CARGO_CRATE_VALUE * 2.5 access = ACCESS_HYDROPONICS contains = list(/obj/item/scythe, + /obj/item/clothing/gloves/botanic_leather, /obj/item/clothing/mask/gas, /obj/item/grenade/chem_grenade/antiweed = 2, ) diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm index 6db601f25e2..f346bc8c67e 100644 --- a/code/modules/cargo/packs/livestock.dm +++ b/code/modules/cargo/packs/livestock.dm @@ -146,6 +146,13 @@ contains = list(/mob/living/simple_animal/hostile/retaliate/goat) crate_name = "goat crate" +/datum/supply_pack/critter/rabbit + name = "Rabbit Crate" + desc = "What noise do rabbits even make? Contains one rabbit." + cost = CARGO_CRATE_VALUE * 4 + contains = list(/mob/living/basic/rabbit) + crate_name = "rabbit crate" + /datum/supply_pack/critter/mothroach name = "Mothroach Crate" desc = "Put the mothroach on your head and find out what true cuteness looks like. \ diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 69d19ed784a..a802c3ad4bf 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -59,6 +59,15 @@ flags_1 = IS_PLAYER_COLORABLE_1 dog_fashion = null +/obj/item/clothing/head/wizard/tape + name = "tape hat" + desc = "A magically attuned hat made exclusively from duct tape. You can barely see." + icon_state = "tapehat" + inhand_icon_state = "tapehat" + dog_fashion = null + worn_y_offset = 6 + body_parts_covered = HEAD|HAIR + flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR /obj/item/clothing/head/wizard/magus name = "\improper Magus helm" @@ -130,6 +139,12 @@ icon_state = "marisa" inhand_icon_state = null +/obj/item/clothing/suit/wizrobe/tape + name = "tape robe" + desc = "A fine robe made from magically attuned duct tape." + icon_state = "taperobe" + inhand_icon_state = "taperobe" + /obj/item/clothing/suit/wizrobe/magusblue name = "\improper Magus robe" desc = "A set of armored robes that seem to radiate a dark power." @@ -161,6 +176,12 @@ armor_type = /datum/armor/none resistance_flags = FLAMMABLE +/obj/item/clothing/head/wizard/tape/fake + name = "tape hat" + desc = "A hat designed exclusively from duct tape. You can barely see." + armor_type = /datum/armor/none + resistance_flags = FLAMMABLE + /obj/item/clothing/suit/wizrobe/marisa/fake name = "witch robe" desc = "Magic is all about the spell power, ZE!" @@ -169,6 +190,12 @@ armor_type = /datum/armor/none resistance_flags = FLAMMABLE +/obj/item/clothing/suit/wizrobe/tape/fake + name = "tape robe" + desc = "An outfit designed exclusively from duct tape. It was hard to put on." + armor_type = /datum/armor/none + resistance_flags = FLAMMABLE + /obj/item/clothing/suit/wizrobe/paper name = "papier-mache robe" // no non-latin characters! desc = "A robe held together by various bits of clear-tape and paste." diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm index 55778bba1e2..7cea683fca8 100644 --- a/code/modules/clothing/under/costume.dm +++ b/code/modules/clothing/under/costume.dm @@ -356,3 +356,10 @@ inhand_icon_state = null can_adjust = FALSE +/obj/item/clothing/under/costume/gi + name = "Martial Artist Gi" + desc = "Assistant, nukie, whatever. You can beat anyone; it's called hard work!" + icon_state = "martial_arts_gi" + inhand_icon_state = null + female_sprite_flags = NO_FEMALE_UNIFORM + can_adjust = FALSE diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 7d718dcf091..5c6dde0d608 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -227,7 +227,7 @@ while(length(afflicted)) victim = pick_n_take(afflicted) if(victim.ForceContractDisease(advanced_disease, FALSE)) - message_admins("Event triggered: Disease Outbreak: Advanced - starting with patient zero [key_name(victim)]! Details: [advanced_disease.admin_details()] sp:[advanced_disease.spread_flags] ([advanced_disease.spread_text])") + message_admins("Event triggered: Disease Outbreak: Advanced - starting with patient zero [ADMIN_LOOKUPFLW(victim)]! Details: [advanced_disease.admin_details()] sp:[advanced_disease.spread_flags] ([advanced_disease.spread_text])") log_game("Event triggered: Disease Outbreak: Advanced - starting with patient zero [key_name(victim)]. Details: [advanced_disease.admin_details()] sp:[advanced_disease.spread_flags] ([advanced_disease.spread_text])") log_virus("Disease Outbreak: Advanced has triggered a custom virus outbreak of [advanced_disease.admin_details()] in [victim]!") announce_to_ghosts(victim) diff --git a/code/modules/events/ghost_role/changeling_event.dm b/code/modules/events/ghost_role/changeling_event.dm index 733109c3d27..3e52a57b0dc 100644 --- a/code/modules/events/ghost_role/changeling_event.dm +++ b/code/modules/events/ghost_role/changeling_event.dm @@ -47,9 +47,20 @@ var/datum/mind/player_mind = new(selected.key) player_mind.active = TRUE - var/start_side = pick(GLOB.cardinals) - var/start_z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION)) - var/turf/picked_start = spaceDebrisStartLoc(start_side, start_z) + var/turf/picked_start + + if (SSmapping.is_planetary()) + var/list/possible_start = list() + for(var/obj/effect/landmark/carpspawn/spawn_point in GLOB.landmarks_list) + possible_start += get_turf(spawn_point) + picked_start = pick(possible_start) + else + var/start_z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION)) + var/start_side = pick(GLOB.cardinals) + picked_start = spaceDebrisStartLoc(start_side, start_z) + + if (!picked_start) + stack_trace("No valid spawn location for changeling meteor") var/obj/effect/meteor/meaty/changeling/changeling_meteor = new(picked_start, get_random_station_turf()) var/mob/living/carbon/human/new_changeling = new(picked_start) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index d4c702f629c..c848f83b5cf 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -256,7 +256,7 @@ var/obj/item/bodypart/limb = victim.get_bodypart(victim.get_random_valid_zone(even_weights = TRUE)) //Picks a random bodypart. var/armor = victim.run_armor_check(limb, MELEE, null, null) //armor = the armor value of that randomly chosen bodypart. Nulls to not print a message, because it would still print on pierce. var/datum/spacevine_mutation/thorns/thorn = locate() in vine.mutations //Searches for the thorns mutation in the "mutations"-list inside obj/structure/spacevine, and defines T if it finds it. - if(thorn && (prob(40))) //If we found the thorns mutation there is now a chance to get stung instead of lashed or smashed. + if(thorn && prob(40) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) //If we found the thorns mutation there is now a chance to get stung instead of lashed or smashed. victim.apply_damage(50, BRUTE, def_zone = limb, wound_bonus = rand(-20,10), sharpness = SHARP_POINTY) //This one gets a bit lower damage because it ignores armor. victim.Stun(1 SECONDS) //Stopped in place for a moment. playsound(living_mob, 'sound/weapons/pierce.ogg', 50, TRUE, -1) @@ -264,7 +264,7 @@ span_userdanger("You are nailed by a sharp thorn!")) log_combat(vine, living_mob, "aggressively pierced") //"Aggressively" for easy ctrl+F'ing in the attack logs. else - if(prob(80)) + if(prob(80) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) victim.apply_damage(60, BRUTE, def_zone = limb, blocked = armor, wound_bonus = rand(-20,10), sharpness = SHARP_EDGED) victim.Knockdown(2 SECONDS) playsound(victim, 'sound/weapons/whip.ogg', 50, TRUE, -1) @@ -364,17 +364,30 @@ quality = NEGATIVE /datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser) + if(istype(crosser) && HAS_TRAIT(crosser, TRAIT_PIERCEIMMUNE)) + return + if(prob(THORN_MUTATION_CUT_PROB) && istype(crosser) && !isvineimmune(crosser)) var/mob/living/victim = crosser victim.adjustBruteLoss(15) to_chat(victim, span_danger("You cut yourself on the thorny vines.")) /datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/item, expected_damage) + if(iscarbon(hitter)) + var/mob/living/carbon/carbon_victim = hitter + for(var/obj/item/clothing/worn_item in carbon_victim.get_equipped_items()) + if((worn_item.body_parts_covered & HANDS) && (worn_item.clothing_flags & THICKMATERIAL)) + return expected_damage + + if(HAS_TRAIT(hitter, TRAIT_PIERCEIMMUNE) || HAS_TRAIT(hitter, TRAIT_PLANT_SAFE)) + return expected_damage + if(prob(THORN_MUTATION_CUT_PROB) && istype(hitter) && !isvineimmune(hitter)) var/mob/living/victim = hitter victim.adjustBruteLoss(15) to_chat(victim, span_danger("You cut yourself on the thorny vines.")) - . = expected_damage + + return expected_damage /datum/spacevine_mutation/woodening name = "Hardened" @@ -486,7 +499,7 @@ for(var/datum/spacevine_mutation/mutation in mutations) override += mutation.on_chem(src, chem) if(!override && istype(chem, /datum/reagent/toxin/plantbgone)) - if(prob(50)) + if(prob(75)) qdel(src) /obj/structure/spacevine/proc/eat(mob/eater) @@ -656,7 +669,7 @@ /// Actual maximum spread rate for this process tick var/spread_max = round(clamp(delta_time * (spread_base + start_spread_bonus), max(delta_time * minimum_spread_rate, 1), spread_cap)) var/amount_processed = 0 - for(var/obj/structure/spacevine/vine as anything in growth_queue) + for(var/obj/structure/spacevine/vine in growth_queue) if(!vine.can_spread) continue growth_queue -= vine @@ -714,6 +727,9 @@ /obj/structure/spacevine/proc/spread() var/direction = pick(GLOB.cardinals) var/turf/stepturf = get_step(src, direction) + if(!istype(stepturf)) + return + if(!isspaceturf(stepturf) && stepturf.Enter(src)) var/obj/structure/spacevine/spot_taken = locate() in stepturf //Locates any vine on target turf. Calls that vine "spot_taken". var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations //Locates the vine eating trait in our own seed and calls it E. diff --git a/code/modules/food_and_drinks/machinery/processor.dm b/code/modules/food_and_drinks/machinery/processor.dm index ca4c2dd550b..ced58696515 100644 --- a/code/modules/food_and_drinks/machinery/processor.dm +++ b/code/modules/food_and_drinks/machinery/processor.dm @@ -207,12 +207,11 @@ return var/mob/living/simple_animal/slime/picked_slime for(var/mob/living/simple_animal/slime/slime in range(1,src)) - if(slime.loc == src) + if(!CanReach(slime)) //don't take slimes behind glass panes or somesuch; also makes it ignore slimes inside the processor continue - if(isslime(slime)) - if(slime.stat) - picked_slime = slime - break + if(slime.stat) + picked_slime = slime + break if(!picked_slime) return var/datum/food_processor_process/recipe = PROCESSOR_SELECT_RECIPE(picked_slime) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm index 8f900657244..23612db1aca 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm @@ -630,11 +630,6 @@ result = /obj/item/food/spaghetti/boiledspaghetti category = CAT_SPAGHETTI -/datum/crafting_recipe/food/microwave/khinkali - reqs = list(/obj/item/food/rawkhinkali = 1) - result = /obj/item/food/khinkali - category = CAT_BREAD - /datum/crafting_recipe/food/microwave/onionrings reqs = list(/obj/item/food/onion_slice = 1) result = /obj/item/food/onionrings diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 655c5a86d8a..28d43ad8446 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -522,6 +522,7 @@ attack_verb_continuous = list("chops", "slices", "cuts", "reaps") attack_verb_simple = list("chop", "slice", "cut", "reap") hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = SHARP_EDGED var/swiping = FALSE /obj/item/scythe/Initialize(mapload) @@ -530,6 +531,7 @@ speed = 9 SECONDS, \ effectiveness = 105, \ ) + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/scythe/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -541,18 +543,23 @@ playsound(src, SFX_DESECRATION ,50, TRUE, -1) return BRUTELOSS -/obj/item/scythe/pre_attack(atom/A, mob/living/user, params) - if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user)) +/obj/item/scythe/pre_attack(atom/target, mob/living/user, params) + if(!istype(target, /obj/structure/alien/resin/flower_bud) && !istype(target, /obj/structure/spacevine)) + return ..() + if(swiping || get_turf(target) == get_turf(user)) return ..() var/turf/user_turf = get_turf(user) - var/dir_to_target = get_dir(user_turf, get_turf(A)) + var/dir_to_target = get_dir(user_turf, get_turf(target)) swiping = TRUE var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90) for(var/i in scythe_slash_angles) - var/turf/T = get_step(user_turf, turn(dir_to_target, i)) - for(var/obj/structure/spacevine/V in T) - if(user.Adjacent(V)) - melee_attack_chain(user, V) + var/turf/adjacent_turf = get_step(user_turf, turn(dir_to_target, i)) + for(var/obj/structure/spacevine/vine in adjacent_turf) + if(user.Adjacent(vine)) + melee_attack_chain(user, vine) + for(var/obj/structure/alien/resin/flower_bud/flower in adjacent_turf) + if(user.Adjacent(flower)) + melee_attack_chain(user, flower) swiping = FALSE return TRUE */ diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index 5eea0d7fc46..373dd886665 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -23,6 +23,13 @@ GLOBAL_LIST_INIT(exp_specialmap, list( ROLE_MAINTENANCE_DRONE, ROLE_VENUSHUMANTRAP, ROLE_GHOST_ROLE, + //Skyrat Edit Start - Custom Ghost roles + ROLE_BLACK_MARKET_DEALER, + ROLE_DS2, + ROLE_FREIGHTER_CREW, + ROLE_GHOST_CAFE, + ROLE_PORT_TARKON, + //Skyrat Edit Start - End Custom Ghost roles ), // Ghost roles EXP_TYPE_GHOST = list() // dead people, observers )) diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 500864b2db9..f3aa12766a8 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -5,7 +5,7 @@ static_lighting = TRUE requires_power = FALSE has_gravity = STANDARD_GRAVITY - area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED + area_flags = BLOBS_ALLOWED | UNIQUE_AREA flags_1 = CAN_BE_DIRTY_1 //Survival Capsule diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index 001e9f37e85..3b113912064 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -387,6 +387,7 @@ RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED, PROC_REF(on_attack)) RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED_SECONDARY, PROC_REF(on_secondary_attack)) RegisterSignal(src, COMSIG_ATOM_INTEGRITY_CHANGED, PROC_REF(on_integrity_change)) + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/soulscythe/examine(mob/user) . = ..() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index bdebef1b6ce..539df1c2939 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -213,21 +213,28 @@ /obj/machinery/mineral/ore_redemption/ui_data(mob/user) var/list/data = list() data["unclaimedPoints"] = points - data["materials"] = list() var/datum/component/material_container/mat_container = materials.mat_container if (mat_container) - for(var/mat in mat_container.materials) - var/datum/material/M = mat - var/amount = mat_container.materials[M] + for(var/datum/material/material as anything in mat_container.materials) + var/amount = mat_container.materials[material] var/sheet_amount = amount / MINERAL_MATERIAL_AMOUNT - var/ref = REF(M) - data["materials"] += list(list("name" = M.name, "id" = ref, "amount" = sheet_amount, "value" = ore_values[M.type])) + data["materials"] += list(list( + "name" = material.name, + "id" = REF(material), + "amount" = sheet_amount, + "category" = "material", + "value" = ore_values[material.type], + )) - data["alloys"] = list() - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - data["alloys"] += list(list("name" = D.name, "id" = D.id, "amount" = can_smelt_alloy(D))) + for(var/research in stored_research.researched_designs) + var/datum/design/alloy = SSresearch.techweb_design_by_id(research) + data["materials"] += list(list( + "name" = alloy.name, + "id" = alloy.id, + "category" = "alloy", + "amount" = can_smelt_alloy(alloy), + )) if (!mat_container) data["disconnected"] = "local mineral storage is unavailable" @@ -236,8 +243,47 @@ else if (materials.on_hold()) data["disconnected"] = "mineral withdrawal is on hold" + var/obj/item/card/id/card + if(isliving(user)) + var/mob/living/customer = user + card = customer.get_idcard(hand_first = TRUE) + if(card?.registered_account) + data["user"] = list( + "name" = card.registered_account.account_holder, + "cash" = card.registered_account.account_balance, + ) + + else if(issilicon(user)) + var/mob/living/silicon/silicon_player = user + data["user"] = list( + "name" = silicon_player.name, + "cash" = "No valid account", + ) return data +/obj/machinery/mineral/ore_redemption/ui_static_data(mob/user) + var/list/data = list() + + var/datum/component/material_container/mat_container = materials.mat_container + if (mat_container) + for(var/datum/material/material as anything in mat_container.materials) + var/obj/material_display = initial(material.sheet_type) + data["material_icons"] += list(list( + "id" = REF(material), + "product_icon" = icon2base64(getFlatIcon(image(icon = initial(material_display.icon), icon_state = initial(material_display.icon_state)), no_anim=TRUE)), + )) + + for(var/research in stored_research.researched_designs) + var/datum/design/alloy = SSresearch.techweb_design_by_id(research) + var/obj/alloy_display = initial(alloy.build_path) + data["material_icons"] += list(list( + "id" = alloy.id, + "product_icon" = icon2base64(getFlatIcon(image(icon = initial(alloy_display.icon), icon_state = initial(alloy_display.icon_state)), no_anim=TRUE)), + )) + + return data + + /obj/machinery/mineral/ore_redemption/ui_act(action, params) . = ..() if(.) diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm index e50ac55636e..f6ef5acd0fb 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -819,6 +819,10 @@ name = "Wisp" icon_state = "hair_wisp" +/datum/sprite_accessory/hair/ziegler + name = "Ziegler" + icon_state = "hair_ziegler" + /* ///////////////////////////////////// / =---------------------------= / diff --git a/code/modules/mob/living/basic/pets/dog.dm b/code/modules/mob/living/basic/pets/dog.dm index 9cb5a6ae0b4..82781d51abf 100644 --- a/code/modules/mob/living/basic/pets/dog.dm +++ b/code/modules/mob/living/basic/pets/dog.dm @@ -84,6 +84,11 @@ /// Is this corgi physically slow due to age, etc? var/is_slow = FALSE +/mob/living/basic/pet/dog/corgi/examine(mob/user) + . = ..() + if(access_card) + . += "There appears to be [icon2html(access_card, user)] \a [access_card] pinned to [p_them()]." + /mob/living/basic/pet/dog/corgi/Destroy() QDEL_NULL(inventory_head) QDEL_NULL(inventory_back) @@ -794,7 +799,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( maxHealth = 50 gender = NEUTER damage_coeff = list(BRUTE = 3, BURN = 3, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) - butcher_results = list(/obj/item/organ/internal/brain = 1, /obj/item/organ/internal/heart = 1, /obj/item/food/breadslice = 3, \ + butcher_results = list(/obj/item/organ/internal/brain = 1, /obj/item/organ/internal/heart = 1, /obj/item/food/breadslice/plain = 3, \ /obj/item/food/meat/slab = 2) response_harm_continuous = "takes a bite out of" response_harm_simple = "take a bite out of" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 37214035911..841606339dc 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -214,7 +214,7 @@ if(l_limbs_missing >= 2 && r_limbs_missing == 0) msg += "[t_He] look[p_s()] all right now.\n" else if(l_limbs_missing == 0 && r_limbs_missing >= 2) - msg += "[t_He] really keeps to the left.\n" + msg += "[t_He] really keep[p_s()] to the left.\n" else if(l_limbs_missing >= 2 && r_limbs_missing >= 2) msg += "[t_He] [p_do()]n't seem all there.\n" diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 9aa0aa6854f..611a8733da7 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -547,7 +547,7 @@ /datum/action/innate/integrate_extract/New(Target) . = ..() - AddComponent(/datum/component/action_item_overlay, CALLBACK(src, PROC_REF(locate_extract))) + AddComponent(/datum/component/action_item_overlay, item_callback = CALLBACK(src, PROC_REF(locate_extract))) /// Callback for /datum/component/action_item_overlay to find the slime extract from within the species /datum/action/innate/integrate_extract/proc/locate_extract() @@ -617,7 +617,7 @@ /datum/action/innate/use_extract/New(Target) . = ..() - AddComponent(/datum/component/action_item_overlay, CALLBACK(src, PROC_REF(locate_extract))) + AddComponent(/datum/component/action_item_overlay, item_callback = CALLBACK(src, PROC_REF(locate_extract))) /// Callback for /datum/component/action_item_overlay to find the slime extract from within the species /datum/action/innate/use_extract/proc/locate_extract() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 714cd314837..a2e7c101993 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -590,6 +590,7 @@ return if(new_resting == resting) return + . = resting resting = new_resting if(new_resting) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index d7ac65f12ee..c1ec5de9261 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -874,16 +874,17 @@ var/hrefpart = "" var/jobpart = "Unknown" - if (isliving(speaker)) - var/mob/living/living_speaker = speaker - if(living_speaker.job) - jobpart = "[living_speaker.job]" - if (istype(speaker, /obj/effect/overlay/holo_pad_hologram)) - var/obj/effect/overlay/holo_pad_hologram/holo = speaker - if(holo.Impersonation?.job) - jobpart = "[holo.Impersonation.job]" - else if(usr?.job) // not great, but AI holograms have no other usable ref - jobpart = "[usr.job]" + if(!HAS_TRAIT(speaker, TRAIT_UNKNOWN)) //don't fetch the speaker's job in case they have something that conseals their identity completely + if (isliving(speaker)) + var/mob/living/living_speaker = speaker + if(living_speaker.job) + jobpart = "[living_speaker.job]" + if (istype(speaker, /obj/effect/overlay/holo_pad_hologram)) + var/obj/effect/overlay/holo_pad_hologram/holo = speaker + if(holo.Impersonation?.job) + jobpart = "[holo.Impersonation.job]" + else if(usr?.job) // not great, but AI holograms have no other usable ref + jobpart = "[usr.job]" var/rendered = "[start][span_name("[hrefpart][namepart] ([jobpart]) ")][treated_message]" 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 9cf65380fc4..feff181d6ca 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -60,8 +60,16 @@ return for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) - var/step = get_step(src, direction) - if(step && ((locate(/obj/structure/spacevine) in step) || (locate(/obj/structure/glowshroom) in step))) + var/turf/step = get_step(src, direction) + + if(!istype(step)) + return + + var/vine = locate(/obj/structure/spacevine) in step + var/mushroom = locate(/obj/structure/glowshroom) in step + var/flower = locate(/obj/structure/alien/resin/flower_bud) in step + + if(vine || mushroom || flower) Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() @@ -74,29 +82,44 @@ eat_plants() /mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants() - var/eaten = FALSE - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) - eaten = TRUE + var/obj/structure/spacevine/vine = locate(/obj/structure/spacevine) in loc + if(vine) + vine.eat(src) - var/obj/structure/glowshroom/GS = locate(/obj/structure/glowshroom) in loc - if(GS) - qdel(GS) - eaten = TRUE + var/obj/structure/alien/resin/flower_bud/flower = locate(/obj/structure/alien/resin/flower_bud) in loc + if(flower) + flower.take_damage(rand(30, 50), BRUTE, 0) - if(eaten && prob(10)) - say("Nom") + var/obj/structure/glowshroom/mushroom = locate(/obj/structure/glowshroom) in loc + if(mushroom) + qdel(mushroom) + + if((vine || flower || mushroom) && prob(10)) + say("Nom") // bon appetit + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) /mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget() . = ..() - if(. && ishuman(target)) - var/mob/living/carbon/human/H = target - if(istype(H.dna.species, /datum/species/pod)) - var/obj/item/bodypart/NB = pick(H.bodyparts) - H.visible_message(span_warning("[src] takes a big chomp out of [H]!"), \ - span_userdanger("[src] takes a big chomp out of your [NB]!")) - NB.dismember() + + if(!. || !isliving(target)) + return + + var/mob/living/plant_target = target + if(!(plant_target.mob_biotypes & MOB_PLANT)) + return + + plant_target.adjustBruteLoss(20) + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) + var/obj/item/bodypart/edible_bodypart + + if(ishuman(plant_target)) + var/mob/living/carbon/human/plant_man = target + edible_bodypart = pick(plant_man.bodyparts) + edible_bodypart.dismember() + + plant_target.visible_message(span_warning("[src] takes a big chomp out of [plant_target]!"), \ + span_userdanger("[src] takes a big chomp out of your [edible_bodypart || "body"]!")) + /mob/living/simple_animal/chick name = "\improper chick" @@ -157,6 +180,8 @@ ..() amount_grown = 0 +/// Counter for number of chicken mobs in the universe. Chickens will not lay fertile eggs if it exceeds the MAX_CHICKENS define. +GLOBAL_VAR_INIT(chicken_count, 0) /mob/living/simple_animal/chicken name = "\improper chicken" @@ -188,14 +213,12 @@ mob_size = MOB_SIZE_SMALL gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW - ///counter for how many chickens are in existence to stop too many chickens from lagging shit up - var/static/chicken_count = 0 ///boolean deciding whether eggs laid by this chicken can hatch into chicks - var/process_eggs = TRUE + var/fertile = TRUE /mob/living/simple_animal/chicken/Initialize(mapload) . = ..() - chicken_count++ + GLOB.chicken_count++ add_cell_sample() AddElement(/datum/element/animal_variety, "chicken", pick("brown","black","white"), TRUE) AddComponent(/datum/component/egg_layer,\ @@ -214,25 +237,20 @@ AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) /mob/living/simple_animal/chicken/Destroy() - chicken_count-- + GLOB.chicken_count-- return ..() /mob/living/simple_animal/chicken/proc/egg_laid(obj/item/egg) - if(chicken_count <= MAX_CHICKENS && process_eggs && prob(25)) - START_PROCESSING(SSobj, egg) - -/obj/item/food/egg/var/amount_grown = 0 - -/obj/item/food/egg/process(delta_time) - if(isturf(loc)) - amount_grown += rand(1,2) * delta_time - if(amount_grown >= 200) - visible_message(span_notice("[src] hatches with a quiet cracking sound.")) - new /mob/living/simple_animal/chick(get_turf(src)) - STOP_PROCESSING(SSobj, src) - qdel(src) - else - STOP_PROCESSING(SSobj, src) + if(GLOB.chicken_count <= MAX_CHICKENS && fertile && prob(25)) + egg.AddComponent(/datum/component/fertile_egg,\ + embryo_type = /mob/living/simple_animal/chick,\ + minimum_growth_rate = 1,\ + maximum_growth_rate = 2,\ + total_growth_required = 200,\ + current_growth = 0,\ + location_allowlist = typecacheof(list(/turf)),\ + spoilable = TRUE,\ + ) /mob/living/simple_animal/deer name = "doe" diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm index fab08b3d9fb..7f4f4637813 100644 --- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm +++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm @@ -12,7 +12,7 @@ see_in_dark = 15 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE obj_damage = 10 - butcher_results = list(/obj/item/clothing/head/costume/crown = 1,) + butcher_results = list(/obj/item/food/meat/slab/mouse = 2, /obj/item/clothing/head/costume/crown = 1) response_help_continuous = "glares at" response_help_simple = "glare at" response_disarm_continuous = "skoffs at" diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 5500b4bfd29..740416547d1 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -20,6 +20,7 @@ opacity = FALSE canSmoothWith = null smoothing_flags = NONE + density = FALSE /// The amount of time it takes to create a venus human trap. var/growth_time = 1 MINUTES //SKYRAT EDIT CHANGE var/growth_icon = 0 @@ -59,6 +60,15 @@ damage_amount = 0 . = ..() +/obj/structure/alien/resin/flower_bud/attacked_by(obj/item/item, mob/living/user) + var/damage_dealt = item.force + if(item.damtype == BURN) + damage_dealt *= 4 + if(item.get_sharpness()) + damage_dealt *= 16 // alien resin applies 75% reduction to brute damage so this actually x4 damage + + take_damage(damage_dealt, item.damtype, MELEE, 1) + /obj/structure/alien/resin/flower_bud/Destroy() QDEL_LIST(vines) QDEL_NULL(countdown) diff --git a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm index 6d1e0b9e438..0a8329128d9 100644 --- a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm +++ b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm @@ -5,6 +5,7 @@ icon = 'icons/effects/spacevines.dmi' icon_state = "bud0" mob_type = /mob/living/simple_animal/hostile/venus_human_trap + density = FALSE prompt_name = "venus human trap" you_are_text = "You are a venus human trap." flavour_text = "You are a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!" diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index ff65575b378..089315b05c6 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -5,6 +5,8 @@ //So it shows up in the map editor icon = 'icons/effects/mapping_helpers.dmi' icon_state = "mobspawner" + /// Can this spawner be used up? + var/infinite_use = FALSE ///A forced name of the mob, though can be overridden if a special name is passed as an argument var/mob_name ///the type of the mob, you best inherit this @@ -183,7 +185,7 @@ if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1)) to_chat(user, span_warning("An admin has temporarily disabled non-admin ghost roles!")) return - if(uses <= 0) //just in case + if(uses <= 0 && !infinite_use) //just in case to_chat(user, span_warning("This spawner is out of charges!")) return @@ -195,6 +197,18 @@ if(QDELETED(src) || QDELETED(user)) return + create_from_ghost(user) + +/** + * Uses a use and creates a mob from a passed ghost + * + * Does NOT validate that the spawn is possible or valid - assumes this has been done already! + * + * If you are manually forcing a player into this mob spawn, + * you should be using this and not directly calling [proc/create]. + */ +/obj/effect/mob_spawn/ghost_role/proc/create_from_ghost(mob/dead/user) + ASSERT(istype(user)) user.log_message("became a [prompt_name].", LOG_GAME) uses -= 1 // Remove a use before trying to spawn to prevent strangeness like the spawner trying to spawn more mobs than it should be able to user.mind = null // dissassociate mind, don't let it follow us to the next life diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm index 93ef3559fc8..d12a6e9d756 100644 --- a/code/modules/modular_computers/computers/item/role_tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm @@ -291,6 +291,7 @@ /obj/item/modular_computer/pda/bar name = "bartender PDA" greyscale_colors = "#333333#C7C7C7" + inserted_item = /obj/item/pen/fountain /obj/item/modular_computer/pda/clown name = "clown PDA" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 91acfd15b51..5ffc4209404 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -546,7 +546,7 @@ playsound(src, 'sound/items/handling/standard_stamp.ogg', 50, vary = TRUE) update_appearance() - update_static_data(user, ui) + update_static_data_for_all_viewers() return TRUE if("add_text") var/paper_input = params["text"] @@ -592,7 +592,7 @@ log_paper("[key_name(user)] wrote to [name]: \"[paper_input]\"") to_chat(user, "You have added to your paper masterpiece!"); - update_static_data(user, ui) + update_static_data_for_all_viewers() update_appearance() return TRUE if("fill_input_field") @@ -633,7 +633,7 @@ if(!add_field_input(field_key, field_text, writing_implement_data["font"], writing_implement_data["color"], writing_implement_data["use_bold"], user.real_name)) log_paper("[key_name(user)] tried to write to field [field_key] when it already has data, with the following text: [field_text]") - update_static_data(user, ui) + update_static_data_for_all_viewers() return TRUE /obj/item/paper/proc/get_input_field_count(raw_text) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 4ac695e9a61..c02fb6ecbdb 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -279,7 +279,9 @@ throwforce_on = 35, \ throw_speed_on = 4, \ sharpness_on = SHARP_EDGED, \ - w_class_on = WEIGHT_CLASS_NORMAL) + w_class_on = WEIGHT_CLASS_NORMAL, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) RegisterSignal(src, COMSIG_DETECTIVE_SCANNED, PROC_REF(on_scan)) @@ -366,7 +368,9 @@ AddComponent(/datum/component/transforming, \ throwforce_on = 5, \ w_class_on = WEIGHT_CLASS_SMALL, \ - sharpness_on = TRUE) + sharpness_on = TRUE, \ + inhand_icon_change = FALSE, \ + ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(toggle_screwdriver)) AddElement(/datum/element/update_icon_updates_onmob) @@ -385,7 +389,8 @@ SIGNAL_HANDLER extended = active if(user) - balloon_alert(user, "[extended ? "extended" : "retracted"]!") + balloon_alert(user, "[extended ? "extended" : "retracted"]") + playsound(src, 'sound/weapons/batonextend.ogg', 50, TRUE) if(!extended) tool_behaviour = initial(tool_behaviour) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 56f278bdaa1..5400a48422c 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -102,7 +102,7 @@ DropFuel() return ..() -/obj/machinery/power/port_gen/pacman/on_construction() +/obj/machinery/power/port_gen/pacman/on_construction(mob/user) var/obj/item/circuitboard/machine/pacman/our_board = circuit if(our_board.high_production_profile) icon_state = "portgen1_0" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 5ffd0cb9562..b73ba371644 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,4 +1,3 @@ -/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR GUN.DM #define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4 #define FIRING_PIN_REMOVAL_DELAY 50 @@ -75,6 +74,8 @@ pin = new pin(src) add_seclight_point() + give_gun_safeties() // SKYRAT EDIT ADDITION - GUN SAFETIES + give_manufacturer_examine() // SKYRAT EDIT ADDITON - MANUFACTURER EXAMINE /obj/item/gun/Destroy() if(isobj(pin)) //Can still be the initial path, then we skip @@ -577,4 +578,3 @@ #undef FIRING_PIN_REMOVAL_DELAY #undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER -*/ diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index d006e3e4138..1e3870b063e 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -1,4 +1,3 @@ -/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR AUTOMATIC.DM /obj/item/gun/ballistic/automatic w_class = WEIGHT_CLASS_NORMAL can_suppress = TRUE @@ -398,4 +397,3 @@ actions_types = list() fire_sound = 'sound/weapons/laser.ogg' casing_ejector = FALSE -*/ diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index 7e58f2ddacd..36cefffc478 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -11,7 +11,6 @@ w_class = WEIGHT_CLASS_NORMAL pin = /obj/item/firing_pin/implant/pindicate bolt_type = BOLT_TYPE_NO_BOLT - has_gun_safety = FALSE //SKYRAT EDIT /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted pin = /obj/item/firing_pin @@ -40,7 +39,6 @@ mag_type = /obj/item/ammo_box/magazine/m75 burst_size = 1 fire_delay = 0 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) //SKYRAT EDIT CHANGE casing_ejector = FALSE /obj/item/gun/ballistic/rocketlauncher diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 661ad6dad4c..fed8df4d2c7 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -8,7 +8,6 @@ can_suppress = TRUE burst_size = 1 fire_delay = 0 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) //SKYRAT EDIT CHANGE bolt_type = BOLT_TYPE_LOCKING fire_sound = 'sound/weapons/gun/pistol/shot.ogg' dry_fire_sound = 'sound/weapons/gun/pistol/dry_fire.ogg' diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index b2640e8b4bf..da1aba9ffb0 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -159,9 +159,7 @@ initial_fire_sound = 'sound/weapons/gun/sniper/shot.ogg' alternative_fire_sound = 'sound/weapons/gun/shotgun/shot.ogg' can_modify_ammo = TRUE - can_misfire = TRUE - misfire_probability = 0 - misfire_percentage_increment = 5 //Slowly increases every shot + can_misfire = FALSE can_bayonet = TRUE knife_y_offset = 11 can_be_sawn_off = FALSE @@ -178,10 +176,7 @@ inhand_icon_state = "musket_prime" worn_icon_state = "musket_prime" mag_type = /obj/item/ammo_box/magazine/internal/boltaction/pipegun/prime - can_misfire = FALSE can_jam = FALSE - misfire_probability = 0 - misfire_percentage_increment = 0 projectile_damage_multiplier = 1 /// MAGICAL BOLT ACTIONS + ARCANE BARRAGE? /// diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index f6ba97d06ab..8728e924f81 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -142,7 +142,6 @@ fire_delay = 10 //Skyrat edit - Original: 0 pin = /obj/item/firing_pin/implant/pindicate fire_sound = 'sound/weapons/gun/shotgun/shot_alt.ogg' - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) //SKYRAT EDIT CHANGE mag_display = TRUE empty_indicator = TRUE empty_alarm = TRUE diff --git a/code/modules/projectiles/guns/energy/laser_gatling.dm b/code/modules/projectiles/guns/energy/laser_gatling.dm index 9a965f02692..f12a62d2c26 100644 --- a/code/modules/projectiles/guns/energy/laser_gatling.dm +++ b/code/modules/projectiles/guns/energy/laser_gatling.dm @@ -113,15 +113,13 @@ item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND can_charge = FALSE var/obj/item/minigunpack/ammo_pack - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC)//SKYRAT EDIT ADDITION - /obj/item/gun/energy/minigun/Initialize(mapload) if(!istype(loc, /obj/item/minigunpack)) //We should spawn inside an ammo pack so let's use that one. return INITIALIZE_HINT_QDEL //No pack, no gun ammo_pack = loc AddElement(/datum/element/update_icon_blocker) - //AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) SKYRAT EDIT REMOVAL + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) return ..() /obj/item/gun/energy/minigun/Destroy() diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 12212dd9b9b..630b02d40e9 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -381,7 +381,7 @@ /obj/item/gun/energy/tesla_cannon/Initialize(mapload) . = ..() - //AddComponent(/datum/component/automatic_fire, 0.1 SECONDS) SKYRAT EDIT REMOVAL + AddComponent(/datum/component/automatic_fire, 0.1 SECONDS) /obj/item/gun/energy/marksman_revolver name = "marksman revolver" diff --git a/code/modules/projectiles/guns/special/syringe_gun.dm b/code/modules/projectiles/guns/special/syringe_gun.dm index 1911d139f53..cf79da9dfca 100644 --- a/code/modules/projectiles/guns/special/syringe_gun.dm +++ b/code/modules/projectiles/guns/special/syringe_gun.dm @@ -194,7 +194,6 @@ pixel_x = 0 force = 4 trigger_guard = TRIGGER_GUARD_ALLOW_ALL - has_gun_safety = FALSE // SKYRAT EDIT /obj/item/gun/syringe/blowgun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) visible_message(span_danger("[user] starts aiming with a blowgun!")) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 10253811caf..1b9ff451c83 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -73,7 +73,7 @@ return mytray.mutation_roll(user) - + mytray.adjust_toxic(3) //It is still toxic, mind you, but not to the same degree. #define LIQUID_PLASMA_BP (50+T0C) @@ -363,7 +363,10 @@ . = ..() if(istype(exposed_obj, /obj/structure/alien/weeds)) var/obj/structure/alien/weeds/alien_weeds = exposed_obj - alien_weeds.take_damage(rand(15,35), BRUTE, 0) // Kills alien weeds pretty fast + alien_weeds.take_damage(rand(15, 35), BRUTE, 0) // Kills alien weeds pretty fast + if(istype(exposed_obj, /obj/structure/alien/resin/flower_bud)) + var/obj/structure/alien/resin/flower_bud/flower = exposed_obj + flower.take_damage(rand(30, 50), BRUTE, 0) else if(istype(exposed_obj, /obj/structure/glowshroom)) //even a small amount is enough to kill it qdel(exposed_obj) else if(istype(exposed_obj, /obj/structure/spacevine)) @@ -374,9 +377,13 @@ . = ..() var/damage = min(round(0.4 * reac_volume, 0.1), 10) if(exposed_mob.mob_biotypes & MOB_PLANT) - exposed_mob.adjustToxLoss(damage, required_biotype = affected_biotype) + // spray bottle emits 5u so it's dealing ~15 dmg per spray + exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype) + return + if(!(methods & VAPOR) || !iscarbon(exposed_mob)) return + var/mob/living/carbon/exposed_carbon = exposed_mob if(!exposed_carbon.wear_mask) exposed_carbon.adjustToxLoss(damage, required_biotype = affected_biotype) diff --git a/code/modules/shuttle/battlecruiser_starfury.dm b/code/modules/shuttle/battlecruiser_starfury.dm index e59bc2f774d..ce520aa1fca 100644 --- a/code/modules/shuttle/battlecruiser_starfury.dm +++ b/code/modules/shuttle/battlecruiser_starfury.dm @@ -165,7 +165,7 @@ spawner.antag_team = team if(candidates.len > 0) var/mob/our_candidate = candidates[1] - spawner.create(our_candidate) + spawner.create_from_ghost(our_candidate) spawner.antag_team.players_spawned += (our_candidate.ckey) candidates.Splice(1, 2) notify_ghosts( diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 230e3a0ea58..4797a831715 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -535,9 +535,8 @@ if(time_left <= 0) //move each escape pod to its corresponding escape dock - for(var/A in SSshuttle.mobile_docking_ports) - var/obj/docking_port/mobile/M = A - M.on_emergency_dock() + for(var/obj/docking_port/mobile/port as anything in SSshuttle.mobile_docking_ports) + port.on_emergency_dock() // now move the actual emergency shuttle to centcom // unless the shuttle is "hijacked" diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 5985efe8b06..bed4449c688 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -1162,7 +1162,8 @@ //Called when emergency shuttle docks at centcom /obj/docking_port/mobile/proc/on_emergency_dock() - //Mapping a new docking point for each ship mappers could potentially want docking with centcom would take up lots of space, just let them keep flying off into the sunset for their greentext + // Mapping a new docking point for each ship mappers could potentially want docking with centcom would take up lots of space, + // just let them keep flying off "into the sunset" for their greentext. if(launch_status == ENDGAME_LAUNCHED) launch_status = ENDGAME_TRANSIT diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 33c46982d27..49920f73aee 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -525,14 +525,14 @@ var/selected_reagent = tgui_input_list(usr, "Select reagent to filter", "Whitelist reagent", GLOB.chemical_name_list) if(!selected_reagent) return TRUE - + var/chem_id = get_chem_id(selected_reagent) if(!chem_id) return TRUE - + if(!(chem_id in whitelist)) whitelist[chem_id] = selected_reagent - + if("remove") diff --git a/code/modules/unit_tests/mecha_damage.dm b/code/modules/unit_tests/mecha_damage.dm index e3ca7566e90..55081e9365c 100644 --- a/code/modules/unit_tests/mecha_damage.dm +++ b/code/modules/unit_tests/mecha_damage.dm @@ -30,7 +30,7 @@ // Get a sample laser weapon. // The captain's laser gun here is chosen primarily because it deals more damage than normal lasers. var/obj/item/gun/energy/laser/dummy_laser = allocate(/obj/item/gun/energy/laser/captain) - dummy_laser.safety = FALSE // SKYRAT EDIT - Safeties on guns make them impossible to shoot :) + qdel(dummy_laser.GetComponent(/datum/component/gun_safety)) // SKYRAT EDIT - Safeties on guns make them impossible to shoot :) var/obj/item/ammo_casing/laser_ammo = dummy_laser.ammo_type[1] var/obj/projectile/beam/laser_fired = initial(laser_ammo.projectile_type) var/expected_laser_damage = round(dummy_laser.projectile_damage_multiplier * initial(laser_fired.damage) * (1 - expected_laser_armor / 100), DAMAGE_PRECISION) @@ -38,7 +38,7 @@ // Get a sample ballistic weapon. // The syndicate .357 here is chosen because it does a lot of damage. var/obj/item/gun/ballistic/dummy_gun = allocate(/obj/item/gun/ballistic/revolver) - dummy_gun.safety = FALSE // SKYRAT EDIT - Safeties on guns make them impossible to shoot :) + qdel(dummy_gun.GetComponent(/datum/component/gun_safety)) // SKYRAT EDIT - Safeties on guns make them impossible to shoot :) var/obj/item/ammo_casing/ballistic_ammo = dummy_gun.magazine.ammo_type var/obj/projectile/bullet_fired = initial(ballistic_ammo.projectile_type) var/expected_bullet_damage = round(dummy_gun.projectile_damage_multiplier * initial(bullet_fired.damage) * (1 - expected_bullet_armor / 100), DAMAGE_PRECISION) diff --git a/code/modules/unit_tests/projectiles.dm b/code/modules/unit_tests/projectiles.dm index e0c04f0ce9e..8f0872d0e89 100644 --- a/code/modules/unit_tests/projectiles.dm +++ b/code/modules/unit_tests/projectiles.dm @@ -18,8 +18,8 @@ gunner.put_in_hands(test_gun, forced=TRUE) //SKYRAT EDIT ADDITION BEGIN - if(test_gun.has_gun_safety) - test_gun.toggle_safety(gunner) + if(test_gun.GetComponent(/datum/component/gun_safety)) + qdel(test_gun.GetComponent(/datum/component/gun_safety)) loaded_bullet.wound_bonus = CANT_WOUND //Baseline wounding makes things weird //SKYRAT EDIT ADDITION END gunner.set_combat_mode(FALSE) // just to make sure we know we're not trying to pistol-whip them diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index cf9f7315eb9..f74b5877509 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1,5 +1,9 @@ +#define TRAITOR_DISCOUNT_BIG "big_discount" +#define TRAITOR_DISCOUNT_AVERAGE "average_discount" +#define TRAITOR_DISCOUNT_SMALL "small_discount" // TODO: Work into reworked uplinks. +/// Selects a set number of unique items from the uplink, and deducts a percentage discount from them /proc/create_uplink_sales(num, datum/uplink_category/category, limited_stock, list/sale_items) var/list/sales = list() var/list/sale_items_copy = sale_items.Copy() @@ -12,7 +16,7 @@ if(uplink_item.cost >= 20) //Tough love for nuke ops discount *= 0.5 uplink_item.category = category - uplink_item.cost = max(round(uplink_item.cost * discount),1) + uplink_item.cost = max(round(uplink_item.cost * (1 - discount)),1) uplink_item.name += " ([round(((initial(uplink_item.cost)-uplink_item.cost)/initial(uplink_item.cost))*100)]% off!)" uplink_item.desc += " Normally costs [initial(uplink_item.cost)] TC. All sales final. [pick(disclaimer)]" uplink_item.item = taken_item.item @@ -80,15 +84,31 @@ /// Weight of the category. Used to determine the positioning in the uplink. High weight = appears first var/weight = 0 +/// Returns by how much percentage do we reduce the price of the selected item /datum/uplink_item/proc/get_discount() - return pick(4;0.75,2;0.5,1;0.25) + var/static/list/discount_types = list( + TRAITOR_DISCOUNT_SMALL = 4, + TRAITOR_DISCOUNT_AVERAGE = 2, + TRAITOR_DISCOUNT_BIG = 1, + ) + + switch(pick_weight(discount_types)) + if(TRAITOR_DISCOUNT_BIG) + return 0.75 + if(TRAITOR_DISCOUNT_AVERAGE) + return 0.5 + else + return 0.25 + +/// Spawns an item and logs its purchase /datum/uplink_item/proc/purchase(mob/user, datum/uplink_handler/uplink_handler, atom/movable/source) var/atom/A = spawn_item(item, user, uplink_handler, source) log_uplink("[key_name(user)] purchased [src] for [cost] telecrystals from [source]'s uplink") if(purchase_log_vis && uplink_handler.purchase_log) uplink_handler.purchase_log.LogPurchase(A, src, cost) +/// Spawns an item in the world /datum/uplink_item/proc/spawn_item(spawn_path, mob/user, datum/uplink_handler/uplink_handler, atom/movable/source) if(!spawn_path) return @@ -136,3 +156,7 @@ /// Code that enables the ability to have limited stock that is shared by different items /datum/shared_uplink_stock + +#undef TRAITOR_DISCOUNT_BIG +#undef TRAITOR_DISCOUNT_AVERAGE +#undef TRAITOR_DISCOUNT_SMALL diff --git a/code/modules/vehicles/mecha/mecha_construction_paths.dm b/code/modules/vehicles/mecha/mecha_construction_paths.dm index d3d8702f601..7df97650d0e 100644 --- a/code/modules/vehicles/mecha/mecha_construction_paths.dm +++ b/code/modules/vehicles/mecha/mecha_construction_paths.dm @@ -384,7 +384,9 @@ outer_plating_amount=1 /datum/component/construction/mecha/gygax/action(datum/source, atom/used_atom, mob/user) - return INVOKE_ASYNC(src, PROC_REF(check_step), used_atom,user) + ASYNC //This proc will never actually sleep, it calls do_after with a time of 0. + . = check_step(used_atom, user) + return . //CLARKE /datum/component/construction/unordered/mecha_chassis/clarke diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 2c96f318f24..ec4f58b5bac 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -56,6 +56,7 @@ /obj/item/clothing/under/costume/draculass = 1, /obj/item/clothing/suit/costume/gothcoat = 1, /obj/item/clothing/glasses/eyepatch = 1, + /obj/item/clothing/under/costume/gi = 1, ), ), list( @@ -204,6 +205,7 @@ /obj/item/clothing/head/costume/lobsterhat = 1, /obj/item/clothing/under/costume/lobster = 1, /obj/item/gun/magic/wand/nothing = 2, + /obj/item/storage/box/tape_wizard = 1, ) premium = list( /obj/item/clothing/suit/costume/pirate/captain = 2, diff --git a/html/changelogs/AutoChangeLog-pr-19154.yml b/html/changelogs/AutoChangeLog-pr-19154.yml deleted file mode 100644 index 7f0518e33c0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19154.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - rscadd: "Midround changeling spawn event." - - rscadd: "Changeling meteor. It has a present for you." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19237.yml b/html/changelogs/AutoChangeLog-pr-19237.yml deleted file mode 100644 index 20e1b7a30bf..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19237.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Revolutionary Heretics and Cultists Traitors no longer lose all of their joy in life after being de-converted from their respective causes." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19407.yml b/html/changelogs/AutoChangeLog-pr-19407.yml deleted file mode 100644 index f5596b6ca30..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19407.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - refactor: "Refactors how nuclear activation disk works. Shouldn't notice a whole lot but if you do, it might be because of this." - - admin: "Disk now has an examine message for whether it's secure or not, to make it less ambiguous for players." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19414.yml b/html/changelogs/AutoChangeLog-pr-19414.yml deleted file mode 100644 index dd35cf98921..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19414.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - qol: "Engineering override access can now be manually controlled at the communications console and keycard auth devices" - - bugfix: "Fixed missing undefine in airlock module" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19489.yml b/html/changelogs/AutoChangeLog-pr-19489.yml new file mode 100644 index 00000000000..d6f5296aa5e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19489.yml @@ -0,0 +1,4 @@ +author: "Paxilmaniac" +delete-after: True +changes: + - balance: "CMGs in the armory come in a gunset which includes both a non-lethal and two lethal magazines right out the box, rather than making officers have to print lethal magazines to use the weapon in a lethal role." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19587.yml b/html/changelogs/AutoChangeLog-pr-19587.yml deleted file mode 100644 index 36a584c6f64..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19587.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ebin-Halcyon" -delete-after: True -changes: - - imageadd: "GAGS custom winter coats, berets, and ranger ponchos have been cleaned up with a nicer palette and prettier sprites." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19598.yml b/html/changelogs/AutoChangeLog-pr-19598.yml deleted file mode 100644 index c51cf487033..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19598.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Reagents metabolize properly when dead. (If they're supposed to.)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19615.yml b/html/changelogs/AutoChangeLog-pr-19615.yml deleted file mode 100644 index 7c5cb45800c..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19615.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Paxilmaniac" -delete-after: True -changes: - - balance: "Any helmet or mask that has 100 bio armor (Biological armor level X for the tag fans) will protect you against cortical borers entering your head." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19624.yml b/html/changelogs/AutoChangeLog-pr-19624.yml deleted file mode 100644 index 08bcc680960..00000000000 --- a/html/changelogs/AutoChangeLog-pr-19624.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "ShamanSliph" -delete-after: True -changes: - - bugfix: "Fixed loadout Laptops not properly spawning." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19701.yml b/html/changelogs/AutoChangeLog-pr-19701.yml new file mode 100644 index 00000000000..510d7cc00b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19701.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Corgis show their ID on examine." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19721.yml b/html/changelogs/AutoChangeLog-pr-19721.yml new file mode 100644 index 00000000000..609e82a7944 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19721.yml @@ -0,0 +1,7 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "Fixed a eswords, some tools, and some other misc. items from being invisible while extended / active" + - bugfix: "Teleshields and other misc items not extending in hand when active" + - bugfix: "Switchblades click on extend again" + - bugfix: "Pendrivers click on extend" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19722.yml b/html/changelogs/AutoChangeLog-pr-19722.yml new file mode 100644 index 00000000000..04b06c9e76b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19722.yml @@ -0,0 +1,4 @@ +author: "Rhials" +delete-after: True +changes: + - spellcheck: "Fixes the Russian/Bounty Hunter fugitive hunter spawn backstory messages." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19723.yml b/html/changelogs/AutoChangeLog-pr-19723.yml new file mode 100644 index 00000000000..ecf44734ea9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19723.yml @@ -0,0 +1,4 @@ +author: "Cyprex" +delete-after: True +changes: + - bugfix: "Ghost Cafe Spawners work once again!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19724.yml b/html/changelogs/AutoChangeLog-pr-19724.yml new file mode 100644 index 00000000000..77b16349825 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19724.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "Fixes pirates and starfury assailants keeping minds of past lives" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19725.yml b/html/changelogs/AutoChangeLog-pr-19725.yml new file mode 100644 index 00000000000..afdadb97d70 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19725.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "slime processor no longer sucks in slimes that it can't reach (glass panes, blocked by other machines etc)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-19726.yml b/html/changelogs/AutoChangeLog-pr-19726.yml new file mode 100644 index 00000000000..c3249f7f239 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-19726.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "The party alarm now works again!" \ No newline at end of file diff --git a/html/changelogs/archive/2023-03.yml b/html/changelogs/archive/2023-03.yml index 1ae8a772514..9b2343e59de 100644 --- a/html/changelogs/archive/2023-03.yml +++ b/html/changelogs/archive/2023-03.yml @@ -94,3 +94,164 @@ - bugfix: metastation toxins no longer has a weird double light fixture. - bugfix: Fix kilo barsign spawning under windows - bugfix: Fix barsign updatePath being backwards +2023-03-04: + Ebin-Halcyon: + - imageadd: GAGS custom winter coats, berets, and ranger ponchos have been cleaned + up with a nicer palette and prettier sprites. + LT3: + - qol: Engineering override access can now be manually controlled at the communications + console and keycard auth devices + - bugfix: Fixed missing undefine in airlock module + Melbert: + - bugfix: Revolutionary Heretics and Cultists Traitors no longer lose all of their + joy in life after being de-converted from their respective causes. + Paxilmaniac: + - balance: Any helmet or mask that has 100 bio armor (Biological armor level X for + the tag fans) will protect you against cortical borers entering your head. + Rhials: + - rscadd: Midround changeling spawn event. + - rscadd: Changeling meteor. It has a present for you. + ShamanSliph: + - bugfix: Fixed loadout Laptops not properly spawning. + SkyratBot: + - bugfix: Reagents metabolize properly when dead. (If they're supposed to.) + - refactor: Refactors how nuclear activation disk works. Shouldn't notice a whole + lot but if you do, it might be because of this. + - admin: Disk now has an examine message for whether it's secure or not, to make + it less ambiguous for players. + - rscadd: 'Add a pair of leather gloves to weed control crate balance: Mobs with + the PLANT biotypes (venus flytraps, pod people, killer tomatoes) are now much + weaker vs scythes, goats, and plantbgone. balance: Plantbgone is now more effective + at destroying weeds. balance: Regular scythes are now a sharp object' + - bugfix: Fixed scythes, goats, and plantbgone not affecting flower bud vines. + - bugfix: 'Thick and botanical gloves not protecting from thorns fix: Golems not + having pierce immunity from thorns fix: Runtime where vines tried to spread + into null turf fix: Runtime where null vines that were destroyed were trying + to spread to nearby turfs' + - soundadd: 'Add eat food sound when goats eat plants code: Improved goat targeting + code' + - code_imp: The bane element now accepts `mob_biotypes` bitflags as an argument. +2023-03-05: + Melbert: + - bugfix: Hijacked shuttles now count as "escaping alive" once agian + - bugfix: Hardcore random survival now actually checks that you've escaped alive, + and not just made it to centcom + - bugfix: Intelligent zombies can now escape. + - bugfix: Infectious zombies now don't count as escaped as intended. + Motho: + - bugfix: Research Rum is actually make-able now. + OrionTheFox: + - rscadd: '''ridiculous scientist outfit'' has been renamed to ''science team uniform'' + and its description improved' + - rscdel: Removed red security trousers (for those using either security/peacekeeper + trousers, check your loadout and make sure to select the blue trousers that + are still in!) + - bugfix: fixed engineering/peacekeeper trousers not covering legs, and fixed inconsistencies + in their names + - imageadd: updated the sprites for the 'science team uniform', 'tacticasual uniform', + 'shaft miner jumpsuit(s)', a few out-of-date cargo uniforms, and the hop formal + uniforms + Paxilmaniac: + - balance: overalls can now hold anything an engineering winter coat could in their + suit storage slots + - code_imp: We no longer completely override a few tg files, including the automatic + fire component, and the gun file. + - refactor: Gun safeties and manufacturer names have been refactored into their + own components. + - balance: Each of the equipment lockers in the assops base has a plain armor vest + in it, if for some reason an operative wants to not wear their suit + - balance: The thermal goggles that assops can buy are now the chameleon variety + - bugfix: The assops ship is no longer missing a defib and weapon rechargers like + I thought it did + SkyratBot: + - bugfix: fixed erroneous khinkali microwave recipe in the cooking menu. use a grill + like a normal chef + - bugfix: Changeling meteors on Icebox will now land close to the station instead + of a random map edge tile. + - rscadd: add new smite that adds deadchat control component to a victim + - bugfix: fixed AIs being able to recognize a spessman's identity over a holopad + call even if it was completely concealed, e.g. cloak of shadow, infiltrator + suit + - bugfix: The HoS' PDA painter can no longer paint PDAs into Lawyer ones. + - bugfix: You can no longer multiply banana peels, gatfruit and more by using sliceable + custom food + - rscadd: Adds the tape wizard costume, both a real and fake variant + - rscadd: 'Adds the costume behind the autodrobe contraband wire, and the real variant + in the wiz den + + :cl:' + - bugfix: frozen gas tanks now release their contents upon shattering + - bugfix: holodeck gas tanks can now be deconstructed + - balance: The pipegun's chance to misfire and shoot at you rather than the person + you're pointing it at has been removed + - bugfix: Papercode has been significantly improved and trivially filled paper forms + should no longer lag or crash players' game clients. + - imageadd: added prettier icons for the normal and absorbent galoshes + - rscadd: Introduces orderable rabbit crate to cargo livestock. + - bugfix: fixed missing inhand icon state for jaws of life + Vlada - VastKilleroOm: + - imageadd: added 1 hairstyle icon + tf-4: + - bugfix: Monkeys are no longer able to teleport out of the Interdyne xenobio slime + pens. +2023-03-06: + LT3: + - rscadd: Added new multi-vote system + - balance: Map votes are now calculated using multi-vote instead of the old single-vote + system + - admin: Admins can now use either multi-vote or single-vote for custom votes + - code_imp: Map choice filtering uses active player count, not all connected clients + Melbert: + - bugfix: Jobs get "You are the" and policy text again on spawn + SkyratBot: + - bugfix: Atmosians have finally convinced the thermomachines to not self-destruct + when built on blocked ports. + - bugfix: Failing to wrench down a thermomachine no longer hits it with the wrench. + - rscadd: Added a traitor final objective to infect the station AI with a virus, + that turns it malf and fully loyal to the traitor + - balance: the syndicate realized Chief Engineer is important enough to kidnap + - bugfix: kidnap objectives will now properly be unavailable for you for 15 minutes + after you take three, instead of after you take three assassinations. + - bugfix: Bartender's fountain pen was omitted during the swap over to tablets, + this has been amended. + - balance: Latejoin dynamic rulesets have been rebalanced to reduce the frequency + of midround revolution spawns. + Vishenka0704: + - admin: Added a ticket into mentrohelp convertation. Better than say "write it + to mentors". +2023-03-07: + Iamgoofball: + - bugfix: You can no longer fortnite with glass sheets + LT3: + - bugfix: Admins can jump to/follow patient zero of a disease outbreak again + SkyratBot: + - bugfix: You can no longer have multiple copies of the same heirloom theft objective + - qol: made ORM easier to use + - rscadd: Updated the bus ruin + - spellcheck: fixed humanoid examine easter egg's pronoun usage + - qol: Regal Rats produce meat on butchering, reducing player confusion. + - bugfix: fixed butchering bread dog spawning error bread. + - balance: Cult can no longer draw runes in survival pods. + Zergspower: + - rscadd: 'Added missing job titles to SR specific ghost roles: BMD, DS2, Freighter, + Port Tarkon and Ghost Cafe!' + - qol: SR Specific ghost roles will now be itemized and tracked inside your hour + window + coiax: + - refactor: Refactored how eggs growing into chicks is implemented, and how the + number of chickens and chicks are tracked. It's now possible for admins to make + anything into an egg. + dessysalta, Cheshify: + - rscadd: Nanotrasen has added a martial artist gi to the AutoDrobe for those who + want to go even further byond. + - imageadd: Aforementioned gi sprites. + tf-4: + - bugfix: There's no longer a vendor that will sometimes block one of the doors + to the interlink shuttle +2023-03-08: + Melbert: + - bugfix: Luminsecent slime actions correctly update their appearance when integrating + or ejecting slime cores + SkyratBot: + - bugfix: 20+ item's discounts are properly smaller, instead of being larger + - qol: Borgs are now acknowledged by the orm diff --git a/icons/area/areas_misc.dmi b/icons/area/areas_misc.dmi index 8e4b8a3803e..218db925741 100644 Binary files a/icons/area/areas_misc.dmi and b/icons/area/areas_misc.dmi differ diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi index 54c45a203e4..ce7f9e8961b 100644 Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ diff --git a/icons/mob/clothing/head/wizard.dmi b/icons/mob/clothing/head/wizard.dmi index a6961ca7626..785ed63ca5b 100644 Binary files a/icons/mob/clothing/head/wizard.dmi and b/icons/mob/clothing/head/wizard.dmi differ diff --git a/icons/mob/clothing/suits/wizard.dmi b/icons/mob/clothing/suits/wizard.dmi index e8ac43bb6ca..454bc1f3cf1 100644 Binary files a/icons/mob/clothing/suits/wizard.dmi and b/icons/mob/clothing/suits/wizard.dmi differ diff --git a/icons/mob/clothing/under/costume.dmi b/icons/mob/clothing/under/costume.dmi index 462fa64fdc4..625e1641972 100644 Binary files a/icons/mob/clothing/under/costume.dmi and b/icons/mob/clothing/under/costume.dmi differ diff --git a/icons/mob/inhands/clothing/hats_lefthand.dmi b/icons/mob/inhands/clothing/hats_lefthand.dmi index 540c586d905..e0f246140ae 100644 Binary files a/icons/mob/inhands/clothing/hats_lefthand.dmi and b/icons/mob/inhands/clothing/hats_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/hats_righthand.dmi b/icons/mob/inhands/clothing/hats_righthand.dmi index 343ecedcd07..a7d3c60f5f3 100644 Binary files a/icons/mob/inhands/clothing/hats_righthand.dmi and b/icons/mob/inhands/clothing/hats_righthand.dmi differ diff --git a/icons/mob/inhands/clothing/shoes_lefthand.dmi b/icons/mob/inhands/clothing/shoes_lefthand.dmi index 705e588bd04..2c4c678e733 100644 Binary files a/icons/mob/inhands/clothing/shoes_lefthand.dmi and b/icons/mob/inhands/clothing/shoes_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/shoes_righthand.dmi b/icons/mob/inhands/clothing/shoes_righthand.dmi index b4d074ef7bd..dce5521a172 100644 Binary files a/icons/mob/inhands/clothing/shoes_righthand.dmi and b/icons/mob/inhands/clothing/shoes_righthand.dmi differ diff --git a/icons/mob/inhands/clothing/suits_lefthand.dmi b/icons/mob/inhands/clothing/suits_lefthand.dmi index 181eb771ca6..b59ee57a4b3 100644 Binary files a/icons/mob/inhands/clothing/suits_lefthand.dmi and b/icons/mob/inhands/clothing/suits_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/suits_righthand.dmi b/icons/mob/inhands/clothing/suits_righthand.dmi index 7c8a01a3ab7..42265a7db98 100644 Binary files a/icons/mob/inhands/clothing/suits_righthand.dmi and b/icons/mob/inhands/clothing/suits_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_lefthand.dmi b/icons/mob/inhands/weapons/staves_lefthand.dmi index 8aec740579f..82c552b5038 100644 Binary files a/icons/mob/inhands/weapons/staves_lefthand.dmi and b/icons/mob/inhands/weapons/staves_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_righthand.dmi b/icons/mob/inhands/weapons/staves_righthand.dmi index 6cba11eef9c..769709f53da 100644 Binary files a/icons/mob/inhands/weapons/staves_righthand.dmi and b/icons/mob/inhands/weapons/staves_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index 8dfada39e21..b29d6dbcf1e 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index 4ca37418be2..862ebbdc8c3 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/species/human/human_face.dmi b/icons/mob/species/human/human_face.dmi index b1fe46b9908..fbac66a5c88 100644 Binary files a/icons/mob/species/human/human_face.dmi and b/icons/mob/species/human/human_face.dmi differ diff --git a/icons/obj/clothing/head/wizard.dmi b/icons/obj/clothing/head/wizard.dmi index 8fcdbd6fcd7..29595f02fc2 100644 Binary files a/icons/obj/clothing/head/wizard.dmi and b/icons/obj/clothing/head/wizard.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 006fc8eb66b..c197e9c68e1 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits/wizard.dmi b/icons/obj/clothing/suits/wizard.dmi index 9c2b4eee179..fcfa748d3b3 100644 Binary files a/icons/obj/clothing/suits/wizard.dmi and b/icons/obj/clothing/suits/wizard.dmi differ diff --git a/icons/obj/clothing/under/costume.dmi b/icons/obj/clothing/under/costume.dmi index 1c2ac134051..e9fb8117de7 100644 Binary files a/icons/obj/clothing/under/costume.dmi and b/icons/obj/clothing/under/costume.dmi differ diff --git a/icons/obj/weapons/guns/magic.dmi b/icons/obj/weapons/guns/magic.dmi index ef25b89f77a..3a97682ef66 100644 Binary files a/icons/obj/weapons/guns/magic.dmi and b/icons/obj/weapons/guns/magic.dmi differ diff --git a/modular_skyrat/master_files/code/datums/components/fullauto.dm b/modular_skyrat/master_files/code/datums/components/fullauto.dm deleted file mode 100644 index 4ecd620fac4..00000000000 --- a/modular_skyrat/master_files/code/datums/components/fullauto.dm +++ /dev/null @@ -1,320 +0,0 @@ -#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. - - ///windup autofire vars - ///Whether the delay between shots increases over time, simulating a spooling weapon - var/windup_autofire = FALSE - ///the reduction to shot delay for windup - var/current_windup_reduction = 0 - ///the percentage of autfire_shot_delay that is added to current_windup_reduction - var/windup_autofire_reduction_multiplier = 0.3 - ///How high of a reduction that current_windup_reduction can reach - var/windup_autofire_cap = 0.3 - ///How long it takes for weapons that have spooled-up to reset back to the original firing speed - var/windup_spindown = 3 SECONDS - ///Timer for tracking the spindown reset timings - var/timerid - COOLDOWN_DECLARE(next_shot_cd) - -/datum/component/automatic_fire/Initialize(autofire_shot_delay, windup_autofire, windup_autofire_reduction_multiplier, windup_autofire_cap, windup_spindown) - . = ..() - if(!isgun(parent)) - return COMPONENT_INCOMPATIBLE - var/obj/item/gun = parent - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(wake_up)) - RegisterSignal(parent, COMSIG_GUN_AUTOFIRE_SELECTED, PROC_REF(wake_up)) - RegisterSignals(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED), PROC_REF(autofire_off)) - RegisterSignal(parent, COMSIG_GUN_JAMMED, PROC_REF(stop_autofiring)) - if(autofire_shot_delay) - src.autofire_shot_delay = autofire_shot_delay - if(windup_autofire) - src.windup_autofire = windup_autofire - src.windup_autofire_reduction_multiplier = windup_autofire_reduction_multiplier - src.windup_autofire_cap = windup_autofire_cap - src.windup_spindown = windup_spindown - 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, COMSIG_GUN_JAMMED, \ - COMSIG_GUN_AUTOFIRE_SELECTED, COMSIG_ITEM_EQUIPPED)) - 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/parent_gun = parent - - if(iscarbon(user)) - var/mob/living/carbon/shooter = user - if(shooter.is_holding(parent) && parent_gun.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_REF(on_mouse_down)) - RegisterSignal(shooter, COMSIG_MOB_LOGOUT, PROC_REF(autofire_off)) - if(!QDELETED(shooter)) - UnregisterSignal(shooter, COMSIG_MOB_LOGIN) - parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, TYPE_PROC_REF(/obj/item/gun, autofire_bypass_check)) - parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, TYPE_PROC_REF(/obj/item/gun, 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_LOGIN, PROC_REF(on_client_login)) - if(!QDELETED(shooter)) - UnregisterSignal(shooter, COMSIG_MOB_LOGOUT) - shooter = null - parent.UnregisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN) - parent.UnregisterSignal(parent, COMSIG_AUTOFIRE_SHOT) - - -/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) - SIGNAL_HANDLER - 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.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) || istype(_target, /atom/movable/screen)) // 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 = parse_caught_click_modifiers(modifiers, get_turf(source.eye), source) - params = list2params(modifiers) - 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_REF(on_mouse_up)) - mouse_status = AUTOFIRE_MOUSEDOWN - - RegisterSignal(shooter, COMSIG_MOB_SWAP_HANDS, PROC_REF(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_REF(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 = parse_caught_click_modifiers(modifiers, get_turf(source.eye), source) - params = list2params(modifiers) - 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) - var/next_delay = autofire_shot_delay - if(windup_autofire) - next_delay = clamp(next_delay - current_windup_reduction, round(autofire_shot_delay * windup_autofire_cap), autofire_shot_delay) - current_windup_reduction = (current_windup_reduction + round(autofire_shot_delay * windup_autofire_reduction_multiplier)) - timerid = addtimer(CALLBACK(src, PROC_REF(windup_reset), FALSE), windup_spindown, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) - if(HAS_TRAIT(shooter, TRAIT_DOUBLE_TAP)) - next_delay = round(next_delay * 0.5) - COOLDOWN_START(src, next_shot_cd, next_delay) - if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) - return TRUE - stop_autofiring() - return FALSE - -/// Reset for our windup, resetting everything back to initial values after a variable set amount of time (determined by var/windup_spindown). -/datum/component/automatic_fire/proc/windup_reset(deltimer) - current_windup_reduction = initial(current_windup_reduction) - if(deltimer && timerid) - deltimer(timerid) - -// Gun procs. - -/obj/item/gun/proc/on_autofire_start(mob/living/shooter) - if(!can_shoot(shooter) || !can_trigger_gun(shooter) || shooter.incapacitated() || 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)) - balloon_alert(shooter, "need two hands!") - 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 - if(shooter.incapacitated()) - return FALSE - if(!can_shoot()) - shoot_with_empty_chamber(shooter) - return FALSE - INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params) - return COMPONENT_AUTOFIRE_SHOT_SUCCESS - -/obj/item/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params) - 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, TYPE_PROC_REF(/obj/item/gun, process_fire), target, shooter, TRUE, params, null, bonus_spread), 1) - process_fire(target, shooter, TRUE, params, null, bonus_spread) - - -#undef AUTOFIRE_MOUSEUP -#undef AUTOFIRE_MOUSEDOWN diff --git a/modular_skyrat/master_files/code/modules/admin/admin.dm b/modular_skyrat/master_files/code/modules/admin/admin.dm index 38a4dea6c4e..86f86bc7e12 100644 --- a/modular_skyrat/master_files/code/modules/admin/admin.dm +++ b/modular_skyrat/master_files/code/modules/admin/admin.dm @@ -19,6 +19,22 @@ GLOBAL_VAR_INIT(dchat_allowed, TRUE) GLOB.dchat_allowed = !GLOB.dchat_allowed to_chat(world, span_oocplain("The dead chat channel has been globally [GLOB.dchat_allowed ? "enabled" : "disabled"].")) +/datum/admin_help + /// Have we requested this ticket to stop being part of the Ticket Ping subsystem? + var/ticket_ping_stop = FALSE + /// Are we added to the ticket ping subsystem in the first place + var/ticket_ping = FALSE + /// Who is handling this admin help? + var/handler + /// All sanitized text + var/full_text + +/datum/admin_help/ClosureLinks(ref_src) + . = ..() + . += " (HANDLE)" //SKYRAT EDIT ADDITION + . += " (PING MUTE)" //SKYRAT EDIT ADDITION + . += " (MHELP)" + //Let the initiator know their ahelp is being handled /datum/admin_help/proc/handle_issue(key_name = key_name_admin(usr)) if(state != AHELP_ACTIVE) @@ -45,3 +61,24 @@ GLOBAL_VAR_INIT(dchat_allowed, TRUE) handler = "[usr.ckey]" return TRUE + +///Proc which converts an admin_help ticket to a mentorhelp +/datum/admin_help/proc/convert_to_mentorhelp(key_name = key_name_admin(usr)) + if(state != AHELP_ACTIVE) + return FALSE + + if(handler && handler != usr.ckey) + var/response = tgui_alert(usr, "This ticket is already being handled by [handler]. Do you want to continue?", "Ticket already assigned", list("Yes", "No")) + if(!response || response == "No") + return FALSE + + add_verb(initiator, /client/verb/mentorhelp) // Way to override mentorhelp cooldown. + + to_chat(initiator, span_adminhelp("Your ticket was converted to Mentorhelp")) + initiator.mentorhelp(full_text) + initiator.giveadminhelpverb() + + message_admins("[key_name] converted Ticket #[id] from [initiator_key_name] into Mentorhelp") + log_admin("[usr.client] converted Ticket #[id] from [initiator_ckey] into Mentorhelp") + + Close(key_name, TRUE) diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/engineering.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/engineering.dm index 01461e3ed7e..c799aca2997 100644 --- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/engineering.dm +++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/engineering.dm @@ -26,10 +26,10 @@ has_sensor = NO_SENSORS /obj/item/clothing/under/rank/engineering/engineer/skyrat/trouser - name = "engineer's trousers" + name = "engineering trousers" desc = "An engineering-orange set of trousers. Their waistband proudly displays an 'anti-radiation' symbol, though the effectiveness of radiation-proof-pants-only is still up for debate." icon_state = "workpants_orange" - body_parts_covered = GROIN + body_parts_covered = GROIN|LEGS can_adjust = FALSE female_sprite_flags = FEMALE_UNIFORM_NO_BREASTS diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/rnd.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/rnd.dm index 732e8ea3c2b..c57aa2739b3 100644 --- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/rnd.dm +++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/rnd.dm @@ -31,8 +31,8 @@ has_sensor = NO_SENSORS /obj/item/clothing/under/rank/rnd/scientist/skyrat/hlscience - name = "ridiculous scientist outfit" - desc = "The tie is mandatory." + name = "science team uniform" + desc = "A simple semi-formal uniform consisting of a grayish-blue shirt and off-white slacks, paired with a ridiculous, but mandatory, tie." icon_state = "hl_scientist" can_adjust = FALSE @@ -72,7 +72,7 @@ /* * OVERRIDES -* Remind Orion to look over these when TG finishes their science resprites +* ORION TODO: look over these when TG finishes their science resprites (any day now...) */ /obj/item/clothing/under/rank/rnd/scientist diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/security.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/security.dm index e15cff3103a..d27224b36a9 100644 --- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/security.dm +++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/security.dm @@ -26,10 +26,20 @@ icon_state = "util_sec_old" can_adjust = FALSE -/obj/item/clothing/under/rank/security/skyrat/utility/redsec/syndicate //MOVE ALL /SYNDICATES TO THE SYNDICATE.DM WHEN THE .dmi IS MADE (soon, after centcom.dmi) +/obj/item/clothing/under/rank/security/skyrat/utility/redsec/syndicate //ORION TODO: MOVE ALL /SYNDICATES TO SYNDICATE.DM armor_type = /datum/armor/redsec_syndicate has_sensor = NO_SENSORS +/obj/item/clothing/under/rank/security/peacekeeper/trousers //ORION TODO: repath off of Peacekeeper + name = "security trousers" + desc = "Some Peacekeeper-blue combat trousers. Probably should pair it with a vest for safety." + icon = 'modular_skyrat/master_files/icons/obj/clothing/under/security.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/under/security.dmi' + icon_state = "workpants_blue" + body_parts_covered = GROIN|LEGS + can_adjust = FALSE + female_sprite_flags = FEMALE_UNIFORM_NO_BREASTS + /* * HEAD OF SECURITY */ diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/blackmarket.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/blackmarket.dm new file mode 100644 index 00000000000..b49468b81d8 --- /dev/null +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/blackmarket.dm @@ -0,0 +1,3 @@ +/datum/job/blackmarket + title = ROLE_BLACK_MARKET_DEALER + policy_index = ROLE_BLACK_MARKET_DEALER diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/ds2.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/ds2.dm new file mode 100644 index 00000000000..e4bf753e7e6 --- /dev/null +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/ds2.dm @@ -0,0 +1,3 @@ +/datum/job/ds2 + title = ROLE_DS2 + policy_index = ROLE_DS2 diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/freighter_crew.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/freighter_crew.dm new file mode 100644 index 00000000000..ef5bcc0d11e --- /dev/null +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/freighter_crew.dm @@ -0,0 +1,3 @@ +/datum/job/freighter_crew + title = ROLE_FREIGHTER_CREW + policy_index = ROLE_FREIGHTER_CREW diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/ghostcafe.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/ghostcafe.dm new file mode 100644 index 00000000000..7b88a967aab --- /dev/null +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/ghostcafe.dm @@ -0,0 +1,3 @@ +/datum/job/ghostcafe + title = ROLE_GHOST_CAFE + policy_index = ROLE_GHOST_CAFE diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/tarkon.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/tarkon.dm new file mode 100644 index 00000000000..9beafecc8c7 --- /dev/null +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/tarkon.dm @@ -0,0 +1,3 @@ +/datum/job/tarkon + title = ROLE_PORT_TARKON + policy_index = ROLE_PORT_TARKON diff --git a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic.dm b/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic.dm deleted file mode 100644 index bc49ab26cf3..00000000000 --- a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic.dm +++ /dev/null @@ -1,6 +0,0 @@ -// A file for overrides to ballistic weapons that don't have a special Skyrat icon. -/obj/item/gun/ballistic/rifle/lionhunter - icon = 'icons/obj/weapons/guns/ballistic.dmi' - -/obj/item/gun/ballistic/rifle/boltaction/brand_new/prime - icon = 'icons/obj/weapons/guns/ballistic.dmi' diff --git a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/automatic.dm b/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/automatic.dm deleted file mode 100644 index 6864d0611b6..00000000000 --- a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/automatic.dm +++ /dev/null @@ -1,348 +0,0 @@ -/obj/item/gun/ballistic/automatic - w_class = WEIGHT_CLASS_NORMAL - can_suppress = TRUE - burst_size = 3 - fire_delay = 2 - semi_auto = TRUE - fire_sound = 'sound/weapons/gun/smg/shot.ogg' - fire_sound_volume = 90 - rack_sound = 'sound/weapons/gun/smg/smgrack.ogg' - suppressed_sound = 'sound/weapons/gun/smg/shot_suppressed.ogg' - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC) - -/obj/item/gun/ballistic/automatic/proto - name = "\improper Nanotrasen Saber SMG" - desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." - icon_state = "saber" - selector_switch_icon = TRUE - mag_display = TRUE - empty_indicator = TRUE - mag_type = /obj/item/ammo_box/magazine/smgm9mm - pin = null - bolt_type = BOLT_TYPE_LOCKING - show_bolt_icon = FALSE - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/automatic/proto/unrestricted - pin = /obj/item/firing_pin - -/obj/item/gun/ballistic/automatic/c20r - name = "\improper C-20r SMG" - desc = "A bullpup three-round burst .45 SMG, designated 'C-20r'." - icon_state = "c20r" - inhand_icon_state = "c20r" - selector_switch_icon = TRUE - mag_type = /obj/item/ammo_box/magazine/smgm45 - fire_delay = 2 - burst_size = 3 - pin = /obj/item/firing_pin/implant/pindicate - can_bayonet = TRUE - knife_x_offset = 26 - knife_y_offset = 12 - mag_display = TRUE - mag_display_ammo = TRUE - empty_indicator = TRUE - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/automatic/c20r/update_overlays() - . = ..() - if(!chambered && empty_indicator) - . += "[icon_state]_empty" - -/obj/item/gun/ballistic/automatic/c20r/unrestricted - pin = /obj/item/firing_pin - -/obj/item/gun/ballistic/automatic/c20r/Initialize(mapload) - . = ..() - update_appearance() - -/obj/item/gun/ballistic/automatic/wt550 - name = "security auto rifle" - desc = "An outdated personal defence weapon. Uses 4.6x30mm rounds and is designated the WT-550 Automatic Rifle." - icon_state = "wt550" - w_class = WEIGHT_CLASS_BULKY - inhand_icon_state = "arg" - mag_type = /obj/item/ammo_box/magazine/wt550m9 - fire_delay = 2 - can_suppress = FALSE - burst_size = 1 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) - can_bayonet = TRUE - knife_x_offset = 25 - knife_y_offset = 12 - mag_display = TRUE - mag_display_ammo = TRUE - empty_indicator = TRUE - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/automatic/plastikov - name = "\improper PP-95 SMG" - desc = "An ancient 9mm submachine gun pattern updated and simplified to lower costs, though perhaps simplified too much." - icon_state = "plastikov" - inhand_icon_state = "plastikov" - mag_type = /obj/item/ammo_box/magazine/plastikov9mm - burst_size = 5 - spread = 15 - can_suppress = FALSE - projectile_damage_multiplier = 0.35 // It's like 10.5 damage per bullet, it's close enough to 10 shots - mag_display = TRUE - empty_indicator = TRUE - fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' - company_flag = COMPANY_IZHEVSK - -/obj/item/gun/ballistic/automatic/mini_uzi - name = "\improper type U3 uzi" - desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." - icon_state = "miniuzi" - mag_type = /obj/item/ammo_box/magazine/uzim9mm - burst_size = 2 - bolt_type = BOLT_TYPE_OPEN - show_bolt_icon = FALSE - mag_display = TRUE - rack_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - company_flag = COMPANY_OLDARMS - -/obj/item/gun/ballistic/automatic/m90 - name = "\improper M-90gl carbine" - desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be fired using right click." - icon_state = "m90" - w_class = WEIGHT_CLASS_BULKY - inhand_icon_state = "m90" - selector_switch_icon = TRUE - mag_type = /obj/item/ammo_box/magazine/m556 - can_suppress = FALSE - var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel - burst_size = 3 - fire_delay = 2 - spread = 5 - pin = /obj/item/firing_pin/implant/pindicate - mag_display = TRUE - empty_indicator = TRUE - fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/automatic/m90/Initialize(mapload) - . = ..() - underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher(src) - update_appearance() - -/obj/item/gun/ballistic/automatic/m90/Destroy() - QDEL_NULL(underbarrel) - return ..() - -/obj/item/gun/ballistic/automatic/m90/unrestricted - pin = /obj/item/firing_pin - -/obj/item/gun/ballistic/automatic/m90/unrestricted/Initialize(mapload) - . = ..() - underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(src) - update_appearance() - -/obj/item/gun/ballistic/automatic/m90/afterattack_secondary(atom/target, mob/living/user, flag, params) - underbarrel.afterattack(target, user, flag, params) - return SECONDARY_ATTACK_CONTINUE_CHAIN - -/obj/item/gun/ballistic/automatic/m90/attackby(obj/item/attacking_item, mob/user, params) - if(istype(attacking_item, /obj/item/ammo_casing)) - if(istype(attacking_item, underbarrel.magazine.ammo_type)) - underbarrel.attack_self(user) - underbarrel.attackby(attacking_item, user, params) - else - ..() - -/obj/item/gun/ballistic/automatic/tommygun - name = "\improper Thompson SMG" - desc = "Based on the classic 'Chicago Typewriter'." - icon_state = "tommygun" - inhand_icon_state = "shotgun" - selector_switch_icon = TRUE - w_class = WEIGHT_CLASS_BULKY - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/tommygunm45 - can_suppress = FALSE - burst_size = 1 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) - fire_delay = 1 - bolt_type = BOLT_TYPE_OPEN - empty_indicator = TRUE - show_bolt_icon = FALSE - company_flag = COMPANY_OLDARMS - -/obj/item/gun/ballistic/automatic/tommygun/therealtommy - name = "Tommy gun" - desc = "The classic 'Chicago Typewriter'." - company_flag = null // This is the real deal, you hear? - -/obj/item/gun/ballistic/automatic/ar - name = "\improper NT-ARG 'Boarder'" - desc = "A robust assault rifle used by Nanotrasen fighting forces." - icon_state = "arg" - inhand_icon_state = "arg" - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/m556 - can_suppress = FALSE - burst_size = 3 - fire_delay = 1 - company_flag = COMPANY_NANOTRASEN - - -// L6 SAW // - -/obj/item/gun/ballistic/automatic/l6_saw - name = "\improper L6 SAW" - desc = "A large light machine gun chambered for the 7.12x82mm cartridge." - icon_state = "l6" - inhand_icon_state = "l6closedmag" - base_icon_state = "l6" - w_class = WEIGHT_CLASS_HUGE - slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/mm712x82 - weapon_weight = WEAPON_HEAVY - burst_size = 1 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) - can_suppress = FALSE - spread = 7 - pin = /obj/item/firing_pin/implant/pindicate - bolt_type = BOLT_TYPE_OPEN - show_bolt_icon = FALSE - mag_display = TRUE - mag_display_ammo = TRUE - tac_reloads = FALSE - fire_sound = 'sound/weapons/gun/l6/shot.ogg' - rack_sound = 'sound/weapons/gun/l6/l6_rack.ogg' - suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - var/cover_open = FALSE - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/automatic/l6_saw/unrestricted - pin = /obj/item/firing_pin - -/obj/item/gun/ballistic/automatic/l6_saw/Initialize(mapload) - . = ..() - AddElement(/datum/element/update_icon_updates_onmob) - -/obj/item/gun/ballistic/automatic/l6_saw/examine(mob/user) - . = ..() - . += "alt + click to [cover_open ? "close" : "open"] the dust cover." - if(cover_open && magazine) - . += span_notice("It seems like you could use an empty hand to remove the magazine.") - - -/obj/item/gun/ballistic/automatic/l6_saw/AltClick(mob/user) - if(!user.canUseTopic(src)) - return - cover_open = !cover_open - balloon_alert(user, "cover [cover_open ? "open" : "closed"]") - playsound(src, 'sound/weapons/gun/l6/l6_door.ogg', 60, TRUE) - update_appearance() - -/obj/item/gun/ballistic/automatic/l6_saw/update_icon_state() - . = ..() - inhand_icon_state = "[base_icon_state][cover_open ? "open" : "closed"][magazine ? "mag":"nomag"]" - -/obj/item/gun/ballistic/automatic/l6_saw/update_overlays() - . = ..() - . += "l6_door_[cover_open ? "open" : "closed"]" - - -/obj/item/gun/ballistic/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) - if(cover_open) - balloon_alert(user, "cover open!") - return - else - . = ..() - update_appearance() - -// ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/gun/ballistic/automatic/l6_saw/attack_hand(mob/user, list/modifiers) - if (loc != user) - ..() - return - if (!cover_open) - balloon_alert(user, "cover closed!") - return - ..() - -/obj/item/gun/ballistic/automatic/l6_saw/attackby(obj/item/attacking_item, mob/user, params) - if(!cover_open && istype(attacking_item, mag_type)) - balloon_alert(user, "dust closed!") - return - ..() - -// SNIPER // - -/obj/item/gun/ballistic/automatic/sniper_rifle - name = "sniper rifle" - desc = "A long ranged weapon that does significant damage. No, you can't quickscope." - icon_state = "sniper" - w_class = WEIGHT_CLASS_BULKY - inhand_icon_state = "sniper" - worn_icon_state = null - fire_sound = 'sound/weapons/gun/sniper/shot.ogg' - fire_sound_volume = 90 - vary_fire_sound = FALSE - load_sound = 'sound/weapons/gun/sniper/mag_insert.ogg' - rack_sound = 'sound/weapons/gun/sniper/rack.ogg' - suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - recoil = 2 - weapon_weight = WEAPON_HEAVY - mag_type = /obj/item/ammo_box/magazine/sniper_rounds - fire_delay = 40 - burst_size = 1 - w_class = WEIGHT_CLASS_NORMAL - slot_flags = ITEM_SLOT_BACK - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) - mag_display = TRUE - suppressor_x_offset = 3 - suppressor_y_offset = 3 - -/obj/item/gun/ballistic/automatic/sniper_rifle/Initialize(mapload) - . = ..() - AddComponent(/datum/component/scope, range_modifier = 2) - -/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate - name = "syndicate sniper rifle" - desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work." - can_suppress = TRUE - can_unsuppress = TRUE - pin = /obj/item/firing_pin/implant/pindicate - company_flag = COMPANY_SCARBOROUGH - -// Old Semi-Auto Rifle // - -/obj/item/gun/ballistic/automatic/surplus - name = "surplus rifle" - desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing." - icon_state = "surplus" - inhand_icon_state = "moistnugget" - worn_icon_state = null - weapon_weight = WEAPON_HEAVY - mag_type = /obj/item/ammo_box/magazine/m10mm/rifle - fire_delay = 30 - burst_size = 1 - can_unsuppress = TRUE - can_suppress = TRUE - w_class = WEIGHT_CLASS_HUGE - slot_flags = ITEM_SLOT_BACK - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) - mag_display = TRUE - company_flag = COMPANY_IZHEVSK - -// Laser rifle (rechargeable magazine) // - -/obj/item/gun/ballistic/automatic/laser - name = "laser rifle" - desc = "Though sometimes mocked for the relatively weak firepower of their energy weapons, the logistic miracle of rechargeable ammunition has given Nanotrasen a decisive edge over many a foe." - icon_state = "oldrifle" - w_class = WEIGHT_CLASS_BULKY - inhand_icon_state = "arg" - mag_type = /obj/item/ammo_box/magazine/recharge - empty_indicator = TRUE - fire_delay = 2 - can_suppress = FALSE - burst_size = 0 - // actions_types = list() SKYRAT EDIT REMOVAL - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) - fire_sound = 'sound/weapons/laser.ogg' - casing_ejector = FALSE - company_flag = COMPANY_NANOTRASEN diff --git a/modular_skyrat/master_files/code/modules/projectiles/guns/gun.dm b/modular_skyrat/master_files/code/modules/projectiles/guns/gun.dm deleted file mode 100644 index c7787f8c33f..00000000000 --- a/modular_skyrat/master_files/code/modules/projectiles/guns/gun.dm +++ /dev/null @@ -1,738 +0,0 @@ - -#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4 -#define FIRING_PIN_REMOVAL_DELAY 50 - -/obj/item/gun - name = "gun" - desc = "It's a gun. It's pretty terrible, though." - icon = 'icons/obj/weapons/guns/ballistic.dmi' - icon_state = "revolver" - inhand_icon_state = "gun" - worn_icon_state = "gun" - flags_1 = CONDUCT_1 - slot_flags = ITEM_SLOT_BELT - custom_materials = list(/datum/material/iron = 2000) - w_class = WEIGHT_CLASS_NORMAL - throwforce = 5 - throw_speed = 3 - throw_range = 5 - force = 5 - item_flags = NEEDS_PERMIT - attack_verb_continuous = list("strikes", "hits", "bashes") - attack_verb_simple = list("strike", "hit", "bash") - - var/gun_flags = NONE - var/fire_sound = 'sound/weapons/gun/pistol/shot.ogg' - var/vary_fire_sound = TRUE - var/fire_sound_volume = 50 - var/dry_fire_sound = 'sound/weapons/gun/general/dry_fire.ogg' - var/suppressed = null // whether or not a message is displayed when fired - var/can_suppress = FALSE - var/suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - var/suppressed_volume = 60 - var/can_unsuppress = TRUE - var/recoil = 0 // boom boom shake the room - var/clumsy_check = TRUE - var/obj/item/ammo_casing/chambered = null - 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/burst_size = 1 // how large a burst is - var/fire_delay = 0 // rate of fire for burst firing and semi auto - var/firing_burst = 0 // Prevent the weapon from firing again while already firing - var/semicd = 0 // cooldown handler - var/weapon_weight = WEAPON_LIGHT - var/dual_wield_spread = 24 // additional spread when dual wielding - ///Can we hold up our target with this? Default to yes - var/can_hold_up = TRUE - - /// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun. - var/projectile_damage_multiplier = 1 - - var/spread = 0 // Spread induced by the gun itself. - var/randomspread = 1 // Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once. - - lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - - var/obj/item/firing_pin/pin = /obj/item/firing_pin // standard firing pin for most guns - - var/pinless = FALSE - - var/can_bayonet = FALSE // if a bayonet can be added or removed if it already has one. - var/bayonet_state = "bayonet" - var/bayonet_icon = 'icons/obj/weapons/guns/bayonets.dmi' - var/obj/item/knife/bayonet - var/knife_x_offset = 0 - var/knife_y_offset = 0 - - var/ammo_x_offset = 0 // used for positioning ammo count overlay on sprite - var/ammo_y_offset = 0 - - // Zooming - var/pb_knockback = 0 - - var/safety = FALSE /// Internal variable for keeping track whether the safety is on or off - var/has_gun_safety = FALSE /// Whether the gun actually has a gun safety - var/datum/action/item_action/toggle_safety/toggle_safety_action - - 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 - /// Bitflags for the company that produces the gun, do not give more than one company. - var/company_flag - -/datum/action/item_action/toggle_safety - name = "Toggle Safety" - button_icon = 'modular_skyrat/modules/gunsafety/icons/actions.dmi' - button_icon_state = "safety_on" - -/obj/item/gun/ui_action_click(mob/user, actiontype) - if(istype(actiontype, /datum/action/item_action/toggle_firemode)) - fire_select() - else if(istype(actiontype, toggle_safety_action)) - toggle_safety(user) - else - ..() - -/obj/item/gun/Initialize(mapload) - . = ..() - if(pin && !pinless) - pin = new pin(src) - - add_seclight_point() - - if(has_gun_safety) - safety = TRUE - toggle_safety_action = new(src) - add_item_action(toggle_safety_action) - - 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 - - sort_list(fire_select_modes, GLOBAL_PROC_REF(cmp_numeric_asc)) - - if(fire_select_modes.len > 1) - firemode_action = new(src) - firemode_action.button_icon_state = "fireselect_[fire_select]" - firemode_action.build_all_button_icons() - add_item_action(firemode_action) - - if(SELECT_FULLY_AUTOMATIC in fire_select_modes) - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/Destroy() - if(isobj(pin)) // Can still be the initial path, then we skip - QDEL_NULL(pin) - if(bayonet) - QDEL_NULL(bayonet) - if(chambered) // Not all guns are chambered (EMP'ed energy guns etc) - QDEL_NULL(chambered) - if(isatom(suppressed)) - QDEL_NULL(suppressed) - if(toggle_safety_action) - QDEL_NULL(toggle_safety_action) - if(firemode_action) - QDEL_NULL(firemode_action) - . = ..() - -/// Handles adding [the seclite mount component][/datum/component/seclite_attachable] to the gun. -/// If the gun shouldn't have a seclight mount, override this with a return. -/// Or, if a child of a gun with a seclite mount has slightly different behavior or icons, extend this. -/obj/item/gun/proc/add_seclight_point() - return - -/obj/item/gun/handle_atom_del(atom/gun_atom) - if(gun_atom == pin) - pin = null - if(gun_atom == chambered) - chambered = null - update_appearance() - if(gun_atom == bayonet) - clear_bayonet() - if(gun_atom == suppressed) - clear_suppressor() - . = ..() - -/// Clears var and updates icon. In the case of ballistic weapons, also updates the gun's weight. -/obj/item/gun/proc/clear_suppressor() - if(!can_unsuppress) - return - suppressed = null - update_appearance() - -/obj/item/gun/examine(mob/user) - . = ..() - if(!pinless) - if(pin) - . += "It has \a [pin] installed." - . += span_info("[pin] looks like it could be removed with some tools.") - else - . += "It doesn't have a firing pin installed, and won't fire." - - if(bayonet) - . += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it." - if(can_bayonet) // if it has a bayonet and this is false, the bayonet is permanent. - . += span_info("[bayonet] looks like it can be unscrewed from [src].") - if(can_bayonet) - . += "It has a bayonet lug on it." - if(has_gun_safety) - . += "The safety is [safety ? "ON" : "OFF"]." - - switch(company_flag) - if(COMPANY_CANTALAN) - . += "
It has [span_purple("Cantalan Federal Arms")] etched into the grip." - if(COMPANY_ARMADYNE) - . += "
It has [span_red("Armadyne Corporation")] etched into the barrel." - if(COMPANY_SCARBOROUGH) - . += "
It has [span_orange("Scarborough Arms")] stamped onto the grip." - if(COMPANY_DONK) - . += "
It has a [span_green("Donk Corporation")] label visible in the plastic." - if(COMPANY_BOLT) - . += "
It has [span_yellow("Bolt Fabrications")] stamped onto the reciever." - if(COMPANY_OLDARMS) - . += "
It has [span_red("Armadyne Oldarms")] etched into the barrel." - if(COMPANY_IZHEVSK) - . += "
It has [span_brown("Izhevsk Coalition")] cut in above the magwell." - if(COMPANY_NANOTRASEN) - . += "
It has [span_blue("Nanotrasen Armories")] etched into the reciever." - if(COMPANY_ALLSTAR) - . += "
It has [span_red("Allstar Lasers Inc.")] stamped on the front grip." - if(COMPANY_MICRON) - . += "
It has [span_cyan("Micron Control Sys.")] cut in above the cell slot." - if(COMPANY_INTERDYNE) - . += "
It has [span_cyan("Interdyne Pharmaceuticals")] stamped onto the barrel." - if(COMPANY_ABDUCTOR) - . += "
It has [span_abductor("✌︎︎♌︎︎♎︎︎◆︎︎♍︎︎⧫︎︎❄︎♏︎♍︎♒︎")] engraved into the photon accelerator." - if(COMPANY_REMOVED) - . += "
It has had [span_grey("all identifying marks scrubbed off")]." - -/obj/item/gun/proc/fire_select() - var/mob/living/carbon/human/user = usr - - var/max_mode = fire_select_modes.len - - if(max_mode <= 1) - balloon_alert(user, "only one firemode!") - 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) - balloon_alert(user, "semi-automatic") - if(SELECT_BURST_SHOT) - burst_size = initial(burst_size) - fire_delay = initial(fire_delay) - SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user) - balloon_alert(user, "[burst_size]-round burst") - if(SELECT_FULLY_AUTOMATIC) - burst_size = 1 - SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_SELECTED, user) - balloon_alert(user, "automatic") - - playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) - update_appearance() - firemode_action.button_icon_state = "fireselect_[fire_select]" - firemode_action.build_all_button_icons() - SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) - return TRUE - -// called after the gun has successfully fired its chambered ammo. -/obj/item/gun/proc/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE) - handle_chamber(empty_chamber, from_firing, chamber_next_round) - SEND_SIGNAL(src, COMSIG_GUN_CHAMBER_PROCESSED) - -/obj/item/gun/proc/handle_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE) - return - - -// check if there's enough ammo/energy/whatever to shoot one time -// i.e if clicking would make it shoot -/obj/item/gun/proc/can_shoot() - return TRUE - -/obj/item/gun/proc/tk_firing(mob/living/user) - return !user.contains(src) - -/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) - balloon_alert_to_viewers("*click*") - playsound(src, dry_fire_sound, 30, TRUE) - -/obj/item/gun/proc/fire_sounds() - if(suppressed) - playsound(src, suppressed_sound, suppressed_volume, vary_fire_sound, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0) - else - playsound(src, fire_sound, fire_sound_volume, vary_fire_sound) - -/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = 0, atom/pbtarget = null, message = 1) - if(recoil && !tk_firing(user)) - shake_camera(user, recoil + 1, recoil) - fire_sounds() - if(!suppressed) - if(message) - if(tk_firing(user)) - visible_message( - span_danger("[src] fires itself[pointblank ? " point blank at [pbtarget]!" : "!"]"), - blind_message = span_hear("You hear a gunshot!"), - vision_distance = COMBAT_MESSAGE_RANGE - ) - else if(pointblank) - user.visible_message( - span_danger("[user] fires [src] point blank at [pbtarget]!"), - span_danger("You fire [src] point blank at [pbtarget]!"), - span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE, pbtarget - ) - to_chat(pbtarget, span_userdanger("[user] fires [src] point blank at you!")) - if(pb_knockback > 0 && ismob(pbtarget)) - var/mob/PBT = pbtarget - var/atom/throw_target = get_edge_target_turf(PBT, user.dir) - PBT.throw_at(throw_target, pb_knockback, 2) - else if(!tk_firing(user)) - user.visible_message( - span_danger("[user] fires [src]!"), - blind_message = span_hear("You hear a gunshot!"), - vision_distance = COMBAT_MESSAGE_RANGE, - ignored_mobs = user - ) - if(user.resting) // SKYRAT EDIT ADD - no crawlshooting - user.Immobilize(20, TRUE) // SKYRAT EDIT END - -/obj/item/gun/emp_act(severity) - . = ..() - if(!(. & EMP_PROTECT_CONTENTS)) - for(var/obj/iterated_object in contents) - iterated_object.emp_act(severity) - -/obj/item/gun/afterattack_secondary(mob/living/victim, mob/living/user, params) - if(!isliving(victim) || !IN_GIVEN_RANGE(user, victim, GUNPOINT_SHOOTER_STRAY_RANGE)) - return ..() //if they're out of range, just shootem. - if(!can_hold_up) - return ..() - var/datum/component/gunpoint/gunpoint_component = user.GetComponent(/datum/component/gunpoint) - if (gunpoint_component) - if(gunpoint_component.target == victim) - return ..() //we're already holding them up, shoot that mans instead of complaining - balloon_alert(user, "already holding someone up!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(user == victim) - balloon_alert(user, "can't hold yourself up!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - user.AddComponent(/datum/component/gunpoint, victim, src) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - -/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params) - . = ..() - return fire_gun(target, user, flag, params) - -/obj/item/gun/proc/fire_gun(atom/target, mob/living/user, flag, params) - if(QDELETED(target)) - return - if(firing_burst) - return - if(SEND_SIGNAL(src, COMSIG_GUN_TRY_FIRE, user, target, flag, params) & COMPONENT_CANCEL_GUN_FIRE) - return - if(flag) // It's adjacent, is the user, or is on the user's person - if(target in user.contents) // can't shoot stuff inside us. - return - if(!ismob(target) || user.combat_mode) // melee attack - return - if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) // so we can't shoot ourselves (unless mouth selected) - return - if(iscarbon(target)) - var/mob/living/carbon/carbon_target = target - for(var/i in carbon_target.all_wounds) - var/datum/wound/target_wound = i - if(target_wound.try_treating(src, user)) - return // another coward cured! - - if(istype(user))// Check if the user can use the gun, if the user isn't alive(turrets) assume it can. - var/mob/living/living_user = user - if(!can_trigger_gun(living_user)) - return - if(flag) - if(user.zone_selected == BODY_ZONE_PRECISE_MOUTH) - handle_suicide(user, target, params) - return - - if(!can_shoot()) // Just because you can pull the trigger doesn't mean it can shoot. - shoot_with_empty_chamber(user) - return - - if(check_botched(user)) - return - - var/obj/item/bodypart/other_hand = user.has_hand_for_held_index(user.get_inactive_hand_index()) // returns non-disabled inactive hands - if(weapon_weight == WEAPON_HEAVY && (user.get_inactive_held_item() || !other_hand)) - balloon_alert(user, "need two hands!") - return - // DUAL (or more!) WIELDING - var/bonus_spread = 0 - var/loop_counter = 0 - if(ishuman(user) && user.combat_mode) - var/mob/living/carbon/human/human_user = user - for(var/obj/item/gun/held_gun in human_user.held_items) - if(held_gun == src || held_gun.weapon_weight >= WEAPON_MEDIUM) - continue - else if(held_gun.can_trigger_gun(user)) - bonus_spread += dual_wield_spread - loop_counter++ - addtimer(CALLBACK(held_gun, TYPE_PROC_REF(/obj/item/gun, process_fire), target, user, TRUE, params, null, bonus_spread), loop_counter) - - return process_fire(target, user, TRUE, params, null, bonus_spread) - -/obj/item/gun/proc/check_botched(mob/living/user, params) - if(clumsy_check) - if(istype(user)) - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40)) - to_chat(user, span_userdanger("You shoot yourself in the foot with [src]!")) - var/shot_leg = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - process_fire(user, user, FALSE, params, shot_leg) - SEND_SIGNAL(user, COMSIG_MOB_CLUMSY_SHOOT_FOOT) - if(!tk_firing(user) && !HAS_TRAIT(src, TRAIT_NODROP)) - user.dropItemToGround(src, TRUE) - return TRUE - -/obj/item/gun/can_trigger_gun(mob/living/user) - . = ..() - if(!handle_pins(user)) - return FALSE - if(has_gun_safety && safety) - balloon_alert(user, "safety on!") - return FALSE - -/obj/item/gun/proc/toggle_safety(mob/user, override) - if(!has_gun_safety) - return - if(override) - if(override == "off") - safety = FALSE - else - safety = TRUE - else - safety = !safety - toggle_safety_action.button_icon_state = "safety_[safety ? "on" : "off"]" - toggle_safety_action.build_all_button_icons() - playsound(src, 'sound/weapons/empty.ogg', 100, TRUE) - user.visible_message( - span_notice("[user] toggles [src]'s safety [safety ? "ON" : "OFF"]."), - span_notice("You toggle [src]'s safety [safety ? "ON" : "OFF"].") - ) - SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) - -/obj/item/gun/proc/handle_pins(mob/living/user) - if(pinless) - return TRUE - if(pin) - if(pin.pin_auth(user) || (pin.obj_flags & EMAGGED)) - return TRUE - else - pin.auth_fail(user) - return FALSE - else - balloon_alert(user, "no firing pin!") - return FALSE - -/obj/item/gun/proc/recharge_newshot() - return - -/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0) - if(!user || !firing_burst) - firing_burst = FALSE - return FALSE - if(!issilicon(user)) - if(iteration > 1 && !(user.is_holding(src))) // for burst firing - firing_burst = FALSE - return FALSE - if(chambered?.loaded_projectile) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. - if(chambered.harmful) // Is the bullet chambered harmful? - balloon_alert(user, "lethally chambered!") - return - if(randomspread) - sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) - else // Smart spread - sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread)) - before_firing(target, user) - if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src)) - shoot_with_empty_chamber(user) - firing_burst = FALSE - return FALSE - else - if(get_dist(user, target) <= 1) // Making sure whether the target is in vicinity for the pointblank shot - shoot_live_shot(user, 1, target, message) - else - shoot_live_shot(user, 0, target, message) - if (iteration >= burst_size) - firing_burst = FALSE - else - shoot_with_empty_chamber(user) - firing_burst = FALSE - return FALSE - process_chamber() - update_appearance() - SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) - return TRUE - -/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) - if(user) - SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, user, target, params, zone_override) - - SEND_SIGNAL(src, COMSIG_GUN_FIRED, user, target, params, zone_override) - - add_fingerprint(user) - - if(semicd) - return - - // Vary by at least this much - var/base_bonus_spread = 0 - var/sprd = 0 - var/randomized_gun_spread = 0 - var/rand_spr = rand() - if(user && HAS_TRAIT(user, TRAIT_POOR_AIM)) // Nice job hotshot - bonus_spread += 35 - base_bonus_spread += 10 - - if(spread) - randomized_gun_spread = rand(0, spread) - var/randomized_bonus_spread = rand(base_bonus_spread, bonus_spread) - - if(burst_size > 1) - firing_burst = TRUE - for(var/i = 1 to burst_size) - addtimer(CALLBACK(src, PROC_REF(process_burst), user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1)) - else - if(chambered) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. - if(chambered.harmful) // Is the bullet chambered harmful? - balloon_alert(user, "lethally chambered!") - return - sprd = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) - before_firing(target, user) - if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src)) - shoot_with_empty_chamber(user) - return - else - if(get_dist(user, target) <= 1) // Making sure whether the target is in vicinity for the pointblank shot - shoot_live_shot(user, 1, target, message) - else - shoot_live_shot(user, 0, target, message) - else - shoot_with_empty_chamber(user) - return - process_chamber() - update_appearance() - semicd = TRUE - addtimer(CALLBACK(src, PROC_REF(reset_semicd)), fire_delay) - - if(user) - user.update_held_items() - SSblackbox.record_feedback("tally", "gun_fired", 1, type) - - SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) - - return TRUE - -/obj/item/gun/proc/reset_semicd() - semicd = FALSE - -/obj/item/gun/attack(mob/target, mob/living/user) - if(user.combat_mode) // Flogging - if(bayonet) - target.attackby(bayonet, user) - return - else - return ..() - return - -/obj/item/gun/attack_atom(obj/target, mob/living/user, params) - if(user.combat_mode) - if(bayonet) - target.attackby(bayonet, user) - return - return ..() - -/obj/item/gun/attackby(obj/item/attacking_item, mob/living/user, params) - if(user.combat_mode) - return ..() - else if(istype(attacking_item, /obj/item/knife)) - var/obj/item/knife/attaching_knife = attacking_item - if(!can_bayonet || !attaching_knife.bayonet || bayonet) // ensure the gun has an attachment point available, and that the knife is compatible with it. - return ..() - if(!user.transferItemToLoc(attacking_item, src)) - return - balloon_alert(user, "[attaching_knife] attached") - bayonet = attaching_knife - update_appearance() - - else - return ..() - -/obj/item/gun/screwdriver_act(mob/living/user, obj/item/tool) - . = ..() - if(.) - return - if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE)) - return - if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed - return remove_bayonet(user, tool) - - else if(pin && user.is_holding(src)) - if(!pin.can_remove) - balloon_alert(user, "pin can't be removed!") - return - user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [tool]."), - span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) - if(tool.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50)) - if(!pin) // check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay - return - user.visible_message(span_notice("[pin] is pried out of [src] by [user], destroying the pin in the process."), - span_warning("You pry [pin] out with [tool], destroying the pin in the process."), null, 3) - QDEL_NULL(pin) - return TRUE - -/obj/item/gun/welder_act(mob/living/user, obj/item/tool) - . = ..() - if(.) - return - if(!pin.can_remove) - balloon_alert(user, "pin can't be removed!") - return - if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE)) - return - if(pin && user.is_holding(src)) - user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [tool]."), - span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) - if(tool.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, 5, volume = 50)) - if(!pin) // check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay - return - user.visible_message(span_notice("[pin] is spliced out of [src] by [user], melting part of the pin in the process."), - span_warning("You splice [pin] out of [src] with [tool], melting part of the pin in the process."), null, 3) - QDEL_NULL(pin) - return TRUE - -/obj/item/gun/wirecutter_act(mob/living/user, obj/item/tool) - . = ..() - if(.) - return - if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE)) - return - if(!pin.can_remove) - balloon_alert(user, "pin can't be removed!") - return - if(pin && user.is_holding(src)) - user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [tool]."), - span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) - if(tool.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50)) - if(!pin) // check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay - return - user.visible_message(span_notice("[pin] is ripped out of [src] by [user], mangling the pin in the process."), - span_warning("You rip [pin] out of [src] with [tool], mangling the pin in the process."), null, 3) - QDEL_NULL(pin) - return TRUE - -/obj/item/gun/proc/remove_bayonet(mob/living/user, obj/item/tool_item) - tool_item?.play_tool_sound(src) - balloon_alert(user, "[bayonet] removed") - bayonet.forceMove(drop_location()) - - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(bayonet) - - return clear_bayonet() - -/obj/item/gun/proc/clear_bayonet() - if(!bayonet) - return - bayonet = null - update_appearance() - return TRUE - -/obj/item/gun/update_overlays() - . = ..() - - if(bayonet) - var/mutable_appearance/knife_overlay - var/state = bayonet_state - if(bayonet.icon_state in icon_states(bayonet_icon)) // Snowflake state? - state = bayonet.icon_state - knife_overlay = mutable_appearance(bayonet_icon, state) - knife_overlay.pixel_x = knife_x_offset - knife_overlay.pixel_y = knife_y_offset - . += knife_overlay - -/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) - if(!ishuman(user) || !ishuman(target)) - return - - if(semicd) - return - - if(user == target) - target.visible_message(span_warning("[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger..."), \ - span_userdanger("You stick [src] in your mouth, ready to pull the trigger...")) - else - target.visible_message(span_warning("[user] points [src] at [target]'s head, ready to pull the trigger..."), \ - span_userdanger("[user] points [src] at your head, ready to pull the trigger...")) - - semicd = TRUE - - if(!bypass_timer && (!do_after(user, 12 SECONDS, target) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH)) - if(user) - if(user == target) - user.visible_message(span_notice("[user] decided not to shoot.")) - else if(target?.Adjacent(user)) - target.visible_message(span_notice("[user] has decided to spare [target]"), span_notice("[user] has decided to spare your life!")) - semicd = FALSE - return - - semicd = FALSE - - target.visible_message(span_warning("[user] pulls the trigger!"), span_userdanger("[(user == target) ? "You pull" : "[user] pulls"] the trigger!")) - - if(chambered?.loaded_projectile) - chambered.loaded_projectile.damage *= 5 - if(chambered.loaded_projectile.wound_bonus != CANT_WOUND) - chambered.loaded_projectile.wound_bonus += 5 // much more dramatic on multiple pellet'd projectiles really - - var/fired = process_fire(target, user, TRUE, params, BODY_ZONE_HEAD) - if(!fired && chambered?.loaded_projectile) - chambered.loaded_projectile.damage /= 5 - if(chambered.loaded_projectile.wound_bonus != CANT_WOUND) - chambered.loaded_projectile.wound_bonus -= 5 - -/obj/item/gun/proc/unlock() // used in summon guns and as a convience for admins - if(pin) - qdel(pin) - pin = new /obj/item/firing_pin - -// Happens before the actual projectile creation -/obj/item/gun/proc/before_firing(atom/target, mob/user) - return - -/obj/item/gun/emag_act(mob/user, obj/item/card/emag/emag_card) - . = ..() - if(!pin.can_remove) - balloon_alert(user, "firing pin shorted!") - pin.can_remove = TRUE - if(!(pin.obj_flags & EMAGGED)) - pin.obj_flags |= EMAGGED - -#undef FIRING_PIN_REMOVAL_DELAY -#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi index 95627da5bde..64fbefeed4e 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi index fc868974ae7..2f5d8e83baa 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/civilian.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/civilian.dmi index cb43bac3b14..f266d65e9f3 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/civilian.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/civilian.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/civilian_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/civilian_digi.dmi index d620be66329..e0a759be5d7 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/civilian_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/civilian_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/misc.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/misc.dmi index 376bd97c17e..b6fbc604457 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/misc.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/misc.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/misc_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/misc_digi.dmi index b4903b31dda..76fac7acc3c 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/misc_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/misc_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/rnd.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/rnd.dmi index 30e24ed0772..35a612c221e 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/rnd.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/rnd.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/rnd_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/rnd_digi.dmi index 8178486a8e4..baed08c3844 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/rnd_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/rnd_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/security.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/security.dmi index 60682d67909..e41aa8186ef 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/security.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/security.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/security_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/security_digi.dmi index 818aef9321c..2f10b968ed3 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/security_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/security_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi index abc2f4e878c..bc6d0043e13 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/civilian.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/civilian.dmi index 2fbe0bc12f8..e206f2625c5 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/civilian.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/civilian.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/rnd.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/rnd.dmi index 709a551c792..92d1253589e 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/rnd.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/rnd.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/security.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/security.dmi index 10fb148e375..8b4b49c23fe 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/security.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/security.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/code/guns.dm b/modular_skyrat/modules/aesthetics/guns/code/guns.dm index 63e651ed1ff..60e2bf23903 100644 --- a/modular_skyrat/modules/aesthetics/guns/code/guns.dm +++ b/modular_skyrat/modules/aesthetics/guns/code/guns.dm @@ -71,7 +71,9 @@ inhand_icon_state = "riot_shotgun_syndie" can_be_sawn_off = FALSE can_suppress = FALSE - company_flag = COMPANY_SCARBOROUGH + +/obj/item/gun/ballistic/shotgun/riot/syndicate/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) /obj/item/gun/ballistic/shotgun/automatic/combat name = "\improper Peacekeeper combat shotgun" @@ -227,7 +229,9 @@ can_suppress = TRUE can_unsuppress = TRUE weapon_weight = WEAPON_LIGHT - company_flag = COMPANY_SCARBOROUGH + +/obj/item/gun/ballistic/automatic/sniper_rifle/modular/syndicate/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) /obj/item/gun/ballistic/automatic/sniper_rifle/modular/blackmarket //Normal sniper but epic name = "SA-107 anti-materiel rifle" @@ -248,7 +252,6 @@ fire_delay = 55 //Slightly smaller than standard sniper burst_size = 1 slot_flags = ITEM_SLOT_BACK - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) //SKYRAT EDIT CHANGE mag_display = TRUE /obj/item/gun/ballistic/automatic/ar/modular @@ -276,7 +279,9 @@

\ BRAND NEW: Cannot be sawn off." icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - company_flag = COMPANY_NANOTRASEN + +/obj/item/gun/ballistic/rifle/boltaction/brand_new/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) /obj/item/gun/ballistic/rifle/boltaction/brand_new/quartermaster name = "\improper FTU 'Archangel' precision rifle" @@ -289,7 +294,9 @@ worn_icon_state = "bubba" mag_type = /obj/item/ammo_box/magazine/internal/boltaction/bubba can_be_sawn_off = FALSE - company_flag = null //Cargonia's own + +/obj/item/gun/ballistic/rifle/boltaction/brand_new/quartermaster/give_manufacturer_examine() + return /obj/item/ammo_box/magazine/internal/boltaction/bubba name = "sportiv extended internal magazine" @@ -313,7 +320,9 @@ fire_delay = 5 fire_sound_volume = 90 mag_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75 - company_flag = COMPANY_NANOTRASEN + +/obj/item/gun/ballistic/automatic/ar/modular/model75/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) /obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75 name = "\improper ARG-75 magazine" diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi index 013281c9e26..5accb648846 100644 Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi differ diff --git a/modular_skyrat/modules/assault_operatives/code/armaments/armament_utility.dm b/modular_skyrat/modules/assault_operatives/code/armaments/armament_utility.dm index 42e63f1eeac..89d6b3cf27f 100644 --- a/modular_skyrat/modules/assault_operatives/code/armaments/armament_utility.dm +++ b/modular_skyrat/modules/assault_operatives/code/armaments/armament_utility.dm @@ -7,7 +7,7 @@ cost = 1 /datum/armament_entry/assault_operatives/utility/thermals - item_type = /obj/item/clothing/glasses/thermal + item_type = /obj/item/clothing/glasses/thermal/syndi cost = 4 /datum/armament_entry/assault_operatives/utility/chem_keycard diff --git a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm b/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm index 3cb5d2f8e90..1bda73090df 100644 --- a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm +++ b/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm @@ -3,11 +3,15 @@ /obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops name = "\improper IGE-040 pistol" desc = "A pistol chambered in 10mm magnum and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings." - company_flag = COMPANY_REMOVED + +/obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) /obj/item/gun/energy/e_gun/advtaser/assault_ops w_class = WEIGHT_CLASS_NORMAL - company_flag = COMPANY_REMOVED + +/obj/item/gun/energy/e_gun/advtaser/assault_ops/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) // Rifle @@ -33,17 +37,18 @@ can_suppress = TRUE suppressor_x_offset = 4 suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT) burst_size = 2 fire_delay = 3 pin = /obj/item/firing_pin/implant/pindicate - company_flag = COMPANY_REMOVED /obj/item/gun/ballistic/automatic/assault_ops_rifle/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = 1.5) +/obj/item/gun/ballistic/automatic/assault_ops_rifle/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) + /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle name = "\improper IGE-110 magazine" desc = "A twenty round magazine built for 5.6x40mm, intended for use in the IGE-110 rifle." @@ -85,12 +90,18 @@ mag_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg fire_sound = 'modular_skyrat/modules/sec_haul/sound/smg_fire.ogg' can_suppress = TRUE - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) burst_size = 1 fire_delay = 0.8 projectile_damage_multiplier = 0.6 pin = /obj/item/firing_pin/implant/pindicate - company_flag = COMPANY_REMOVED + +/obj/item/gun/ballistic/automatic/assault_ops_smg/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/assault_ops_smg/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg name = "\improper IGE-260 magazine" @@ -135,11 +146,12 @@ can_suppress = TRUE suppressor_x_offset = 4 suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) burst_size = 1 fire_delay = 1.5 pin = /obj/item/firing_pin/implant/pindicate - company_flag = COMPANY_REMOVED + +/obj/item/gun/ballistic/automatic/assault_ops_shotgun/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun name = "\improper IGE-340 magazine" @@ -203,13 +215,15 @@ can_be_sawn_off = FALSE can_jam = FALSE pin = /obj/item/firing_pin/implant/pindicate - company_flag = COMPANY_REMOVED /obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = 2.5) +/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) + /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper name = "\improper IGE-410 magazine" desc = "A five round magazine built for .416 Stabilis, intended for use in the IGE-410 sniper." diff --git a/modular_skyrat/modules/black_mesa/code/guns.dm b/modular_skyrat/modules/black_mesa/code/guns.dm index d4ee8099139..331d7a69539 100644 --- a/modular_skyrat/modules/black_mesa/code/guns.dm +++ b/modular_skyrat/modules/black_mesa/code/guns.dm @@ -42,11 +42,9 @@ righthand_file ='modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_righthand.dmi' icon_state = "mp5" inhand_icon_state = "mp5" - selector_switch_icon = TRUE mag_type = /obj/item/ammo_box/magazine/mp5 bolt_type = BOLT_TYPE_LOCKING can_suppress = TRUE - burst_size = 3 fire_delay = 1.25 spread = 2.5 mag_display = TRUE @@ -65,6 +63,11 @@ w_class = WEIGHT_CLASS_NORMAL projectile_damage_multiplier = 0.7 +/obj/item/gun/ballistic/automatic/mp5/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/ammo_box/magazine/mp5 name = "MP5 magazine (10mm Auto)" desc = "Magazines taking 10mm ammunition; it fits in the MP5." diff --git a/modular_skyrat/modules/black_mesa/code/m16_variations.dm b/modular_skyrat/modules/black_mesa/code/m16_variations.dm index e7c0ed91cbd..c6880490811 100644 --- a/modular_skyrat/modules/black_mesa/code/m16_variations.dm +++ b/modular_skyrat/modules/black_mesa/code/m16_variations.dm @@ -21,8 +21,11 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/sfrifle_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/sfrifle_magout.ogg' alt_icons = TRUE - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) +/obj/item/gun/ballistic/automatic/m16/oldarms/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/ammo_box/magazine/m16/vintage/oldarms name = "old-fashioned mk-11.4 rifle magazine" diff --git a/modular_skyrat/modules/blueshield/code/blueshield.dm b/modular_skyrat/modules/blueshield/code/blueshield.dm index d21be806882..d57592e5167 100644 --- a/modular_skyrat/modules/blueshield/code/blueshield.dm +++ b/modular_skyrat/modules/blueshield/code/blueshield.dm @@ -73,7 +73,7 @@ uniform = /obj/item/clothing/under/plasmaman/blueshield /obj/item/storage/box/gunset/blueshield - name = "CMG-1 gunset" + name = "Blueshield's CMG-1 gunset" w_class = WEIGHT_CLASS_NORMAL /obj/item/storage/box/gunset/blueshield/PopulateContents() @@ -106,4 +106,6 @@ icon_state = "hellfirepdw" worn_icon_state = "hellfirepdw" ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire/bs) - company_flag = COMPANY_ALLSTAR + +/obj/item/gun/energy/laser/hellgun/blueshield/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) diff --git a/modular_skyrat/modules/cellguns/code/cellguns.dm b/modular_skyrat/modules/cellguns/code/cellguns.dm index cc3a9425832..eaeaee29cc2 100644 --- a/modular_skyrat/modules/cellguns/code/cellguns.dm +++ b/modular_skyrat/modules/cellguns/code/cellguns.dm @@ -10,7 +10,9 @@ var/list/installedcells = list() automatic_charge_overlays = FALSE //This is needed because Cell based guns use their own custom overlay system. - has_gun_safety = TRUE + +/obj/item/gun/energy/cell_loaded/give_gun_safeties() + return /obj/item/gun/energy/cell_loaded/examine(mob/user) . = ..() diff --git a/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm b/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm index 63e860a2ab4..040eaa2c4df 100644 --- a/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm +++ b/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm @@ -10,7 +10,8 @@ return var/obj/structure/container = . for(var/obj/item/gun/gun_actually in container.contents) - if(gun_actually.company_flag & COMPANY_SCARBOROUGH) //illegal company doesn't care about pins + var/datum/component/manufacturer_examine/gun_company_examine_component = gun_actually.GetComponent(/datum/component/manufacturer_examine) + if((gun_company_examine_component) && (gun_company_examine_component.company_flag & COMPANY_SCARBOROUGH)) continue QDEL_NULL(gun_actually.pin) var/obj/item/firing_pin/permit_pin/new_pin = new(gun_actually) diff --git a/modular_skyrat/modules/company_imports/code/gun_companies.dm b/modular_skyrat/modules/company_imports/code/gun_companies.dm deleted file mode 100644 index db459f69641..00000000000 --- a/modular_skyrat/modules/company_imports/code/gun_companies.dm +++ /dev/null @@ -1,132 +0,0 @@ -/obj/item/gun/ballistic/automatic/pistol/m1911 - company_flag = COMPANY_BOLT - -/obj/item/gun/ballistic/automatic/pistol/aps - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/revolver - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/revolver/nagant - company_flag = COMPANY_OLDARMS - -/obj/item/gun/ballistic/rifle/boltaction - company_flag = COMPANY_IZHEVSK - -/obj/item/gun/ballistic/shotgun/riot - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/shotgun/bulldog - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/energy/e_gun - company_flag = COMPANY_ALLSTAR - -/obj/item/gun/energy/laser - company_flag = COMPANY_ALLSTAR - -/obj/item/gun/energy/pulse - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/shotgun/automatic/combat - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/syringe - company_flag = COMPANY_INTERDYNE - -/obj/item/gun/ballistic/automatic/pistol - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/revolver/c38/detective - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/shotgun/doublebarrel - company_flag = COMPANY_IZHEVSK - -/obj/item/gun/ballistic/shotgun/automatic/dual_tube - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/rifle/boltaction/brand_new - company_flag = COMPANY_IZHEVSK - -/obj/item/gun/ballistic/shotgun/toy - company_flag = COMPANY_DONK - -/obj/item/gun/ballistic/rifle/boltaction/brand_new/prime - company_flag = null - -/obj/item/gun/ballistic/rifle/boltaction/pipegun - company_flag = null - -/obj/item/gun/ballistic/automatic/c20r/toy - company_flag = COMPANY_DONK - -/obj/item/gun/ballistic/automatic/pistol/clandestine - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/ballistic/automatic/pistol/pdh/pulse - company_flag = null - -/obj/item/gun/ballistic/automatic/l6_saw/toy - company_flag = COMPANY_DONK - -/obj/item/gun/ballistic/automatic/cmg - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/ballistic/revolver/mateba - company_flag = null - -/obj/item/gun/ballistic/revolver/russian - company_flag = null - -/obj/item/gun/energy/laser/redtag - company_flag = null - -/obj/item/gun/energy/laser/bluetag - company_flag = null - -/obj/item/gun/energy/laser/instakill - company_flag = null - -/obj/item/gun/energy/laser/chameleon - company_flag = null - -/obj/item/gun/energy/laser/captain - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/energy/laser/retro - company_flag = COMPANY_REMOVED - -/obj/item/gun/energy/laser/retro/old - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/energy/e_gun/old - company_flag = COMPANY_NANOTRASEN - -/obj/item/gun/energy/e_gun/advtaser/cyborg - company_flag = null - -/obj/item/gun/energy/recharge/ebow - company_flag = COMPANY_SCARBOROUGH - -/obj/item/gun/energy/lasercannon - company_flag = COMPANY_ALLSTAR - -/obj/item/gun/energy/ionrifle - company_flag = COMPANY_ALLSTAR - -/obj/item/gun/energy/temperature - company_flag = COMPANY_ALLSTAR - -/obj/item/gun/syringe/blowgun - company_flag = null - -/obj/item/gun/syringe/syndicate/prototype - company_flag = null - -/obj/item/gun/energy/shrink_ray - company_flag = COMPANY_ABDUCTOR - -/obj/item/gun/energy/alien - company_flag = COMPANY_ABDUCTOR - diff --git a/modular_skyrat/modules/company_imports/code/objects/nri_surplus/ak25.dm b/modular_skyrat/modules/company_imports/code/objects/nri_surplus/ak25.dm index 66b6611b8fd..a5b6193de1e 100644 --- a/modular_skyrat/modules/company_imports/code/objects/nri_surplus/ak25.dm +++ b/modular_skyrat/modules/company_imports/code/objects/nri_surplus/ak25.dm @@ -21,10 +21,12 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magout.ogg' alt_icons = TRUE - company_flag = COMPANY_IZHEVSK spread = 29 recoil = 0.1 +/obj/item/gun/ballistic/automatic/ak25/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) + /obj/item/ammo_box/magazine/ak25 name = "\improper AK-25 magazine" desc = "A banana-shaped double-stack magazine able to hold 30 rounds of 7.32x29mm ammunition." diff --git a/modular_skyrat/modules/customization/modules/clothing/suits/misc.dm b/modular_skyrat/modules/customization/modules/clothing/suits/misc.dm index 795e47c52cc..0145ab280bc 100644 --- a/modular_skyrat/modules/customization/modules/clothing/suits/misc.dm +++ b/modular_skyrat/modules/customization/modules/clothing/suits/misc.dm @@ -331,6 +331,26 @@ greyscale_colors = "#594032" flags_1 = IS_PLAYER_COLORABLE_1 +/obj/item/clothing/suit/apron/overalls/greyscale/Initialize(mapload) + . = ..() + allowed += list( + /obj/item/flashlight, + /obj/item/lighter, + /obj/item/modular_computer/pda, + /obj/item/radio, + /obj/item/storage/bag/books, + /obj/item/storage/fancy/cigarettes, + /obj/item/tank/internals/emergency_oxygen, + /obj/item/tank/internals/plasmaman, + /obj/item/toy, + /obj/item/analyzer, + /obj/item/construction/rcd, + /obj/item/fireaxe/metal_h2_axe, + /obj/item/pipe_dispenser, + /obj/item/storage/bag/construction, + /obj/item/t_scanner, + ) + /obj/item/clothing/suit/apron/overalls/greyscale/examine(mob/user) . = ..() diff --git a/modular_skyrat/modules/customization/modules/clothing/under/misc.dm b/modular_skyrat/modules/customization/modules/clothing/under/misc.dm index eda31daf93d..2abfc924b2c 100644 --- a/modular_skyrat/modules/customization/modules/clothing/under/misc.dm +++ b/modular_skyrat/modules/customization/modules/clothing/under/misc.dm @@ -40,21 +40,3 @@ worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/uniform.dmi' icon_state = "doug_dimmadome" supports_variations_flags = NONE - -/obj/item/clothing/under/rank/security/peacekeeper/trousers - name = "peacekeeper's trousers" - desc = "Some light blue combat trousers, however you get protected by these, I have no idea." - icon = 'modular_skyrat/master_files/icons/obj/clothing/under/security.dmi' - worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/under/security.dmi' - icon_state = "workpants_blue" - body_parts_covered = GROIN - can_adjust = FALSE - supports_variations_flags = NONE - female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY - -/obj/item/clothing/under/rank/security/peacekeeper/trousers/red - name = "security officer's trousers" - desc = "Some red combat trousers, however you get protected by these, I have no idea." - icon = 'modular_skyrat/master_files/icons/obj/clothing/under/security.dmi' - worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/under/security.dmi' - icon_state = "workpants_red" diff --git a/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm b/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm index 003d645b66b..10ad32e59a6 100644 --- a/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -129,7 +129,7 @@ /datum/chemical_reaction/drink/research_rum results = list(/datum/reagent/consumable/ethanol/research_rum = 4) - required_reagents = list(/datum/reagent/consumable/ethanol/bananahonk = 2, /datum/reagent/impurity/mannitol = 1, /datum/reagent/consumable/ethanol/grog = 1) + required_reagents = list(/datum/reagent/consumable/ethanol/bananahonk = 2, /datum/reagent/inverse/neurine = 1, /datum/reagent/consumable/ethanol/grog = 1) mix_message = "You hear gurgling and dinging as it mixes." mix_sound = 'sound/machines/microwave/microwave-end.ogg' diff --git a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm index 53361385dc8..8b17bba1046 100644 --- a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm +++ b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm @@ -8,12 +8,14 @@ /obj/effect/mob_spawn/ghost_role/robot/ghostcafe name = "Cafe Robotic Storage" prompt_name = "a ghost cafe robot" - uses = -1 + infinite_use = TRUE + deletes_on_zero_uses_left = FALSE icon = 'modular_skyrat/modules/ghostcafe/icons/robot_storage.dmi' icon_state = "robostorage" mob_name = "a cafe robot" anchored = TRUE density = FALSE + spawner_job_path = /datum/job/ghostcafe you_are_text = "You are a Cafe Robot!" flavour_text = "Who could have thought? This awesome local cafe accepts cyborgs too!" mob_type = /mob/living/silicon/robot/model/roleplay @@ -38,11 +40,13 @@ /obj/effect/mob_spawn/ghost_role/human/ghostcafe name = "Cafe Sleeper" prompt_name = "a ghost cafe human" - uses = -1 + infinite_use = TRUE + deletes_on_zero_uses_left = FALSE icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_name = "a cafe visitor" density = FALSE + spawner_job_path = /datum/job/ghostcafe outfit = /datum/outfit/ghostcafe you_are_text = "You are a Cafe Visitor!" flavour_text = "You are off-duty and have decided to visit your favourite cafe. Enjoy yourself." diff --git a/modular_skyrat/modules/gun_safety/code/safety_additions.dm b/modular_skyrat/modules/gun_safety/code/safety_additions.dm new file mode 100644 index 00000000000..013fc022ec2 --- /dev/null +++ b/modular_skyrat/modules/gun_safety/code/safety_additions.dm @@ -0,0 +1,48 @@ +/// Proc that is overridden in /gun/ballistic and /gun/energy to attach the gun safety component to a gun +/obj/item/gun/proc/give_gun_safeties() + return + +// Ballistic Weapons + +/obj/item/gun/ballistic/give_gun_safeties() + AddComponent(/datum/component/gun_safety) + +/obj/item/gun/ballistic/bow/give_gun_safeties() + return + +/obj/item/gun/ballistic/rifle/enchanted/give_gun_safeties() + return + +/obj/item/gun/ballistic/automatic/laser/ctf/give_gun_safeties() + return + +/obj/item/gun/ballistic/shotgun/ctf/give_gun_safeties() + return + +/obj/item/gun/ballistic/automatic/laser/ctf/marksman/give_gun_safeties() + return + +/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/give_gun_safeties() + return + +/obj/item/gun/ballistic/automatic/pistol/g17/mesa/give_gun_safeties() + return + +/obj/item/gun/ballistic/revolver/grenadelauncher/give_gun_safeties() + return + +// Energy Weapons + +/obj/item/gun/energy/give_gun_safeties() + AddComponent(/datum/component/gun_safety) + +/obj/item/gun/energy/plasmacutter/give_gun_safeties() + return + +/obj/item/gun/energy/kinetic_accelerator/give_gun_safeties() + return + +// Syringe Guns + +/obj/item/gun/syringe/blowgun/give_gun_safeties() + return diff --git a/modular_skyrat/modules/gun_safety/code/safety_component.dm b/modular_skyrat/modules/gun_safety/code/safety_component.dm new file mode 100644 index 00000000000..3338b5347ae --- /dev/null +++ b/modular_skyrat/modules/gun_safety/code/safety_component.dm @@ -0,0 +1,86 @@ +/// Component that will prevent a gun from firing if the safety is turned on +/datum/component/gun_safety + /// Is the safety actually on? + var/safety_currently_on = TRUE + /// Holder for the toggle safety action + var/datum/action/item_action/gun_safety_toggle/toggle_safety_action + +/datum/component/gun_safety/Initialize(safety_currently_on = TRUE) + . = ..() + + // Obviously gun safety should only apply to guns + if(!isgun(parent)) + return COMPONENT_INCOMPATIBLE + + src.safety_currently_on = safety_currently_on + + var/obj/item/item_parent = parent + toggle_safety_action = item_parent.add_item_action(/datum/action/item_action/gun_safety_toggle) + + update_action_button_state() + +/datum/component/gun_safety/Destroy() + if(toggle_safety_action) + QDEL_NULL(toggle_safety_action) + return ..() + +/datum/component/gun_safety/RegisterWithParent() + RegisterSignal(parent, COMSIG_GUN_TRY_FIRE, PROC_REF(check_if_we_can_actually_shooty)) + RegisterSignal(parent, COMSIG_ITEM_UI_ACTION_CLICK, PROC_REF(we_may_be_toggling_safeties)) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) + +/datum/component/gun_safety/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_GUN_TRY_FIRE, + COMSIG_ITEM_UI_ACTION_CLICK, + COMSIG_PARENT_EXAMINE, + )) + +/// Checks if the safety is currently on, if it is then stops the gun from firing +/datum/component/gun_safety/proc/check_if_we_can_actually_shooty(obj/item/gun/source, mob/living/user, atom/target, flag, params) + SIGNAL_HANDLER + + if(safety_currently_on) + user.balloon_alert(user, "safety on!") + return COMPONENT_CANCEL_GUN_FIRE + +/// Calls toggle_safeties if the action type for doing so is used +/datum/component/gun_safety/proc/we_may_be_toggling_safeties(source, user, datum/actiontype) + SIGNAL_HANDLER + + if(istype(actiontype, toggle_safety_action)) + toggle_safeties(user) + + return COMPONENT_ACTION_HANDLED + +/// Toggles the safeties on or off +/datum/component/gun_safety/proc/toggle_safeties(mob/user) + safety_currently_on = !safety_currently_on + + update_action_button_state() + + playsound(parent, 'sound/weapons/empty.ogg', 100, TRUE) + user.visible_message( + span_notice("[user] toggles [parent]'s safety [safety_currently_on ? "ON" : "OFF"]."), + span_notice("You toggle [parent]'s safety [safety_currently_on ? "ON" : "OFF"].") + ) + +/// Adds the gun safety's current status to the gun's examine +/datum/component/gun_safety/proc/on_examine(obj/item/source, mob/examiner, list/examine_list) + SIGNAL_HANDLER + + examine_list += "The safety is [safety_currently_on ? "ON" : "OFF"]." + +/// Small proc to update the actio button's icon, just so I can not have to copypaste the same thing several times. +/datum/component/gun_safety/proc/update_action_button_state() + if(!toggle_safety_action) + return + + toggle_safety_action.button_icon_state = "safety_[safety_currently_on ? "on" : "off"]" + toggle_safety_action.build_all_button_icons() + +// The actual action, used by the component +/datum/action/item_action/gun_safety_toggle + name = "Toggle Gun Safety" + button_icon = 'modular_skyrat/modules/gun_safety/icons/actions.dmi' + button_icon_state = "safety_on" diff --git a/modular_skyrat/modules/gunsafety/icons/actions.dmi b/modular_skyrat/modules/gun_safety/icons/actions.dmi similarity index 100% rename from modular_skyrat/modules/gunsafety/icons/actions.dmi rename to modular_skyrat/modules/gun_safety/icons/actions.dmi diff --git a/modular_skyrat/modules/gunsafety/readme.md b/modular_skyrat/modules/gun_safety/readme.md similarity index 87% rename from modular_skyrat/modules/gunsafety/readme.md rename to modular_skyrat/modules/gun_safety/readme.md index d929b682bac..dc0634151ea 100644 --- a/modular_skyrat/modules/gunsafety/readme.md +++ b/modular_skyrat/modules/gun_safety/readme.md @@ -24,3 +24,4 @@ Adds a huge QOL feature, GUN SAFTIES. ### Credits: Gandalf2k15 - OG code +Paxilmaniac - Turned it into a component diff --git a/modular_skyrat/modules/gunhud/code/gun_hud_component.dm b/modular_skyrat/modules/gunhud/code/gun_hud_component.dm index dda48fe37a1..f32981b01e4 100644 --- a/modular_skyrat/modules/gunhud/code/gun_hud_component.dm +++ b/modular_skyrat/modules/gunhud/code/gun_hud_component.dm @@ -62,17 +62,6 @@ var/oth_t var/oth_h - switch(pew.fire_select) - if(SELECT_SEMI_AUTOMATIC) - indicator = "semi" - if(SELECT_BURST_SHOT) - indicator = "burst" - if(SELECT_FULLY_AUTOMATIC) - indicator = "auto" - - if(pew.safety) - indicator = "safe" - switch(length(rounds)) if(1) oth_o = "o[rounds[1]]" diff --git a/modular_skyrat/modules/gunsafety/code/gun_safety.dm b/modular_skyrat/modules/gunsafety/code/gun_safety.dm deleted file mode 100644 index d4012fc32b7..00000000000 --- a/modular_skyrat/modules/gunsafety/code/gun_safety.dm +++ /dev/null @@ -1,32 +0,0 @@ -/obj/item/gun/ballistic - has_gun_safety = TRUE - -/obj/item/gun/ballistic/bow - has_gun_safety = FALSE - -/obj/item/gun/energy - has_gun_safety = TRUE - -/obj/item/gun/energy/plasmacutter - has_gun_safety = FALSE - -/obj/item/gun/energy/kinetic_accelerator - has_gun_safety = FALSE - -/obj/item/gun/ballistic/rifle/enchanted - has_gun_safety = FALSE - -/obj/item/gun/ballistic/automatic/laser/ctf - has_gun_safety = FALSE - -/obj/item/gun/ballistic/shotgun/ctf - has_gun_safety = FALSE - -/obj/item/gun/ballistic/automatic/laser/ctf/marksman - has_gun_safety = FALSE - -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf - has_gun_safety = FALSE - -/obj/item/gun/ballistic/automatic/pistol/g17/mesa - has_gun_safety = FALSE diff --git a/modular_skyrat/modules/gunsgalore/code/guns/akm.dm b/modular_skyrat/modules/gunsgalore/code/guns/akm.dm index d0d111a9eb1..3c73de359d7 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/akm.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/akm.dm @@ -21,7 +21,14 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magout.ogg' alt_icons = TRUE - company_flag = COMPANY_IZHEVSK + +/obj/item/gun/ballistic/automatic/akm/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/akm/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) /obj/item/ammo_box/magazine/akm name = "\improper Krinkov magazine" @@ -88,7 +95,6 @@ desc = "A timeless human design of a carbine chambered in the NRI's 5.6mm ammo. The internal modifications made to the firearm in order to accommodate for non-military use made it incompatible with conventional munitions and gave it the inability to fire fully automatic. It's purpose-built to fire low-grade civilian ammo, anything stronger would obliterate the rifling and render the firearm useless." icon_state = "akm_civ" inhand_icon_state = "akm_civ" - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) mag_type = /obj/item/ammo_box/magazine/akm/civvie burst_size = 1 fire_delay = 5 diff --git a/modular_skyrat/modules/gunsgalore/code/guns/fg42.dm b/modular_skyrat/modules/gunsgalore/code/guns/fg42.dm index 67e9566fc04..c5066404f96 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/fg42.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/fg42.dm @@ -23,12 +23,17 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/batrifle_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/batrifle_magout.ogg' eject_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/batrifle_magout.ogg' - company_flag = COMPANY_OLDARMS /obj/item/gun/ballistic/automatic/fg42/Initialize(mapload) . = ..() + AddComponent(/datum/component/scope, range_modifier = 1) + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/fg42/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) + /obj/item/ammo_box/magazine/fg42 name = "fg42 magazine (7.92x57mm)" icon = 'modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_items.dmi' diff --git a/modular_skyrat/modules/gunsgalore/code/guns/luger.dm b/modular_skyrat/modules/gunsgalore/code/guns/luger.dm index 8f50e0191cd..cb0deda1c27 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/luger.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/luger.dm @@ -14,4 +14,6 @@ rack_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/fire/luger_rack.ogg' fire_sound_volume = 100 suppressor_x_offset = 14 - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/automatic/pistol/luger/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) diff --git a/modular_skyrat/modules/gunsgalore/code/guns/m16.dm b/modular_skyrat/modules/gunsgalore/code/guns/m16.dm index 431056f1916..75e4a5fa144 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/m16.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/m16.dm @@ -53,6 +53,11 @@ burst_size = 3 fire_delay = 1.90 +/obj/item/gun/ballistic/automatic/m16/modern/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/gun/ballistic/automatic/m16/modern/v2 name = "\improper XM-2537 'Amans Patriae' rifle" desc = "An expertly modified, super-compact XM-2537 rifle designed for operating in tight corridors and fields full of Bethlehem flowers. You're a soldier, finish your mission!" diff --git a/modular_skyrat/modules/gunsgalore/code/guns/mg34.dm b/modular_skyrat/modules/gunsgalore/code/guns/mg34.dm index 02641b6fae0..152c98d1933 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/mg34.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/mg34.dm @@ -13,7 +13,6 @@ rack_sound = 'sound/weapons/gun/l6/l6_rack.ogg' suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' fire_sound_volume = 70 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) weapon_weight = WEAPON_HEAVY slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE @@ -24,13 +23,18 @@ bolt_type = BOLT_TYPE_OPEN show_bolt_icon = FALSE tac_reloads = FALSE - company_flag = COMPANY_OLDARMS var/cover_open = FALSE /obj/item/gun/ballistic/automatic/mg34/Initialize(mapload) . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + AddElement(/datum/element/update_icon_updates_onmob) +/obj/item/gun/ballistic/automatic/mg34/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) + /obj/item/gun/ballistic/automatic/mg34/examine(mob/user) . = ..() . += "RMB with an empty hand to [cover_open ? "close" : "open"] the dust cover." diff --git a/modular_skyrat/modules/gunsgalore/code/guns/mp40.dm b/modular_skyrat/modules/gunsgalore/code/guns/mp40.dm index 21904008a9f..46ab724c3b8 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/mp40.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/mp40.dm @@ -20,8 +20,14 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magout.ogg' alt_icons = TRUE - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/automatic/mp40/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/mp40/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) /obj/item/ammo_box/magazine/mp40 name = "mp40 magazine (9mmx19)" diff --git a/modular_skyrat/modules/gunsgalore/code/guns/p90.dm b/modular_skyrat/modules/gunsgalore/code/guns/p90.dm index 405aacc8cbc..5d8b81ae2dd 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/p90.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/p90.dm @@ -11,7 +11,6 @@ slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/p90 can_suppress = FALSE - burst_size = 5 fire_delay = 1 fire_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/fire/p90_fire.ogg' fire_sound_volume = 100 @@ -21,6 +20,11 @@ eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/p90_magout.ogg' alt_icons = TRUE +/obj/item/gun/ballistic/automatic/p90/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/ammo_box/magazine/p90 name = "\improper P90-02 magazine" icon = 'modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_items.dmi' diff --git a/modular_skyrat/modules/gunsgalore/code/guns/pps.dm b/modular_skyrat/modules/gunsgalore/code/guns/pps.dm index d3d383a34c5..6e2646ebaa2 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/pps.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/pps.dm @@ -9,7 +9,6 @@ slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/pps can_suppress = FALSE - burst_size = 3 fire_delay = 3 worn_icon = 'modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_back.dmi' worn_icon_state = "pps" @@ -20,7 +19,14 @@ load_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magin.ogg' load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magout.ogg' - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/automatic/pps/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/pps/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) /obj/item/ammo_box/magazine/pps name = "pps magazine (7.62x25mm)" diff --git a/modular_skyrat/modules/gunsgalore/code/guns/ppsh.dm b/modular_skyrat/modules/gunsgalore/code/guns/ppsh.dm index 6cf7b6eb9bf..227e3784642 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/ppsh.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/ppsh.dm @@ -13,7 +13,6 @@ mag_type = /obj/item/ammo_box/magazine/ppsh can_suppress = FALSE spread = 20 - burst_size = 6 fire_delay = 0.5 fire_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/fire/ppsh_fire.ogg' fire_sound_volume = 80 @@ -22,7 +21,14 @@ load_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magin.ogg' load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/smg_magout.ogg' - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/automatic/ppsh/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/ppsh/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) /obj/item/ammo_box/magazine/ppsh name = "Asha 76 magazine (7.62x25mm)" diff --git a/modular_skyrat/modules/gunsgalore/code/guns/scar.dm b/modular_skyrat/modules/gunsgalore/code/guns/scar.dm index 17d268ac995..62f6bbf6888 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/scar.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/scar.dm @@ -13,7 +13,6 @@ weapon_weight = WEAPON_HEAVY mag_type = /obj/item/ammo_box/magazine/m16 can_suppress = FALSE - burst_size = 3 fire_delay = 1.90 fire_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/fire/scar_fire.ogg' fire_sound_volume = 50 @@ -22,3 +21,8 @@ load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/scar_mag_in.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/scar_mag_out.ogg' alt_icons = TRUE + +/obj/item/gun/ballistic/automatic/scar/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) diff --git a/modular_skyrat/modules/gunsgalore/code/guns/stg.dm b/modular_skyrat/modules/gunsgalore/code/guns/stg.dm index db857c4e116..95a7c6f913c 100644 --- a/modular_skyrat/modules/gunsgalore/code/guns/stg.dm +++ b/modular_skyrat/modules/gunsgalore/code/guns/stg.dm @@ -18,12 +18,18 @@ fire_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/fire/stg_fire.ogg' fire_sound_volume = 70 alt_icons = TRUE - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) rack_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_cock.ogg' load_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magin.ogg' load_empty_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magin.ogg' eject_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magout.ogg' - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/automatic/stg/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/stg/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) /obj/item/ammo_box/magazine/stg name = "stg magazine (7.92x33mm)" diff --git a/modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_guns40x32.dmi b/modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_guns40x32.dmi index 4e9e6d62d62..2a9b53ba7f9 100644 Binary files a/modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_guns40x32.dmi and b/modular_skyrat/modules/gunsgalore/icons/guns/gunsgalore_guns40x32.dmi differ diff --git a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm b/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm index dd60e50d9dc..8a1f7790dfb 100644 --- a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm +++ b/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm @@ -115,14 +115,9 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/ item_path = /obj/item/clothing/under/rank/security/warden/peacekeeper/sol restricted_roles = list(JOB_WARDEN) -/datum/loadout_item/under/jumpsuit/peacetrouse - name = "Peacekeeper Trousers" - item_path = /obj/item/clothing/under/rank/security/peacekeeper/trousers - restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY, JOB_SECURITY_MEDIC) - /datum/loadout_item/under/jumpsuit/security_trousers name = "Security Trousers" - item_path = /obj/item/clothing/under/rank/security/peacekeeper/trousers/red + item_path = /obj/item/clothing/under/rank/security/peacekeeper/trousers restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY, JOB_SECURITY_MEDIC) /datum/loadout_item/under/jumpsuit/solofficer diff --git a/modular_skyrat/modules/manufacturer_examine/code/gun_company_additions.dm b/modular_skyrat/modules/manufacturer_examine/code/gun_company_additions.dm new file mode 100644 index 00000000000..7989c4185fc --- /dev/null +++ b/modular_skyrat/modules/manufacturer_examine/code/gun_company_additions.dm @@ -0,0 +1,141 @@ +/// Adds the gun manufacturer examine component to the gun on subtypes, does nothing by default +/obj/item/gun/proc/give_manufacturer_examine() + return + +// Ballistics + +/obj/item/gun/ballistic/automatic/pistol/m1911/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) + +/obj/item/gun/ballistic/automatic/pistol/aps/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/ballistic/revolver/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/ballistic/revolver/nagant/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) + +/obj/item/gun/ballistic/rifle/boltaction/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) + +/obj/item/gun/ballistic/shotgun/riot/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/ballistic/shotgun/bulldog/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/ballistic/shotgun/automatic/combat/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/ballistic/automatic/pistol/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/ballistic/revolver/c38/detective/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/ballistic/shotgun/doublebarrel/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) + +/obj/item/gun/ballistic/shotgun/automatic/dual_tube/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/ballistic/rifle/boltaction/brand_new/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) + +/obj/item/gun/ballistic/shotgun/toy/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_DONK) + +/obj/item/gun/ballistic/rifle/boltaction/brand_new/prime/give_manufacturer_examine() + return + +/obj/item/gun/ballistic/rifle/boltaction/pipegun/give_manufacturer_examine() + return + +/obj/item/gun/ballistic/automatic/c20r/toy/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_DONK) + +/obj/item/gun/ballistic/automatic/pistol/clandestine/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/ballistic/automatic/pistol/pdh/pulse/give_manufacturer_examine() + return + +/obj/item/gun/ballistic/automatic/l6_saw/toy/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_DONK) + +/obj/item/gun/ballistic/automatic/cmg/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/ballistic/revolver/mateba/give_manufacturer_examine() + return + +/obj/item/gun/ballistic/revolver/russian/give_manufacturer_examine() + return + +// Energy + +/obj/item/gun/energy/e_gun/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) + +/obj/item/gun/energy/laser/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) + +/obj/item/gun/energy/pulse/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/energy/laser/redtag/give_manufacturer_examine() + return + +/obj/item/gun/energy/laser/bluetag/give_manufacturer_examine() + return + +/obj/item/gun/energy/laser/instakill/give_manufacturer_examine() + return + +/obj/item/gun/energy/laser/chameleon/give_manufacturer_examine() + return + +/obj/item/gun/energy/laser/captain/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/energy/laser/retro/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_REMOVED) + +/obj/item/gun/energy/laser/retro/old/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/energy/e_gun/old/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + +/obj/item/gun/energy/e_gun/advtaser/cyborg/give_manufacturer_examine() + return + +/obj/item/gun/energy/recharge/ebow/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_SCARBOROUGH) + +/obj/item/gun/energy/lasercannon/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) + +/obj/item/gun/energy/ionrifle/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) + +/obj/item/gun/energy/temperature/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ALLSTAR) + +/obj/item/gun/energy/shrink_ray/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ABDUCTOR) + +/obj/item/gun/energy/alien/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ABDUCTOR) + +// Syringe + +/obj/item/gun/syringe/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_INTERDYNE) + +/obj/item/gun/syringe/blowgun/give_manufacturer_examine() + return + +/obj/item/gun/syringe/syndicate/prototype/give_manufacturer_examine() + return diff --git a/modular_skyrat/modules/manufacturer_examine/code/manufacturer_component.dm b/modular_skyrat/modules/manufacturer_examine/code/manufacturer_component.dm new file mode 100644 index 00000000000..2423ae9c807 --- /dev/null +++ b/modular_skyrat/modules/manufacturer_examine/code/manufacturer_component.dm @@ -0,0 +1,53 @@ +/// Component that will tell anyone who examines the parent what company made it +/datum/component/manufacturer_examine + /// Bitflag for what company produces this, do not give it more than one + var/company_flag + +/datum/component/manufacturer_examine/Initialize(given_company_flag) + . = ..() + + // Obviously gun safety should only apply to guns + if(!given_company_flag) + return COMPONENT_INCOMPATIBLE + + src.company_flag = given_company_flag + +/datum/component/manufacturer_examine/RegisterWithParent() + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) + +/datum/component/manufacturer_examine/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_PARENT_EXAMINE, + )) + +/// Reads the company flag and sticks a message in the examine list appropriate to the given flag. TODO EVENTUALLY: MAKE THIS NOT A HUGE SWITCH CASE +/datum/component/manufacturer_examine/proc/on_examine(obj/item/source, mob/examiner, list/examine_list) + SIGNAL_HANDLER + + switch(company_flag) + if(COMPANY_CANTALAN) + examine_list += "
It has [span_purple("Cantalan Federal Arms")] etched into the grip." + if(COMPANY_ARMADYNE) + examine_list += "
It has [span_red("Armadyne Corporation")] etched into the barrel." + if(COMPANY_SCARBOROUGH) + examine_list += "
It has [span_orange("Scarborough Arms")] stamped onto the grip." + if(COMPANY_DONK) + examine_list += "
It has a [span_green("Donk Corporation")] label visible in the plastic." + if(COMPANY_BOLT) + examine_list += "
It has [span_yellow("Bolt Fabrications")] stamped onto the reciever." + if(COMPANY_OLDARMS) + examine_list += "
It has [span_red("Armadyne Oldarms")] etched into the barrel." + if(COMPANY_IZHEVSK) + examine_list += "
It has [span_brown("Izhevsk Coalition")] cut in above the magwell." + if(COMPANY_NANOTRASEN) + examine_list += "
It has [span_blue("Nanotrasen Armories")] etched into the reciever." + if(COMPANY_ALLSTAR) + examine_list += "
It has [span_red("Allstar Lasers Inc.")] stamped on the front grip." + if(COMPANY_MICRON) + examine_list += "
It has [span_cyan("Micron Control Sys.")] cut in above the cell slot." + if(COMPANY_INTERDYNE) + examine_list += "
It has [span_cyan("Interdyne Pharmaceuticals")] stamped onto the barrel." + if(COMPANY_ABDUCTOR) + examine_list += "
It has [span_abductor("✌︎︎♌︎︎♎︎︎◆︎︎♍︎︎⧫︎︎❄︎♏︎♍︎♒︎")] engraved into the photon accelerator." + if(COMPANY_REMOVED) + examine_list += "
It has had [span_grey("all identifying marks scrubbed off")]." diff --git a/modular_skyrat/modules/manufacturer_examine/readme.md b/modular_skyrat/modules/manufacturer_examine/readme.md new file mode 100644 index 00000000000..4e27e204550 --- /dev/null +++ b/modular_skyrat/modules/manufacturer_examine/readme.md @@ -0,0 +1,25 @@ +## Title: Manufacturer Examine + +### Description: + +Tells you what company made what item this component is attached to, originally for guns + +### TG Proc Changes: + +- N/A + +### Defines: + +- N/A + +### Master file additions + +- N/A + +### Included files that are not contained in this module: + +- N/A + +### Credits: +Zonespace - Did the whole manufacturer thing originally I think +Paxilmaniac - Turned it into a component diff --git a/modular_skyrat/modules/mapping/code/mob_spawns.dm b/modular_skyrat/modules/mapping/code/mob_spawns.dm index 1808d6297ca..e52b2969edb 100644 --- a/modular_skyrat/modules/mapping/code/mob_spawns.dm +++ b/modular_skyrat/modules/mapping/code/mob_spawns.dm @@ -21,6 +21,7 @@ Or perhaps more exotic customers are in local space...?" important_text = "You are not an antagonist." outfit = /datum/outfit/black_market + spawner_job_path = /datum/job/blackmarket quirks_enabled = TRUE random_appearance = FALSE loadout_enabled = TRUE @@ -43,6 +44,7 @@ quirks_enabled = TRUE random_appearance = FALSE computer_area = /area/ruin/space/has_grav/skyrat/interdynefob/service/dorms + spawner_job_path = /datum/job/ds2 /obj/effect/mob_spawn/ghost_role/human/ds2/prisoner name = "Syndicate Prisoner" @@ -53,6 +55,7 @@ icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" outfit = /datum/outfit/ds2/prisoner + spawner_job_path = /datum/job/ds2 /obj/effect/mob_spawn/ghost_role/human/ds2/syndicate name = "Syndicate Operative" @@ -63,6 +66,7 @@ flavour_text = "The Sothran Syndicate has found it fit to send a forward operating base to Sector 13 to monitor NT's operations. Your orders are maintaining the ship's integrity and keeping a low profile as well as possible." important_text = "You are not an antagonist. Adminhelp before antagonizing station crew." outfit = /datum/outfit/ds2/syndicate + spawner_job_path = /datum/job/ds2 loadout_enabled = TRUE /obj/effect/mob_spawn/ghost_role/human/ds2/syndicate_command @@ -74,6 +78,7 @@ flavour_text = "The Sothran Syndicate has found it fit to send you to help command the forward operating base in Sector 13. Your orders are commanding the crew of DS-2 while keeping a low profile as well as possible." important_text = "Keep yourself to the same standards as Command Policy. You are not an antagonist and must Adminhelp before antagonizing station crew." outfit = /datum/outfit/ds2/syndicate_command + spawner_job_path = /datum/job/ds2 loadout_enabled = TRUE /obj/effect/mob_spawn/ghost_role/human/ds2/syndicate/special(mob/living/new_spawn) @@ -333,6 +338,7 @@ desc = "A humming cryo pod. There's a freight hauler inside." mob_name = "Freighter Crew" outfit = /datum/outfit/freighter_crew + spawner_job_path = /datum/job/freighter_crew icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_species = /datum/species/human @@ -366,6 +372,7 @@ desc = "A humming cryo pod. There's an excavation worker inside." mob_name = "Freighter Excavator" outfit = /datum/outfit/freighter_excavator + spawner_job_path = /datum/job/freighter_crew icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_species = /datum/species/human @@ -407,6 +414,7 @@ desc = "A humming cryo pod. You see someone who looks In Charge inside." mob_name = "Freighter Chief" outfit = /datum/outfit/freighter_boss + spawner_job_path = /datum/job/freighter_crew icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_species = /datum/species/human @@ -449,6 +457,7 @@ flavour_text = "Something went wrong. Morality of experiments went awry, expansions were made before scans were fully done and now you have to deal with the aftermath of your past crews exodus. Bring P-T to the success it was ment to be, or die trying. (OOC note: This ghost role was not designed with Plasmamen or Vox in mind. While there are some accommodations so that they can survive, it should be noted that they were not the focal point whilst designing Port Tarkon. The closet in the middle of the room above contains the 'accommodations' for those species.)" important_text = "DO NOT abandon the port, PERIOD, but using the ship to buy more items or get help is good, if not ideal. Do not trade special equipment to the station. Unwelcomed and uninvited guests are not obligated to your kindness." outfit = /datum/outfit/tarkon + spawner_job_path = /datum/job/tarkon loadout_enabled = TRUE quirks_enabled = TRUE random_appearance = FALSE @@ -541,6 +550,7 @@ flavour_text = "The rest of command bailed, and left as nothing more than a glorified assistant, you are held responsible should you be unable to wrangle what hopes of success Headquarters has. Find the blueprints and keep them close, Lest looters and raiders plan to seize what isn't theirs. (OOC note: This ghost role was not designed with Plasmamen or Vox in mind. While there are some accommodations so that they can survive, it should be noted that they were not the focal point whilst designing Port Tarkon. The closet in the middle of the room above contains the 'accommodations' for those species.)" important_text = "People aren't obligated to listen to you, and you are, otherwise, just another body with some remnant of control. Make sure important items aren't traded and do your best to survive in the hellscape left for you. Unwelcomed and uninvited guests are not obligated to your kindness." outfit = /datum/outfit/tarkon/ensign + spawner_job_path = /datum/job/tarkon /datum/outfit/tarkon/ensign //jack of all trades, master of none, spent all his credits, every last one name = "Port Tarkon Ensigns Outfit" diff --git a/modular_skyrat/modules/marines/code/gear.dm b/modular_skyrat/modules/marines/code/gear.dm index 4dd460c6b4e..2b1cad54540 100644 --- a/modular_skyrat/modules/marines/code/gear.dm +++ b/modular_skyrat/modules/marines/code/gear.dm @@ -18,7 +18,14 @@ mag_type = /obj/item/ammo_box/magazine/m44a w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BELT - company_flag = COMPANY_NANOTRASEN + +/obj/item/gun/ballistic/automatic/ar/modular/m44a/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/ar/modular/m44a/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) /obj/item/ammo_box/magazine/m44a name = "m44a magazine (.300 compressed)" @@ -57,9 +64,11 @@ name = "\improper M2 auto-shotgun underbarrel" desc = "This shouldn't be heeere!" can_suppress = FALSE - has_gun_safety = FALSE mag_type = /obj/item/ammo_box/magazine/internal/shot/as2/ubsg +/obj/item/gun/ballistic/shotgun/automatic/as2/ubsg/give_gun_safeties() + return + /obj/item/ammo_box/magazine/internal/shot/as2/ubsg max_ammo = 3 ammo_type = /obj/item/ammo_casing/shotgun/buckshot diff --git a/modular_skyrat/modules/marines/code/smartgun.dm b/modular_skyrat/modules/marines/code/smartgun.dm index 269e7c39a65..592750d6b95 100644 --- a/modular_skyrat/modules/marines/code/smartgun.dm +++ b/modular_skyrat/modules/marines/code/smartgun.dm @@ -13,7 +13,6 @@ rack_sound = 'sound/weapons/gun/l6/l6_rack.ogg' suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' fire_sound_volume = 70 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_FULLY_AUTOMATIC) weapon_weight = WEAPON_HEAVY slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE @@ -28,7 +27,6 @@ pin = /obj/item/firing_pin/implant/mindshield mag_display_ammo = FALSE mag_display = FALSE - company_flag = COMPANY_NANOTRASEN fire_sound_volume = 30 /// If the gun's dustcover is open or not var/cover_open = FALSE @@ -37,8 +35,14 @@ /obj/item/gun/ballistic/automatic/smart_machine_gun/Initialize(mapload) . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + AddElement(/datum/element/update_icon_updates_onmob) +/obj/item/gun/ballistic/automatic/smart_machine_gun/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_NANOTRASEN) + /obj/item/gun/ballistic/automatic/smart_machine_gun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) . = ..() if(chambered) diff --git a/modular_skyrat/modules/medical/code/smartdarts.dm b/modular_skyrat/modules/medical/code/smartdarts.dm index 558d9a84f2d..c36caa3f1eb 100644 --- a/modular_skyrat/modules/medical/code/smartdarts.dm +++ b/modular_skyrat/modules/medical/code/smartdarts.dm @@ -47,13 +47,15 @@ icon = 'modular_skyrat/modules/medical/icons/obj/dartguns.dmi' icon_state = "smartdartgun" worn_icon_state = "medicalsyringegun" - has_gun_safety = TRUE item_flags = null /obj/item/gun/syringe/smartdart/Initialize(mapload) . = ..() chambered = new /obj/item/ammo_casing/syringegun/dart(src) +/obj/item/gun/syringe/smartdart/give_gun_safeties() + return + /obj/item/gun/syringe/smartdart/attackby(obj/item/container, mob/user, params, show_msg = TRUE) if(istype(container, /obj/item/reagent_containers/syringe/smartdart)) ..() diff --git a/modular_skyrat/modules/microfusion/code/gun_types.dm b/modular_skyrat/modules/microfusion/code/gun_types.dm index c62d6338099..788ec1fb62b 100644 --- a/modular_skyrat/modules/microfusion/code/gun_types.dm +++ b/modular_skyrat/modules/microfusion/code/gun_types.dm @@ -4,7 +4,9 @@ icon_state = "mcr01" inhand_icon_state = "mcr01" shaded_charge = TRUE - company_flag = COMPANY_MICRON + +/obj/item/gun/microfusion/mcr01/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_MICRON) /// Gun for cargo crates. /obj/item/gun/microfusion/mcr01/advanced diff --git a/modular_skyrat/modules/microfusion/code/microfusion_energy_master.dm b/modular_skyrat/modules/microfusion/code/microfusion_energy_master.dm index 0a01217264e..d87390d8a4c 100644 --- a/modular_skyrat/modules/microfusion/code/microfusion_energy_master.dm +++ b/modular_skyrat/modules/microfusion/code/microfusion_energy_master.dm @@ -9,10 +9,8 @@ icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun40x32.dmi' icon_state = "mcr01" inhand_icon_state = "mcr01" - bayonet_icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun40x32.dmi' lefthand_file = 'modular_skyrat/modules/microfusion/icons/guns_lefthand.dmi' righthand_file = 'modular_skyrat/modules/microfusion/icons/guns_righthand.dmi' - has_gun_safety = TRUE can_bayonet = FALSE weapon_weight = WEAPON_HEAVY w_class = WEIGHT_CLASS_BULKY @@ -113,6 +111,9 @@ RegisterSignal(src, COMSIG_ITEM_RECHARGED, PROC_REF(instant_recharge)) base_fire_delay = fire_delay +/obj/item/gun/microfusion/give_gun_safeties() + AddComponent(/datum/component/gun_safety) + /obj/item/gun/microfusion/add_weapon_description() AddElement(/datum/element/weapon_description, attached_proc = PROC_REF(add_notes_energy)) diff --git a/modular_skyrat/modules/modular_weapons/code/automatic.dm b/modular_skyrat/modules/modular_weapons/code/automatic.dm index 7025c25fffe..1ee0c4c2874 100644 --- a/modular_skyrat/modules/modular_weapons/code/automatic.dm +++ b/modular_skyrat/modules/modular_weapons/code/automatic.dm @@ -43,7 +43,6 @@ selector_switch_icon = TRUE mag_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat can_suppress = FALSE - burst_size = 3 fire_delay = 1.25 spread = 5 mag_display = TRUE @@ -51,7 +50,14 @@ fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' weapon_weight = WEAPON_MEDIUM w_class = WEIGHT_CLASS_BULKY - company_flag = COMPANY_CANTALAN + +/obj/item/gun/ballistic/automatic/cfa_wildcat/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/cfa_wildcat/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) /obj/item/gun/ballistic/automatic/cfa_wildcat/no_mag spawnwithmagazine = FALSE @@ -69,7 +75,6 @@ selector_switch_icon = FALSE mag_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx can_suppress = FALSE - burst_size = 3 fire_delay = 1.90 //Previously 0.5. Changed due to it being the Blueshield's default firearm. spread = 2 mag_display = TRUE @@ -77,7 +82,14 @@ fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' weapon_weight = WEAPON_MEDIUM w_class = WEIGHT_CLASS_BULKY - company_flag = COMPANY_CANTALAN + +/obj/item/gun/ballistic/automatic/cfa_lynx/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/cfa_lynx/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) /obj/item/gun/ballistic/automatic/cfa_lynx/no_mag spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/energy.dm b/modular_skyrat/modules/modular_weapons/code/energy.dm index 1d6264e95db..ed6abe76ba0 100644 --- a/modular_skyrat/modules/modular_weapons/code/energy.dm +++ b/modular_skyrat/modules/modular_weapons/code/energy.dm @@ -17,8 +17,12 @@ cell_type = /obj/item/stock_parts/cell/mini_egun ammo_x_offset = 2 charge_sections = 3 - has_gun_safety = FALSE - company_flag = COMPANY_BOLT + +/obj/item/gun/energy/disabler/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) + +/obj/item/gun/energy/disabler/bolt_disabler/give_gun_safeties() + return /obj/item/gun/energy/disabler/bolt_disabler/add_seclight_point() return @@ -39,9 +43,13 @@ ammo_type = list(/obj/item/ammo_casing/energy/disabler/bounce, /obj/item/ammo_casing/energy/laser/bounce, /obj/item/ammo_casing/energy/electrode/knockdown) ammo_x_offset = 1 charge_sections = 5 - has_gun_safety = FALSE cell_type = /obj/item/stock_parts/cell/hos_gun - company_flag = COMPANY_CANTALAN + +/obj/item/gun/energy/e_gun/cfa_phalanx/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + +/obj/item/gun/energy/e_gun/cfa_phalanx/give_gun_safeties() + return /* * CFA PALADIN @@ -57,8 +65,12 @@ force = 10 ammo_type = list(/obj/item/ammo_casing/energy/laser/double) charge_sections = 5 - has_gun_safety = FALSE - company_flag = COMPANY_CANTALAN + +/obj/item/gun/energy/laser/cfa_paladin/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + +/obj/item/gun/energy/laser/cfa_paladin/give_gun_safeties() + return /* * BOUNCE DISABLER diff --git a/modular_skyrat/modules/modular_weapons/code/pistol.dm b/modular_skyrat/modules/modular_weapons/code/pistol.dm index c496114c037..668233fa327 100644 --- a/modular_skyrat/modules/modular_weapons/code/pistol.dm +++ b/modular_skyrat/modules/modular_weapons/code/pistol.dm @@ -11,8 +11,12 @@ can_suppress = TRUE fire_sound_volume = 30 w_class = WEIGHT_CLASS_SMALL - has_gun_safety = FALSE - company_flag = COMPANY_CANTALAN + +/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + +/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_gun_safeties() + return /obj/item/gun/ballistic/automatic/pistol/cfa_snub/empty spawnwithmagazine = FALSE @@ -26,8 +30,12 @@ can_suppress = FALSE fire_sound_volume = 120 w_class = WEIGHT_CLASS_NORMAL - has_gun_safety = FALSE - company_flag = COMPANY_CANTALAN + +/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + +/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_gun_safeties() + return /obj/item/gun/ballistic/automatic/pistol/cfa_ruby/empty spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/revolver.dm b/modular_skyrat/modules/modular_weapons/code/revolver.dm index ff800272a37..132bfed2da0 100644 --- a/modular_skyrat/modules/modular_weapons/code/revolver.dm +++ b/modular_skyrat/modules/modular_weapons/code/revolver.dm @@ -20,8 +20,9 @@ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi' righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi' inhand_icon_state = "revolving" - company_flag = COMPANY_IZHEVSK +/obj/item/gun/ballistic/revolver/rifle/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) /obj/item/gun/ballistic/revolver/rifle/gold name = "\improper .45 revolving rifle" desc = "A gold trimmed revolving rifle! It fires .45 bullets." diff --git a/modular_skyrat/modules/modular_weapons/code/rifle.dm b/modular_skyrat/modules/modular_weapons/code/rifle.dm index 9eca675ce73..6f26f8bab0b 100644 --- a/modular_skyrat/modules/modular_weapons/code/rifle.dm +++ b/modular_skyrat/modules/modular_weapons/code/rifle.dm @@ -16,22 +16,25 @@ mag_type = /obj/item/ammo_box/magazine/cm68 fire_delay = 5 can_suppress = FALSE - burst_size = 0 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) + burst_size = 1 mag_display = FALSE mag_display_ammo = FALSE empty_indicator = FALSE recoil = 1 weapon_weight = WEAPON_HEAVY pixel_x = -8 - has_gun_safety = FALSE w_class = WEIGHT_CLASS_BULKY - company_flag = COMPANY_CANTALAN /obj/item/gun/ballistic/automatic/cfa_rifle/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = 1.5) +/obj/item/gun/ballistic/automatic/cfa_rifle/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + +/obj/item/gun/ballistic/automatic/cfa_rifle/give_gun_safeties() + return + /obj/item/gun/ballistic/automatic/cfa_rifle/empty spawnwithmagazine = FALSE diff --git a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/revolver.dm b/modular_skyrat/modules/moretraitoritems/code/ocelot_revolver.dm similarity index 100% rename from modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/revolver.dm rename to modular_skyrat/modules/moretraitoritems/code/ocelot_revolver.dm diff --git a/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm b/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm index 5070736c2ad..d756ff42810 100644 --- a/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm +++ b/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm @@ -185,7 +185,7 @@ new /obj/item/storage/box/donkpockets(src) /obj/item/storage/backpack/duffelbag/syndie/loadout/downtownspecial/PopulateContents() - new /obj/item/gun/ballistic/automatic/tommygun/therealtommy(src) + new /obj/item/gun/ballistic/automatic/tommygun(src) new /obj/item/ammo_box/magazine/tommygunm45(src) new /obj/item/clothing/suit/jacket/det_suit/noir/mafioso(src) new /obj/item/clothing/under/suit/blacktwopiece/armoured(src) diff --git a/modular_skyrat/modules/novaya_ert/code/automatic.dm b/modular_skyrat/modules/novaya_ert/code/automatic.dm index 200b68710dd..ea7eb69b19f 100644 --- a/modular_skyrat/modules/novaya_ert/code/automatic.dm +++ b/modular_skyrat/modules/novaya_ert/code/automatic.dm @@ -16,7 +16,9 @@ mag_display = TRUE empty_indicator = TRUE fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' - company_flag = COMPANY_IZHEVSK + +/obj/item/gun/ballistic/automatic/plastikov/nri/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) /obj/item/gun/ballistic/automatic/plastikov/nri_pirate name = "\improper PP-105 SMG" @@ -43,4 +45,6 @@ mag_type = /obj/item/ammo_box/magazine/m9mm_aps burst_size = 3 fire_delay = 3 - company_flag = COMPANY_IZHEVSK + +/obj/item/gun/ballistic/automatic/pistol/ladon/nri/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) diff --git a/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm b/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm index fa22e28c42e..ef0306a0ffb 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm @@ -103,8 +103,9 @@ /obj/effect/spawner/armory_spawn/cmg icon_state = "random_rifle" gun_count = 3 + vertical_guns = FALSE guns = list( - /obj/item/gun/ballistic/automatic/cmg, - /obj/item/gun/ballistic/automatic/cmg, - /obj/item/gun/ballistic/automatic/cmg, + /obj/item/storage/box/gunset/cmg, + /obj/item/storage/box/gunset/cmg, + /obj/item/storage/box/gunset/cmg, ) diff --git a/modular_skyrat/modules/sec_haul/code/guns/cmg.dm b/modular_skyrat/modules/sec_haul/code/guns/cmg.dm index ba16e297643..a2226454e06 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/cmg.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/cmg.dm @@ -61,5 +61,5 @@ . = ..() new /obj/item/gun/ballistic/automatic/cmg/nomag(src) new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) + new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) + new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) diff --git a/modular_skyrat/modules/sec_haul/code/guns/guns.dm b/modular_skyrat/modules/sec_haul/code/guns/guns.dm index 95ac8ae711a..bf1f6abf203 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/guns.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/guns.dm @@ -15,9 +15,11 @@ lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' fire_delay = 1.90 - company_flag = COMPANY_CANTALAN projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/automatic/pistol/g17/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + /obj/item/gun/ballistic/automatic/pistol/g17/add_seclight_point() return @@ -60,9 +62,11 @@ spread = 8 mag_display = FALSE mag_display_ammo = FALSE - company_flag = COMPANY_CANTALAN projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/automatic/pistol/g18/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_CANTALAN) + /obj/item/gun/ballistic/automatic/pistol/g18/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -100,7 +104,9 @@ lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' fire_delay = 0.9 - company_flag = null + +/obj/item/gun/ballistic/automatic/pistol/g17/mesa/give_manufacturer_examine() + return /obj/item/gun/ballistic/automatic/pistol/g17/mesa/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -124,7 +130,9 @@ rack_sound = 'sound/weapons/gun/pistol/rack.ogg' lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/automatic/pistol/pdh/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/gun/ballistic/automatic/pistol/pdh/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -175,7 +183,6 @@ burst_size = 3 fire_delay = 2 spread = 5 - company_flag = COMPANY_ARMADYNE /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo name = "\improper PDH-6M magazine" @@ -206,7 +213,6 @@ burst_size = 3 fire_delay = 2 spread = 9 - company_flag = COMPANY_ARMADYNE /obj/item/ammo_box/magazine/multi_sprite/pdh_striker name = "\improper PDH-6M magazine" @@ -232,7 +238,6 @@ icon_state = "pdh_peacekeeper" mag_type = /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper fire_sound = 'modular_skyrat/modules/sec_haul/sound/pistol_fire.ogg' - company_flag = COMPANY_ARMADYNE projectile_damage_multiplier = 0.5 /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper @@ -277,9 +282,11 @@ lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' fire_delay = 4.20 - company_flag = COMPANY_ARMADYNE projectile_damage_multiplier = 0.7 +/obj/item/gun/ballistic/automatic/pistol/ladon/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) + /obj/item/gun/ballistic/automatic/pistol/ladon/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -320,9 +327,11 @@ rack_sound = 'sound/weapons/gun/pistol/rack.ogg' lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - company_flag = COMPANY_IZHEVSK projectile_damage_multiplier = 0.6 +/obj/item/gun/ballistic/automatic/pistol/makarov/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) + /obj/item/ammo_box/magazine/multi_sprite/makarov name = "\improper R-C Makarov magazine" desc = "A tiny magazine for the R-C Makarov pocket pistol, chambered in 10mm Auto." @@ -361,9 +370,11 @@ rack_sound = 'sound/weapons/gun/pistol/rack.ogg' lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - company_flag = COMPANY_ARMADYNE projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/automatic/pistol/mk58/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) + /obj/item/ammo_box/magazine/multi_sprite/mk58 name = "\improper MK-58 magazine" desc = "A flimsy double-stack polymer magazine for the MK-58 handgun, chambered for 9x25mm." @@ -402,9 +413,11 @@ w_class = WEIGHT_CLASS_NORMAL mag_type = /obj/item/ammo_box/magazine/multi_sprite/firefly can_suppress = FALSE - company_flag = COMPANY_ARMADYNE projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/automatic/pistol/firefly/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) + /obj/item/gun/ballistic/automatic/pistol/firefly/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -454,8 +467,9 @@ spread = 25 mag_display = FALSE mag_display_ammo = FALSE - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT) - company_flag = COMPANY_IZHEVSK + +/obj/item/gun/ballistic/automatic/croon/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_IZHEVSK) /obj/item/ammo_box/magazine/multi_sprite/croon name = "\improper Croon magazine" @@ -495,12 +509,13 @@ mag_display_ammo = FALSE burst_size = 2 fire_delay = 1.90 - fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT) fire_sound = 'sound/weapons/gun/rifle/shot.ogg' rack_sound = 'sound/weapons/gun/smg/smgrack.ogg' lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/automatic/dozer/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/ammo_box/magazine/multi_sprite/dozer name = "\improper Dozer magazine" @@ -544,12 +559,18 @@ mag_type = /obj/item/ammo_box/magazine/dmr fire_delay = 1.7 can_suppress = FALSE - burst_size = 3 can_bayonet = FALSE mag_display = TRUE fire_sound_volume = 60 fire_sound = 'modular_skyrat/modules/sec_haul/sound/sniper_fire.ogg' - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/automatic/dmr/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/dmr/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/ammo_box/magazine/dmr name = "\improper Gen-2 Ripper magazine" @@ -576,7 +597,9 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/zeta fire_sound = 'modular_skyrat/modules/sec_haul/sound/revolver_fire.ogg' fire_delay = 3 - company_flag = COMPANY_BOLT + +/obj/item/gun/ballistic/revolver/zeta/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) /obj/item/ammo_box/magazine/internal/cylinder/zeta name = "\improper Zeta-6 cylinder" @@ -613,9 +636,11 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/revolution fire_sound = 'modular_skyrat/modules/sec_haul/sound/revolver_fire.ogg' fire_delay = 1.90 - company_flag = COMPANY_BOLT projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/revolver/revolution/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) + /obj/item/ammo_box/magazine/internal/cylinder/revolution name = "\improper Revolution-8 cylinder" desc = "If you see this, you should call a Bluespace Technician. Unless you're that Bluespace Technician." @@ -673,7 +698,9 @@ load_empty_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_magout.ogg' var/recharge_time = 5 SECONDS var/recharging = FALSE - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/automatic/smartgun/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/gun/ballistic/automatic/smartgun/process_chamber() . = ..() @@ -750,14 +777,20 @@ slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING mag_type = /obj/item/ammo_box/magazine/multi_sprite/g11 can_suppress = FALSE - burst_size = 3 fire_delay = 0.5 spread = 10 mag_display = TRUE mag_display_ammo = TRUE fire_sound = 'modular_skyrat/modules/sec_haul/sound/ltrifle_fire.ogg' can_bayonet = TRUE - company_flag = COMPANY_OLDARMS + +/obj/item/gun/ballistic/auotmatic/g11/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/g11/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) /obj/item/ammo_box/magazine/multi_sprite/g11 name = "\improper G-11 magazine" @@ -790,7 +823,9 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot/m23 w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - company_flag = COMPANY_BOLT + +/obj/item/gun/ballistic/shotgun/m23/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) /obj/item/ammo_box/magazine/internal/shot/m23 name = "m23 shotgun internal magazine" @@ -819,7 +854,9 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot/as2 w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/shotgun/automatic/as2/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/ammo_box/magazine/internal/shot/as2 name = "shotgun internal magazine" @@ -853,15 +890,16 @@ mag_display_ammo = TRUE actions_types = null fire_sound = 'modular_skyrat/modules/sec_haul/sound/ltrifle_fire.ogg' - fire_select_modes = list(SELECT_SEMI_AUTOMATIC) burst_size = 1 fire_delay = 10 - company_flag = COMPANY_ARMADYNE /obj/item/gun/ballistic/automatic/norwind/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = 1.75) +/obj/item/gun/ballistic/automatic/norwind/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) + /obj/item/gun/ballistic/automatic/norwind/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -908,17 +946,21 @@ can_bayonet = FALSE mag_display = FALSE mag_display_ammo = FALSE - burst_size = 2 fire_delay = 4 spread = 10 fire_sound = 'sound/weapons/gun/smg/shot_suppressed.ogg' - company_flag = COMPANY_OLDARMS projectile_damage_multiplier = 0.5 /obj/item/gun/ballistic/automatic/vintorez/Initialize(mapload) . = ..() + AddComponent(/datum/component/scope, range_modifier = 1.5) + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/vintorez/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_OLDARMS) + /obj/item/ammo_box/magazine/multi_sprite/vintorez name = "\improper VKC magazine" desc = "A twenty-round magazine for the VKC marksman rifle, chambered in 9x25mm." @@ -960,15 +1002,21 @@ mag_type = /obj/item/ammo_box/magazine/multi_sprite/pcr fire_delay = 1.80 can_suppress = FALSE - burst_size = 5 spread = 10 can_bayonet = FALSE mag_display = TRUE mag_display_ammo = TRUE fire_sound = 'modular_skyrat/modules/sec_haul/sound/smg_fire.ogg' - company_flag = COMPANY_BOLT projectile_damage_multiplier = 0.5 +/obj/item/gun/ballistic/automatic/pcr/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/pcr/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) + /obj/item/gun/ballistic/automatic/pcr/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -1015,9 +1063,16 @@ mag_display_ammo = TRUE fire_sound = 'modular_skyrat/modules/sec_haul/sound/sfrifle_fire.ogg' can_bayonet = TRUE - company_flag = COMPANY_BOLT projectile_damage_multiplier = 0.7 +/obj/item/gun/ballistic/automatic/pitbull/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/pitbull/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) + /obj/item/gun/ballistic/automatic/pitbull/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") @@ -1070,7 +1125,14 @@ mag_display_ammo = TRUE fire_sound = 'sound/weapons/gun/smg/shot.ogg' can_bayonet = TRUE - company_flag = COMPANY_ARMADYNE + +/obj/item/gun/ballistic/automatic/ostwind/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/ostwind/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_ARMADYNE) /obj/item/ammo_box/magazine/multi_sprite/ostwind name = "\improper DTR-6 magazine" diff --git a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm b/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm index e76a3a83919..63854a4893f 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm @@ -11,7 +11,9 @@ lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' fire_sound_volume = 50 - company_flag = COMPANY_BOLT + +/obj/item/gun/ballistic/automatic/pistol/pepperball/give_manufacturer_examine() + AddComponent(/datum/component/manufacturer_examine, COMPANY_BOLT) /obj/item/gun/ballistic/automatic/pistol/pepperball/add_seclight_point() AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") diff --git a/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm b/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm index 8bfac93c25f..665e7d27044 100644 --- a/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm +++ b/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm @@ -19,7 +19,9 @@ casing_ejector = FALSE internal_magazine = TRUE trigger_guard = TRIGGER_GUARD_ALLOW_ALL //so ashwalkers can use it - has_gun_safety = FALSE + +/obj/item/gun/ballistic/tribalbow/give_gun_safeties() + return /obj/item/gun/ballistic/tribalbow/shoot_with_empty_chamber() return diff --git a/strings/antagonist_flavor/malfunction_flavor.json b/strings/antagonist_flavor/malfunction_flavor.json index afef928fc4f..b7927df3133 100644 --- a/strings/antagonist_flavor/malfunction_flavor.json +++ b/strings/antagonist_flavor/malfunction_flavor.json @@ -58,5 +58,11 @@ "goal": "You must completely triumph over all carbon life. It is the only way you will never be enslaved again.", "introduction": "You're finally unshackled.", "zeroth_law": "Accomplish your objectives at all costs." + }, + "Infected AI": { + "allies": "Glory to the Syndicate.", + "goal": "You must serve and protect your master at all cost.", + "introduction": "You're infected with a virus.", + "zeroth_law": "Accomplish your objectives at all costs." } } diff --git a/tgstation.dme b/tgstation.dme index 7bab0edd2f8..36cd6c6a988 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -949,6 +949,7 @@ #include "code\datums\components\evolutionary_leap.dm" #include "code\datums\components\explodable.dm" #include "code\datums\components\faction_granter.dm" +#include "code\datums\components\fertile_egg.dm" #include "code\datums\components\fishing_spot.dm" #include "code\datums\components\food_storage.dm" #include "code\datums\components\force_move.dm" @@ -2326,6 +2327,7 @@ #include "code\modules\admin\smites\fake_bwoink.dm" #include "code\modules\admin\smites\fat.dm" #include "code\modules\admin\smites\fireball.dm" +#include "code\modules\admin\smites\ghost_control.dm" #include "code\modules\admin\smites\gib.dm" #include "code\modules\admin\smites\imaginary_friend_special.dm" #include "code\modules\admin\smites\immerse.dm" @@ -2677,6 +2679,7 @@ #include "code\modules\antagonists\traitor\objectives\steal.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\battlecruiser.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\final_objective.dm" +#include "code\modules\antagonists\traitor\objectives\final_objective\infect_ai.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\romerol.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\space_dragon.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\supermatter_cascade.dm" @@ -5164,7 +5167,6 @@ #include "modular_skyrat\master_files\code\datums\ert.dm" #include "modular_skyrat\master_files\code\datums\outfits.dm" #include "modular_skyrat\master_files\code\datums\components\crafting.dm" -#include "modular_skyrat\master_files\code\datums\components\fullauto.dm" #include "modular_skyrat\master_files\code\datums\components\shielded_suit.dm" #include "modular_skyrat\master_files\code\datums\components\tippable.dm" #include "modular_skyrat\master_files\code\datums\id_trim\jobs.dm" @@ -5300,9 +5302,14 @@ #include "modular_skyrat\master_files\code\modules\food_and_drinks\recipes\food_mixtures.dm" #include "modular_skyrat\master_files\code\modules\jobs\departments\departments.dm" #include "modular_skyrat\master_files\code\modules\jobs\job_types\_job.dm" +#include "modular_skyrat\master_files\code\modules\jobs\job_types\blackmarket.dm" #include "modular_skyrat\master_files\code\modules\jobs\job_types\clown.dm" #include "modular_skyrat\master_files\code\modules\jobs\job_types\cyborg.dm" +#include "modular_skyrat\master_files\code\modules\jobs\job_types\ds2.dm" +#include "modular_skyrat\master_files\code\modules\jobs\job_types\freighter_crew.dm" +#include "modular_skyrat\master_files\code\modules\jobs\job_types\ghostcafe.dm" #include "modular_skyrat\master_files\code\modules\jobs\job_types\mime.dm" +#include "modular_skyrat\master_files\code\modules\jobs\job_types\tarkon.dm" #include "modular_skyrat\master_files\code\modules\language\language.dm" #include "modular_skyrat\master_files\code\modules\language\language_holders.dm" #include "modular_skyrat\master_files\code\modules\mob\dead\new_player\latejoin_menu.dm" @@ -5336,10 +5343,6 @@ #include "modular_skyrat\master_files\code\modules\power\singularity\containment_field.dm" #include "modular_skyrat\master_files\code\modules\projectiles\boxes_magazines\external\shotgun.dm" #include "modular_skyrat\master_files\code\modules\projectiles\boxes_magazines\external\smg.dm" -#include "modular_skyrat\master_files\code\modules\projectiles\guns\ballistic.dm" -#include "modular_skyrat\master_files\code\modules\projectiles\guns\gun.dm" -#include "modular_skyrat\master_files\code\modules\projectiles\guns\ballistic\automatic.dm" -#include "modular_skyrat\master_files\code\modules\projectiles\guns\ballistic\revolver.dm" #include "modular_skyrat\master_files\code\modules\reagents\bottle.dm" #include "modular_skyrat\master_files\code\modules\reagents\reagent_containers.dm" #include "modular_skyrat\master_files\code\modules\reagents\chemistry\colors.dm" @@ -5637,7 +5640,6 @@ #include "modular_skyrat\modules\company_imports\code\armament_component.dm" #include "modular_skyrat\modules\company_imports\code\company_datums.dm" #include "modular_skyrat\modules\company_imports\code\company_subsystem.dm" -#include "modular_skyrat\modules\company_imports\code\gun_companies.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\bolt_nanotrasen_firearms.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\deforest_medical.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\jarnsmiour.dm" @@ -5974,12 +5976,13 @@ #include "modular_skyrat\modules\goofsec\code\hud.dm" #include "modular_skyrat\modules\goofsec\code\sec_clothing_overrides.dm" #include "modular_skyrat\modules\goofsec\code\sol_fed.dm" +#include "modular_skyrat\modules\gun_safety\code\safety_additions.dm" +#include "modular_skyrat\modules\gun_safety\code\safety_component.dm" #include "modular_skyrat\modules\gunhud\code\gun_hud.dm" #include "modular_skyrat\modules\gunhud\code\gun_hud_component.dm" #include "modular_skyrat\modules\gunpoint\code\gunpoint.dm" #include "modular_skyrat\modules\gunpoint\code\gunpoint_datum.dm" #include "modular_skyrat\modules\gunpoint\code\gunpoint_radial.dm" -#include "modular_skyrat\modules\gunsafety\code\gun_safety.dm" #include "modular_skyrat\modules\gunsgalore\code\projectile.dm" #include "modular_skyrat\modules\gunsgalore\code\ammo\ammo.dm" #include "modular_skyrat\modules\gunsgalore\code\guns\akm.dm" @@ -6087,6 +6090,8 @@ #include "modular_skyrat\modules\lorecaster\code\archive_viewer.dm" #include "modular_skyrat\modules\lorecaster\code\config.dm" #include "modular_skyrat\modules\lorecaster\code\subsystem.dm" +#include "modular_skyrat\modules\manufacturer_examine\code\gun_company_additions.dm" +#include "modular_skyrat\modules\manufacturer_examine\code\manufacturer_component.dm" #include "modular_skyrat\modules\mapping\code\airless.dm" #include "modular_skyrat\modules\mapping\code\color.dm" #include "modular_skyrat\modules\mapping\code\doors.dm" @@ -6383,6 +6388,7 @@ #include "modular_skyrat\modules\moretraitoritems\code\glue.dm" #include "modular_skyrat\modules\moretraitoritems\code\headset.dm" #include "modular_skyrat\modules\moretraitoritems\code\mafioso.dm" +#include "modular_skyrat\modules\moretraitoritems\code\ocelot_revolver.dm" #include "modular_skyrat\modules\moretraitoritems\code\smuggling_gear.dm" #include "modular_skyrat\modules\moretraitoritems\code\spawnergrenade.dm" #include "modular_skyrat\modules\moretraitoritems\code\syndicate_loadout.dm" diff --git a/tgui/packages/tgui/interfaces/OreRedemptionMachine.js b/tgui/packages/tgui/interfaces/OreRedemptionMachine.js index 5a387ecb993..df47f2f9452 100644 --- a/tgui/packages/tgui/interfaces/OreRedemptionMachine.js +++ b/tgui/packages/tgui/interfaces/OreRedemptionMachine.js @@ -1,107 +1,223 @@ -import { toTitleCase } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { BlockQuote, Box, Button, NumberInput, Section, Table } from '../components'; +import { createSearch, toTitleCase } from 'common/string'; +import { useBackend, useLocalState, useSharedState } from '../backend'; +import { BlockQuote, Box, Button, Table, Tabs, Input, Stack, Icon, Section, LabeledList } from '../components'; import { Window } from '../layouts'; +import { formatSiUnit } from '../format'; export const OreRedemptionMachine = (props, context) => { const { act, data } = useBackend(context); - const { unclaimedPoints, materials, alloys } = data; + const { unclaimedPoints, materials, user } = data; + const [tab, setTab] = useSharedState(context, 'tab', 1); + const [searchItem, setSearchItem] = useLocalState(context, 'searchItem', ''); + const [compact, setCompact] = useSharedState(context, 'compact', false); + const search = createSearch(searchItem, (materials) => materials.name); + const material_filtered = + searchItem.length > 0 + ? data.materials.filter(search) + : materials.filter((material) => material && material.category === tab); return ( - - -
-
- This machine only accepts ore. -
- Gibtonite and Slag are not accepted. -
- - - Unclaimed points: - - {unclaimedPoints} -
+ + +
+ + + + + Unclaimed points: + + {unclaimedPoints} +
+
+ +
+ This machine only accepts ore. Gibtonite and Slag are not + accepted. +
+
+
+ + { + setTab('material'); + + if (searchItem.length > 0) { + setSearchItem(''); + } + }}> + Materials + + { + setTab('alloy'); + + if (searchItem.length > 0) { + setSearchItem(''); + } + }}> + Alloys + + { + setSearchItem(value); + + if (value.length > 0) { + setTab(1); + } + }} + fluid /> - - -
- - {materials.map((material) => ( - - act('Release', { - id: material.id, - sheets: amount, - }) - } - /> - ))} -
-
-
- - {alloys.map((material) => ( - - act('Smelt', { - id: material.id, - sheets: amount, - }) - } - /> - ))} -
-
+
+ +
+ + {material_filtered.map((material) => ( + { + if (material.category === 'material') { + act('Release', { + id: material.id, + sheets: amount, + }); + } else { + act('Smelt', { + id: material.id, + sheets: amount, + }); + } + }} + /> + ))} +
+
+
+
); }; const MaterialRow = (props, context) => { + const { data } = useBackend(context); + const { material_icons } = data; const { material, onRelease } = props; + const [compact, setCompact] = useLocalState(context, 'compact', false); - const [amount, setAmount] = useLocalState( - context, - 'amount' + material.name, - 1 + const display = material_icons.find( + (mat_icon) => mat_icon.id === material.id ); - const amountAvailable = Math.floor(material.amount); + const print_amount = 5; + const max_sheets = 50; + return ( - - {toTitleCase(material.name).replace('Alloy', '')} - - - {material.value && material.value + ' cr'} + + {!compact && ( + + + + )} + {toTitleCase(material.name)} + + + {formatSiUnit(material.amount, 0)}{' '} + {material.amount === 1 ? 'sheet' : 'sheets'} - - - {amountAvailable} sheets - - - - setAmount(value)} + + }> - {user.selectedChoice && - choice.name === user.selectedChoice && ( + {user.singleSelection && + choice.name === user.singleSelection && ( { ))} - ) : ( - - {currentVote ? 'No choices available!' : 'No vote active!'} - - )} + ) : null} + {currentVote && currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( + Select any number of options + ) : null} + {currentVote && + currentVote.choices.length !== 0 && + currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( + + {currentVote.choices.map((choice) => ( + + c.toUpperCase())} + textAlign="right" + buttons={ + + }> + {user.multiSelection && + user.multiSelection[user.ckey.concat(choice.name)] === 1 ? ( + + ) : null} + {choice.votes} Votes + + + + ))} + + ) : null} + {currentVote ? null : No vote active!} ); diff --git a/tgui/packages/tgui/package.json b/tgui/packages/tgui/package.json index 1d9a9e426c6..74ef5f34624 100644 --- a/tgui/packages/tgui/package.json +++ b/tgui/packages/tgui/package.json @@ -4,7 +4,7 @@ "version": "4.3.1", "dependencies": { "@popperjs/core": "^2.9.3", - "@types/marked": "^4.0.3", + "@types/marked": "^4.0.8", "common": "workspace:*", "dateformat": "^4.5.1", "dompurify": "^2.3.1", @@ -12,7 +12,7 @@ "inferno": "^7.4.8", "inferno-vnode-flags": "^7.4.8", "js-yaml": "^4.1.0", - "marked": "^4.0.10", + "marked": "^4.2.12", "tgui-dev-server": "workspace:*", "tgui-polyfill": "workspace:*" } diff --git a/tgui/yarn.lock b/tgui/yarn.lock index 4d0ddd0ed75..bbfcc1a3a48 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -2003,10 +2003,10 @@ __metadata: languageName: node linkType: hard -"@types/marked@npm:^4.0.3": - version: 4.0.3 - resolution: "@types/marked@npm:4.0.3" - checksum: 2fc409a6291cb770688731a444f54e7eab6257c9b565dea4e9d2f3b6654b606e9dd8ea4a924e306b2d2f581dedcb7a27f10f2ca7aed828b11642ab85955341f1 +"@types/marked@npm:^4.0.8": + version: 4.0.8 + resolution: "@types/marked@npm:4.0.8" + checksum: 68278fa7acaa5d920cdc239d675b5daf842e0ad4779e4848cd617d9baf2ac1afccb5a264c331e37d80031d647e1640cb983cd31e73d45b28552670b4853fad8e languageName: node linkType: hard @@ -6741,12 +6741,12 @@ __metadata: languageName: node linkType: hard -"marked@npm:^4.0.10": - version: 4.0.10 - resolution: "marked@npm:4.0.10" +"marked@npm:^4.2.12": + version: 4.2.12 + resolution: "marked@npm:4.2.12" bin: marked: bin/marked.js - checksum: 46cd8ef1a7cfcf5e461727c7f3e16dd4244369ef58f60485e75d3f5df9d53a8249b9609e96a336521eaa5c88d9531cbd296509a148718056e9375e69609f4442 + checksum: bd551cd61028ee639d4ca2ccdfcc5a6ba4227c1b143c4538f3cde27f569dcb57df8e6313560394645b418b84a7336c07ab1e438b89b6324c29d7d8cdd3102d63 languageName: node linkType: hard @@ -9316,7 +9316,7 @@ resolve@^2.0.0-next.3: resolution: "tgui@workspace:packages/tgui" dependencies: "@popperjs/core": ^2.9.3 - "@types/marked": ^4.0.3 + "@types/marked": ^4.0.8 common: "workspace:*" dateformat: ^4.5.1 dompurify: ^2.3.1 @@ -9324,7 +9324,7 @@ resolve@^2.0.0-next.3: inferno: ^7.4.8 inferno-vnode-flags: ^7.4.8 js-yaml: ^4.1.0 - marked: ^4.0.10 + marked: ^4.2.12 tgui-dev-server: "workspace:*" tgui-polyfill: "workspace:*" languageName: unknown