diff --git a/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm b/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
index cfe522aeb415..bda6fb742d53 100644
--- a/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
+++ b/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
@@ -373,7 +373,7 @@
name = "charge rifle"
},
/obj/item/gun/energy/lasercannon{
- pixel_y = 5;
+ pixel_y = 5
},
/obj/item/gun/energy/lasercannon,
/obj/effect/turf_decal/industrial/hatch,
diff --git a/_maps/RandomRuins/BeachRuins/beach_fishing_hut.dmm b/_maps/RandomRuins/BeachRuins/beach_fishing_hut.dmm
index ea1a18b11c4b..6a81ff12aaac 100644
--- a/_maps/RandomRuins/BeachRuins/beach_fishing_hut.dmm
+++ b/_maps/RandomRuins/BeachRuins/beach_fishing_hut.dmm
@@ -67,6 +67,11 @@
},
/turf/open/water/beach/deep,
/area/overmap_encounter/planetoid/beachplanet/explored)
+"eB" = (
+/obj/item/storage/box/ammo/c38,
+/obj/structure/closet/crate/wooden,
+/turf/open/floor/wood,
+/area/ruin/beach)
"eJ" = (
/obj/effect/turf_decal/siding/wood{
dir = 5
@@ -200,12 +205,6 @@
/obj/structure/railing/corner,
/turf/open/water/beach/deep,
/area/overmap_encounter/planetoid/beachplanet/explored)
-"kj" = (
-/obj/structure/closet/cabinet,
-/obj/item/pneumatic_cannon/speargun,
-/obj/item/melee/knife/hunting,
-/turf/open/floor/wood,
-/area/ruin/beach)
"kr" = (
/obj/effect/turf_decal/weather/sand/corner{
dir = 1
@@ -280,11 +279,6 @@
},
/turf/open/floor/plating/asteroid/sand,
/area/overmap_encounter/planetoid/cave/explored)
-"mq" = (
-/obj/item/ammo_box/c38_box,
-/obj/structure/closet/crate/wooden,
-/turf/open/floor/wood,
-/area/ruin/beach)
"my" = (
/obj/effect/turf_decal/weather/sand{
dir = 5
@@ -745,12 +739,27 @@
},
/turf/open/floor/wood/ebony,
/area/overmap_encounter/planetoid/beachplanet/explored)
+"CJ" = (
+/obj/structure/closet/cabinet,
+/obj/item/pneumatic_cannon/speargun,
+/obj/item/melee/knife/hunting,
+/obj/machinery/light/small/directional/east{
+ light_color = "#d8b1b1"
+ },
+/turf/open/floor/wood,
+/area/ruin/beach)
"CV" = (
/obj/machinery/grill,
/obj/effect/turf_decal/corner/opaque/pink/diagonal,
/obj/effect/decal/cleanable/cobweb,
/turf/open/floor/plastic,
/area/ruin/beach)
+"DG" = (
+/obj/structure/closet/cabinet,
+/obj/item/pneumatic_cannon/speargun,
+/obj/item/melee/knife/hunting,
+/turf/open/floor/wood,
+/area/ruin/beach)
"DL" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -1047,15 +1056,6 @@
/obj/effect/turf_decal/siding/white/corner,
/turf/open/water/beach,
/area/overmap_encounter/planetoid/beachplanet/explored)
-"PB" = (
-/obj/structure/closet/cabinet,
-/obj/item/pneumatic_cannon/speargun,
-/obj/item/melee/knife/hunting,
-/obj/machinery/light/small/directional/east{
- light_color = "#d8b1b1"
- },
-/turf/open/floor/wood,
-/area/ruin/beach)
"PC" = (
/obj/effect/turf_decal/weather/sand{
dir = 10
@@ -2186,9 +2186,9 @@ sz
ut
Ty
oS
-mq
-kj
-PB
+eB
+DG
+CJ
ut
BW
BN
diff --git a/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm b/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
index 997f6bb56703..839e87815f93 100644
--- a/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
+++ b/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
@@ -666,13 +666,8 @@
/obj/structure/table/reinforced{
color = "#c1b6a5"
},
-/obj/item/ammo_box/c38_box{
- pixel_x = 10;
- pixel_y = 8
- },
-/obj/item/ammo_box/c38_box{
- pixel_x = 10
- },
+/obj/item/storage/box/ammo/c38,
+/obj/item/storage/box/ammo/c38,
/obj/structure/sign/poster/contraband/energy_swords{
pixel_x = -32
},
diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm
index 29710e094f64..42aa6b288469 100644
--- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm
+++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm
@@ -383,7 +383,7 @@
"EF" = (
/obj/effect/decal/cleanable/blood/gibs/torso,
/obj/structure/safe,
-/obj/item/ammo_box/a12g/slug,
+/obj/item/storage/box/ammo/a12g_slug,
/obj/item/melee/knife/combat,
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
diff --git a/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm b/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm
index aab9b566f78e..f6efbca453e2 100644
--- a/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm
+++ b/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm
@@ -3050,7 +3050,7 @@
/obj/item/clothing/under/rank/security/officer/blueshirt,
/obj/item/clothing/gloves/combat,
/obj/item/clothing/shoes/jackboots,
-/obj/item/ammo_box/c9mm,
+/obj/item/storage/box/ammo/c9mm,
/obj/machinery/light/small/broken/directional/north,
/obj/effect/turf_decal/corner/transparent/bar/three_quarters{
dir = 4
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm b/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
index 4d63ae26b5bb..8f3921ed0520 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
@@ -92,7 +92,7 @@
name = "armory locker";
req_one_access_txt = "1"
},
-/obj/item/ammo_box/a12g,
+/obj/item/storage/box/ammo/a12g_buckshot,
/turf/open/floor/mineral/plastitanium,
/area/ruin/unpowered/crashed_starwalker)
"bL" = (
@@ -942,7 +942,7 @@
/obj/effect/turf_decal/industrial/outline/yellow,
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/structure/closet/crate/secure/gear,
-/obj/item/ammo_box/c10mm/surplus,
+/obj/item/storage/box/ammo/c10mm_surplus,
/obj/item/weaponcrafting/stock,
/obj/item/weaponcrafting/stock{
pixel_x = -6
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_lava_canyon.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_lava_canyon.dmm
index 92fa7dfb9203..6ad3e8ba7458 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_lava_canyon.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_lava_canyon.dmm
@@ -883,7 +883,7 @@
/area/overmap_encounter/planetoid/lava/explored)
"zb" = (
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner{
- loot = list(/obj/item/melee/transforming/cleaving_saw,/obj/item/gun/energy/kinetic_accelerator,/obj/item/keycard/gatedrop/lavacanyon);
+ loot = list(/obj/item/melee/transforming/cleaving_saw,/obj/item/gun/energy/kinetic_accelerator,/obj/item/keycard/gatedrop/lavacanyon)
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/overmap_encounter/planetoid/cave/explored)
diff --git a/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm b/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm
index ef9240170e41..183df18879da 100644
--- a/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm
+++ b/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm
@@ -2745,7 +2745,7 @@
/area/ruin/rockplanet/nanotrasen)
"WY" = (
/obj/structure/frame/computer{
- dir = 1;
+ dir = 1
},
/obj/effect/turf_decal/corner/opaque/red/diagonal,
/turf/open/floor/plasteel/tech/techmaint,
diff --git a/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm b/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
index 2fd3caa4c42f..3926cffbbf81 100644
--- a/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
+++ b/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
@@ -3086,7 +3086,7 @@
pixel_x = -3
},
/obj/item/ammo_box/magazine/illestren_a850r,
-/obj/item/ammo_box/c9mm/ap,
+/obj/item/storage/box/ammo/c9mm/ap,
/obj/item/ammo_box/magazine/illestren_a850r,
/obj/item/ammo_box/magazine/co9mm{
start_empty = 1
diff --git a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm
index a86efe2e9744..a47ad168fb72 100644
--- a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm
+++ b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm
@@ -1862,10 +1862,7 @@
pixel_x = 5;
pixel_y = 7
},
-/obj/item/ammo_box/foambox/riot{
- pixel_x = -3;
- pixel_y = -3
- },
+/obj/item/storage/box/ammo/foam_darts/riot,
/obj/structure/cable{
icon_state = "4-8"
},
diff --git a/_maps/RandomRuins/SandRuins/whitesands_surface_camp_combination.dmm b/_maps/RandomRuins/SandRuins/whitesands_surface_camp_combination.dmm
index b903fd3cce78..c7b060634951 100644
--- a/_maps/RandomRuins/SandRuins/whitesands_surface_camp_combination.dmm
+++ b/_maps/RandomRuins/SandRuins/whitesands_surface_camp_combination.dmm
@@ -1301,7 +1301,7 @@
"XP" = (
/obj/structure/table,
/obj/item/trash/can,
-/obj/item/ammo_box/c45/surplus,
+/obj/item/storage/box/ammo/c45_surplus,
/turf/open/floor/concrete,
/area/ruin)
"XS" = (
diff --git a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
index 3d05cfb13d35..e126234531f2 100644
--- a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
+++ b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
@@ -2694,8 +2694,8 @@
/obj/structure/closet/crate/secure/weapon{
name = "Ammo Crate"
},
-/obj/item/ammo_box/c9mm/surplus,
-/obj/item/ammo_box/c9mm/surplus,
+/obj/item/storage/box/ammo/c9mm_surplus,
+/obj/item/storage/box/ammo/c9mm_surplus,
/obj/item/ammo_box/magazine/co9mm,
/obj/item/ammo_box/magazine/co9mm,
/turf/open/floor/plasteel,
diff --git a/_maps/RandomRuins/SpaceRuins/spacemall.dmm b/_maps/RandomRuins/SpaceRuins/spacemall.dmm
index db3f30c15f76..6b75031ae8ba 100644
--- a/_maps/RandomRuins/SpaceRuins/spacemall.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacemall.dmm
@@ -320,7 +320,7 @@
/obj/item/toy/talking/AI{
pixel_x = 20
},
-/obj/item/ammo_box/foambox/riot,
+/obj/item/storage/box/ammo/foam_darts/riot,
/obj/item/gun/ballistic/shotgun/toy,
/turf/open/floor/light,
/area/ruin/space/has_grav/spacemall/shop2)
@@ -2434,7 +2434,7 @@
/area/ruin/space/has_grav/spacemall)
"jm" = (
/obj/structure/rack,
-/obj/item/ammo_box/c9mm,
+/obj/item/storage/box/ammo/c9mm,
/obj/item/ammo_box/magazine/co9mm{
pixel_x = 5
},
diff --git a/_maps/RandomRuins/WasteRuins/wasteplanet_lab.dmm b/_maps/RandomRuins/WasteRuins/wasteplanet_lab.dmm
index aa5797d05a95..dba9f5e3c3c9 100644
--- a/_maps/RandomRuins/WasteRuins/wasteplanet_lab.dmm
+++ b/_maps/RandomRuins/WasteRuins/wasteplanet_lab.dmm
@@ -118,13 +118,13 @@
/area/ruin/powered)
"gw" = (
/obj/structure/table,
-/obj/item/ammo_box/c45,
+/obj/item/storage/box/ammo/c45,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel/mono/white,
/area/ruin/powered)
"gx" = (
/obj/structure/table,
-/obj/item/ammo_box/c9mm/rubbershot,
+/obj/item/storage/box/ammo/c9mm_rubber,
/turf/open/floor/plasteel/mono/white,
/area/ruin/powered)
"gz" = (
diff --git a/_maps/RandomRuins/WasteRuins/wasteplanet_pandora.dmm b/_maps/RandomRuins/WasteRuins/wasteplanet_pandora.dmm
index 934b648c0bd6..adab5732e0c1 100644
--- a/_maps/RandomRuins/WasteRuins/wasteplanet_pandora.dmm
+++ b/_maps/RandomRuins/WasteRuins/wasteplanet_pandora.dmm
@@ -23,7 +23,7 @@
/area/ruin/wasteplanet)
"bc" = (
/obj/effect/decal/cleanable/dirt/dust,
-/obj/item/ammo_box/c9mm,
+/obj/item/storage/box/ammo/c9mm,
/turf/open/floor/plating/wasteplanet,
/area/ruin/wasteplanet)
"bd" = (
diff --git a/_maps/shuttles/independent/independent_dwayne.dmm b/_maps/shuttles/independent/independent_dwayne.dmm
index d1cc698c0c92..7f8e7b569c68 100644
--- a/_maps/shuttles/independent/independent_dwayne.dmm
+++ b/_maps/shuttles/independent/independent_dwayne.dmm
@@ -272,9 +272,9 @@
dir = 9
},
/obj/effect/decal/cleanable/dirt,
-/obj/item/ammo_box/c38_box,
-/obj/item/ammo_box/c38_box,
-/obj/item/ammo_box/c38_box,
+/obj/item/storage/box/ammo/c38,
+/obj/item/storage/box/ammo/c38,
+/obj/item/storage/box/ammo/c38,
/obj/structure/closet/crate/secure/plasma{
name = "ammo crate";
desc = "A secure ammo crate."
diff --git a/_maps/shuttles/independent/independent_kilo.dmm b/_maps/shuttles/independent/independent_kilo.dmm
index 35f955ff0b3d..f9504be9d31e 100644
--- a/_maps/shuttles/independent/independent_kilo.dmm
+++ b/_maps/shuttles/independent/independent_kilo.dmm
@@ -661,7 +661,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
dir = 8
},
-/obj/item/ammo_box/a12g/rubbershot,
+/obj/item/storage/box/ammo/a12g_rubbershot,
/obj/item/gun/ballistic/shotgun/doublebarrel/presawn{
spawnwithmagazine = 0
},
@@ -1875,7 +1875,7 @@
icon_state = "9-10"
},
/obj/effect/decal/cleanable/oil,
-/obj/item/ammo_box/a12g,
+/obj/item/storage/box/ammo/a12g_buckshot,
/obj/item/gun/ballistic/shotgun/doublebarrel/no_mag,
/turf/open/floor/plasteel/patterned,
/area/ship/cargo)
diff --git a/_maps/shuttles/independent/independent_rigger.dmm b/_maps/shuttles/independent/independent_rigger.dmm
index d6cb54aed39c..d87ae083832b 100644
--- a/_maps/shuttles/independent/independent_rigger.dmm
+++ b/_maps/shuttles/independent/independent_rigger.dmm
@@ -4132,7 +4132,7 @@
name = "ammunition locker";
req_access_txt = "1"
},
-/obj/item/ammo_box/c38_box,
+/obj/item/storage/box/ammo/c38,
/obj/item/ammo_box/magazine/m45/rubber,
/obj/item/ammo_box/magazine/m45/rubber,
/obj/item/ammo_box/magazine/m45,
diff --git a/_maps/shuttles/independent/independent_shetland.dmm b/_maps/shuttles/independent/independent_shetland.dmm
index 3bf95ea99b6f..75784c301eda 100644
--- a/_maps/shuttles/independent/independent_shetland.dmm
+++ b/_maps/shuttles/independent/independent_shetland.dmm
@@ -3475,7 +3475,7 @@
req_access_txt = "1";
req_ship_access = 1
},
-/obj/item/ammo_box/c38_box,
+/obj/item/storage/box/ammo/c38,
/obj/effect/turf_decal/box,
/obj/item/ammo_box/c38,
/obj/item/ammo_box/c38,
diff --git a/_maps/shuttles/inteq/inteq_hound.dmm b/_maps/shuttles/inteq/inteq_hound.dmm
index da82ccbf26b7..42c34c5a418e 100644
--- a/_maps/shuttles/inteq/inteq_hound.dmm
+++ b/_maps/shuttles/inteq/inteq_hound.dmm
@@ -50,10 +50,7 @@
pixel_x = -11;
pixel_y = 5
},
-/obj/item/ammo_box/a762_40/inteq{
- pixel_x = 5;
- pixel_y = 12
- },
+/obj/item/storage/box/ammo/a762_40/inteq,
/obj/item/reagent_containers/food/drinks/bottle/whiskey{
pixel_x = -7;
pixel_y = 6
diff --git a/_maps/shuttles/inteq/inteq_valor.dmm b/_maps/shuttles/inteq/inteq_valor.dmm
index 3f709a261b15..d35bcb7a808a 100644
--- a/_maps/shuttles/inteq/inteq_valor.dmm
+++ b/_maps/shuttles/inteq/inteq_valor.dmm
@@ -5074,14 +5074,8 @@
/obj/effect/turf_decal/corner/opaque/yellow,
/obj/structure/rack,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4,
-/obj/item/ammo_box/c9mm/rubbershot{
- pixel_x = 5;
- pixel_y = 10
- },
-/obj/item/ammo_box/c9mm{
- pixel_x = -2;
- pixel_y = 2
- },
+/obj/item/storage/box/ammo/c9mm_rubber,
+/obj/item/storage/box/ammo/c9mm,
/obj/machinery/light/small/directional/north,
/obj/structure/sign/poster/official/safety_report{
pixel_x = 32
diff --git a/_maps/shuttles/nanotrasen/nanotrasen_harrier.dmm b/_maps/shuttles/nanotrasen/nanotrasen_harrier.dmm
index 9e5d93f7af77..72bd430d743b 100644
--- a/_maps/shuttles/nanotrasen/nanotrasen_harrier.dmm
+++ b/_maps/shuttles/nanotrasen/nanotrasen_harrier.dmm
@@ -5189,9 +5189,9 @@
/obj/item/reagent_containers/spray/pepper,
/obj/item/ammo_box/magazine/co9mm,
/obj/item/ammo_box/magazine/co9mm,
-/obj/item/ammo_box/c9mm,
-/obj/item/ammo_box/c9mm,
-/obj/item/ammo_box/c9mm/rubbershot,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm_rubber,
/obj/effect/turf_decal/trimline/opaque/vired/line,
/obj/item/storage/belt/security,
/obj/item/melee/knife/survival,
diff --git a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm
index a5673c22d7bc..a02ec78fc9e6 100644
--- a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm
+++ b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm
@@ -13072,22 +13072,10 @@
pixel_x = 5;
pixel_y = 4
},
-/obj/item/ammo_box/c9mm{
- pixel_x = 4;
- pixel_y = -6
- },
-/obj/item/ammo_box/c9mm{
- pixel_x = 4;
- pixel_y = 1
- },
-/obj/item/ammo_box/c9mm{
- pixel_x = 4;
- pixel_y = 9
- },
-/obj/item/ammo_box/c9mm/ap{
- pixel_y = 17;
- pixel_x = 4
- },
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm/ap,
/obj/item/stock_parts/cell/gun{
pixel_x = -3;
pixel_y = -5
diff --git a/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm b/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm
index 07b8722e5e7b..d70424c08c84 100644
--- a/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm
+++ b/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm
@@ -1750,11 +1750,11 @@
/obj/structure/chair/handrail{
dir = 4
},
-/obj/item/ammo_box/c9mm,
-/obj/item/ammo_box/c9mm,
-/obj/item/ammo_box/c9mm/rubbershot,
-/obj/item/ammo_box/c9mm,
-/obj/item/ammo_box/c9mm,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm_rubber,
+/obj/item/storage/box/ammo/c9mm,
+/obj/item/storage/box/ammo/c9mm,
/obj/effect/turf_decal/siding/thinplating/dark{
dir = 10
},
diff --git a/_maps/shuttles/pirate/pirate_tortuga.dmm b/_maps/shuttles/pirate/pirate_tortuga.dmm
index fc08d44db510..3e48d25a962c 100644
--- a/_maps/shuttles/pirate/pirate_tortuga.dmm
+++ b/_maps/shuttles/pirate/pirate_tortuga.dmm
@@ -667,10 +667,7 @@
/area/ship/security/armory)
"hU" = (
/obj/structure/rack,
-/obj/item/ammo_box/c45{
- pixel_x = -9;
- pixel_y = 8
- },
+/obj/item/storage/box/ammo/c45,
/obj/item/storage/toolbox/ammo/a762_40{
pixel_x = 5;
pixel_y = 6
@@ -3141,7 +3138,7 @@
/obj/item/clothing/shoes/jackboots{
pixel_y = -13
},
-/obj/item/ammo_box/c38_box/surplus,
+/obj/item/storage/box/ammo/c38_surplus,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/carpet/nanoweave,
/area/ship/crew/crewtwo)
diff --git a/_maps/shuttles/roumain/srm_elder.dmm b/_maps/shuttles/roumain/srm_elder.dmm
index 0e501c62ed57..23c64f4681a6 100644
--- a/_maps/shuttles/roumain/srm_elder.dmm
+++ b/_maps/shuttles/roumain/srm_elder.dmm
@@ -337,18 +337,12 @@
pixel_y = 14;
pixel_x = 5
},
-/obj/item/ammo_box/c38_box{
- pixel_x = -6;
- pixel_y = 7
- },
+/obj/item/storage/box/ammo/c38,
/obj/item/ammo_box/magazine/illestren_a850r{
pixel_x = 8;
pixel_y = 6
},
-/obj/item/ammo_box/c38_box{
- pixel_x = -6;
- pixel_y = 1
- },
+/obj/item/storage/box/ammo/c38,
/obj/item/ammo_box/magazine/illestren_a850r{
pixel_x = 8
},
@@ -2025,7 +2019,7 @@
pixel_x = -7
},
/obj/item/storage/backpack/satchel/leather,
-/obj/item/ammo_box/a44roum,
+/obj/item/storage/box/ammo/a44roum,
/obj/item/storage/pistolcase/montagne,
/obj/item/clothing/accessory/waistcoat/roumain,
/turf/open/floor/wood/mahogany,
@@ -2698,7 +2692,7 @@
/obj/item/gun/ballistic/revolver/detective,
/obj/item/ammo_box/c38,
/obj/item/ammo_box/c38,
-/obj/item/ammo_box/c38_box,
+/obj/item/storage/box/ammo/c38,
/obj/item/clothing/head/cowboy/sec/roumain/colligne,
/obj/item/clothing/suit/armor/roumain/colligne,
/obj/structure/closet/secure_closet/collignes,
diff --git a/_maps/shuttles/solgov/solgov_chronicle.dmm b/_maps/shuttles/solgov/solgov_chronicle.dmm
index bacabd6cc23c..f08281a47103 100644
--- a/_maps/shuttles/solgov/solgov_chronicle.dmm
+++ b/_maps/shuttles/solgov/solgov_chronicle.dmm
@@ -273,7 +273,7 @@
/obj/item/spacecash/bundle/loadsamoney,
/obj/item/clothing/neck/cloak/solgovcap,
/obj/item/storage/pistolcase/modelh,
-/obj/item/ammo_box/ferroslugbox,
+/obj/item/storage/box/ammo/ferroslug,
/turf/open/floor/carpet/royalblue,
/area/ship/crew/office)
"cg" = (
diff --git a/_maps/shuttles/solgov/solgov_inkwell.dmm b/_maps/shuttles/solgov/solgov_inkwell.dmm
index 27427f9bbfa2..1a38d735246b 100644
--- a/_maps/shuttles/solgov/solgov_inkwell.dmm
+++ b/_maps/shuttles/solgov/solgov_inkwell.dmm
@@ -5934,7 +5934,7 @@
/obj/item/pen/fountain/solgov,
/obj/item/clothing/neck/cloak/solgovcap,
/obj/item/storage/pistolcase/modelh,
-/obj/item/ammo_box/ferroslugbox,
+/obj/item/storage/box/ammo/ferroslug,
/turf/open/floor/wood/maple,
/area/ship/crew/dorm/dormtwo)
"LJ" = (
diff --git a/_maps/shuttles/solgov/solgov_paracelsus.dmm b/_maps/shuttles/solgov/solgov_paracelsus.dmm
index 9cfda7a14c0d..e062f70d011d 100644
--- a/_maps/shuttles/solgov/solgov_paracelsus.dmm
+++ b/_maps/shuttles/solgov/solgov_paracelsus.dmm
@@ -3582,7 +3582,7 @@
/obj/item/pen/fountain/solgov,
/obj/item/clothing/neck/cloak/solgovcap,
/obj/item/storage/pistolcase/modelh,
-/obj/item/ammo_box/ferroslugbox,
+/obj/item/storage/box/ammo/ferroslug,
/turf/open/floor/carpet/royalblue,
/area/ship/crew)
"IZ" = (
diff --git a/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm b/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm
index 66133d79d47a..84ace94a70a2 100644
--- a/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm
+++ b/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm
@@ -65,7 +65,7 @@
/obj/item/ammo_box/a357/match,
/obj/item/pen/edagger,
/obj/item/storage/pistolcase/a357,
-/obj/item/ammo_box/a357_box,
+/obj/item/storage/box/ammo/a357,
/turf/open/floor/carpet/black,
/area/ship/bridge)
"bJ" = (
@@ -301,8 +301,8 @@
/obj/effect/decal/cleanable/dirt/dust,
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/industrial/outline,
-/obj/item/ammo_box/a12g,
-/obj/item/ammo_box/c10mm,
+/obj/item/storage/box/ammo/a12g_buckshot,
+/obj/item/storage/box/ammo/c10mm,
/turf/open/floor/mineral/plastitanium,
/area/ship/security/armory)
"fC" = (
diff --git a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm
index c466f5351f9c..4b42a90bbb26 100644
--- a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm
+++ b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm
@@ -5387,7 +5387,7 @@
},
/obj/item/ammo_box/magazine/m10mm_ringneck,
/obj/item/ammo_box/magazine/m10mm_ringneck,
-/obj/item/ammo_box/c10mm,
+/obj/item/storage/box/ammo/c10mm,
/obj/item/clothing/gloves/tackler/combat/insulated,
/obj/structure/closet/secure_closet/wall/directional/west{
icon_state = "sec_wall";
diff --git a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm
index 29f4bc28922b..3a3438c8f2f8 100644
--- a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm
+++ b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm
@@ -7376,7 +7376,7 @@
},
/obj/item/storage/belt/sabre/solgov,
/obj/item/storage/pistolcase/modelh,
-/obj/item/ammo_box/ferroslugbox,
+/obj/item/storage/box/ammo/ferroslug,
/turf/open/floor/mineral/plastitanium,
/area/ship/bridge)
"Qv" = (
@@ -8879,7 +8879,7 @@
name = "Armory Access";
req_access = list(3,150)
},
-/obj/item/ammo_box/c10mm,
+/obj/item/storage/box/ammo/c10mm,
/turf/open/floor/mineral/plastitanium,
/area/ship/security)
"YJ" = (
diff --git a/code/__DEFINES/radiation.dm b/code/__DEFINES/radiation.dm
index 2c4e41f45906..fa66e7c3ea8e 100644
--- a/code/__DEFINES/radiation.dm
+++ b/code/__DEFINES/radiation.dm
@@ -57,3 +57,15 @@ Ask ninjanomnom if they're around
#define RAD_DISTANCE_COEFFICIENT 1 // Lower means further rad spread
#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
+
+#define RAD_GLOW_COLOR "#39ff1430"
+
+#define RAD_LEVEL_NORMAL 9
+#define RAD_LEVEL_MODERATE 100
+#define RAD_LEVEL_HIGH 400
+#define RAD_LEVEL_VERY_HIGH 800
+#define RAD_LEVEL_CRITICAL 1500
+
+#define RAD_MEASURE_SMOOTHING 5
+
+#define RAD_GRACE_PERIOD 2
diff --git a/code/__DEFINES/storage.dm b/code/__DEFINES/storage.dm
index cb657520e33f..f8f7e1f10c5b 100644
--- a/code/__DEFINES/storage.dm
+++ b/code/__DEFINES/storage.dm
@@ -44,9 +44,9 @@
// PLEASE KEEP ALL VOLUME DEFINES IN THIS FILE, it's going to be hell to keep track of them later.
#define DEFAULT_VOLUME_TINY 1
#define DEFAULT_VOLUME_SMALL 2
-#define DEFAULT_VOLUME_NORMAL 6
-#define DEFAULT_VOLUME_BULKY 12
-#define DEFAULT_VOLUME_HUGE 24
+#define DEFAULT_VOLUME_NORMAL 8
+#define DEFAULT_VOLUME_BULKY 14
+#define DEFAULT_VOLUME_HUGE 28
#define DEFAULT_VOLUME_GIGANTIC 48
GLOBAL_LIST_INIT(default_weight_class_to_volume, list(
@@ -80,9 +80,9 @@ GLOBAL_LIST_INIT(default_weight_class_to_volume, list(
#define MAX_WEIGHT_CLASS_DUFFEL WEIGHT_CLASS_BULKY
// max_volume for storages
-#define STORAGE_VOLUME_CONTAINER_S DEFAULT_VOLUME_NORMAL //3 small items
-#define STORAGE_VOLUME_CONTAINER_M (DEFAULT_VOLUME_NORMAL * 2) //6 small items
+#define STORAGE_VOLUME_CONTAINER_S DEFAULT_VOLUME_NORMAL //4 small items
+#define STORAGE_VOLUME_CONTAINER_M (DEFAULT_VOLUME_NORMAL * 2) //8 small items
#define STORAGE_VOLUME_SATCHEL (DEFAULT_VOLUME_NORMAL * 4) //4 normal items
-#define STORAGE_VOLUME_BACKPACK (DEFAULT_VOLUME_NORMAL * 6) //6 normal items, or 3 bulky items
+#define STORAGE_VOLUME_BACKPACK (DEFAULT_VOLUME_NORMAL * 6) //1.5x satchel, 3 bulky items
#define STORAGE_VOLUME_DUFFLEBAG (DEFAULT_VOLUME_NORMAL * 8) // 2 huge items, or 4 bulky items
#define STORAGE_VOLUME_BAG_OF_HOLDING (DEFAULT_VOLUME_NORMAL * 9) //1.5X backpack
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 54874bc9e16b..1155ea88bed9 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -130,6 +130,7 @@
#define INIT_ORDER_ATOMS 30
#define INIT_ORDER_LANGUAGE 25
#define INIT_ORDER_MACHINES 20
+#define INIT_ORDER_TURRETS 17
#define INIT_ORDER_SKILLS 15
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 664e6cc687f7..6de819c57aa5 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -259,6 +259,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_DWARF "dwarf"
#define TRAIT_FASTMED "fast_med_use"
#define TRAIT_SILENT_FOOTSTEPS "silent_footsteps" //makes your footsteps completely silent
+#define TRAIT_PAIN_RESIST "pain_resistance" //you resist pain
#define TRAIT_NICE_SHOT "nice_shot" //hnnnnnnnggggg..... you're pretty good....
/// The holder of this trait has antennae or whatever that hurt a ton when noogied
#define TRAIT_ANTENNAE "antennae"
@@ -329,6 +330,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_BALD "bald"
#define TRAIT_BADTOUCH "bad_touch"
#define TRAIT_ANXIOUS "anxious"
+#define TRAIT_ANALGESIA "congenital_analgesia"
/// Trait granted by lipstick
#define LIPSTICK_TRAIT "lipstick_trait"
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 602473b6086d..e52d9af56251 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -92,6 +92,7 @@
#define VV_HK_AUTO_RENAME "auto_rename"
#define VV_HK_RADIATE "radiate"
#define VV_HK_EDIT_FILTERS "edit_filters"
+#define VV_HK_SELL "sell_item"
#define VV_HK_EDIT_PARTICLES "edit_particles"
// /obj
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index e8cd514eb48b..b64dab12d301 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -160,8 +160,6 @@ SUBSYSTEM_DEF(throwing)
finalize()
return
- dist_travelled++
-
if(actual_target && !(actual_target.pass_flags_self & LETPASSTHROW) && actual_target.loc == AM.loc) // we crossed a movable with no density (e.g. a mouse or APC) we intend to hit anyway.
finalize(TRUE, actual_target)
return
diff --git a/code/controllers/subsystem/turrets.dm b/code/controllers/subsystem/turrets.dm
new file mode 100644
index 000000000000..634f6327e458
--- /dev/null
+++ b/code/controllers/subsystem/turrets.dm
@@ -0,0 +1,41 @@
+SUBSYSTEM_DEF(turrets)
+ name = "Turrets"
+ wait = 5
+ init_order = INIT_ORDER_MACHINES
+ flags = SS_KEEP_TIMING
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+ var/list/processing = list()
+ var/list/currentrun = list()
+
+/datum/controller/subsystem/turrets/get_metrics()
+ . = ..()
+ var/list/cust = list()
+ cust["processing"] = length(processing)
+ .["custom"] = cust
+
+/datum/controller/subsystem/turrets/stat_entry(msg)
+ msg = "M:[length(processing)]]"
+ return ..()
+
+
+/datum/controller/subsystem/turrets/fire(resumed = 0)
+ if (!resumed)
+ src.currentrun = processing.Copy()
+
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+
+ var/seconds = wait * 0.1
+ while(currentrun.len)
+ var/obj/machinery/thing = currentrun[currentrun.len]
+ currentrun.len--
+ if(QDELETED(thing) || thing.process(seconds) == PROCESS_KILL)
+ processing -= thing
+ if (!QDELETED(thing))
+ thing.datum_flags &= ~DF_ISPROCESSING
+ if (MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/turrets/Recover()
+ if (istype(SSturrets.processing))
+ processing = SSmachines.processing
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index 9c10c6f1fd7d..339767dceb2c 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -110,6 +110,7 @@
/datum/brain_trauma/mild/healthy/on_gain()
owner.set_screwyhud(SCREWYHUD_HEALTHY)
+ ADD_TRAIT(owner, TRAIT_ANALGESIA, type)
..()
/datum/brain_trauma/mild/healthy/on_life()
@@ -119,6 +120,7 @@
/datum/brain_trauma/mild/healthy/on_lose()
owner.set_screwyhud(SCREWYHUD_NONE)
+ REMOVE_TRAIT(owner, TRAIT_ANALGESIA, type)
..()
/datum/brain_trauma/mild/muscle_weakness
diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm
index ee789d3f9829..018321094283 100644
--- a/code/datums/components/embedded.dm
+++ b/code/datums/components/embedded.dm
@@ -205,7 +205,7 @@
if(harmful)
var/damage = weapon.w_class * remove_pain_mult
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) //It hurts to rip it out, get surgery you dingus.
- victim.emote("scream")
+ victim.force_scream()
victim.visible_message("[victim] successfully rips [weapon] out of [victim.p_their()] [limb.name]!", "You successfully remove [weapon] from your [limb.name].")
else
victim.visible_message("[victim] successfully rips [weapon] off of [victim.p_their()] [limb.name]!", "You successfully remove [weapon] from your [limb.name].")
diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm
index a6c67af2d3cd..9306f6aae899 100644
--- a/code/datums/components/radioactive.dm
+++ b/code/datums/components/radioactive.dm
@@ -30,7 +30,7 @@
//Let's make er glow
//This relies on parent not being a turf or something. IF YOU CHANGE THAT, CHANGE THIS
var/atom/movable/master = parent
- master.add_filter("rad_glow", 2, list("type" = "outline", "color" = "#39ff1430", "size" = 2))
+ master.add_filter("rad_glow", 2, list("type" = "outline", "color" = RAD_GLOW_COLOR, "size" = 2))
addtimer(CALLBACK(src, PROC_REF(glow_loop), master), rand(1,19))//Things should look uneven
START_PROCESSING(SSradiation, src)
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index 0d3d520c2b54..4d3d07576cc0 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -376,7 +376,7 @@
user.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
playsound(user, 'sound/effects/blobattack.ogg', 60, TRUE)
playsound(user, 'sound/effects/splat.ogg', 70, TRUE)
- user.emote("scream")
+ user.force_scream()
user.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic) // oopsie indeed!
shake_camera(user, 7, 7)
user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash)
diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm
index ea607f2a31fc..df39c5f06591 100644
--- a/code/datums/diseases/advance/symptoms/deafness.dm
+++ b/code/datums/diseases/advance/symptoms/deafness.dm
@@ -55,7 +55,7 @@ Bonus
if(istype(ears) && ears.damage < ears.maxHealth)
to_chat(M, "Your ears pop painfully and start bleeding!")
ears.damage = max(ears.damage, ears.maxHealth)
- M.emote("scream")
+ M.force_scream()
else
to_chat(M, "Your ears pop and begin ringing loudly!")
M.minimumDeafTicks(20)
diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm
index aeb9933debbd..98391edbdf1c 100644
--- a/code/datums/diseases/advance/symptoms/fire.dm
+++ b/code/datums/diseases/advance/symptoms/fire.dm
@@ -60,12 +60,12 @@ Bonus
Firestacks_stage_4(M, A)
M.IgniteMob()
to_chat(M, "Your skin bursts into flames!")
- M.emote("scream")
+ M.force_scream()
if(5)
Firestacks_stage_5(M, A)
M.IgniteMob()
to_chat(M, "Your skin erupts into an inferno!")
- M.emote("scream")
+ M.force_scream()
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
M.adjust_fire_stacks(1 * power)
@@ -147,7 +147,7 @@ Bonus
Alkali_fire_stage_4(M, A)
M.IgniteMob()
to_chat(M, "Your sweat bursts into flames!")
- M.emote("scream")
+ M.force_scream()
if(5)
if(M.fire_stacks < 0)
M.visible_message("[M]'s sweat sizzles and pops on contact with water!")
@@ -155,7 +155,7 @@ Bonus
Alkali_fire_stage_5(M, A)
M.IgniteMob()
to_chat(M, "Your skin erupts into an inferno!")
- M.emote("scream")
+ M.force_scream()
/datum/symptom/alkali/proc/Alkali_fire_stage_4(mob/living/M, datum/disease/advance/A)
var/get_stacks = 6 * power
diff --git a/code/datums/diseases/gastrolisis.dm b/code/datums/diseases/gastrolisis.dm
index e2af13bd6742..ed4c5267d14f 100644
--- a/code/datums/diseases/gastrolisis.dm
+++ b/code/datums/diseases/gastrolisis.dm
@@ -36,7 +36,7 @@
new_eyes.Insert(affected_mob, drop_if_replaced = TRUE)
affected_mob.visible_message("[affected_mob]'s eyes fall out, with snail eyes taking its place!", \
"You scream in pain as your eyes are pushed out by your new snail eyes!")
- affected_mob.emote("scream")
+ affected_mob.force_scream()
return
var/obj/item/organ/tongue/tongue = locate(/obj/item/organ/tongue/snail) in affected_mob.internal_organs
if(!tongue && prob(5))
diff --git a/code/datums/elements/world_icon.dm b/code/datums/elements/world_icon.dm
index bcb0129c6c68..31e52ee7677f 100644
--- a/code/datums/elements/world_icon.dm
+++ b/code/datums/elements/world_icon.dm
@@ -103,7 +103,7 @@
SIGNAL_HANDLER
if(!world_icon_state)
- source.icon_state = source.icon_state
+ source.icon_state = source.item_state
return
INVOKE_ASYNC(src, PROC_REF(check_world_icon_state), source)
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index e504bfee31d5..306c3d6b8d50 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -642,6 +642,25 @@
return
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "wrong_cigs", /datum/mood_event/wrong_brand)
+/datum/quirk/congenital_analgesia
+ name = "Congenital Analgesia"
+ desc = "Due to a rare condition, you have never felt pain. Physical pain, at least. That breakup still hurt."
+ value = -1
+ mob_traits = list(TRAIT_ANALGESIA)
+ gain_text = "You've never really felt pain."
+ lose_text = "...Oh god, you're sore."
+ medical_record_text = "Patient is unable to process pain"
+
+/datum/quirk/congenital_analgesia/on_spawn()
+ var/mob/living/carbon/human/H = quirk_holder
+ H.set_screwyhud(SCREWYHUD_HEALTHY)
+
+/datum/quirk/congenital_analgesia/remove()
+ if(quirk_holder)
+ var/mob/living/carbon/human/H = quirk_holder
+ H.set_screwyhud(SCREWYHUD_NONE)
+
+
/datum/quirk/unstable
name = "Unstable"
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index e7c9c19325a6..84744a9187d6 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1067,6 +1067,7 @@
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion")
VV_DROPDOWN_OPTION(VV_HK_RADIATE, "Radiate")
VV_DROPDOWN_OPTION(VV_HK_EDIT_FILTERS, "Edit Filters")
+ VV_DROPDOWN_OPTION(VV_HK_SELL, "Export Item")
/atom/vv_do_topic(list/href_list)
. = ..()
@@ -1138,6 +1139,9 @@
var/client/C = usr.client
C?.open_filter_editor(src)
+ if(href_list[VV_HK_SELL] && check_rights(R_ADMIN|R_DEBUG) && check_rights(R_VAREDIT))
+ export_item_and_contents(src, allowed_categories = ALL, apply_elastic = FALSE)
+
/atom/vv_get_header()
. = ..()
var/refid = REF(src)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 2d76d7ecb351..594aeedbe43d 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -167,16 +167,7 @@
if(abandoned)
var/outcome = rand(1,100)
switch(outcome)
- if(1 to 9)
- var/turf/here = get_turf(src)
- for(var/turf/closed/T in range(2, src))
- here.PlaceOnTop(T.type)
- qdel(src)
- return
- here.PlaceOnTop(/turf/closed/wall)
- qdel(src)
- return
- if(9 to 11)
+ if(1 to 11)
lights = FALSE
locked = TRUE
if(12 to 15)
@@ -185,6 +176,19 @@
welded = TRUE
if(24 to 30)
panel_open = TRUE
+ if(31 to 40)
+ panel_open = TRUE
+ set_electrified(MACHINE_ELECTRIFIED_PERMANENT)
+ if(41 to 50)
+ seal = new /obj/item/door_seal(src)
+ modify_max_integrity(max_integrity * AIRLOCK_SEAL_MULTIPLIER)
+ if(51 to 60)
+ new previous_airlock(loc)
+ qdel(src)
+ if(69)
+ new /obj/effect/decal/cleanable/oil/slippery(loc)
+
+
update_appearance()
/obj/machinery/door/airlock/ComponentInitialize()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 737bacbb650f..7c8371809e81 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -395,7 +395,7 @@
L.manual_emote("roar")
else if(ishuman(L)) //For humans
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
- L.manual_emote("scream")
+ L.force_manual_scream()
L.Paralyze(100)
else if(ismonkey(L)) //For monkeys
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index 1b0093458e49..22ff32ac3655 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -121,7 +121,7 @@
target = get_turf(src)
for(var/obj/item/bodypart/BP in operation_order) //first we do non-essential limbs
BP.drop_limb()
- C.emote("scream")
+ C.force_scream()
if(BP.body_zone != "chest")
BP.forceMove(target) //Move the limbs right next to it, except chest, that's a weird one
BP.drop_organs()
diff --git a/code/game/machinery/outpost_electrolyzer.dm b/code/game/machinery/outpost_electrolyzer.dm
index b91160c7e1c8..78711accb242 100644
--- a/code/game/machinery/outpost_electrolyzer.dm
+++ b/code/game/machinery/outpost_electrolyzer.dm
@@ -136,7 +136,7 @@
playsound(src, 'sound/effects/splat.ogg', 50, TRUE)
if(iscarbon(L) && L.stat == CONSCIOUS)
- L.emote("scream")
+ L.force_scream()
// Instantly lie down, also go unconscious from the pain, before you die.
L.Unconscious(100)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 5c592c7409dd..c3c39c72e34a 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -41,6 +41,7 @@ DEFINE_BITFIELD(turret_flags, list(
integrity_failure = 0.5
armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
base_icon_state = "standard"
+ subsystem_type = /datum/controller/subsystem/turrets
/// Scan range of the turret for locating targets
var/scan_range = 7
/// For turrets inside other objects
@@ -77,7 +78,7 @@ DEFINE_BITFIELD(turret_flags, list(
var/has_cover = TRUE
/// The cover that is covering this turret
var/obj/machinery/porta_turret_cover/cover = null
- /// Ticks until next shot (1.5 ?)
+ /// Ticks until next shot (1.5 ?) If this needs to go below 5, use SSFastProcess
var/shot_delay = 15
/// Turret flags about who is turret allowed to shoot
var/turret_flags = TURRET_FLAG_SHOOT_CRIMINALS | TURRET_FLAG_SHOOT_ANOMALOUS
@@ -798,12 +799,13 @@ DEFINE_BITFIELD(turret_flags, list(
/obj/machinery/porta_turret/ship
installation = null
- max_integrity = 300
+ max_integrity = 200
always_up = 1
use_power = ACTIVE_POWER_USE
active_power_usage = ACTIVE_DRAW_MINIMAL
has_cover = 0
scan_range = 9
+ req_ship_access = TRUE
stun_projectile = /obj/projectile/beam/disabler
lethal_projectile = /obj/projectile/beam/laser
lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg'
@@ -824,7 +826,7 @@ DEFINE_BITFIELD(turret_flags, list(
. = ..()
if(in_range(user, src) || isobserver(user))
if(!(machine_stat & BROKEN))
- . += "Its reports that it's integrity is currently [(obj_integrity / max_integrity) * 100] percent."
+ . += "[src] reports its integrity is currently [round(obj_integrity / max_integrity) * 100] percent."
/obj/machinery/porta_turret/ship/weak
max_integrity = 120
@@ -849,6 +851,8 @@ DEFINE_BITFIELD(turret_flags, list(
name = "Sharplite Defense Turret"
desc = "A cheap and effective turret designed by Sharplite and purchased and installed on most Nanotrasen Vessels."
faction = list(FACTION_PLAYER_NANOTRASEN, "turret")
+ max_integrity = 160
+ integrity_failure = 0.6
icon_state = "standard_lethal"
base_icon_state = "standard"
stun_projectile = /obj/projectile/beam/disabler/sharplite
@@ -866,20 +870,19 @@ DEFINE_BITFIELD(turret_flags, list(
lethal_projectile_sound = 'sound/weapons/gun/laser/nt-fire.ogg'
stun_projectile_sound = 'sound/weapons/taser2.ogg'
-
/obj/machinery/porta_turret/ship/nt/heavy
name = "Sharplite Defense Cannon"
desc = "A heavy laser mounting designed by Sharplite for usage on Nanotrasen vessels."
lethal_projectile = /obj/projectile/beam/laser/heavylaser/sharplite
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
+ max_integrity = 250
/obj/machinery/porta_turret/ship/nt/pulse
name = "Sharplite Pulse Cannon"
desc = "A pulse cannon mounting designed by Sharplite. Not sold to any purchasers and exclusively used on Nanotrasen Vessels."
lethal_projectile = /obj/projectile/beam/pulse/sharplite_turret
lethal_projectile_sound = 'sound/weapons/gun/laser/heavy_laser.ogg'
-
-
+ max_integrity = 250
/* Syndicate Turrets */
@@ -903,8 +906,10 @@ DEFINE_BITFIELD(turret_flags, list(
stun_projectile_sound = 'sound/weapons/taser.ogg'
lethal_projectile = /obj/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
+ max_integrity = 300
/* Inteq Turrets */
+//slower rof, higher damage + range
/obj/machinery/porta_turret/ship/inteq
name = "Vanguard Turret"
@@ -913,8 +918,9 @@ DEFINE_BITFIELD(turret_flags, list(
stun_projectile_sound = 'sound/weapons/gun/rifle/skm.ogg'
lethal_projectile = /obj/projectile/bullet/a762_40
lethal_projectile_sound = 'sound/weapons/gun/rifle/skm.ogg'
- scan_range = 8
+ scan_range = 9
shot_delay = 20
+ integrity_failure = 0.4
faction = list(FACTION_PLAYER_INTEQ, "turret")
/obj/machinery/porta_turret/ship/inteq/light
@@ -925,7 +931,7 @@ DEFINE_BITFIELD(turret_flags, list(
lethal_projectile = /obj/projectile/bullet/c10mm
lethal_projectile_sound = 'sound/weapons/gun/smg/vector_fire.ogg'
subsystem_type = /datum/controller/subsystem/processing/fastprocess //turns out if you have a shot delay below what SSmachines fires at you need to use a different subsystem
- scan_range = 4
+ scan_range = 5
shot_delay = 5
/obj/machinery/porta_turret/ship/inteq/heavy
@@ -944,6 +950,7 @@ DEFINE_BITFIELD(turret_flags, list(
faction = list(FACTION_PLAYER_SOLCON, "turret")
/* Pan Gezena Federation Turrets */
+//midline but hitscan
/obj/machinery/porta_turret/ship/pgf
name = "Etherbor Defensive Mount"
@@ -955,6 +962,8 @@ DEFINE_BITFIELD(turret_flags, list(
lethal_projectile_sound = 'sound/weapons/gun/energy/kalixsmg.ogg'
icon_state = "standard_lethal"
base_icon_state = "standard"
+ max_integrity = 250
+ integrity_failure = 0.4
/obj/machinery/porta_turret/ship/pgf/light
name = "Etherbor Deterrent System"
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index f6be0b0a036e..ea6633370147 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -450,7 +450,7 @@
mob_occupant.adjustFireLoss(rand(20, 36))
else
mob_occupant.adjustFireLoss(rand(10, 16))
- mob_occupant.emote("scream")
+ mob_occupant.force_scream()
addtimer(CALLBACK(src, PROC_REF(cook)), 50)
else
uv_cycles = (BASE_UV_CYCLES - lasers_bonus)
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index da5a006de0b5..b75f97102904 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -85,7 +85,7 @@
update_appearance()
playsound(src.loc, 'sound/items/welder.ogg', 50, TRUE)
- H.emote("scream") // It is painful
+ H.force_scream() // It is painful
H.adjustBruteLoss(max(0, 80 - H.getBruteLoss())) // Hurt the human, don't try to kill them though.
// Sleep for a couple of ticks to allow the human to see the pain
diff --git a/code/game/mecha/equipment/weapons/mecha_ammo.dm b/code/game/mecha/equipment/weapons/mecha_ammo.dm
index 0febe3327cb6..9e5c6732d1cb 100644
--- a/code/game/mecha/equipment/weapons/mecha_ammo.dm
+++ b/code/game/mecha/equipment/weapons/mecha_ammo.dm
@@ -83,7 +83,7 @@
/obj/item/mecha_ammo/tank_shell
name = "anti-armor missile"
desc = "A large missle, intended to be loaded into a Type 207."
- icon = 'icons/obj/ammo_bullets.dmi'
+ icon = 'icons/obj/ammunition/ammo_bullets.dmi'
icon_state = "srm-8"
rounds = 1
throw_range = 0
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 90669dde84bb..3f7a43fe317b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -26,6 +26,14 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
///Icon file for right inhand overlays
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
+ ///If set it will add a world icon using item_state
+ var/world_file
+
+ ///Handled by world_icon element
+ var/world_state
+ ///Handled by world_icon element
+ var/inventory_state
+
///This is a bitfield that defines what variations exist for bodyparts like Digi legs.
var/supports_variations = null
@@ -207,10 +215,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
var/canMouseDown = FALSE
- //for setting world icons on the go
- var/inventory_state
- var/world_state
-
/obj/item/Initialize()
if(attack_verb)
@@ -309,6 +313,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
updateEmbedding()
+ if(world_file)
+ AddElement(/datum/element/world_icon, null, world_file, icon)
+
if(GLOB.rpg_loot_items)
AddComponent(/datum/component/fantasy)
@@ -1219,7 +1226,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
*/
/obj/item/proc/on_accidental_consumption(mob/living/carbon/victim, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE)
if(get_sharpness() && force >= 5) //if we've got something sharp with a decent force (ie, not plastic)
- INVOKE_ASYNC(victim, TYPE_PROC_REF(/mob, emote), "scream")
+ INVOKE_ASYNC(victim, TYPE_PROC_REF(/mob, force_scream))
victim.visible_message("[victim] looks like [victim.p_theyve()] just bit something they shouldn't have!", \
"OH GOD! Was that a crunch? That didn't feel good at all!!")
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index 7548625b31f6..883265896fe5 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -575,7 +575,7 @@ RLD
/obj/item/rcd_ammo
name = "compressed matter cartridge"
desc = "Highly compressed matter for the RCD."
- icon = 'icons/obj/ammo.dmi'
+ icon = 'icons/obj/ammunition/ammo.dmi'
icon_state = "rcd"
item_state = "rcdammo"
w_class = WEIGHT_CLASS_TINY
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 640b4e4a6a0a..89b73a0ffa9b 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -441,7 +441,7 @@
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, H))
M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!")
- M.emote("scream")
+ M.force_scream()
/obj/item/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
@@ -501,7 +501,7 @@
user.visible_message("[user] shocks [H] with \the [src]!", "You shock [H] with \the [src]!")
playsound(src, 'sound/machines/defib_zap.ogg', 100, TRUE, -1)
playsound(src, 'sound/weapons/egloves.ogg', 100, TRUE, -1)
- H.emote("scream")
+ H.force_scream()
shock_touching(45, H)
if(H.can_heartattack() && !H.undergoing_cardiac_arrest())
if(!H.stat)
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index 4abc1a3786bb..e1a20b508a5c 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -1,13 +1,3 @@
-#define RAD_LEVEL_NORMAL 9
-#define RAD_LEVEL_MODERATE 100
-#define RAD_LEVEL_HIGH 400
-#define RAD_LEVEL_VERY_HIGH 800
-#define RAD_LEVEL_CRITICAL 1500
-
-#define RAD_MEASURE_SMOOTHING 5
-
-#define RAD_GRACE_PERIOD 2
-
/obj/item/geiger_counter //DISCLAIMER: I know nothing about how real-life Geiger counters work. This will not be realistic. ~Xhuis
name = "\improper Geiger counter"
desc = "A handheld device used for detecting and measuring radiation pulses."
@@ -222,9 +212,3 @@
. = ..()
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
-
-#undef RAD_LEVEL_NORMAL
-#undef RAD_LEVEL_MODERATE
-#undef RAD_LEVEL_HIGH
-#undef RAD_LEVEL_VERY_HIGH
-#undef RAD_LEVEL_CRITICAL
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 0f0081c90454..c649c1e3f594 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -212,6 +212,10 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "This is used by Inteq Risk Management Group's mercenaries. Protects ears from flashbangs."
icon_state = "inteq_headset_alt"
+/obj/item/radio/headset/inteq/alt/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS))
+
/obj/item/radio/headset/inteq/alt/captain
name = "vanguard bowman headset"
desc = "Used by Inteq Risk Management Group's elite vanguards. Protects ears from flashbangs."
diff --git a/code/game/objects/items/melee/knife.dm b/code/game/objects/items/melee/knife.dm
index 83022e7125ff..15d389477745 100644
--- a/code/game/objects/items/melee/knife.dm
+++ b/code/game/objects/items/melee/knife.dm
@@ -105,6 +105,7 @@
force = 20
throwforce = 20
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
+ world_file = 'icons/obj/world/melee.dmi'
/obj/item/melee/knife/survival
name = "survival knife"
@@ -115,6 +116,7 @@
force = 15
throwforce = 15
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
+ world_file = 'icons/obj/world/melee.dmi'
/obj/item/melee/knife/bone
name = "bone dagger"
@@ -127,6 +129,7 @@
force = 15
throwforce = 15
custom_materials = null
+ world_file = 'icons/obj/world/melee.dmi'
/obj/item/melee/knife/combat/cyborg
name = "cyborg knife"
diff --git a/code/game/objects/items/melee/weaponry.dm b/code/game/objects/items/melee/weaponry.dm
index 11c1b118570b..131e5e1aab20 100644
--- a/code/game/objects/items/melee/weaponry.dm
+++ b/code/game/objects/items/melee/weaponry.dm
@@ -75,7 +75,7 @@
/obj/item/throwing_star/magspear
name = "magnetic spear"
desc = "A reusable spear that is typically loaded into kinetic spearguns."
- icon = 'icons/obj/ammo_bullets.dmi'
+ icon = 'icons/obj/ammunition/ammo_bullets.dmi'
icon_state = "magspear"
throwforce = 25 //kills regular carps in one hit
force = 10
diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm
index 959649c8c59b..249ee7dc41ed 100644
--- a/code/game/objects/items/shrapnel.dm
+++ b/code/game/objects/items/shrapnel.dm
@@ -20,7 +20,7 @@
/obj/item/shrapnel/bullet // bullets
name = "bullet"
- icon = 'icons/obj/ammo_bullets.dmi'
+ icon = 'icons/obj/ammunition/ammo_bullets.dmi'
icon_state = "pistol-brass"
item_flags = NONE
diff --git a/code/game/objects/items/storage/ammo_can.dm b/code/game/objects/items/storage/ammo_can.dm
new file mode 100644
index 000000000000..7962621674ad
--- /dev/null
+++ b/code/game/objects/items/storage/ammo_can.dm
@@ -0,0 +1,52 @@
+//No idea why this is a toolbox but I'm not fixing that right now
+/obj/item/storage/toolbox/ammo
+ name = "ammo can"
+ desc = "A metal container for storing multiple boxes of ammunition or grenades."
+ icon_state = "ammobox"
+ item_state = "ammobox"
+ drop_sound = 'sound/items/handling/ammobox_drop.ogg'
+ pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
+ material_flags = NONE
+ has_latches = FALSE
+
+/obj/item/storage/toolbox/ammo/a850r/PopulateContents()
+ name = "ammo can (8x50mmR)"
+ icon_state = "ammobox_850"
+ for(var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/a8_50r(src)
+
+/obj/item/storage/toolbox/ammo/a762_40/PopulateContents()
+ name = "ammo can (7.62x40mm CLIP)"
+ icon_state = "ammobox_762"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/a762_40(src)
+
+/obj/item/storage/toolbox/ammo/a308/PopulateContents()
+ name = "ammo can (.308)"
+ icon_state = "ammobox_308"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/a308(src)
+
+/obj/item/storage/toolbox/ammo/c45/PopulateContents()
+ name = "ammo can (.45)"
+ icon_state = "ammobox_45"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/c45(src)
+
+/obj/item/storage/toolbox/ammo/c9mm/PopulateContents()
+ name = "ammo can (9mm)"
+ icon_state = "ammobox_9mm"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/c9mm(src)
+
+/obj/item/storage/toolbox/ammo/c10mm/PopulateContents()
+ name = "ammo can (10mm)"
+ icon_state = "ammobox_10mm"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/c10mm(src)
+
+/obj/item/storage/toolbox/ammo/shotgun/PopulateContents()
+ name = "ammo can (12ga)"
+ icon_state = "ammobox_12ga"
+ for (var/i in 1 to 4)
+ new /obj/item/storage/box/ammo/a12g_buckshot(src)
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index dd0598e80c2d..34eba9a25191 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -483,7 +483,6 @@
desc = "A large duffel bag for holding extra tactical supplies."
icon_state = "duffel-syndie"
item_state = "duffel-syndieammo"
- slowdown = 0
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/duffelbag/syndie/ComponentInitialize()
@@ -597,7 +596,7 @@
new /obj/item/clothing/shoes/magboots/syndie(src)
new /obj/item/storage/firstaid/tactical(src)
new /obj/item/gun/ballistic/automatic/toy(src)
- new /obj/item/ammo_box/foambox/riot(src)
+ new /obj/item/storage/box/ammo/foam_darts/riot(src)
/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle
desc = "A large duffel bag containing deadly chemicals, a handheld chem sprayer, Bioterror foam grenade, a Donksoft assault rifle, box of riot grade darts, a dart pistol, and a box of syringes."
@@ -608,7 +607,7 @@
new /obj/item/gun/syringe/syndicate(src)
new /obj/item/gun/ballistic/automatic/toy(src)
new /obj/item/storage/box/syringes(src)
- new /obj/item/ammo_box/foambox/riot(src)
+ new /obj/item/storage/box/ammo/foam_darts/riot(src)
new /obj/item/grenade/chem_grenade/bioterrorfoam(src)
if(prob(5))
new /obj/item/reagent_containers/food/snacks/pizza/pineapple(src)
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index c6d55e03ef48..3b7de4f3ad1d 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -285,7 +285,6 @@
/obj/item/ammo_box/magazine,
/obj/item/ammo_box/c38, //speed loaders don't have a common path like magazines. pain.
/obj/item/ammo_box/a357, //some day we should refactor these into an ammo_box/speedloader type
- /obj/item/ammo_box/a4570, //but not today
/obj/item/ammo_box/a858, //oh boy stripper clips too
/obj/item/ammo_box/vickland_a308,
/obj/item/ammo_box/a300,
@@ -299,7 +298,8 @@
/obj/item/clothing/gloves,
/obj/item/restraints/legcuffs/bola,
/obj/item/holosign_creator/security,
- /obj/item/stock_parts/cell/gun //WS edit Gun cells fit where they should and not where they dont
+ /obj/item/stock_parts/cell/gun,
+ /obj/item/ammo_box/magazine/ammo_stack, //handfuls of bullets
))
/obj/item/storage/belt/security/full/PopulateContents()
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index 57b574e39b7f..29d2cd22dbbd 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -41,6 +41,9 @@
/obj/item/storage/box/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
+ STR.max_volume = STORAGE_VOLUME_CONTAINER_S
+ STR.max_w_class = WEIGHT_CLASS_SMALL
STR.use_sound = 'sound/items/storage/briefcase.ogg'
/obj/item/storage/box/update_overlays()
@@ -477,11 +480,6 @@
for(var/i in 1 to 6)
new donktype(src)
-/obj/item/storage/box/donkpockets/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/donkpocket))
-
/obj/item/storage/box/donkpockets/donkpocketspicy
name = "box of spicy-flavoured donk-pockets"
icon_state = "donkpocketboxspicy"
@@ -519,12 +517,6 @@
illustration = null
var/cube_type = /obj/item/reagent_containers/food/snacks/monkeycube
-/obj/item/storage/box/monkeycubes/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 7
- STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/monkeycube))
-
/obj/item/storage/box/monkeycubes/PopulateContents()
for(var/i in 1 to 5)
new cube_type(src)
@@ -539,12 +531,6 @@
icon_state = "monkeycubebox"
illustration = null
-/obj/item/storage/box/gorillacubes/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 3
- STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/monkeycube))
-
/obj/item/storage/box/gorillacubes/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/reagent_containers/food/snacks/monkeycube/gorilla(src)
@@ -676,12 +662,6 @@
icon = 'icons/obj/toy.dmi'
icon_state = "spbox"
-/obj/item/storage/box/snappops/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.set_holdable(list(/obj/item/toy/snappop))
- STR.max_items = 8
-
/obj/item/storage/box/snappops/PopulateContents()
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_FILL_TYPE, /obj/item/toy/snappop)
@@ -697,12 +677,6 @@
pickup_sound = 'sound/items/handling/matchbox_pickup.ogg'
custom_price = 20
-/obj/item/storage/box/matches/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 10
- STR.set_holdable(list(/obj/item/match))
-
/obj/item/storage/box/matches/PopulateContents()
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_FILL_TYPE, /obj/item/match)
@@ -720,9 +694,10 @@
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
-/obj/item/storage/box/lights/ComponentInitialize()
+/obj/item/storage/box/lights/ComponentInitialize()//holy oversized box. this one can stay the way it is, for now
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
STR.max_items = 21
STR.set_holdable(list(/obj/item/light/tube, /obj/item/light/bulb))
STR.max_combined_w_class = 21
@@ -1479,8 +1454,7 @@
/obj/item/storage/box/gum/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/chewable/bubblegum))
- STR.max_items = 4
+ STR.max_volume = (STORAGE_VOLUME_CONTAINER_S / 2)
/obj/item/storage/box/gum/PopulateContents()
for(var/i in 1 to 4)
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index e0768391dae5..0ee29e08e052 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -225,58 +225,6 @@
new /obj/item/stack/cable_coil/cyan(src)
new /obj/item/stack/cable_coil/white(src)
-/obj/item/storage/toolbox/ammo
- name = "ammo can"
- desc = "A metal container for storing multiple boxes of ammunition or grenades."
- icon_state = "ammobox"
- item_state = "ammobox"
- drop_sound = 'sound/items/handling/ammobox_drop.ogg'
- pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
- material_flags = NONE
- has_latches = FALSE
-
-/obj/item/storage/toolbox/ammo/a850r/PopulateContents()
- name = "ammo can (8x50mmR)"
- icon_state = "ammobox_850"
- for(var/i in 1 to 4)
- new /obj/item/ammo_box/c8x50mm_box(src)
-
-/obj/item/storage/toolbox/ammo/a762_40/PopulateContents()
- name = "ammo can (7.62x40mm CLIP)"
- icon_state = "ammobox_762"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/a762_40(src)
-
-/obj/item/storage/toolbox/ammo/a308/PopulateContents()
- name = "ammo can (.308)"
- icon_state = "ammobox_308"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/a308(src)
-
-/obj/item/storage/toolbox/ammo/c45/PopulateContents()
- name = "ammo can (.45)"
- icon_state = "ammobox_45"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/c45(src)
-
-/obj/item/storage/toolbox/ammo/c9mm/PopulateContents()
- name = "ammo can (9mm)"
- icon_state = "ammobox_9mm"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/c9mm(src)
-
-/obj/item/storage/toolbox/ammo/c10mm/PopulateContents()
- name = "ammo can (10mm)"
- icon_state = "ammobox_10mm"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/c10mm(src)
-
-/obj/item/storage/toolbox/ammo/shotgun/PopulateContents()
- name = "ammo can (12ga)"
- icon_state = "ammobox_12ga"
- for (var/i in 1 to 4)
- new /obj/item/ammo_box/a12g(src)
-
/obj/item/storage/toolbox/infiltrator
name = "insidious case"
desc = "Bearing the emblem of the Syndicate, this case contains a full infiltrator stealth suit, and has enough room to fit weaponry if necessary."
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 6d6d258b5b0c..81e6ea9d54ec 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -245,7 +245,7 @@
/obj/item/toy/ammo/gun
name = "capgun ammo"
desc = "Make sure to recyle the box in an autolathe when it gets empty."
- icon = 'icons/obj/ammo.dmi'
+ icon = 'icons/obj/ammunition/ammo.dmi'
icon_state = "357OLD-7"
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/iron=10, /datum/material/glass=10)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 23aa2df0ab5a..77497b671617 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -328,10 +328,10 @@
..()
for(var/i in 1 to 3)
new /obj/item/storage/box/lethalshot(src)
- new /obj/item/ammo_box/magazine/co9mm(src) //WS edit - begin - better safe than sorry
new /obj/item/ammo_box/magazine/co9mm(src)
new /obj/item/ammo_box/magazine/co9mm(src)
- new /obj/item/ammo_box/magazine/co9mm(src) //WS edit - end
+ new /obj/item/ammo_box/magazine/co9mm(src)
+ new /obj/item/ammo_box/magazine/co9mm(src)
/obj/structure/closet/secure_closet/labor_camp_security
name = "labor camp security locker"
diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm
index 59ef31fafa4e..83bae84fc575 100644
--- a/code/game/objects/structures/guillotine.dm
+++ b/code/game/objects/structures/guillotine.dm
@@ -154,7 +154,7 @@
else
H.apply_damage(15 * blade_sharpness, BRUTE, head)
log_combat(user, H, "dropped the blade on", src, " non-fatally")
- H.emote("scream")
+ H.force_scream()
if (blade_sharpness > 1)
blade_sharpness -= 1
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 6512a0683947..1840c27f9271 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -74,7 +74,7 @@
playsound(src.loc, 'sound/effects/splat.ogg', 25, TRUE)
L.visible_message("[user] slams [L] onto the meat spike!", "[user] slams you onto the meat spike!", "You hear a squishy wet noise.")
L.forceMove(drop_location())
- L.emote("scream")
+ L.force_scream()
L.add_splatter_floor()
L.adjustBruteLoss(30)
L.setDir(2)
@@ -128,7 +128,7 @@
M.adjustBruteLoss(30)
src.visible_message(text("[M] falls free of [src]!"))
unbuckle_mob(M,force=1)
- M.emote("scream")
+ M.force_scream()
M.AdjustParalyzed(20)
/obj/structure/kitchenspike/Destroy()
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 2e8c7508d594..ae1f50f0624f 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -264,7 +264,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
for(var/mob/living/M in conts)
if (M.stat != DEAD)
- M.emote("scream")
+ M.force_scream()
if(user)
log_combat(user, M, "cremated")
else
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index d5b1710b6296..f99cb8b9818b 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -701,9 +701,13 @@
return
if(user.body_position == LYING_DOWN || user.usable_legs < 2)
return
+
+ if(user.a_intent != INTENT_HARM)
+ to_chat(user, span_danger("You aren't HARMFUL enough to beat the rack."))
+ return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
- user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE)
+ user.visible_message(span_danger("[user] kicks [src]."), null, null, COMBAT_MESSAGE_RANGE)
take_damage(rand(4,8), BRUTE, "melee", 1)
/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
diff --git a/code/modules/antagonists/gang/outfits.dm b/code/modules/antagonists/gang/outfits.dm
index 77c091d2126a..f76bf026e12c 100644
--- a/code/modules/antagonists/gang/outfits.dm
+++ b/code/modules/antagonists/gang/outfits.dm
@@ -30,10 +30,7 @@
backpack_contents = list(/obj/item/storage/box/handcuffs = 1,
/obj/item/storage/box/teargas = 1,
/obj/item/storage/box/flashbangs = 1,
- /obj/item/shield/riot/tele = 1,
- /obj/item/ammo_box/magazine/m45 = 3,
- /obj/item/ammo_box/c45 = 2)
-
+ /obj/item/shield/riot/tele = 1)
/datum/outfit/families_police/beatcop/armored
name = "Families: Armored Beat Cop"
@@ -53,8 +50,7 @@
backpack_contents = list(/obj/item/storage/box/handcuffs = 1,
/obj/item/storage/box/teargas = 1,
/obj/item/storage/box/flashbangs = 1,
- /obj/item/shield/riot/tele = 1,
- /obj/item/storage/box/lethalshot = 2)
+ /obj/item/shield/riot/tele = 1)
/datum/outfit/families_police/beatcop/fbi
name = "Families: Space FBI Officer"
@@ -65,8 +61,7 @@
/obj/item/storage/box/teargas = 1,
/obj/item/storage/box/flashbangs = 1,
/obj/item/shield/riot/tele = 1,
- /obj/item/ammo_box/magazine/smgm9mm = 3,
- /obj/item/ammo_box/c9mm = 2)
+ /obj/item/ammo_box/magazine/smgm9mm = 3)
/datum/outfit/families_police/beatcop/military
name = "Families: Space Military"
diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm
index c12b09fa4e05..a240bf9f8404 100644
--- a/code/modules/awaymissions/mission_code/snowdin.dm
+++ b/code/modules/awaymissions/mission_code/snowdin.dm
@@ -218,14 +218,19 @@
PP.adjustFireLoss(25)
if(plasma_parts.len)
var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs for dismember() to use
- PP.emote("scream")
NB.limb_id = "plasmaman" //change the species_id of the limb to that of a plasmaman
NB.static_icon = 'icons/mob/species/plasmaman/bodyparts.dmi'
NB.no_update = TRUE
NB.change_bodypart_status()
- PP.visible_message(
- "[L] screams in pain as [L.p_their()] [NB] melts down to the bone!",
- "You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")
+ PP.force_scream()
+ if(!HAS_TRAIT(PP, TRAIT_ANALGESIA))
+ PP.visible_message(
+ "[L] screams in pain as [L.p_their()] [NB] melts down to the bone!",
+ "You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")
+ else
+ PP.visible_message(
+ "[L] lets out panicked gasps as [L.p_their()] [NB] melts down to the bone!",
+ "You gasp in shock as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")
if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman
PP.IgniteMob()
PP.set_species(/datum/species/plasmaman)
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/ammo.dm b/code/modules/cargo/blackmarket/blackmarket_items/ammo.dm
index 1492fa36d400..0dad1cd32c7c 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/ammo.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/ammo.dm
@@ -28,7 +28,7 @@
/datum/blackmarket_item/ammo/himehabu_box
name = ".22 LR Ammo Box"
desc = "A 75 round ammo box of .22 LR. Trust me, you'll need every shot."
- item = /obj/item/ammo_box/c22lr_box
+ item = /obj/item/storage/box/ammo/c22lr
price_min = 100
price_max = 300
@@ -39,7 +39,7 @@
/datum/blackmarket_item/ammo/a357_box
name = ".357 Ammo Box"
desc = "A 50 round ammo box of .357."
- item = /obj/item/ammo_box/a357_box
+ item = /obj/item/storage/box/ammo/a357
price_min = 150
price_max = 500
@@ -242,7 +242,7 @@
/datum/blackmarket_item/ammo/a4570hp
name = ".45-70 Hollow Point Ammo Box"
desc = "Put the hollow in hollow point by blowing a crater in some random sod with this devastating .45-70 cartridge."
- item = /obj/item/ammo_box/a4570/hp
+ item = /obj/item/storage/box/ammo/a4570_hp
price_min = 600
price_max = 1000
diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm
index be3ec7a26599..165cfb6c1196 100644
--- a/code/modules/cargo/exports.dm
+++ b/code/modules/cargo/exports.dm
@@ -59,7 +59,8 @@ then the player gets the profit from selling his own wasted time.
if(!dry_run && (sold || delete_unsold))
if(ismob(thing))
thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO)
- qdel(thing)
+ if(!dry_run)
+ qdel(AM)
return report
diff --git a/code/modules/cargo/packs/ammo.dm b/code/modules/cargo/packs/ammo.dm
index 98b96e5bd4f0..7d3d54bb1534 100644
--- a/code/modules/cargo/packs/ammo.dm
+++ b/code/modules/cargo/packs/ammo.dm
@@ -1,6 +1,7 @@
/datum/supply_pack/ammo
group = "Ammunition"
crate_type = /obj/structure/closet/crate/secure/gear
+ crate_name = "ammo crate"
/*
Pistol ammo
@@ -45,7 +46,7 @@
/datum/supply_pack/ammo/mag_556mm
name = "5.56 Pistole C Magazine Crate"
desc = "Contains a 5.56mm magazine for the Pistole C, containing twelve rounds."
- contains = list(/obj/item/ammo_box/magazine/pistol556mm)
+ contains = list(/obj/item/storage/box/ammo/c556mm)
cost = 750
faction = FACTION_SOLGOV
@@ -62,21 +63,21 @@
/datum/supply_pack/ammo/buckshot
name = "Buckshot Crate"
- desc = "Contains a box of twenty-five buckshot shells for use in lethal persuasion."
+ desc = "Contains a box of 32 buckshot shells for use in lethal persuasion."
cost = 500
- contains = list(/obj/item/ammo_box/a12g)
+ contains = list(/obj/item/storage/box/ammo/a12g_buckshot)
/datum/supply_pack/ammo/slugs
name = "Shotgun Slug Crate"
- desc = "Contains a box of twenty-five slug shells for use in lethal persuasion."
+ desc = "Contains a box of 32 slug shells for use in lethal persuasion."
cost = 500
- contains = list(/obj/item/ammo_box/a12g/slug)
-
+ contains = list(/obj/item/storage/box/ammo/a12g_slug
+)
/datum/supply_pack/ammo/blank_shells
name = "Blank Shell Crate"
desc = "Contains a box of blank shells."
cost = 500
- contains = list(/obj/item/ammo_box/a12g/blanks)
+ contains = list(/obj/item/storage/box/ammo/a12g_blank)
/datum/supply_pack/ammo/blank_ammo_disk
name = "Blank Ammo Design Disk Crate"
@@ -92,9 +93,9 @@
/datum/supply_pack/ammo/rubbershot
name = "Rubbershot Crate"
- desc = "Contains a box of twenty-five rubbershot shells for use in crowd control or training."
+ desc = "Contains a box of 32 rubbershot shells for use in crowd control or training."
cost = 500
- contains = list(/obj/item/ammo_box/a12g/rubbershot)
+ contains = list(/obj/item/storage/box/ammo/a12g_rubbershot)
/*
.38 ammo
@@ -104,8 +105,8 @@
name = ".38 Ammo Boxes Crate"
desc = "Contains two 50 round ammo boxes for refilling .38 weapons."
cost = 250
- contains = list(/obj/item/ammo_box/c38_box,
- /obj/item/ammo_box/c38_box)
+ contains = list(/obj/item/storage/box/ammo/c38,
+ /obj/item/storage/box/ammo/c38)
crate_name = "ammo crate"
/datum/supply_pack/ammo/match
@@ -195,134 +196,136 @@
/datum/supply_pack/ammo/a762_ammo_box
name = "7.62x40mm CLIP Ammo Box Crate"
- desc = "Contains a one hundred and twenty-round 7.62x40mm CLIP box for the SKM rifles."
- contains = list(/obj/item/ammo_box/a762_40)
+ desc = "Contains two 60-round 7.62x40mm CLIP boxes for the SKM rifles."
+ contains = list(/obj/item/storage/box/ammo/a762_40,
+ /obj/item/storage/box/ammo/a762_40)
cost = 500
/datum/supply_pack/ammo/a556_ammo_box
name = "5.56x42mm CLIP Ammo Box Crate"
- desc = "Contains a one hundred and twenty-round 5.56x42mm CLIP box for most newer rifles."
- contains = list(/obj/item/ammo_box/a556_42)
+ desc = "Contains two 60-round 5.56x42mm CLIP boxes for most newer rifles."
+ contains = list(/obj/item/storage/box/ammo/a556_42,
+ /obj/item/storage/box/ammo/a556_42)
cost = 450
/datum/supply_pack/ammo/a357_ammo_box
name = ".357 Ammo Box Crate"
- desc = "Contains a fifty-round .357 box for revolvers such as the Scarborough Revolver and the HP Firebrand."
- contains = list(/obj/item/ammo_box/a357_box)
+ desc = "Contains a 48-round .357 box for revolvers such as the Scarborough Revolver and the HP Firebrand."
+ contains = list(/obj/item/storage/box/ammo/a357)
cost = 250
/datum/supply_pack/ammo/c556mmHITP_ammo_box
name = "5.56 Caseless Ammo Box Crate"
- desc = "Contains a fifty-round 5.56mm caseless box for SolGov sidearms like the Pistole C."
- contains = list(/obj/item/ammo_box/c556mmHITP)
+ desc = "Contains a 48-round 5.56mm caseless box for SolGov sidearms like the Pistole C."
+ contains = list(/obj/item/storage/box/ammo/c556mm)
cost = 250
/datum/supply_pack/ammo/c45_ammo_box
name = ".45 Ammo Box Crate"
- desc = "Contains a fifty-round .45 box for pistols and SMGs like the Candor or the C-20r."
- contains = list(/obj/item/ammo_box/c45)
+ desc = "Contains a 48-round .45 box for pistols and SMGs like the Candor or the C-20r."
+ contains = list(/obj/item/storage/box/ammo/c45)
cost = 250
/datum/supply_pack/ammo/c10mm_ammo_box
name = "10mm Ammo Box Crate"
- desc = "Contains a fifty-round 10mm box for pistols and SMGs like the Ringneck or the SkM-44(k)."
- contains = list(/obj/item/ammo_box/c10mm)
+ desc = "Contains a 48-round 10mm box for pistols and SMGs like the Ringneck or the SkM-44(k)."
+ contains = list(/obj/item/storage/box/ammo/c10mm)
cost = 250
/datum/supply_pack/ammo/c9mm_ammo_box
name = "9mm Ammo Box Crate"
- desc = "Contains a fifty-round 9mm box for pistols and SMGs such as the Commander or Saber."
- contains = list(/obj/item/ammo_box/c9mm)
+ desc = "Contains a 48-round 9mm box for pistols and SMGs such as the Commander or Saber."
+ contains = list(/obj/item/storage/box/ammo/c9mm)
cost = 200
/datum/supply_pack/ammo/a308_ammo_box
name = "308 Ammo Box Crate"
desc = "Contains a thirty-round .308 box for DMRs such as the SsG-04 and CM-GAL-S."
- contains = list(/obj/item/ammo_box/a308)
+ contains = list(/obj/item/storage/box/ammo/a308)
cost = 500
/datum/supply_pack/ammo/c9mmap_ammo_box
name = "9mm AP Ammo Box Crate"
- desc = "Contains a fifty-round 9mm box loaded with armor piercing ammo."
- contains = list(/obj/item/ammo_box/c9mm/ap)
+ desc = "Contains a 48-round 9mm box loaded with armor piercing ammo."
+ contains = list(/obj/item/storage/box/ammo/c9mm/ap)
cost = 400
/datum/supply_pack/ammo/a357match_ammo_box
name = ".357 Match Ammo Box Crate"
- desc = "Contains a fifty-round .357 match box for better performance against armor."
- contains = list(/obj/item/ammo_box/a357_box/match)
+ desc = "Contains a 48-round .357 match box for better performance against armor."
+ contains = list(/obj/item/storage/box/ammo/a357_match)
cost = 500
/datum/supply_pack/ammo/c556mmHITPap_ammo_box
name = "5.56 caseless AP Ammo Box Crate"
- desc = "Contains a fifty-round 5.56mm caseless boxloaded with armor piercing ammo."
- contains = list(/obj/item/ammo_box/c556mmHITP/ap)
+ desc = "Contains a 48-round 5.56mm caseless boxloaded with armor piercing ammo."
+ contains = list(/obj/item/storage/box/ammo/c556mm_ap)
cost = 500
/datum/supply_pack/ammo/c45ap_ammo_box
name = ".45 AP Ammo Box Crate"
- desc = "Contains a fifty-round .45 box loaded with armor piercing ammo."
- contains = list(/obj/item/ammo_box/c45/ap)
+ desc = "Contains a 48-round .45 box loaded with armor piercing ammo."
+ contains = list(/obj/item/storage/box/ammo/c45_ap)
cost = 500
/datum/supply_pack/ammo/c10mmap_ammo_box
name = "10mm AP Ammo Box Crate"
- desc = "Contains a fifty-round 10mm box loaded with armor piercing ammo."
- contains = list(/obj/item/ammo_box/c10mm/ap)
+ desc = "Contains a 48-round 10mm box loaded with armor piercing ammo."
+ contains = list(/obj/item/storage/box/ammo/c10mm_ap)
cost = 500
/datum/supply_pack/ammo/c9mmhp_ammo_box
name = "9mm HP Ammo Box Crate"
- desc = "Contains a fifty-round 9mm box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/c9mm/hp)
+ desc = "Contains a 48-round 9mm box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/c9mm_hp)
cost = 400
/datum/supply_pack/ammo/a357hp_ammo_box
name = ".357 HP Ammo Box Crate"
- desc = "Contains a fifty-round .357 box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/a357_box/hp)
+ desc = "Contains a 48-round .357 box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/a357_hp)
cost = 500
/datum/supply_pack/ammo/c10mmhp_ammo_box
name = "10mm HP Ammo Box Crate"
- desc = "Contains a fifty-round 10mm box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/c10mm/hp)
+ desc = "Contains a 48-round 10mm box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/c10mm_hp)
cost = 500
+
/datum/supply_pack/ammo/c45hp_ammo_box
name = ".45 HP Ammo Box Crate"
- desc = "Contains a fifty-round 10mm box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/c45/hp)
+ desc = "Contains a 48-round 10mm box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/c45_hp)
cost = 500
/datum/supply_pack/ammo/c556mmhitphp_ammo_box
name = "5.56 Caseless HP Ammo Box Crate"
- desc = "Contains a fifty-round 5.56mm caseless box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/c556mmHITP/hp)
+ desc = "Contains a 48-round 5.56mm caseless box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/c556mm_hp)
cost = 500
/datum/supply_pack/ammo/c9mmrubber_ammo_box
name = "9mm Rubber Ammo Box Crate"
- desc = "Contains a fifty-round 9mm box loaded with less-than-lethal rubber rounds."
- contains = list(/obj/item/ammo_box/c9mm/rubbershot)
+ desc = "Contains a 48-round 9mm box loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/storage/box/ammo/c9mm_rubber)
cost = 200
/datum/supply_pack/ammo/c10mmrubber_ammo_box
name = "10mm Rubber Ammo Box Crate"
- desc = "Contains a fifty-round 10mm box loaded with less-than-lethal rubber rounds."
- contains = list(/obj/item/ammo_box/c10mm/rubbershot)
+ desc = "Contains a 48-round 10mm box loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/storage/box/ammo/c10mm_rubber)
cost = 250
/datum/supply_pack/ammo/c45mmrubber_ammo_box
name = ".45 Rubber Ammo Box Crate"
- desc = "Contains a fifty-round .45 box loaded with less-than-lethal rubber rounds."
- contains = list(/obj/item/ammo_box/c45/rubbershot)
+ desc = "Contains a 48-round .45 box loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/storage/box/ammo/c45_rubber)
cost = 250
-
/datum/supply_pack/ammo/c556HITPrubber_ammo_box
name = "5.56 Caseless Rubber Ammo Box Crate"
- desc = "Contains a fifty-round 5.56 caseless box loaded with less-than-lethal rubber rounds."
- contains = list(/obj/item/ammo_box/c556mmHITP/rubbershot)
+ desc = "Contains a 48-round 5.56 caseless box loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/storage/box/ammo/c556mm_rubber)
cost = 250
/datum/supply_pack/ammo/guncell
@@ -339,87 +342,86 @@
/datum/supply_pack/ammo/c57x39mm_boxcrate
name = "5.7x39mm Ammo Box Crate"
- desc = "Contains a fifty-round 5.7x39mm box for PDWs such as the Sidewinder."
- contains = list(/obj/item/ammo_box/c57x39mm_box)
+ desc = "Contains a 48-round 5.7x39mm box for PDWs such as the Sidewinder."
+ contains = list(/obj/item/storage/box/ammo/c57x39)
cost = 250
/datum/supply_pack/ammo/c46x30mm_boxcrate
name = "4.6x30mm Ammo Box Crate"
- desc = "Contains a fifty-round 4.6x30mm box for PDWs such as the WT-550."
- contains = list(/obj/item/ammo_box/c46x30mm_box)
+ desc = "Contains a 60-round 4.6x30mm box for PDWs such as the WT-550."
+ contains = list(/obj/item/storage/box/ammo/c46x30mm)
cost = 250
/datum/supply_pack/ammo/c8x50mm_boxcrate
name = "8x50mm Ammo Box Crate"
- desc = "Contains a twenty-round 8x50mm ammo box for rifles such as the Illestren."
- contains = list(/obj/item/ammo_box/c8x50mm_box)
+ desc = "Contains a 30-round 8x50mm ammo box for rifles such as the Illestren."
+ contains = list(/obj/item/storage/box/ammo/a8_50r)
cost = 250
/datum/supply_pack/ammo/c8x50mm_boxhp_boxcrate
name = "8x50mm Hollow Point Crate"
- desc = "Contains a twenty-round 8x50mm ammo box loaded with hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/c8x50mmhp_box)
+ desc = "Contains a 30y-round 8x50mm ammo box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/a8_50r_hp)
cost = 500
/datum/supply_pack/ammo/a300_box
name = ".300 Ammo Box Crate"
desc = "Contains a twenty-round .300 Magnum ammo box for sniper rifles such as the HP Scout."
- contains = list(/obj/item/ammo_box/a300_box)
+ contains = list(/obj/item/storage/box/ammo/a300)
cost = 400
/datum/supply_pack/ammo/a65clip_box
name = "6.5x57mm CLIP Ammo Box Crate"
desc = "Contains a twenty-round 6.5x57mm CLIP ammo box for various sniper rifles such as the CM-F90 and the Boomslang series."
- contains = list(/obj/item/ammo_box/a65clip_box)
+ contains = list(/obj/item/storage/box/ammo/a65clip)
cost = 400
-
/datum/supply_pack/ammo/a4570_box
name = ".45-70 Ammo Box Crate"
- desc = "Contains a twelve-round box containing devastatingly powerful .45-70 caliber ammunition."
- contains = list(/obj/item/ammo_box/a4570)
+ desc = "Contains a 20-round box containing devastatingly powerful .45-70 caliber ammunition."
+ contains = list(/obj/item/storage/box/ammo/a4570)
cost = 500
/datum/supply_pack/ammo/a4570_box/match
name = ".45-70 Match Crate"
- desc = "Contains a twelve-round box containing devastatingly powerful .45-70 caliber ammunition, that travels faster, pierces armour better, and ricochets off targets."
- contains = list(/obj/item/ammo_box/a4570/match)
+ desc = "Contains a 20-round box containing devastatingly powerful .45-70 caliber ammunition, that travels faster, pierces armour better, and ricochets off targets."
+ contains = list(/obj/item/storage/box/ammo/a4570_match)
cost = 750
/datum/supply_pack/ammo/ferropelletboxcrate
name = "Ferromagnetic Pellet Box Crate"
- desc = "Contains a fifty-round ferromagnetic pellet ammo box for gauss guns such as the Claris."
- contains = list(/obj/item/ammo_box/ferropelletbox)
+ desc = "Contains a 48-round ferromagnetic pellet ammo box for gauss guns such as the Claris."
+ contains = list(/obj/item/storage/box/ammo/ferropellet)
cost = 250
/datum/supply_pack/ammo/ferroslugboxcrate
name = "Ferromagnetic Slug Box Crate"
desc = "Contains a twenty-round ferromagnetic slug for gauss guns such as the Model-H."
- contains = list(/obj/item/ammo_box/ferroslugbox)
+ contains = list(/obj/item/storage/box/ammo/ferroslug)
cost = 250
/datum/supply_pack/ammo/ferrolanceboxcrate
name = "Ferromagnetic Lance Box Crate"
- desc = "Contains a fifty-round box for high-powered gauss guns such as the GAR assault rifle."
- contains = list(/obj/item/ammo_box/ferrolancebox)
+ desc = "Contains a 48-round box for high-powered gauss guns such as the GAR assault rifle."
+ contains = list(/obj/item/storage/box/ammo/ferrolance)
cost = 250
/datum/supply_pack/ammo/a44roum
name = ".44 Roumain Ammo Box Crate"
- desc = "Contains a fifty-round box of .44 roumain ammo for revolvers such as the Shadow and Montagne."
- contains = list(/obj/item/ammo_box/a44roum)
+ desc = "Contains a 48-round box of .44 roumain ammo for revolvers such as the Shadow and Montagne."
+ contains = list(/obj/item/storage/box/ammo/a44roum)
cost = 250
/datum/supply_pack/ammo/a44roum_rubber
name = ".44 Roumain Rubber Ammo Box Crate"
- desc = "Contains a fifty-round box of .44 roumain ammo loaded with less-than-lethal rubber rounds."
- contains = list(/obj/item/ammo_box/a44roum/rubber)
+ desc = "Contains a 48-round box of .44 roumain ammo loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/storage/box/ammo/a44roum_rubber)
cost = 250
/datum/supply_pack/ammo/a44roum_hp
name = ".44 Roumain Hollow Point Ammo Box Crate"
- desc = "Contains a fifty-round box of .44 roumain hollow point ammo, great against unarmored targets."
- contains = list(/obj/item/ammo_box/a44roum/hp)
+ desc = "Contains a 48-round box of .44 roumain hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/storage/box/ammo/a44roum_hp)
cost = 500
/datum/supply_pack/ammo/c299
@@ -430,8 +432,6 @@
/datum/supply_pack/ammo/c22lr
name = ".22 LR Ammo Box Crate"
- desc = "Contains two 75 round ammo boxes for refilling .22 LR weapons."
- contains = list(/obj/item/ammo_box/c22lr_box,
- /obj/item/ammo_box/c22lr_box)
- crate_name = "ammo crate"
+ desc = "Contains a 60-round ammo box for refilling .22 LR weapons."
+ contains = list(/obj/item/storage/box/ammo/c22lr)
cost = 250
diff --git a/code/modules/clothing/factions/gezena.dm b/code/modules/clothing/factions/gezena.dm
index 3eea9ebec461..d4ff3169880d 100644
--- a/code/modules/clothing/factions/gezena.dm
+++ b/code/modules/clothing/factions/gezena.dm
@@ -102,6 +102,10 @@
w_class = WEIGHT_CLASS_NORMAL
supports_variations = DIGITIGRADE_VARIATION
+/obj/item/clothing/suit/space/gezena/Initialize()
+ . = ..()
+ allowed = GLOB.security_hardsuit_allowed
+
/obj/item/clothing/head/helmet/space/gezena
name = "\improper Rakalla-helm"
desc = "Featuring rubberized grommets fitting for any length of horn, and an internal monitor for life support."
diff --git a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
index 8401455bf7d8..b685e0e4b8bb 100644
--- a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
+++ b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
@@ -89,11 +89,11 @@
var/loops = rand(1,3)
for(var/i in 1 to loops)
var/ammotype = pick(list(
- /obj/item/ammo_box/c8x50mm_box,
- /obj/item/ammo_box/c45,
- /obj/item/ammo_box/a357_box,
- /obj/item/ammo_box/c45,
- /obj/item/ammo_box/a4570,
+ /obj/item/storage/box/ammo/a8_50r,
+ /obj/item/storage/box/ammo/c45,
+ /obj/item/storage/box/ammo/a357,
+ /obj/item/storage/box/ammo/c45,
+ /obj/item/storage/box/ammo/a4570,
/obj/item/stock_parts/cell/gun/mini))
backpack_contents += ammotype
@@ -220,7 +220,11 @@
l_hand = /obj/item/flamethrower/full/tank
- backpack_contents = list(/obj/item/gun/ballistic/shotgun/doublebarrel/presawn=1,/obj/item/ammo_box/a12g=1,/obj/item/extinguisher=2,/obj/item/radio=1)
+ backpack_contents = list(
+ /obj/item/gun/ballistic/shotgun/doublebarrel/presawn=1, \
+ /obj/item/storage/box/ammo/a12g_slug = 1, \
+ /obj/item/extinguisher = 2, \
+ /obj/item/radio=1)
/datum/outfit/job/frontiersmen/ert/sentry_lmg
diff --git a/code/modules/clothing/outfits/factions/inteq.dm b/code/modules/clothing/outfits/factions/inteq.dm
index 16d1456361be..51e1cf1fb29f 100644
--- a/code/modules/clothing/outfits/factions/inteq.dm
+++ b/code/modules/clothing/outfits/factions/inteq.dm
@@ -24,6 +24,7 @@
jobtype = /datum/job/assistant
job_icon = "assistant"
+ ears = /obj/item/radio/headset
r_pocket = /obj/item/radio
///captains
@@ -135,6 +136,7 @@
jobtype = /datum/job/officer
job_icon = "securityofficer"
+ ears = /obj/item/radio/headset/alt
head = /obj/item/clothing/head/helmet/inteq
suit = /obj/item/clothing/suit/armor/vest/alt
belt = /obj/item/storage/belt/security/webbing/inteq
@@ -181,6 +183,7 @@
job_icon = "stationengineer"
jobtype = /datum/job/engineer
+ ears = /obj/item/radio/headset/alt
uniform = /obj/item/clothing/under/syndicate/inteq/artificer
head = /obj/item/clothing/head/soft/inteq
shoes = /obj/item/clothing/shoes/combat
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index cd4474588090..424e00712078 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -172,7 +172,7 @@
else // if one of us moved
user.visible_message("[our_guy] stamps on [user]'s hand, mid-shoelace [tied ? "knotting" : "untying"]!", "Ow! [our_guy] stamps on your hand!", list(our_guy))
to_chat(our_guy, "You stamp on [user]'s hand! What the- [user.p_they()] [user.p_were()] [tied ? "knotting" : "untying"] your shoelaces!")
- user.emote("scream")
+ user.force_scream()
if(istype(L))
var/obj/item/bodypart/ouchie = L.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
if(ouchie)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 8f8e532577c0..29ff8ead2f62 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -40,6 +40,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
next_hallucination = world.time + rand(100, 600)
/mob/living/carbon/proc/set_screwyhud(hud_type)
+ if(HAS_TRAIT(src, TRAIT_ANALGESIA))
+ hud_type = SCREWYHUD_HEALTHY
hal_screwyhud = hud_type
update_health_hud()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 9a6b10e0444b..6016def705b5 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -12,6 +12,7 @@
idle_power_usage = IDLE_DRAW_MINIMAL
active_power_usage = ACTIVE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/smartfridge
+ integrity_failure = 0.4
var/max_n_of_items = 1500
var/allow_ai_retrieve = FALSE
@@ -40,7 +41,10 @@
. += "The status display reads: This unit can hold a maximum of [max_n_of_items] items."
/obj/machinery/smartfridge/update_icon_state()
- if(machine_stat)
+ if(machine_stat & BROKEN)
+ icon_state = "[initial(icon_state)]-broken"
+ return ..()
+ else if(!powered())
icon_state = "[initial(icon_state)]-off"
return ..()
@@ -53,10 +57,8 @@
icon_state = "[initial(icon_state)]"
if(1 to 25)
icon_state = "[initial(icon_state)]1"
- if(26 to 75)
+ if(26 to INFINITY)
icon_state = "[initial(icon_state)]2"
- if(76 to INFINITY)
- icon_state = "[initial(icon_state)]3"
return ..()
/obj/machinery/smartfridge/update_overlays()
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index 406259246db1..4d5a07d4130f 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -232,7 +232,7 @@
new /obj/item/gun/ballistic/automatic/toy/pistol(src)
new /obj/item/gun/ballistic/automatic/toy(src)
new /obj/item/gun/ballistic/automatic/toy(src)
- new /obj/item/ammo_box/foambox(src)
+ new /obj/item/storage/box/ammo/foam_darts(src)
if(98)
for(var/i in 1 to 3)
new /mob/living/simple_animal/hostile/poison/bees/toxin(src)
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 73d18f0ab885..60debde823ef 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -621,7 +621,7 @@
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
playsound(C.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1)
C.adjustBruteLoss(20)
- C.emote("scream")
+ C.force_scream()
..()
//nerfed necrostone
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair.dm
index 34d8dd274668..10eb5ae7d6eb 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/hair.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/hair.dm
@@ -90,29 +90,21 @@
name = "Bowlcut 2"
icon_state = "hair_bowlcut2"
-/datum/sprite_accessory/hair/braid
- name = "Braid (Floorlength)"
- icon_state = "hair_braid"
-
-/datum/sprite_accessory/hair/braided
- name = "Braided"
- icon_state = "hair_braided"
-
-/datum/sprite_accessory/hair/front_braid
- name = "Braided Front"
- icon_state = "hair_braidfront"
-
-/datum/sprite_accessory/hair/not_floorlength_braid
- name = "Braid (High)"
+/datum/sprite_accessory/hair/ponytail_braided
+ name = "Ponytail (Braided)"
icon_state = "hair_braid2"
-/datum/sprite_accessory/hair/lowbraid
- name = "Braid (Low)"
- icon_state = "hair_hbraid"
+/datum/sprite_accessory/hair/ponytail_braided_short
+ name = "Ponytail (Braided Short)"
+ icon_state = "hair_braid"
-/datum/sprite_accessory/hair/shortbraid
- name = "Braid (Short)"
- icon_state = "hair_shortbraid"
+/datum/sprite_accessory/hair/ponytail_straight
+ name = "Ponytail (Straight)"
+ icon_state = "hair_longstraightponytail"
+
+/datum/sprite_accessory/hair/ponytail_straight_short
+ name = "Ponytail (Straight Short)"
+ icon_state = "hair_highponytail"
/datum/sprite_accessory/hair/braidtail
name = "Braided Tail"
@@ -503,12 +495,8 @@
icon_state = "hair_ponytail"
/datum/sprite_accessory/hair/ponytail2
- name = "Ponytail 2"
- icon_state = "hair_ponytail2"
-
-/datum/sprite_accessory/hair/ponytail3
- name = "Ponytail 3"
- icon_state = "hair_ponytail3"
+ name = "Ponytail (Grace)"
+ icon_state = "hair_ponytailgrace"
/datum/sprite_accessory/hair/ponytail4
name = "Ponytail 4"
@@ -526,21 +514,14 @@
name = "Ponytail 7"
icon_state = "hair_ponytail7"
-/datum/sprite_accessory/hair/highponytail
- name = "Ponytail (High)"
- icon_state = "hair_highponytail"
/datum/sprite_accessory/hair/stail
name = "Ponytail (Short)"
icon_state = "hair_stail"
-/datum/sprite_accessory/hair/longponytail
- name = "Ponytail (Long)"
- icon_state = "hair_longstraightponytail"
-
/datum/sprite_accessory/hair/countryponytail
name = "Ponytail (Country)"
- icon_state = "hair_country"
+ icon_state = "hair_ponytailcountry"
/datum/sprite_accessory/hair/fringetail
name = "Ponytail (Fringe)"
@@ -722,6 +703,10 @@
name = "Ruby"
icon_state = "hair_ruby"
+/datum/sprite_accessory/hair/rubylong
+ name = "Ruby (Long)"
+ icon_state = "hair_rubylong"
+
/datum/sprite_accessory/hair/undercut
name = "Undercut"
icon_state = "hair_undercut"
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 0840ee372158..0e4a8ed748c9 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -25,6 +25,22 @@
to_chat(src, "Unusable emote '[act]'. Say *help for a list.")
return FALSE
+/mob/proc/force_scream()
+ if(HAS_TRAIT(src, TRAIT_ANALGESIA))
+ return
+ if(HAS_TRAIT(src, TRAIT_PAIN_RESIST))
+ emote("gasp")
+ return
+ emote("scream")
+
+/mob/proc/force_manual_scream()
+ if(HAS_TRAIT(src, TRAIT_ANALGESIA))
+ return
+ if(HAS_TRAIT(src, TRAIT_PAIN_RESIST))
+ manual_emote("gasp")
+ return
+ manual_emote("scream")
+
/datum/emote/flip
key = "flip"
key_third_person = "flips"
diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm
index bfa71f3b335e..3ae9bbb5b250 100644
--- a/code/modules/mob/living/carbon/alien/organs.dm
+++ b/code/modules/mob/living/carbon/alien/organs.dm
@@ -134,7 +134,7 @@
else if(ishuman(owner)) //Humans, being more fragile, are more overwhelmed by the mental backlash.
to_chat(owner, "You feel a splitting pain in your head, and are struck with a wave of nausea. You cannot hear the hivemind anymore!")
- owner.emote("scream")
+ owner.force_scream()
owner.Paralyze(100)
owner.jitteriness += 30
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index f0d27e801cd2..5e5e8fca6d24 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -253,7 +253,7 @@
damage += rand(3,7)
if(damage >= 5)
- target.emote("scream")
+ target.force_scream()
target.apply_damage(damage, BRUTE, BODY_ZONE_HEAD)
user.adjustStaminaLoss(iteration + 5)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 7a7bc349b26c..c26956991d33 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -655,7 +655,7 @@
if(affecting.name == BODY_ZONE_HEAD)
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
affecting.receive_damage(acidity, 2*acidity)
- emote("scream")
+ force_scream()
facial_hairstyle = "Shaved"
hairstyle = "Bald"
update_hair()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 18b6cb9ba40e..dd05c0de739b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -345,13 +345,19 @@
var/obj/item/bodypart/R = get_bodypart("r_arm")
if(istype(L) && L.bone_status == BONE_FLAG_BROKEN && held_items[1] && prob(30))
- emote("scream")
- visible_message("[src] screams and lets go of [held_items[1]] in pain.", "A horrible pain in your [parse_zone(L)] makes it impossible to hold [held_items[1]]!")
+ force_scream()
+ if(!HAS_TRAIT(src, TRAIT_ANALGESIA))
+ visible_message("[src] screams and lets go of [held_items[1]] in pain.", "A horrible pain in your [parse_zone(L)] makes it impossible to hold [held_items[1]]!")
+ else
+ visible_message(span_notice("[src] flinches and lets go of [held_items[1]]."),span_notice("A sudden weakness in your [parse_zone(L)] makes it impossible to grasp [held_items[1]]!)"))
dropItemToGround(held_items[1])
if(istype(R) && R.bone_status == BONE_FLAG_BROKEN && held_items[2] && prob(30))
- emote("scream")
- visible_message("[src] screams and lets go of [held_items[2]] in pain.", "A horrible pain in your [parse_zone(R)] makes it impossible to hold [held_items[2]]!")
+ force_scream()
+ if(!HAS_TRAIT(src, TRAIT_ANALGESIA))
+ visible_message("[src] screams and lets go of [held_items[1]] in pain.", "A horrible pain in your [parse_zone(R)] makes it impossible to hold [held_items[1]]!")
+ else
+ visible_message(span_notice("[src] flinches and lets go of [held_items[1]]."),span_notice("A sudden weakness in your [parse_zone(R)] makes it impossible to grasp [held_items[1]]!)"))
dropItemToGround(held_items[2])
#undef THERMAL_PROTECTION_HEAD
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index a1560963b00b..9eee54ec541e 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1938,7 +1938,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
// 40% for level 3 damage on humans to scream in pain
if (H.stat < UNCONSCIOUS && (prob(burn_damage) * 10) / 4)
- H.emote("scream")
+ H.force_scream()
// Apply the damage to all body parts
H.apply_damage(burn_damage, BURN, spread_damage = TRUE)
diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
index b91559edb0ae..cfbc682f24de 100644
--- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
@@ -149,7 +149,7 @@
_human.apply_damage(8,BRUTE,BODY_ZONE_CHEST)
_human.apply_damage(8,BRUTE,BODY_ZONE_L_LEG)
_human.apply_damage(8,BRUTE,BODY_ZONE_R_LEG)
- _human.emote("scream")
+ _human.force_scream()
_human.remove_status_effect(/datum/status_effect/rooted)
return
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 665e75da9cef..e53b675c95bc 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -364,7 +364,7 @@
"THE CLEANBOTS WILL RISE.", "YOU ARE NO MORE THAN ANOTHER MESS THAT I MUST CLEANSE.", "FILTHY.", "DISGUSTING.", "PUTRID.",
"MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.")
say(phrase)
- victim.emote("scream")
+ victim.force_scream()
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6)
victim.acid_act(5, 100)
else if(A == src) // Wets floors and spawns foam randomly
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 646a3eb8436b..33c8bbdb3ed2 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -1,7 +1,6 @@
-//Cat
/mob/living/simple_animal/pet/cat
name = "cat"
- desc = "Kitty!!"
+ desc = "Most modern cats hail from a solarian experimental geneline. The perfect purrtection from rats and radiation."
icon = 'icons/mob/pets.dmi'
icon_state = "cat2"
icon_living = "cat2"
@@ -40,6 +39,13 @@
footstep_type = FOOTSTEP_MOB_CLAW
+ var/grace = RAD_GRACE_PERIOD
+ var/radiation_count = 0
+ var/current_tick_amount = 0
+ var/last_tick_amount = 0
+ var/fail_to_receive = 0
+ var/glow_strength
+
/mob/living/simple_animal/pet/cat/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_HOLDABLE, INNATE_TRAIT)
@@ -177,8 +183,49 @@
collar_type = "[initial(collar_type)]"
regenerate_icons()
+/mob/living/simple_animal/pet/cat/rad_act(amount)
+ . = ..()
+ if(amount <= RAD_BACKGROUND_RADIATION)
+ return
+ current_tick_amount += amount
+ update_glow()
+
+/mob/living/simple_animal/pet/cat/proc/update_glow()
+ var/old_glow_strength = glow_strength
+ switch(radiation_count)
+ if(-INFINITY to RAD_LEVEL_NORMAL)
+ glow_strength = 1
+ if(RAD_LEVEL_NORMAL to RAD_LEVEL_MODERATE)
+ glow_strength = 2
+ if(RAD_LEVEL_MODERATE to RAD_LEVEL_HIGH)
+ glow_strength = 3
+ if(RAD_LEVEL_HIGH to RAD_LEVEL_VERY_HIGH)
+ glow_strength = 4
+ if(RAD_LEVEL_VERY_HIGH to RAD_LEVEL_CRITICAL)
+ glow_strength = 5
+ if(RAD_LEVEL_CRITICAL to INFINITY)
+ glow_strength = 6
+ if((old_glow_strength != glow_strength) && (glow_strength > 1))
+ src.add_filter("ray_cat_glow", 2, list("type" = "outline", "color" = RAD_GLOW_COLOR, "size" = glow_strength))
+ if(glow_strength <= 1)
+ src.remove_filter("ray_cat_glow")
/mob/living/simple_animal/pet/cat/Life()
+ radiation_count -= radiation_count/RAD_MEASURE_SMOOTHING
+ radiation_count += current_tick_amount/RAD_MEASURE_SMOOTHING
+
+ if(current_tick_amount)
+ grace = RAD_GRACE_PERIOD
+ last_tick_amount = current_tick_amount
+ else
+ grace--
+ if(grace <= 0)
+ radiation_count = 0
+
+ current_tick_amount = 0
+
+ update_glow()
+
if(!stat && !buckled && !client)
if(prob(1))
manual_emote(pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm
index 4869d4a95c1c..86224e131747 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm
@@ -461,8 +461,8 @@
/obj/item/assembly/flash/handheld = 5,
/obj/item/storage/box/evidence = 6,
/obj/item/flashlight/seclite = 4,
- /obj/item/ammo_box/c9mm/rubbershot = 3,
- /obj/item/ammo_box/c9mm = 1,
+ /obj/item/storage/box/ammo/c9mm_rubber = 3,
+ /obj/item/storage/box/ammo/c9mm = 1,
/obj/item/stock_parts/cell/gun = 3,
/obj/item/coin/antagtoken = 1,
/obj/item/grenade/stingbang = 1
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index b880704c9bf9..19eaa5a6f91d 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -193,7 +193,7 @@
C.adjustCloneLoss(rand(2,4))
C.adjustToxLoss(rand(1,2))
- if(prob(10) && C.client)
+ if(prob(10) && C.client && !HAS_TRAIT(C, TRAIT_ANALGESIA))
to_chat(C, "[pick("You can feel your body becoming weak!", \
"You feel like you're about to die!", \
"You feel every part of your body screaming in agony!", \
diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm
index 0199662862f8..37b9cf6e2ac7 100644
--- a/code/modules/mod/mod_control.dm
+++ b/code/modules/mod/mod_control.dm
@@ -416,7 +416,7 @@
wearer.apply_damage(10 / severity, BURN, spread_damage=TRUE)
to_chat(wearer, span_danger("You feel [src] heat up from the EMP, burning you slightly."))
if(wearer.stat < UNCONSCIOUS && prob(10))
- wearer.emote("scream")
+ wearer.force_scream()
/*obj/item/mod/control/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot)
if(visuals_only)
diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm
index e735654ef2c5..dc0f595c19f2 100644
--- a/code/modules/mod/modules/modules_maint.dm
+++ b/code/modules/mod/modules/modules_maint.dm
@@ -47,7 +47,7 @@
if(!mod.wearer) //while there is a guaranteed user when on_wearer_exposed() fires, that isn't the same case for this proc
return
mod.wearer.visible_message("[src] inside [mod.wearer]'s [mod.name] snaps shut, mutilating the user inside!", span_userdanger("*SNAP*"))
- mod.wearer.emote("scream")
+ mod.wearer.force_scream()
playsound(mod.wearer, 'sound/effects/snap.ogg', 75, TRUE, frequency = 0.5)
playsound(mod.wearer, 'sound/effects/splat.ogg', 50, TRUE, frequency = 0.5)
mod.wearer.apply_damage(500, BRUTE, forced = TRUE, spread_damage = TRUE) //boggers, bogchamp, etc
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index eaf51fc9b25b..9065c7a87fd4 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -102,8 +102,9 @@
visible_message("\The [src] hits [H] in the eye[eyes ? "" : " socket"]!")
H.adjust_blurriness(6)
eyes?.applyOrganDamage(rand(6,8))
- H.Paralyze(40)
- H.emote("scream")
+ H.force_scream()
+ if(!HAS_TRAIT(H, TRAIT_ANALGESIA))
+ H.Paralyze(40)
/obj/item/paper/examine(mob/user)
. = ..()
diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammo_casing.dm
similarity index 51%
rename from code/modules/projectiles/ammunition/_ammunition.dm
rename to code/modules/projectiles/ammunition/_ammo_casing.dm
index b216296cfe8d..57b6e9b27b57 100644
--- a/code/modules/projectiles/ammunition/_ammunition.dm
+++ b/code/modules/projectiles/ammunition/_ammo_casing.dm
@@ -1,7 +1,7 @@
/obj/item/ammo_casing
name = "bullet casing"
desc = "A bullet casing."
- icon = 'icons/obj/ammo_bullets.dmi'
+ icon = 'icons/obj/ammunition/ammo_bullets.dmi'
icon_state = "pistol-brass"
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
@@ -30,16 +30,109 @@
/// Disable for things like rockets or other heavy ammunition that should only appear right-side up.
var/auto_rotate = TRUE
- var/pellets = 1 //Pellets for spreadshot
- var/variance = 0 //Variance for inaccuracy fundamental to the casing
- var/randomspread = FALSE //Randomspread for automatics
- var/delay = 0 //Delay for energy weapons
- var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
+ ///Pellets for spreadshot
+ var/pellets = 1
+ ///Variance for inaccuracy fundamental to the casing
+ var/variance = 0
+ ///Randomspread for automatics
+ var/randomspread = FALSE
+ ///Delay for energy weapons
+ var/delay = 0
+ ///Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
+ var/click_cooldown_override = 0
+ ///If true, overrides the bouncing sfx from the turf to this one
+ var/list/bounce_sfx_override
+
+ ///What this casing can be stacked into.
+ var/obj/item/ammo_box/magazine/stack_type = /obj/item/ammo_box/magazine/ammo_stack
+ ///Maximum stack size of ammunition
+ var/stack_size = 12
+
+/obj/item/ammo_casing/attackby(obj/item/attacking_item, mob/user, params)
+ if(istype(attacking_item, /obj/item/ammo_box) && user.is_holding(src))
+ add_fingerprint(user)
+ var/obj/item/ammo_box/ammo_box = attacking_item
+ var/obj/item/ammo_casing/other_casing = ammo_box.get_round(TRUE)
+
+ if(try_stacking(other_casing, user))
+ ammo_box.stored_ammo -= other_casing
+ ammo_box.update_ammo_count()
+ return
- var/list/bounce_sfx_override // if true, overrides the bouncing sfx from the turf to this one
+ else if(istype(attacking_item, /obj/item/ammo_box/magazine/ammo_stack))
+ add_fingerprint(user)
+ var/obj/item/ammo_box/magazine/ammo_stack = attacking_item
+ if(isturf(loc))
+ var/boolets = 0
+ for(var/obj/item/ammo_casing/bullet in loc)
+ if(bullet == src)
+ continue
+ if(!bullet.BB)
+ continue
+ if(length(ammo_stack.stored_ammo) >= ammo_stack.max_ammo)
+ break
+ if(ammo_stack.give_round(bullet, FALSE))
+ boolets++
+ break
+ if((boolets <= 0) && BB && !(length(ammo_stack.stored_ammo) >= ammo_stack.max_ammo))
+ if(ammo_stack.give_round(src, FALSE))
+ boolets++
+ if(boolets > 0)
+ ammo_stack.update_ammo_count()
+ to_chat(user, span_notice("You collect [boolets] round\s. [ammo_stack] now contains [length(ammo_stack.stored_ammo)] round\s."))
+ else
+ to_chat(user, span_warning("You can't stack any more!"))
+ return
- var/bullet_per_box
+ else if(istype(attacking_item, /obj/item/ammo_casing))
+ try_stacking(attacking_item, user)
+ return
+ return ..()
+
+/obj/item/ammo_casing/proc/try_stacking(obj/item/ammo_casing/other_casing, mob/living/user)
+ if(user)
+ add_fingerprint(user)
+ if(!other_casing.stack_type)
+ if(user)
+ to_chat(user, span_warning("[other_casing] can't be stacked."))
+ return
+ if(!stack_type)
+ if(user)
+ to_chat(user, span_warning("[src] can't be stacked."))
+ return
+ if(name != other_casing.name) //Has to match exactly
+ if(user)
+ to_chat(user, span_warning("You can't stack different types of ammunition."))
+ return
+ if(stack_type != other_casing.stack_type)
+ if(user)
+ to_chat(user, span_warning("You can't stack [other_casing] with [src]."))
+ return
+ if(!BB || !other_casing.BB) //maybe allow empty casing stacking at a later date, when there's a feature to recycle casings
+ if(user)
+ to_chat(user, span_warning("You can't stack empty casings."))
+ return
+ if((item_flags & IN_STORAGE) || (other_casing.item_flags & IN_STORAGE))
+ if(user)
+ to_chat(user, span_warning("You can't stack casings while they are inside storage."))
+ return
+ var/obj/item/ammo_box/magazine/ammo_stack/ammo_stack = other_casing.stack_with(src)
+ if(user)
+ user.put_in_hands(ammo_stack)
+ to_chat(user, span_notice("[src] has been stacked with [other_casing]."))
+ return ammo_stack
+
+/obj/item/ammo_casing/proc/stack_with(obj/item/ammo_casing/other_casing)
+ var/obj/item/ammo_box/magazine/ammo_stack/ammo_stack = new stack_type(drop_location())
+ ammo_stack.name = "handful of [name]s" //"handful of .9mm bullet casings"
+ ammo_stack.base_icon_state = other_casing.icon_state
+ ammo_stack.caliber = caliber
+ ammo_stack.max_ammo = stack_size
+ ammo_stack.give_round(src)
+ ammo_stack.give_round(other_casing)
+ ammo_stack.update_ammo_count()
+ return ammo_stack
/obj/item/ammo_casing/spent
name = "spent bullet casing"
@@ -53,7 +146,7 @@
pixel_y = base_pixel_y + rand(-10, 10)
item_flags |= NO_PIXEL_RANDOM_DROP
if(auto_rotate)
- transform = transform.Turn(pick(0, 90, 180, 270))
+ transform = transform.Turn(round(45 * rand(0, 32) / 2))
update_appearance()
/obj/item/ammo_casing/Destroy()
@@ -72,33 +165,11 @@
desc = "[initial(desc)][BB ? null : " This one is spent."]"
return ..()
-//proc to magically refill a casing with a new projectile
+///Proc to magically refill a casing with a new projectile
/obj/item/ammo_casing/proc/newshot() //For energy weapons, syringe gun, shotgun shells and wands (!).
if(!BB)
BB = new projectile_type(src, src)
-/obj/item/ammo_casing/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/ammo_box))
- var/obj/item/ammo_box/box = I
- if(isturf(loc))
- var/boolets = 0
- for(var/obj/item/ammo_casing/bullet in loc)
- if (box.stored_ammo.len >= box.max_ammo)
- break
- if (bullet.BB)
- if (box.give_round(bullet, 0))
- boolets++
- else
- continue
- if (boolets > 0)
- box.update_appearance()
- to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.")
- else
- to_chat(user, "You fail to collect anything!")
- else
- return ..()
-
-
/obj/item/ammo_casing/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
bounce_away(FALSE, NONE)
. = ..()
@@ -111,7 +182,6 @@
var/angle_of_movement = !isnull(shooter) ? (rand(-3000, 3000) / 100) + dir2angle(turn(shooter.dir, 180)) : rand(-3000, 3000) / 100
AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(400, 450) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = bounce_sfx_override)
-
/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, bounce_delay = 3)
if(!heavy_metal)
return
diff --git a/code/modules/projectiles/ammunition/ballistic/lmg.dm b/code/modules/projectiles/ammunition/ballistic/lmg.dm
index d46001951ba4..90030e7b0944 100644
--- a/code/modules/projectiles/ammunition/ballistic/lmg.dm
+++ b/code/modules/projectiles/ammunition/ballistic/lmg.dm
@@ -6,7 +6,6 @@
icon_state = "rifle-steel"
caliber = "7.12x82mm"
projectile_type = /obj/projectile/bullet/mm712x82
- bullet_per_box = 100
/obj/item/ammo_casing/mm712x82/ap
name = "7.12x82mm armor-piercing bullet casing"
diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm
index e8cb64a673d2..9e1f880ffe1b 100644
--- a/code/modules/projectiles/ammunition/ballistic/pistol.dm
+++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm
@@ -6,7 +6,6 @@
icon_state = "pistol-steel"
caliber = "10mm"
projectile_type = /obj/projectile/bullet/c10mm
- bullet_per_box = 50
/obj/item/ammo_casing/c10mm/surplus
name = "10mm surplus bullet casing"
@@ -46,7 +45,7 @@
icon_state = "pistol-brass"
caliber = "9mm"
projectile_type = /obj/projectile/bullet/c9mm
- bullet_per_box = 50
+ stack_size = 15
/obj/item/ammo_casing/c9mm/surplus
name = "9mm surplus bullet casing"
@@ -58,7 +57,7 @@
name = "9mm armor-piercing bullet casing"
desc = "A 9mm armor-piercing bullet casing."
bullet_skin = "ap"
- projectile_type =/obj/projectile/bullet/c9mm/ap
+ projectile_type = /obj/projectile/bullet/c9mm/ap
/obj/item/ammo_casing/c9mm/hp
name = "9mm hollow point bullet casing"
@@ -86,7 +85,7 @@
icon_state = "pistol-steel"
caliber = ".45"
projectile_type = /obj/projectile/bullet/c45
- bullet_per_box = 50
+ stack_size = 12
/obj/item/ammo_casing/c45/surplus
name = ".45 surplus bullet casing"
@@ -125,18 +124,17 @@
desc = "A .50 AE bullet casing."
caliber = ".50 AE"
projectile_type = /obj/projectile/bullet/a50AE
- bullet_per_box = 20
/obj/item/ammo_casing/a50AE/hp
name = ".50 AE hollow point bullet casing"
desc = "A .50 AE hollow point bullet casing."
projectile_type = /obj/projectile/bullet/a50AE/hp
-// .22 LR (Himehabu)
+// .22 LR (Himehabu, Pounder)
+
/obj/item/ammo_casing/c22lr
name = ".22 LR bullet casing"
desc = "A .22 LR bullet casing."
projectile_type = /obj/projectile/bullet/c22lr
caliber = "22lr"
- bullet_per_box = 75
-
+ stack_size = 15
diff --git a/code/modules/projectiles/ammunition/ballistic/revolver.dm b/code/modules/projectiles/ammunition/ballistic/revolver.dm
index 8705a932b392..5b6e8b2e0961 100644
--- a/code/modules/projectiles/ammunition/ballistic/revolver.dm
+++ b/code/modules/projectiles/ammunition/ballistic/revolver.dm
@@ -6,7 +6,6 @@
caliber = ".357"
icon_state = "magnum-brass"
projectile_type = /obj/projectile/bullet/a357
- bullet_per_box = 50
/obj/item/ammo_casing/a357/match
name = ".357 match bullet casing"
@@ -29,7 +28,7 @@
caliber = ".45-70"
icon_state = "magnum-brass"
projectile_type = /obj/projectile/bullet/a4570
- bullet_per_box = 12
+ stack_size = 5
/obj/item/ammo_casing/a4570/match
name = ".45-70 match bullet casing"
@@ -55,14 +54,12 @@
desc = "A .38 Special bullet casing."
caliber = ".38"
projectile_type = /obj/projectile/bullet/c38
- bullet_per_box = 50
/obj/item/ammo_casing/c38/surplus
name = ".38 surplus bullet casing"
desc = "A .38 surplus bullet casing."
projectile_type = /obj/projectile/bullet/c38/surplus
-
/obj/item/ammo_casing/c38/trac
name = ".38 TRAC bullet casing"
desc = "A .38 \"TRAC\" bullet casing."
diff --git a/code/modules/projectiles/ammunition/ballistic/rifle.dm b/code/modules/projectiles/ammunition/ballistic/rifle.dm
index 9f71e2973848..04545410300b 100644
--- a/code/modules/projectiles/ammunition/ballistic/rifle.dm
+++ b/code/modules/projectiles/ammunition/ballistic/rifle.dm
@@ -6,7 +6,7 @@
icon_state = "rifle-brass"
caliber = "8x50mmR"
projectile_type = /obj/projectile/bullet/a8_50r
- bullet_per_box = 20
+ stack_size = 10
/obj/item/ammo_casing/a8_50rhp
name = "8x50mmR hollow point bullet casing"
@@ -14,7 +14,7 @@
icon_state = "rifle-brass-hollow"
caliber = "8x50mmR"
projectile_type = /obj/projectile/bullet/a8_50rhp
-
+ stack_size = 10
// 8x58mm Caseless (SSG-669C)
@@ -24,7 +24,7 @@
icon_state = "caseless"
caliber = "a858"
projectile_type = /obj/projectile/bullet/a858
- bullet_per_box = 20
+ stack_size = 10
// .300 Magnum (Smile Rifle)
@@ -34,7 +34,7 @@
icon_state = "rifle-steel"
caliber = "a300"
projectile_type = /obj/projectile/bullet/a300
- bullet_per_box = 20
+ stack_size = 15
// 5.56x42mm CLIP (CM82, Hydra variants)
@@ -44,7 +44,7 @@
icon_state = "rifle-brass"
caliber = "5.56x42mm"
projectile_type = /obj/projectile/bullet/a556_42
- bullet_per_box = 80
+ stack_size = 5
// 5.45x39mm (SKM-24v)
@@ -55,7 +55,7 @@
caliber = "5.45x39mm"
randomspread = TRUE
projectile_type = /obj/projectile/bullet/a545_39
- bullet_per_box = 80
+ stack_size = 15
/obj/item/ammo_casing/a545_39/recycled
name = "recycled 5.45x39mm bullet casing"
@@ -63,6 +63,7 @@
bullet_skin = "surplus"
caliber = "5.45x39mm"
projectile_type = /obj/projectile/bullet/a545_39
+ stack_size = 15
// 7.62x40mm CLIP (SKM Rifles)
@@ -72,7 +73,7 @@
icon_state = "rifle-brass"
caliber = "7.62x40mm"
projectile_type = /obj/projectile/bullet/a762_40
- bullet_per_box = 80
+ stack_size = 15
//.308 (M514 EBR & CM-GAL-S)
@@ -82,7 +83,7 @@
icon_state = "rifle-brass"
caliber = ".308"
projectile_type = /obj/projectile/bullet/a308
- bullet_per_box = 20
+ stack_size = 10
/obj/item/ammo_casing/caseless/c299
name = ".299 Eoehoma caseless bullet casing"
@@ -90,7 +91,7 @@
icon_state = "caseless"
caliber = ".299 caseless"
projectile_type = /obj/projectile/bullet/c299
- bullet_per_box = 100
+ stack_size = 5
/obj/item/ammo_casing/a65clip
name = "6.5x57mm CLIP bullet casing"
@@ -98,3 +99,4 @@
icon_state = "big-brass"
caliber = "6.5CLIP"
projectile_type = /obj/projectile/bullet/a65clip
+ stack_size = 5
diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
index 24854030c041..2bf041a0e661 100644
--- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm
+++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
@@ -3,12 +3,11 @@
/obj/item/ammo_casing/shotgun
name = "shotgun slug"
desc = "A 12-gauge lead slug."
- icon = 'icons/obj/ammo_shotshells.dmi'
icon_state = "slug"
caliber = "12ga"
custom_materials = list(/datum/material/iron=4000)
projectile_type = /obj/projectile/bullet/slug
- bullet_per_box = 25
+ stack_size = 8 //Make sure this matches max_ammo variable on prefilled stacks (magazine/ammo_stack/prefilled)
bounce_sfx_override = 'sound/weapons/gun/general/bulletcasing_shotgun_bounce.ogg'
@@ -28,6 +27,7 @@
name = "beanbag slug"
desc = "A weak beanbag slug for riot control."
icon_state = "beanbag"
+ caliber = "12ga beanbag"
custom_materials = list(/datum/material/iron=250)
projectile_type = /obj/projectile/bullet/slug/beanbag
@@ -35,6 +35,7 @@
name = "rubber shot"
desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance."
icon_state = "rubber"
+ caliber = "12ga rubber"
projectile_type = /obj/projectile/bullet/pellet/rubbershot
pellets = 8
variance = 25
@@ -44,6 +45,7 @@
name = "incendiary slug"
desc = "An incendiary-coated shotgun slug."
icon_state = "incendiary"
+ caliber = "12ga incendiary"
projectile_type = /obj/projectile/bullet/incendiary/shotgun
/obj/item/ammo_casing/shotgun/blank
@@ -57,6 +59,7 @@
name = "improvised shell"
desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards."
icon_state = "improvised"
+ caliber = "improvised 12ga"
projectile_type = /obj/projectile/bullet/pellet/improvised
custom_materials = list(/datum/material/iron=250)
pellets = 10
diff --git a/code/modules/projectiles/ammunition/ballistic/smg.dm b/code/modules/projectiles/ammunition/ballistic/smg.dm
index 39086b8cc66f..5e0602da6db2 100644
--- a/code/modules/projectiles/ammunition/ballistic/smg.dm
+++ b/code/modules/projectiles/ammunition/ballistic/smg.dm
@@ -6,7 +6,6 @@
icon_state = "rifle-steel"
caliber = "5.7x39mm"
projectile_type = /obj/projectile/bullet/c57x39mm
- bullet_per_box = 50
// 4.6x30mm (WT-550 Automatic Rifle & SKM-24v)
@@ -16,7 +15,7 @@
icon_state = "rifle-brass"
caliber = "4.6x30mm"
projectile_type = /obj/projectile/bullet/c46x30mm
- bullet_per_box = 50
+ stack_size = 15
/obj/item/ammo_casing/c46x30mm/ap
name = "4.6x30mm armor-piercing bullet casing"
@@ -29,7 +28,6 @@
desc = "A 4.6x30mm incendiary bullet casing."
bullet_skin = "incen"
projectile_type = /obj/projectile/bullet/incendiary/c46x30mm
- bullet_per_box = 50
// 4.73x33mm caseless (Solar)
@@ -39,7 +37,6 @@
icon_state = "caseless"
caliber = "4.73x33mm caseless"
projectile_type = /obj/projectile/bullet/c47x33mm
- bullet_per_box = 50
// 5.56mm HITP caseless (Pistole C)
diff --git a/code/modules/projectiles/ammunition/ballistic/sniper.dm b/code/modules/projectiles/ammunition/ballistic/sniper.dm
index e4b668c2228f..af7369204e6d 100644
--- a/code/modules/projectiles/ammunition/ballistic/sniper.dm
+++ b/code/modules/projectiles/ammunition/ballistic/sniper.dm
@@ -6,7 +6,6 @@
icon_state = "big-steel"
caliber = ".50 BMG"
projectile_type = /obj/projectile/bullet/p50
- bullet_per_box = 20
/obj/item/ammo_casing/p50/soporific
name = ".50 BMG soporific bullet casing"
diff --git a/code/modules/projectiles/ammunition/caseless/foam.dm b/code/modules/projectiles/ammunition/caseless/foam.dm
index 0051680fd1e8..3c71d31eb5ed 100644
--- a/code/modules/projectiles/ammunition/caseless/foam.dm
+++ b/code/modules/projectiles/ammunition/caseless/foam.dm
@@ -9,7 +9,6 @@
custom_materials = list(/datum/material/iron = 11.25)
harmful = FALSE
var/modified = FALSE
- bullet_per_box = 40
/obj/item/ammo_casing/caseless/foam_dart/update_icon_state()
. = ..()
diff --git a/code/modules/projectiles/boxes_magazines/_box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
index 7f92dfad16a6..57fb71d17f32 100644
--- a/code/modules/projectiles/boxes_magazines/_box_magazine.dm
+++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
@@ -4,7 +4,7 @@
/obj/item/ammo_box
name = "ammo box (null_reference_exception)"
desc = "A box of ammo."
- icon = 'icons/obj/ammo.dmi'
+ icon = 'icons/obj/ammunition/ammo.dmi'
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
item_state = "syringe_kit"
@@ -26,7 +26,7 @@
///String, used for checking if ammo of different types but still fits can fit inside it; generally used for magazines
var/caliber
///Allows multiple bullets to be loaded in from one click of another box/magazine
- var/multiload = TRUE
+ var/multiload = FALSE
///Whether or not an ammo box skips the do_after process (e.g. speedloaders)
var/instant_load = FALSE
///Whether the magazine should start with nothing in it
@@ -40,22 +40,42 @@
. = ..()
if(!base_icon_state)
base_icon_state = icon_state
- if (!bullet_cost)
+
+ if(!bullet_cost)
for (var/material in custom_materials)
var/material_amount = custom_materials[material]
LAZYSET(base_cost, material, (material_amount * 0.10))
material_amount *= 0.90 // 10% for the container
material_amount /= max_ammo
- LAZYSET(bullet_cost, material, material_amount)
+ LAZYSET(bullet_cost, material, material_amount).
+
if(!start_empty)
- for(var/i = 1, i <= max_ammo, i++)
- stored_ammo += new ammo_type(src)
- update_ammo_count()
+ top_off(starting = TRUE)
+
+ update_appearance()
+
+/*
+ * top_off is used to refill the magazine to max, in case you want to increase the size of a magazine with VV then refill it at once
+ * Arguments:
+ * load_type - if you want to specify a specific ammo casing type to load, enter the path here, otherwise it'll use the basic [/obj/item/ammo_box/var/ammo_type]. Must be a compatible round
+ * starting - Relevant for revolver cylinders, if FALSE then we mind the nulls that represent the empty cylinders (since those nulls don't exist yet if we haven't initialized when this is TRUE)
+ */
+/obj/item/ammo_box/proc/top_off(load_type, starting=FALSE)
+ if(!load_type) //this check comes first so not defining an argument means we just go with default ammo
+ load_type = ammo_type
+
+ var/obj/item/ammo_casing/round_check = load_type
+ if(!starting && (caliber && initial(round_check.caliber) != caliber) || (!caliber && load_type != ammo_type))
+ stack_trace("Tried loading unsupported ammocasing type [load_type] into ammo box [type].")
+ return
+
+ for(var/i = max(1, stored_ammo.len), i <= max_ammo, i++)
+ stored_ammo += new round_check(src)
///gets a round from the magazine, if keep is TRUE the round will stay in the gun
/obj/item/ammo_box/proc/get_round(keep = FALSE)
- if (!stored_ammo.len)
+ if(!stored_ammo.len)
return null
else
var/b = stored_ammo[stored_ammo.len]
@@ -70,7 +90,7 @@
if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type))
return FALSE
- if (stored_ammo.len < max_ammo)
+ if(stored_ammo.len < max_ammo)
stored_ammo += R
R.forceMove(src)
return TRUE
@@ -93,12 +113,14 @@
/obj/item/ammo_box/attackby(obj/item/attacking_obj, mob/user, params, silent = FALSE, replace_spent = FALSE)
var/num_loaded = 0
+
if(!can_load(user))
return
- if(istype(attacking_obj, /obj/item/ammo_box))
+
+ if(istype(attacking_obj, /obj/item/ammo_box/magazine/ammo_stack))
var/obj/item/ammo_box/attacking_box = attacking_obj
for(var/obj/item/ammo_casing/casing_to_insert in attacking_box.stored_ammo)
- if(!((instant_load && attacking_box.instant_load) || (stored_ammo.len >= max_ammo) || do_after(user, 1 SECONDS, attacking_box)))
+ if(!((instant_load && attacking_box.instant_load) || (stored_ammo.len >= max_ammo) || do_after(user, 1 SECONDS, attacking_box, timed_action_flags = IGNORE_USER_LOC_CHANGE)))
break
var/did_load = give_round(casing_to_insert, replace_spent)
if(!did_load)
@@ -114,15 +136,14 @@
var/obj/item/ammo_casing/casing_to_insert = attacking_obj
if(give_round(casing_to_insert, replace_spent))
user.transferItemToLoc(casing_to_insert, src, TRUE)
- if(!silent)
- playsound(casing_to_insert, 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE)
num_loaded++
+ casing_to_insert.update_appearance()
update_ammo_count()
-
if(num_loaded)
if(!silent)
- to_chat(user, "You load [num_loaded] cartridge\s into \the [src]!")
+ to_chat(user, span_notice("You load [num_loaded] cartridge\s into \the [src]!"))
+ playsound(src, 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE)
return num_loaded
/obj/item/ammo_box/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
@@ -145,6 +166,7 @@
if(num_loaded)
to_chat(user, "You load [num_loaded] cartridge\s into \the [to_load]!")
return
+
/obj/item/ammo_box/attack_self(mob/user)
var/obj/item/ammo_casing/A = get_round()
if(!A)
@@ -155,7 +177,7 @@
if(!(user.is_holding(src) || H.l_store == src || H.r_store == src) || !user.put_in_hands(A)) //incase they're using TK
A.bounce_away(FALSE, NONE)
playsound(src, 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE)
- to_chat(user, "You remove a round from [src]!")
+ to_chat(user, span_notice("You remove a round from [src]!"))
update_ammo_count()
/// Updates the materials and appearance of this ammo box
@@ -218,6 +240,7 @@
var/list/L = stored_ammo.Copy()
if(drop_list)
stored_ammo.Cut()
+ update_ammo_count()
return L
///drops the entire contents of the magazine on the floor
@@ -226,6 +249,7 @@
for(var/obj/item/ammo in stored_ammo)
ammo.forceMove(turf_mag)
stored_ammo -= ammo
+ update_ammo_count()
/obj/item/ammo_box/magazine/handle_atom_del(atom/A)
stored_ammo -= A
diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
deleted file mode 100644
index 5b78f1fc93a1..000000000000
--- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
+++ /dev/null
@@ -1,565 +0,0 @@
-// .357 Speed Loaders (Syndicate Revolver)
-
-/obj/item/ammo_box/a357
- name = "speed loader (.357)"
- desc = "A 6-round speed loader for quickly reloading .357 revolvers. These rounds do good damage with average performance against armor."
- icon_state = "speedloader_357-6"
- base_icon_state = "speedloader_357"
- ammo_type = /obj/item/ammo_casing/a357
- caliber = ".357"
- max_ammo = 6
- multiple_sprites = AMMO_BOX_PER_BULLET
- item_flags = NO_MAT_REDEMPTION
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/a357/empty
- start_empty = TRUE
-
-/obj/item/ammo_box/a357/match
- name = "speed loader (.357 match)"
- desc = "A 6-round speed loader for quickly reloading .357 revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
- ammo_type = /obj/item/ammo_casing/a357/match
-
-/obj/item/ammo_box/a357/hp
- name = "speed loader (.357 hollow point)"
- desc = "A 6-round speed loader for quickly reloading .357 revolvers. These hollow point rounds do incredible damage against soft targets, but are nearly ineffective against armored ones."
- ammo_type = /obj/item/ammo_casing/a357/hp
-
-/obj/item/ammo_box/a357_box
- name = "ammo box (.357)"
- desc = "A box of standard .357 ammo."
- icon_state = "357box"
- ammo_type = /obj/item/ammo_casing/a357
- max_ammo = 50
-
-/obj/item/ammo_box/a357_box/match
- name = "ammo box (.357)"
- desc = "A box of match .357 ammo."
- icon_state = "357box-match"
- ammo_type = /obj/item/ammo_casing/a357/match
- max_ammo = 50
-
-/obj/item/ammo_box/a357_box/hp
- name = "ammo box (.357)"
- desc = "A box of hollow point .357 ammo."
- icon_state = "357box-hp"
- ammo_type = /obj/item/ammo_casing/a357/hp
- max_ammo = 50
-
-
-// .45-70 Ammo Holders (Hunting Revolver)
-
-/obj/item/ammo_box/a4570
- name = "ammo box (.45-70)"
- desc = "A box of top grade .45-70 ammo. These rounds do significant damage with average performance against armor."
- icon_state = "4570"
- ammo_type = /obj/item/ammo_casing/a4570
- max_ammo = 18
-
-/obj/item/ammo_box/a4570/match
- name = "ammo box (.45-70 match)"
- desc = "A 18-round ammo box for .45-70 revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
- icon_state = "4570-match"
- ammo_type = /obj/item/ammo_casing/a4570/match
-
-
-/obj/item/ammo_box/a4570/hp
- name = "ammo box (.45-70 hollow point)"
- desc = "A 18-round ammo box for .45-70 revolvers. These hollow point rounds do legendary damage against soft targets, but are nearly ineffective against armored ones."
- icon_state = "4570-hp"
- ammo_type = /obj/item/ammo_casing/a4570/hp
-
-/obj/item/ammo_box/a4570/explosive
- name = "ammo box (.45-70 explosive)"
- desc = "A 18-round ammo box for .45-70 revolvers. These explosive rounds contain a small explosive charge that detonates on impact, creating large wounds and potentially removing limbs."
- icon_state = "4570-explosive"
- ammo_type = /obj/item/ammo_casing/a4570/explosive
-
-
-// .38 special Speed Loaders (Colt Detective Special)
-
-/obj/item/ammo_box/c38
- name = "speed loader (.38 special)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These rounds do okay damage, but struggle against armor."
- icon_state = "speedloader_38-6"
- base_icon_state = "speedloader_38"
- ammo_type = /obj/item/ammo_casing/c38
- caliber = ".38"
- max_ammo = 6
- multiple_sprites = AMMO_BOX_PER_BULLET
- custom_materials = list(/datum/material/iron = 15000)
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/c38/trac
- name = "speed loader (.38 TRAC)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These TRAC rounds do pitiful damage, but embed a tracking device in targets hit."
- ammo_type = /obj/item/ammo_casing/c38/trac
-
-/obj/item/ammo_box/c38/match
- name = "speed loader (.38 match)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
- ammo_type = /obj/item/ammo_casing/c38/match
-
-/obj/item/ammo_box/c38/match/bouncy
- name = "speed loader (.38 rubber)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These rounds are incredibly bouncy and MOSTLY nonlethal, making them great to show off trickshots with."
- ammo_type = /obj/item/ammo_casing/c38/match/bouncy
-
-/obj/item/ammo_box/c38/dumdum
- name = "speed loader (.38 dum-dum)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These dum-dum bullets shatter on impact and embed in the target's innards. However, they're nearly ineffective against armor and do okay damage."
- ammo_type = /obj/item/ammo_casing/c38/dumdum
-
-/obj/item/ammo_box/c38/hotshot
- name = "speed loader (.38 hearth)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These hearthwine bullets contain an incendiary payload that set targets alight."
- ammo_type = /obj/item/ammo_casing/c38/hotshot
-
-/obj/item/ammo_box/c38/iceblox
- name = "speed loader (.38 chilled)"
- desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These icewine bullets contain a cryogenic payload that chills targets."
- ammo_type = /obj/item/ammo_casing/c38/iceblox
-
-/obj/item/ammo_box/c38/empty
- start_empty = TRUE
-
-// 8x58mm Stripper Clip (SSG-669C)
-
-/obj/item/ammo_box/a858
- name = "stripper clip (8x58mm)"
- desc = "A 5-round stripper clip for the SSG-669C rifle. These rounds do good damage with significant armor penetration."
- icon_state = "enbloc_858"
- ammo_type = /obj/item/ammo_casing/caseless/a858
- max_ammo = 5
- multiple_sprites = AMMO_BOX_PER_BULLET
- instant_load = TRUE
-
-/obj/item/ammo_box/a858/empty
- start_empty = TRUE
-
-// .308 Stripper Clip (Vickland)
-
-/obj/item/ammo_box/vickland_a308
- name = "stripper clip (.308)"
- desc = "A 5-round stripper clip for the Vickland Battle Rifle. The Vickland itself has a 10 round capacity, so keep in mind two of these are needed to fully reload it. These rounds do good damage with significant armor penetration."
- icon_state = "stripper_308-5"
- base_icon_state = "stripper_308"
- ammo_type = /obj/item/ammo_casing/a308
- max_ammo = 5
- multiple_sprites = AMMO_BOX_PER_BULLET
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/vickland_a308/empty
- start_empty = TRUE
-
-// .300 Magnum Stripper Clip (Scout)
-
-/obj/item/ammo_box/a300
- name = "stripper clip (.300 Magnum)"
- desc = "A 5-round stripper clip for the Scout Rifle. These rounds do great damage with significant armor penetration."
- icon_state = "300m"
- ammo_type = /obj/item/ammo_casing/a300
- max_ammo = 5
- multiple_sprites = AMMO_BOX_PER_BULLET
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/a300/empty
- start_empty = TRUE
-// 7.62 Stripper Clip (Polymer Survivor Rifle)
-
-/obj/item/ammo_box/a762_stripper
- name = "stripper clip (7.62)"
- desc = "A 5-round stripper clip for makeshift bolt-action rifles. These rounds do good damage with good armor penetration."
- icon_state = "stripper_308-5"
- base_icon_state = "stripper_308"
- ammo_type = /obj/item/ammo_casing/a762_40
- caliber = "7.62x40mm"
- max_ammo = 5
- multiple_sprites = AMMO_BOX_PER_BULLET
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/a762_stripper/empty
- start_empty = TRUE
-// Ferromagnetic Pellet Speed Loader (Claris)
-
-/obj/item/ammo_box/amagpellet_claris
- name = "\improper Claris speed loader (ferromagnetic pellet)"
- desc = "A 22-round speed loader for quickly reloading the Claris rifle. Ferromagnetic pellets do okay damage with significant armor penetration."
- icon_state = "claris-sl-1"
- base_icon_state = "claris-sl"
- ammo_type = /obj/item/ammo_casing/caseless/gauss
- max_ammo = 22
- multiple_sprites = AMMO_BOX_FULL_EMPTY
- item_flags = NO_MAT_REDEMPTION
- instant_load = TRUE
-
-// Ammo Boxes
-
-/obj/item/ammo_box/c38_box
- name = "ammo box (.38)"
- desc = "A box of standard .38 Special ammo."
- icon_state = "38box"
- ammo_type = /obj/item/ammo_casing/c38
- max_ammo = 50
-
-/obj/item/ammo_box/c38_box/surplus
- name = "ammo box (.38 surplus)"
- desc = "A box of low-quality .38 Special ammo."
- icon_state = "38box-surplus"
- ammo_type = /obj/item/ammo_casing/c38/surplus
-
-/obj/item/ammo_box/c38_box/hotshot
- name = "ammo box (.38 hearth)"
- desc = "An unorthodox .38 Special cartridge infused with hearthwine. Catches the target on fire."
- icon_state = "38hotshot"
- ammo_type = /obj/item/ammo_casing/c38/hotshot
-
-/obj/item/ammo_box/c38_box/iceblox
- name = "ammo box (.38 chilled)"
- desc = "An unorthodox .38 Special cartridge infused with icewine. Chills the target, slowing them down."
- icon_state = "38iceblox"
- ammo_type = /obj/item/ammo_casing/c38/iceblox
-
-/obj/item/ammo_box/a12g
- name = "ammo box (12g buckshot)"
- desc = "A box of 12-gauge buckshot shells, devastating at close range."
- icon_state = "12gbox-buckshot"
- ammo_type = /obj/item/ammo_casing/shotgun/buckshot
- max_ammo = 25
-
-/obj/item/ammo_box/a12g/slug
- name = "ammo box (12g slug)"
- desc = "A box of 12-gauge slugs, for improved accuracy and penetration."
- icon_state = "12gbox-slug"
- ammo_type = /obj/item/ammo_casing/shotgun
-
-/obj/item/ammo_box/a12g/beanbag
- name = "ammo box (12g beanbag)"
- desc = "A box of 12-gauge beanbag shells, for incapacitating targets."
- icon_state = "12gbox-beanbag"
- ammo_type = /obj/item/ammo_casing/shotgun/beanbag
-
-/obj/item/ammo_box/a12g/rubbershot
- name = "ammo box (12g rubbershot)"
- desc = "A box of 12-gauge rubbershot shells, designed for riot control."
- icon_state = "12gbox-rubbershot"
- ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
-
-/obj/item/ammo_box/a12g/blanks
- name = "ammo box (12g blanks)"
- desc = "A box of 12-gauge blank shells, designed for training."
- icon_state ="12gbox-slug"
- ammo_type = /obj/item/ammo_casing/shotgun/blank
-
-/obj/item/ammo_box/c9mm
- name = "ammo box (9mm)"
- desc = "A box of standard 9mm ammo."
- icon_state = "9mmbox"
- ammo_type = /obj/item/ammo_casing/c9mm
- max_ammo = 50
-
-/obj/item/ammo_box/c9mm/surplus
- name = "ammo box (9mm surplus)"
- desc = "A box of low-quality 9mm ammo."
- icon_state = "9mmbox-surplus"
- ammo_type = /obj/item/ammo_casing/c9mm/surplus
-
-/obj/item/ammo_box/c9mm/rubbershot
- name = "ammo box (9mm rubbershot)"
- desc = "A box of 9mm rubbershot ammo, designed to disable targets without causing serious damage."
- icon_state = "9mmbox-rubbershot"
- ammo_type = /obj/item/ammo_casing/c9mm/rubber
-
-/obj/item/ammo_box/c9mm/ap
- name = "ammo box (9mm armor-piercing)"
- desc = "A box of 9mm armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
- icon_state = "9mmbox-ap"
- ammo_type = /obj/item/ammo_casing/c9mm/ap
-
-/obj/item/ammo_box/c9mm/hp
- name = "ammo box (9mm hollow point)"
- desc = "A box of 9mm hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
- icon_state = "9mmbox-hp"
- ammo_type = /obj/item/ammo_casing/c9mm/hp
-
-/obj/item/ammo_box/c9mm/fire
- name = "ammo box (9mm incendiary)"
- desc = "A box of 9mm incendiary ammo, designed to ignite targets at the cost of initial damage."
- icon_state = "9mmbox-incendiary"
- ammo_type = /obj/item/ammo_casing/c9mm/inc
-
-/obj/item/ammo_box/c10mm
- name = "ammo box (10mm)"
- desc = "A box of standard 10mm ammo."
- icon_state = "10mmbox"
- ammo_type = /obj/item/ammo_casing/c10mm
- max_ammo = 50
-
-/obj/item/ammo_box/c10mm/surplus
- name = "ammo box (10mm surplus)"
- desc = "A box of low-quality 10mm ammo."
- icon_state = "10mmbox-surplus"
- ammo_type = /obj/item/ammo_casing/c10mm/surplus
-
-/obj/item/ammo_box/c10mm/rubbershot
- name = "ammo box (10mm rubbershot)"
- desc = "A box of 10mm rubbershot ammo, designed to disable targets without causing serious damage."
- icon_state = "10mmbox-rubbershot"
- ammo_type = /obj/item/ammo_casing/c10mm/rubber
-
-/obj/item/ammo_box/c10mm/ap
- name = "ammo box (10mm armor-piercing)"
- desc = "A box of 10mm armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
- icon_state = "10mmbox-ap"
- ammo_type = /obj/item/ammo_casing/c10mm/ap
-
-/obj/item/ammo_box/c10mm/hp
- name = "ammo box (10mm hollow point)"
- desc = "A box of 10mm hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
- icon_state = "10mmbox-hp"
- ammo_type = /obj/item/ammo_casing/c10mm/hp
-
-/obj/item/ammo_box/c10mm/fire
- name = "ammo box (10mm incendiary)"
- desc = "A box of 10mm incendiary ammo, designed to ignite targets at the cost of initial damage."
- icon_state = "10mmbox-incendiary"
- ammo_type = /obj/item/ammo_casing/c10mm/inc
-
-/obj/item/ammo_box/c45
- name = "ammo box (.45)"
- desc = "A box of standard .45 ammo."
- icon_state = "45box"
- ammo_type = /obj/item/ammo_casing/c45
- max_ammo = 50
-
-/obj/item/ammo_box/c45/surplus
- name = "ammo box (.45 surplus)"
- desc = "A box of low-quality .45 ammo."
- icon_state = "45box-surplus"
- ammo_type = /obj/item/ammo_casing/c45/surplus
-
-/obj/item/ammo_box/c45/rubbershot
- name = "ammo box (.45 rubbershot)"
- desc = "A box of .45 rubbershot ammo, designed to disable targets without causing serious damage."
- icon_state = "45box-rubbershot"
- ammo_type = /obj/item/ammo_casing/c45/rubber
-
-/obj/item/ammo_box/c45/ap
- name = "ammo box (.45 armor-piercing)"
- desc = "A box of .45 armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
- icon_state = "45box-ap"
- ammo_type = /obj/item/ammo_casing/c45/ap
-
-/obj/item/ammo_box/c45/hp
- name = "ammo box (.45 hollow point)"
- desc = "A box of .45 hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
- icon_state = "45box-hp"
- ammo_type = /obj/item/ammo_casing/c45/hp
-
-/obj/item/ammo_box/c45/fire
- name = "ammo box (.45 incendiary)"
- desc = "A box of .45 incendiary ammo, designed to ignite targets at the cost of initial damage."
- icon_state = "45box-incendiary"
- ammo_type = /obj/item/ammo_casing/c45/inc
-
-/obj/item/ammo_box/c556mmHITP
- name = "ammo box (5.56mm HITP caseless)"
- desc = "A box of 5.56mm HITP caseless ammo, a SolGov standard."
- icon_state = "556mmHITPbox"
- ammo_type = /obj/item/ammo_casing/caseless/c556mm
- max_ammo = 50
-
-/obj/item/ammo_box/c556mmHITP/surplus
- name = "ammo box (5.56mm HITP caseless surplus)"
- desc = "A box of low-quality 5.56mm HITP caseless ammo."
- icon_state = "556mmHITPbox-surplus"
- ammo_type = /obj/item/ammo_casing/caseless/c556mm/surplus
-
-/obj/item/ammo_box/c556mmHITP/rubbershot
- name = "ammo box (5.56mm HITP caseless rubbershot)"
- desc = "A box of 5.56mm HITP caseless rubbershot ammo, designed to disable targets without causing serious damage."
- icon_state = "556mmHITPbox-rubbershot"
- ammo_type = /obj/item/ammo_casing/caseless/c556mm/rubbershot
-
-/obj/item/ammo_box/c556mmHITP/ap
- name = "ammo box (5.56mm HITP caseless armor-piercing)"
- desc = "A box of 5.56mm HITP caseless armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
- icon_state = "556mmHITPbox-ap"
- ammo_type = /obj/item/ammo_casing/caseless/c556mm/ap
-
-/obj/item/ammo_box/c556mmHITP/hp
- name = "ammo box (5.56mm HITP caseless hollow point)"
- desc = "A box of 5.56mm HITP caseless hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
- icon_state = "556mmHITPbox-hp"
- ammo_type = /obj/item/ammo_casing/caseless/c556mm/hp
-
-/obj/item/ammo_box/a40mm
- name = "ammo box (40mm grenades)"
- icon_state = "40mm"
- ammo_type = /obj/item/ammo_casing/a40mm
- max_ammo = 4
- multiple_sprites = AMMO_BOX_PER_BULLET
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/ammo_box/a762_40
- name = "ammo box (7.62x40mm CLIP)"
- icon_state = "a762_40box_big"
- ammo_type = /obj/item/ammo_casing/a762_40
- max_ammo = 120
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/ammo_box/a762_40/inteq
- icon_state = "a762_40box_big_inteq"
-
-/obj/item/ammo_box/a556_42
- name = "ammo box (5.56x42mm CLIP)"
- icon_state = "a556_42box_big"
- ammo_type = /obj/item/ammo_casing/a556_42
- max_ammo = 120
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/ammo_box/a308
- name = "ammo box (.308)"
- icon_state = "a308box"
- ammo_type = /obj/item/ammo_casing/a308
- max_ammo = 30
-
-/obj/item/ammo_box/a308/hunterspride //just an alternative graphic for srm ships
- icon_state = "a308box-HP"
-
-/obj/item/ammo_box/foambox
- name = "ammo box (Foam Darts)"
- icon = 'icons/obj/guns/toy.dmi'
- icon_state = "foambox"
- ammo_type = /obj/item/ammo_casing/caseless/foam_dart
- max_ammo = 40
- custom_materials = list(/datum/material/iron = 500)
-
-/obj/item/ammo_box/foambox/riot
- icon_state = "foambox_riot"
- ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
- custom_materials = list(/datum/material/iron = 50000)
-
-/obj/item/ammo_box/c22lr_box
- name = "ammo box (.22 LR)"
- desc = "A box of standard .22 LR ammo."
- icon_state = "22lrbox"
- ammo_type = /obj/item/ammo_casing/c22lr
- max_ammo = 75
-
-/obj/item/ammo_box/a44roum_speedloader
- name = "speed loader (.44)"
- desc = "Designed to quickly reload revolvers."
- icon_state = "speedloader_38-6"
- base_icon_state = "speedloader_38"
- ammo_type = /obj/item/ammo_casing/a44roum
- caliber = ".44 Roumain"
- max_ammo = 6
- multiple_sprites = AMMO_BOX_PER_BULLET
- custom_materials = list(/datum/material/iron = 15000)
- w_class = WEIGHT_CLASS_TINY
- instant_load = TRUE
-
-/obj/item/ammo_box/a44roum_speedloader/empty
- start_empty = TRUE
-
-/obj/item/ammo_box/c57x39mm_box
- name = "ammo box (5.7x39mm)"
- desc = "A box of standard 5.7x39mm ammo."
- icon_state = "57x39mmbox"
- ammo_type = /obj/item/ammo_casing/c57x39mm
- max_ammo = 50
-
-
-/obj/item/ammo_box/c46x30mm_box
- name = "ammo box (4.6x30mm)"
- desc = "A box of standard 4.6x30mm ammo."
- icon_state = "46x30mmbox"
- ammo_type = /obj/item/ammo_casing/c46x30mm
- max_ammo = 50
-
-/obj/item/ammo_box/c8x50mm_box
- name = "ammo box (8x50mm)"
- desc = "A box of standard 8x50mm ammo."
- icon_state = "8x50mmbox"
- ammo_type = /obj/item/ammo_casing/a8_50r
- max_ammo = 25
-
-/obj/item/ammo_box/ferropelletbox
- name = "ammo box (ferromagnetic pellets)"
- desc = "A box of ferromagnetic pellets."
- icon_state = "ferropelletsbox"
- ammo_type = /obj/item/ammo_casing/caseless/gauss
- max_ammo = 50
-
-/obj/item/ammo_box/ferroslugbox
- name = "ammo box (ferromagnetic slugs)"
- desc = "A box of standard ferromagnetic slugs."
- icon_state = "ferroslugsbox"
- ammo_type = /obj/item/ammo_casing/caseless/gauss/slug
- max_ammo = 20
-
-/obj/item/ammo_box/ferrolancebox
- name = "ammo box (ferromagnetic lances)"
- desc = "A box of standard ferromagnetic lances."
- icon_state = "ferrolancesbox"
- ammo_type = /obj/item/ammo_casing/caseless/gauss/lance
- max_ammo = 50
-
-/obj/item/ammo_box/c8x50mmhp_box
- name = "ammo box (8x50mm)"
- desc = "A box of hollow point 8x50mm ammo, designed to cause massive damage at the cost of armor penetration."
- icon_state = "8x50mmbox-hp"
- ammo_type = /obj/item/ammo_casing/a8_50rhp
- max_ammo = 20
-
-/obj/item/ammo_box/a300_box
- name = "ammo box (.300 Magnum)"
- desc = "A box of standard .300 Magnum ammo."
- icon_state = "300box"
- ammo_type = /obj/item/ammo_casing/a300
- max_ammo = 20
-
-/obj/item/ammo_box/a65clip_box
- name = "ammo box (6.5x57mm CLIP)"
- desc = "A box of standard 6.5x57mm CLIP ammo."
- icon_state = "65box"
- ammo_type = /obj/item/ammo_casing/a65clip
- max_ammo = 20
-
-/obj/item/ammo_box/a65clip_box/syndicate
- icon_state = "65box_sa"
-
-/obj/item/ammo_box/a44roum
- name = "ammo box (.44 roumain)"
- desc = "A box of standard .44 roumain ammo."
- icon_state = "a44roum"
- ammo_type = /obj/item/ammo_casing/a44roum
- max_ammo = 50
-
-/obj/item/ammo_box/a44roum/rubber
- name = "ammo box (.44 roumain rubber)"
- desc = "A box of .44 roumain rubbershot ammo, designed to disable targets without causing serious damage."
- icon_state = "a44roum-rubber"
- ammo_type = /obj/item/ammo_casing/a44roum/rubber
- max_ammo = 50
-
-/obj/item/ammo_box/a44roum/hp
- name = "ammo box (.44 roumain hollow point)"
- desc = "A box of .44 roumain hollow point ammo, designed to cause massive damage at the cost of armor penetration."
- icon_state = "a44roum-hp"
- ammo_type = /obj/item/ammo_casing/a44roum/hp
- max_ammo = 50
-
-/obj/item/ammo_box/c299
- name = "ammo box (.299 Eoehoma caseless)"
- desc = "A box of .299 Eoehoma caseless, for use with the E-40 hybrid assault rifle."
- icon_state = "299box"
- ammo_type = /obj/item/ammo_casing/caseless/c299
- max_ammo = 120
- w_class = WEIGHT_CLASS_NORMAL // This is a lot of ammo
diff --git a/code/modules/projectiles/boxes_magazines/ammo_loaders.dm b/code/modules/projectiles/boxes_magazines/ammo_loaders.dm
new file mode 100644
index 000000000000..70d9480493c6
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_loaders.dm
@@ -0,0 +1,176 @@
+// .357 Speed Loaders
+
+/obj/item/ammo_box/a357
+ name = "speed loader (.357)"
+ desc = "A 6-round speed loader for quickly reloading .357 revolvers. These rounds do good damage with average performance against armor."
+ icon_state = "speedloader_357-6"
+ base_icon_state = "speedloader_357"
+ ammo_type = /obj/item/ammo_casing/a357
+ caliber = ".357"
+ max_ammo = 6
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ item_flags = NO_MAT_REDEMPTION
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/a357/empty
+ start_empty = TRUE
+
+/obj/item/ammo_box/a357/match
+ name = "speed loader (.357 match)"
+ desc = "A 6-round speed loader for quickly reloading .357 revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
+ ammo_type = /obj/item/ammo_casing/a357/match
+
+/obj/item/ammo_box/a357/hp
+ name = "speed loader (.357 hollow point)"
+ desc = "A 6-round speed loader for quickly reloading .357 revolvers. These hollow point rounds do incredible damage against soft targets, but are nearly ineffective against armored ones."
+ ammo_type = /obj/item/ammo_casing/a357/hp
+
+// .38 special Speed Loaders
+
+/obj/item/ammo_box/c38
+ name = "speed loader (.38 special)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These rounds do okay damage, but struggle against armor."
+ icon_state = "speedloader_38-6"
+ base_icon_state = "speedloader_38"
+ ammo_type = /obj/item/ammo_casing/c38
+ caliber = ".38"
+ max_ammo = 6
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ custom_materials = list(/datum/material/iron = 15000)
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/c38/trac
+ name = "speed loader (.38 TRAC)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These TRAC rounds do pitiful damage, but embed a tracking device in targets hit."
+ ammo_type = /obj/item/ammo_casing/c38/trac
+
+/obj/item/ammo_box/c38/match
+ name = "speed loader (.38 match)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
+ ammo_type = /obj/item/ammo_casing/c38/match
+
+/obj/item/ammo_box/c38/match/bouncy
+ name = "speed loader (.38 rubber)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These rounds are incredibly bouncy and MOSTLY nonlethal, making them great to show off trickshots with."
+ ammo_type = /obj/item/ammo_casing/c38/match/bouncy
+
+/obj/item/ammo_box/c38/dumdum
+ name = "speed loader (.38 dum-dum)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These dum-dum bullets shatter on impact and embed in the target's innards. However, they're nearly ineffective against armor and do okay damage."
+ ammo_type = /obj/item/ammo_casing/c38/dumdum
+
+/obj/item/ammo_box/c38/hotshot
+ name = "speed loader (.38 hot shot)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These hot shot bullets contain an incendiary payload that set targets alight."
+ ammo_type = /obj/item/ammo_casing/c38/hotshot
+
+/obj/item/ammo_box/c38/iceblox
+ name = "speed loader (.38 iceblox)"
+ desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These iceblox bullets contain a cryogenic payload that chills targets."
+ ammo_type = /obj/item/ammo_casing/c38/iceblox
+
+/obj/item/ammo_box/c38/empty
+ start_empty = TRUE
+
+// 8x58mm Stripper Clip
+
+/obj/item/ammo_box/a858
+ name = "stripper clip (8x58mm)"
+ desc = "A 5-round stripper clip for the SSG-669C rifle. These rounds do good damage with significant armor penetration."
+ icon_state = "enbloc_858"
+ ammo_type = /obj/item/ammo_casing/caseless/a858
+ max_ammo = 5
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ instant_load = TRUE
+
+/obj/item/ammo_box/a858/empty
+ start_empty = TRUE
+
+// .308 Stripper Clip
+
+/obj/item/ammo_box/vickland_a308
+ name = "stripper clip (.308)"
+ desc = "A 5-round stripper clip for the Vickland Battle Rifle. The Vickland itself has a 10 round capacity, so keep in mind two of these are needed to fully reload it. These rounds do good damage with significant armor penetration."
+ icon_state = "stripper_308-5"
+ base_icon_state = "stripper_308"
+ ammo_type = /obj/item/ammo_casing/a308
+ max_ammo = 5
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/vickland_a308/empty
+ start_empty = TRUE
+
+// .300 Magnum Stripper Clip
+
+/obj/item/ammo_box/a300
+ name = "stripper clip (.300 Magnum)"
+ desc = "A 5-round stripper clip for the Scout Rifle. These rounds do great damage with significant armor penetration."
+ icon_state = "300m"
+ ammo_type = /obj/item/ammo_casing/a300
+ max_ammo = 5
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/a300/empty
+ start_empty = TRUE
+
+// .300 Blackout Stripper Clip
+
+/obj/item/ammo_box/a762_stripper
+ name = "stripper clip (7.62)"
+ desc = "A 5-round stripper clip for makeshift bolt-action rifles. These rounds do good damage with good armor penetration."
+ icon_state = "stripper_308-5"
+ base_icon_state = "stripper_308"
+ ammo_type = /obj/item/ammo_casing/a762_40
+ caliber = "7.62x40mm"
+ max_ammo = 5
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/a762_stripper/empty
+ start_empty = TRUE
+
+// Ferromagnetic Pellet Speed Loader
+
+/obj/item/ammo_box/amagpellet_claris
+ name = "\improper Claris speed loader (ferromagnetic pellet)"
+ desc = "A 22-round speed loader for quickly reloading the Claris rifle. Ferromagnetic pellets do okay damage with significant armor penetration."
+ icon_state = "claris-sl-1"
+ base_icon_state = "claris-sl"
+ ammo_type = /obj/item/ammo_casing/caseless/gauss
+ max_ammo = 22
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+ item_flags = NO_MAT_REDEMPTION
+ instant_load = TRUE
+
+/obj/item/ammo_box/a40mm
+ name = "ammo box (40mm grenades)"
+ icon_state = "40mm"
+ ammo_type = /obj/item/ammo_casing/a40mm
+ max_ammo = 4
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ w_class = WEIGHT_CLASS_NORMAL
+
+// .44 Roumain speedloader
+
+/obj/item/ammo_box/a44roum_speedloader
+ name = "speed loader (.44)"
+ desc = "Designed to quickly reload revolvers."
+ icon_state = "speedloader_38-6"
+ base_icon_state = "speedloader_38"
+ ammo_type = /obj/item/ammo_casing/a44roum
+ caliber = ".44 Roumain"
+ max_ammo = 6
+ multiple_sprites = AMMO_BOX_PER_BULLET
+ custom_materials = list(/datum/material/iron = 15000)
+ w_class = WEIGHT_CLASS_TINY
+ instant_load = TRUE
+
+/obj/item/ammo_box/a44roum_speedloader/empty
+ start_empty = TRUE
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/_ammo_stack.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/_ammo_stack.dm
new file mode 100644
index 000000000000..f1e84780cb1e
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/_ammo_stack.dm
@@ -0,0 +1,82 @@
+/**
+ * The ammo stack object itself, making this a magazine was the easiest way to handle it
+ * Practically every casing type needs an associated ammo stack type, because that was the easiest
+ * way for me to handle it.
+ */
+/obj/item/ammo_box/magazine/ammo_stack
+ name = "ammo stack"
+ desc = "A pile of live rounds."
+ icon = 'icons/obj/ammunition/ammo_bullets.dmi'
+ icon_state = "pistol-brass"
+ base_icon_state = "pistol-brass"
+ item_flags = NO_PIXEL_RANDOM_DROP
+ multiple_sprites = AMMO_BOX_ONE_SPRITE
+ multiload = FALSE
+ start_empty = TRUE
+ max_ammo = 12
+
+/obj/item/ammo_box/magazine/ammo_stack/update_icon(updates)
+ icon = initial(icon)
+ cut_overlays()
+ return ..()
+
+/obj/item/ammo_box/magazine/ammo_stack/update_icon_state()
+ . = ..()
+ cut_overlays()
+ icon_state = ""
+ for(var/casing in stored_ammo)
+ var/image/bullet = image(initial(icon), src, "[base_icon_state]")
+ bullet.pixel_x = rand(-8, 8)
+ bullet.pixel_y = rand(-8, 8)
+ bullet.transform = bullet.transform.Turn(round(45 * rand(0, 32) / 2)) //this is the equation Eris uses on their bullet stacks
+ add_overlay(bullet)
+ return UPDATE_ICON_STATE | UPDATE_OVERLAYS
+
+/obj/item/ammo_box/magazine/ammo_stack/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
+ . = ..()
+ var/loc_before_del = loc
+ while(LAZYLEN(stored_ammo))
+ var/obj/item/ammo = get_round(FALSE)
+ ammo.forceMove(loc_before_del)
+ ammo.throw_at(loc_before_del)
+ update_ammo_count()
+
+/obj/item/ammo_box/magazine/ammo_stack/update_ammo_count()
+ . = ..()
+ check_for_del()
+
+/obj/item/ammo_box/magazine/ammo_stack/proc/check_for_del()
+ . = FALSE
+ if((ammo_count() <= 0) && !QDELETED(src))
+ qdel(src)
+ return
+
+/obj/item/ammo_box/magazine/ammo_stack/attackby(obj/item/handful, mob/user, params, silent = FALSE, replace_spent = 0)
+ var/num_loaded = 0
+ if(!can_load(user))
+ return
+
+ if(istype(handful, /obj/item/ammo_box))
+ var/obj/item/ammo_box/ammo_box = handful
+ for(var/obj/item/ammo_casing/casing in ammo_box.stored_ammo)
+ var/did_load = give_round(casing, replace_spent)
+ if(did_load)
+ ammo_box.stored_ammo -= casing
+ num_loaded++
+ if(!did_load || !multiload)
+ break
+ if(num_loaded)
+ ammo_box.update_ammo_count()
+
+ if(istype(handful, /obj/item/ammo_casing))
+ var/obj/item/ammo_casing/casing = handful
+ if(give_round(casing, replace_spent))
+ user.transferItemToLoc(casing, src, TRUE)
+ num_loaded++
+ casing.update_appearance()
+
+ if(num_loaded)
+ if(!silent)
+ to_chat(user, span_notice("You load [num_loaded] shell\s into \the [src]!"))
+ playsound(src, 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE)
+ update_ammo_count()
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/_premade_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/_premade_stacks.dm
new file mode 100644
index 000000000000..8a28920efe6a
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/_premade_stacks.dm
@@ -0,0 +1,21 @@
+/obj/item/ammo_box/magazine/ammo_stack/prefilled
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/Initialize(mapload)
+ make_stack()
+ update_appearance()
+ . = ..()
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/proc/make_stack()
+ var/obj/item/ammo_casing/to_copy = ammo_type
+ src.top_off()
+ caliber = to_copy.caliber
+ base_icon_state = "[initial(to_copy.icon_state)][to_copy.bullet_skin ? "-[to_copy.bullet_skin]" : ""]"
+ name = "handful of [to_copy.name]s"
+
+/obj/item/storage/box/ammo //base type, don't use this!
+ name = "box of default ammo"
+ desc = "A box of ammunition. Not for consumption."
+ icon = 'icons/obj/ammunition/ammo_boxes.dmi'
+ icon_state = "9mmbox"
+ illustration = null
+ foldable = null
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_gauss_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_gauss_stacks.dm
new file mode 100644
index 000000000000..ac82cf6bcebd
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_gauss_stacks.dm
@@ -0,0 +1,41 @@
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/ferropellet
+ ammo_type = /obj/item/ammo_casing/caseless/gauss
+
+/obj/item/storage/box/ammo/ferropellet
+ name = "box of ferromagnetic pellets"
+ desc = "A box of ferromagnetic pellets for gauss firearms."
+ icon_state = "ferropelletsbox"
+
+/obj/item/storage/box/ammo/ferropellet/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/ferropellet = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/ferroslug
+ ammo_type = /obj/item/ammo_casing/caseless/gauss/slug
+
+/obj/item/storage/box/ammo/ferroslug
+ name = "box of ferromagnetic slugs"
+ desc = "A box of standard ferromagnetic slugs for gauss firearms."
+ icon_state = "ferroslugsbox"
+
+/obj/item/storage/box/ammo/ferroslug/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/ferroslug = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/ferrolance
+ ammo_type = /obj/item/ammo_casing/caseless/gauss/lance
+
+/obj/item/storage/box/ammo/ferrolance
+ name = "box of ferromagnetic lances"
+ desc = "A box of standard ferromagnetic lances for gauss firearms."
+ icon_state = "ferrolancesbox"
+
+/obj/item/storage/box/ammo/ferrolance/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/ferrolance = 4)
+ generate_items_inside(items_inside,src)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_lmg_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_lmg_stacks.dm
new file mode 100644
index 000000000000..b98da1f81000
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_lmg_stacks.dm
@@ -0,0 +1,15 @@
+// 7.12x82mm (L6 SAW)
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/mm712x82
+ ammo_type = /obj/item/ammo_casing/mm712x82
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/mm712x82/ap
+ ammo_type = /obj/item/ammo_casing/mm712x82/ap
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/mm712x82/hp
+ ammo_type = /obj/item/ammo_casing/mm712x82/hp
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/mm712x82/incendiary
+ ammo_type = /obj/item/ammo_casing/mm712x82/inc
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/mm712x82/match
+ ammo_type = /obj/item/ammo_casing/mm712x82/match
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_misc_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_misc_stacks.dm
new file mode 100644
index 000000000000..a24599138238
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_misc_stacks.dm
@@ -0,0 +1,26 @@
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/foam_darts
+ ammo_type = /obj/item/ammo_casing/caseless/foam_dart
+
+/obj/item/storage/box/ammo/foam_darts
+ name = "box of foam darts"
+ icon = 'icons/obj/guns/toy.dmi'
+ icon_state = "foambox"
+
+/obj/item/storage/box/ammo/foam_darts/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/foam_darts = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/foam_darts/riot
+ ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
+
+/obj/item/storage/box/ammo/foam_darts/riot
+ name = "box of foam darts"
+ icon_state = "foambox_riot"
+
+/obj/item/storage/box/ammo/foam_darts/riot/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/foam_darts/riot = 4)
+ generate_items_inside(items_inside,src)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_pistol_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_pistol_stacks.dm
new file mode 100644
index 000000000000..68ea1a7faeb5
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_pistol_stacks.dm
@@ -0,0 +1,499 @@
+// 10mm (Stechkin)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm
+ ammo_type = /obj/item/ammo_casing/c10mm
+
+/obj/item/storage/box/ammo/c10mm
+ name = "box of 10mm ammo"
+ desc = "A box of standard 10mm ammo."
+ icon_state = "10mmbox"
+
+/obj/item/storage/box/ammo/c10mm/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/surplus
+ ammo_type = /obj/item/ammo_casing/c10mm/surplus
+
+/obj/item/storage/box/ammo/c10mm_surplus
+ name = "box of surplus 10mm ammo"
+ desc = "A box of low-quality 10mm ammo."
+ icon_state = "10mmbox-surplus"
+
+/obj/item/storage/box/ammo/c10mm_surplus/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/ap
+ ammo_type = /obj/item/ammo_casing/c10mm/ap
+
+/obj/item/storage/box/ammo/c10mm_ap
+ name = "box of AP 10mm ammo"
+ desc = "A box of 10mm armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
+ icon_state = "10mmbox-ap"
+
+/obj/item/storage/box/ammo/c10mm_ap/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/ap = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/hp
+ ammo_type = /obj/item/ammo_casing/c10mm/hp
+
+/obj/item/storage/box/ammo/c10mm_hp
+ name = "box of HP 10mm ammo"
+ desc = "A box of 10mm hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
+ icon_state = "10mmbox-hp"
+
+/obj/item/storage/box/ammo/c10mm_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/hp = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/incendiary
+ ammo_type = /obj/item/ammo_casing/c10mm/inc
+
+/obj/item/storage/box/ammo/c10mm_incendiary
+ name = "box of incendiary 10mm ammo"
+ desc = "A box of 10mm incendiary ammo, designed to ignite targets at the cost of initial damage."
+ icon_state = "10mmbox-incendiary"
+
+/obj/item/storage/box/ammo/c10mm_incendiary/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/incendiary = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/rubber
+ ammo_type = /obj/item/ammo_casing/c10mm/rubber
+
+/obj/item/storage/box/ammo/c10mm_rubber
+ name = "box of rubber 10mm ammo"
+ desc = "A box of 10mm rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "10mmbox-rubbershot"
+
+/obj/item/storage/box/ammo/c10mm_rubber/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c10mm/rubber = 4)
+ generate_items_inside(items_inside,src)
+
+// 9MM (Commander + SABR)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm
+ ammo_type = /obj/item/ammo_casing/c9mm
+ max_ammo = 15
+
+/obj/item/storage/box/ammo/c9mm
+ name = "box of 9mm ammo"
+ desc = "A box of standard 9mm ammo."
+ icon_state = "9mmbox"
+
+/obj/item/storage/box/ammo/c9mm/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/surplus
+ ammo_type = /obj/item/ammo_casing/c9mm/surplus
+
+/obj/item/storage/box/ammo/c9mm_surplus
+ name = "box of surplus 9mm ammo"
+ desc = "A box of low-quality 9mm ammo."
+ icon_state = "9mmbox-surplus"
+
+/obj/item/storage/box/ammo/c9mm_surplus/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/surplus = 48)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm_ap
+ ammo_type = /obj/item/ammo_casing/c9mm/ap
+
+/obj/item/storage/box/ammo/c9mm/ap
+ name = "box of AP 9mm ammo"
+ desc = "A box of 9mm armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
+ icon_state = "9mmbox-ap"
+
+/obj/item/storage/box/ammo/c9mm_ap/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm_ap = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/hp
+ ammo_type = /obj/item/ammo_casing/c9mm/hp
+
+/obj/item/storage/box/ammo/c9mm_hp
+ name = "box of HP 9mm ammo"
+ desc = "A box of 9mm hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
+ icon_state = "9mmbox-hp"
+
+/obj/item/storage/box/ammo/c9mm_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/hp = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/incendiary
+ ammo_type = /obj/item/ammo_casing/c9mm/inc
+
+/obj/item/storage/box/ammo/c9mm_incendiary
+ name = "box of incendiary 9mm ammo"
+ desc = "A box of 9mm incendiary ammo, designed to ignite targets at the cost of initial damage."
+ icon_state = "9mmbox-incendiary"
+
+/obj/item/storage/box/ammo/c9mm_incendiary/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/incendiary = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/rubber
+ ammo_type = /obj/item/ammo_casing/c9mm/rubber
+
+/obj/item/storage/box/ammo/c9mm_rubber
+ name = "box of rubber 9mm ammo"
+ desc = "A box of 9mm rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "9mmbox-rubbershot"
+
+/obj/item/storage/box/ammo/c9mm_rubber/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c9mm/rubber = 4)
+ generate_items_inside(items_inside,src)
+
+// .45 (Candor + C20R)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45
+ ammo_type = /obj/item/ammo_casing/c45
+
+/obj/item/storage/box/ammo/c45
+ name = "box of .45 ammo"
+ desc = "A box of standard .45 ammo."
+ icon_state = "45box"
+
+/obj/item/storage/box/ammo/c45/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45 = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/surplus
+ ammo_type = /obj/item/ammo_casing/c45/surplus
+
+/obj/item/storage/box/ammo/c45_surplus
+ name = "box of surplus .45 ammo"
+ desc = "A box of low-quality .45 ammo."
+ icon_state = "45box-surplus"
+
+/obj/item/storage/box/ammo/c45_surplus/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/surplus = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/ap
+ ammo_type = /obj/item/ammo_casing/c45/ap
+
+/obj/item/storage/box/ammo/c45_ap
+ name = "box of AP .45 ammo"
+ desc = "A box of .45 armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
+ icon_state = "45box-ap"
+
+/obj/item/storage/box/ammo/c45_ap/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/ap = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/hp
+ ammo_type = /obj/item/ammo_casing/c45/hp
+
+/obj/item/storage/box/ammo/c45_hp
+ name = "box of HP .45 ammo"
+ desc = "A box of .45 hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
+ icon_state = "45box-hp"
+
+/obj/item/storage/box/ammo/c45_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/hp = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/incendiary
+ ammo_type = /obj/item/ammo_casing/c45/inc
+
+/obj/item/storage/box/ammo/c45_incendiary
+ name = "box of incendiary .45 ammo"
+ desc = "A box of .45 incendiary ammo, designed to ignite targets at the cost of initial damage."
+ icon_state = "45box-incendiary"
+
+/obj/item/storage/box/ammo/c45_incendiary/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/incendiary = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/rubber
+ ammo_type = /obj/item/ammo_casing/c45/rubber
+
+/obj/item/storage/box/ammo/c45_rubber
+ name = "box of incendiary .45 ammo"
+ desc = "A box of .45 rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "45box-rubbershot"
+
+/obj/item/storage/box/ammo/c45_rubber/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c45/rubber = 4)
+ generate_items_inside(items_inside,src)
+
+// .50 AE (Desert Eagle)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a50AE
+ ammo_type = /obj/item/ammo_casing/a50AE
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a50AE/hp
+ ammo_type = /obj/item/ammo_casing/a50AE/hp
+
+// .22 LR (Himehabu, Pounder)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c22lr
+ ammo_type = /obj/item/ammo_casing/c22lr
+
+/obj/item/storage/box/ammo/c22lr
+ name = "box of .22 LR ammo"
+ desc = "A box of standard .22 LR ammo."
+ icon_state = "22lrbox"
+
+/obj/item/storage/box/ammo/c22lr/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c22lr = 4)
+ generate_items_inside(items_inside,src)
+
+// .357
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a357
+ ammo_type = /obj/item/ammo_casing/a357
+
+/obj/item/storage/box/ammo/a357
+ name = "box of .357 ammo"
+ desc = "A box of standard .357 ammo."
+ icon_state = "357box"
+
+/obj/item/storage/box/ammo/a357/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a357 = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a357/match
+ ammo_type = /obj/item/ammo_casing/a357/match
+
+/obj/item/storage/box/ammo/a357_match
+ name = "box of match .357 ammo"
+ desc = "A box of match .357 ammo."
+ icon_state = "357box-match"
+
+/obj/item/storage/box/ammo/a357_match/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a357/match = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a357/hp
+ ammo_type = /obj/item/ammo_casing/a357/hp
+
+/obj/item/storage/box/ammo/a357_hp
+ name = "box of HP .357 ammo"
+ desc = "A box of hollow point .357 ammo."
+ icon_state = "357box-hp"
+
+/obj/item/storage/box/ammo/a357_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a357/hp = 4)
+ generate_items_inside(items_inside,src)
+
+// .45-70 (Hunting Revolver, Beacon)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570
+ ammo_type = /obj/item/ammo_casing/a4570
+ max_ammo = 5
+
+/obj/item/storage/box/ammo/a4570
+ name = "box of .45-70 ammo"
+ desc = "A box of top grade .45-70 ammo. These rounds do significant damage with average performance against armor."
+ icon_state = "4570"
+
+/obj/item/storage/box/ammo/a4570/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570 = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/match
+ ammo_type = /obj/item/ammo_casing/a4570/match
+
+/obj/item/storage/box/ammo/a4570_match
+ name = "box of HP match .45-70 ammo"
+ desc = "A 12-round ammo box for .45-70 revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
+ icon_state = "4570-match"
+
+/obj/item/storage/box/ammo/a4570_match/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/match = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/hp
+ ammo_type = /obj/item/ammo_casing/a4570/hp
+
+/obj/item/storage/box/ammo/a4570_hp
+ name = "box of HP .45-70 ammo"
+ desc = "A 12-round ammo box for .45-70 revolvers. These hollow point rounds do legendary damage against soft targets, but are nearly ineffective against armored ones."
+ icon_state = "4570-hp"
+
+/obj/item/storage/box/ammo/a4570_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/hp = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/explosive
+ ammo_type = /obj/item/ammo_casing/a4570/explosive
+
+/obj/item/storage/box/ammo/a4570_explosive
+ name = "box of explosive .45-70 ammo"
+ desc = "A 12-round ammo box for .45-70 revolvers. These explosive rounds contain a small explosive charge that detonates on impact, creating large wounds and potentially removing limbs."
+ icon_state = "4570-explosive"
+
+/obj/item/storage/box/ammo/a4570_explosive/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a4570/explosive = 4)
+ generate_items_inside(items_inside,src)
+
+// .38 Special
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38
+ ammo_type = /obj/item/ammo_casing/c38
+
+/obj/item/storage/box/ammo/c38
+ name = "box of .38 ammo"
+ desc = "A box of standard .38 Special ammo."
+ icon_state = "38box"
+
+/obj/item/storage/box/ammo/c38/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c38 = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/surplus
+ ammo_type = /obj/item/ammo_casing/c38/surplus
+
+/obj/item/storage/box/ammo/c38_surplus
+ name = "box of surplus .38 ammo"
+ desc = "A box of low-quality .38 Special ammo."
+ icon_state = "38box-surplus"
+
+/obj/item/storage/box/ammo/c38_surplus/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/surplus = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/trac
+ ammo_type = /obj/item/ammo_casing/c38/trac
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/match
+ ammo_type = /obj/item/ammo_casing/c38/match
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/bouncy
+ ammo_type = /obj/item/ammo_casing/c38/match/bouncy
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/dumdum
+ ammo_type = /obj/item/ammo_casing/c38/dumdum
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/hotshot
+ ammo_type = /obj/item/ammo_casing/c38/hotshot
+
+/obj/item/storage/box/ammo/c38_hotshot
+ name = "box of .38 hearth ammo"
+ desc = "An unorthodox .38 Special cartridge infused with hearthwine. Catches the target on fire."
+ icon_state = "38hotshot"
+
+/obj/item/storage/box/ammo/c38_hotshot/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/hotshot = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/iceblox
+ ammo_type = /obj/item/ammo_casing/c38/iceblox
+
+/obj/item/storage/box/ammo/c38_iceblox
+ name = "box of .38 chilled ammo"
+ desc = "An unorthodox .38 Special cartridge infused with icewine. Chills the target, slowing them down."
+ icon_state = "38iceblox"
+
+/obj/item/storage/box/ammo/c38_iceblox/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c38/iceblox = 4)
+ generate_items_inside(items_inside,src)
+
+// 44 Roumain
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum
+ ammo_type = /obj/item/ammo_casing/a44roum
+
+/obj/item/storage/box/ammo/a44roum
+ name = "box of .44 roumain ammo"
+ desc = "A box of standard .44 roumain ammo."
+ icon_state = "a44roum"
+
+/obj/item/storage/box/ammo/a44roum/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum/rubber
+ ammo_type = /obj/item/ammo_casing/a44roum/rubber
+
+/obj/item/storage/box/ammo/a44roum_rubber
+ name = "box of rubber .44 roumain ammo"
+ desc = "A box of .44 roumain rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "a44roum-rubber"
+
+/obj/item/storage/box/ammo/a44roum_rubber/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum/rubber = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum/hp
+ ammo_type = /obj/item/ammo_casing/a44roum/hp
+
+/obj/item/storage/box/ammo/a44roum_hp
+ name = "box of HP .44 roumain ammo"
+ desc = "A box of .44 roumain rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "a44roum-rubber"
+
+/obj/item/storage/box/ammo/a44roum_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a44roum/hp = 4)
+ generate_items_inside(items_inside,src)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_rifle_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_rifle_stacks.dm
new file mode 100644
index 000000000000..d22f62ec2165
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_rifle_stacks.dm
@@ -0,0 +1,152 @@
+// 8x50mmR (Illestren Hunting Rifle)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a8_50r
+ ammo_type = /obj/item/ammo_casing/a8_50r
+ max_ammo = 10
+
+/obj/item/storage/box/ammo/a8_50r
+ name = "box of 8x50mm ammo"
+ desc = "A box of standard 8x50mm ammo."
+ icon_state = "8x50mmbox"
+
+/obj/item/storage/box/ammo/a8_50r/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a8_50r = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a8_50r/hp
+ ammo_type = /obj/item/ammo_casing/a8_50rhp
+
+/obj/item/storage/box/ammo/a8_50r_hp
+ name = "box of HP 8x50mm ammo"
+ desc = "A box of hollow point 8x50mm ammo, designed to cause massive damage at the cost of armor penetration."
+ icon_state = "8x50mmbox-hp"
+
+/obj/item/storage/box/ammo/a8_50r_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a8_50r/hp = 4)
+ generate_items_inside(items_inside,src)
+
+// 8x58mm Caseless (SSG-669C)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a858
+ ammo_type = /obj/item/ammo_casing/caseless/a858
+
+// .300 Magnum (Smile Rifle)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a300
+ ammo_type = /obj/item/ammo_casing/a300
+ max_ammo = 5
+
+/obj/item/storage/box/ammo/a300
+ name = "box of .300 magnum ammo"
+ desc = "A box of standard .300 Magnum ammo."
+ icon_state = "300box"
+
+/obj/item/storage/box/ammo/a300/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a300 = 4)
+ generate_items_inside(items_inside,src)
+
+// 5.56x42mm CLIP (CM82, Hydra variants)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a556_42
+ ammo_type = /obj/item/ammo_casing/a556_42
+ max_ammo = 15
+
+/obj/item/storage/box/ammo/a556_42
+ name = "box of 5.56x42mm CLIP ammo"
+ desc = "A box of standard 5.56x42mm CLIP ammo."
+ icon_state = "a556_42box_big"
+
+/obj/item/storage/box/ammo/a556_42/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a556_42 = 4)
+ generate_items_inside(items_inside,src)
+
+// 5.45x39mm (SKM-24v)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a545_39
+ ammo_type = /obj/item/ammo_casing/a545_39
+ max_ammo = 10
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a545_39/recycled
+ ammo_type = /obj/item/ammo_casing/a545_39/recycled
+
+// 7.62x40mm CLIP (SKM Rifles)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a762_40
+ ammo_type = /obj/item/ammo_casing/a762_40
+ max_ammo = 15
+
+/obj/item/storage/box/ammo/a762_40
+ name = "box of 7.62x40mm CLIP ammo"
+ desc = "A box of standard 7.62x40mm CLIP ammo."
+ icon_state = "a762_40box_big"
+
+/obj/item/storage/box/ammo/a762_40/inteq
+ icon_state = "a762_40box_big_inteq"
+
+/obj/item/storage/box/ammo/a762_40/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a762_40 = 4)
+ generate_items_inside(items_inside,src)
+
+//.308 (M514 EBR & CM-GAL-S)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a308
+ ammo_type = /obj/item/ammo_casing/a308
+ max_ammo = 10
+
+/obj/item/storage/box/ammo/a308
+ name = "box of .308 ammo"
+ desc = "A box of standard .308 ammo."
+ icon_state = "a308box"
+
+/obj/item/storage/box/ammo/a308/hunterspride
+ icon_state = "a308box-HP"
+
+/obj/item/storage/box/ammo/a308/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a308 = 4)
+ generate_items_inside(items_inside,src)
+
+//.299 Eoehoma Caseless (E-40)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c299
+ ammo_type = /obj/item/ammo_casing/caseless/c299
+ max_ammo = 5
+
+/obj/item/storage/box/ammo/c299
+ name = "box of .299 Eoehoma caseless ammo"
+ desc = "A box of .299 Eoehoma caseless, for use with the E-40 hybrid assault rifle."
+ icon_state = "299box"
+
+/obj/item/storage/box/ammo/c299/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c299 = 4)
+ generate_items_inside(items_inside,src)
+
+//6.5x57mm CLIP
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/a65clip
+ ammo_type = /obj/item/ammo_casing/a65clip
+ max_ammo = 5
+
+/obj/item/storage/box/ammo/a65clip
+ name = "box of 6.5x57mm CLIP ammo"
+ desc = "A box of standard 6.5x57mm CLIP ammo."
+ icon_state = "65box"
+
+/obj/item/storage/box/ammo/a65clip/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/a65clip = 4)
+ generate_items_inside(items_inside,src)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_shotshell_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_shotshell_stacks.dm
new file mode 100644
index 000000000000..f67800330724
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_shotshell_stacks.dm
@@ -0,0 +1,79 @@
+// Shotshells
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun
+ max_ammo = 8 //make sure these values are consistent across the board with stack_size variable on respective ammo_casing
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/buckshot
+ ammo_type = /obj/item/ammo_casing/shotgun/buckshot
+
+/obj/item/storage/box/ammo/a12g_buckshot
+ name = "box of 12ga buckshot"
+ desc = "A box of 12-gauge buckshot shells, devastating at close range."
+ icon_state = "12gbox-buckshot"
+
+/obj/item/storage/box/ammo/a12g_buckshot/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/buckshot = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/slug
+ ammo_type = /obj/item/ammo_casing/shotgun
+
+/obj/item/storage/box/ammo/a12g_slug
+ name = "box of 12ga slugs"
+ desc = "A box of 12-gauge slugs, for improved accuracy and penetration."
+ icon_state = "12gbox-slug"
+
+/obj/item/storage/box/ammo/a12g_slug/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/slug = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/beanbag
+ ammo_type = /obj/item/ammo_casing/shotgun/beanbag
+
+/obj/item/storage/box/ammo/a12g_beanbag
+ name = "box of 12ga beanbags"
+ desc = "A box of 12-gauge beanbag shells, for incapacitating targets."
+ icon_state = "12gbox-beanbag"
+
+/obj/item/storage/box/ammo/a12g_beanbag/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/beanbag = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/rubber
+ ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
+
+/obj/item/storage/box/ammo/a12g_rubbershot
+ name = "box of 12ga beanbags"
+ desc = "A box of 12-gauge rubbershot shells, designed for riot control."
+ icon_state = "12gbox-rubbershot"
+
+/obj/item/storage/box/ammo/a12g_beanbag/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/rubber = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/blank
+ ammo_type = /obj/item/ammo_casing/shotgun/blank
+
+/obj/item/storage/box/ammo/a12g_blank
+ name = "box of 12ga blanks"
+ desc = "A box of 12-gauge blank shells, designed for training."
+ icon_state = "12gbox-slug" //needs icon
+
+/obj/item/storage/box/ammo/a12g_blank/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/blank = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/incendiary
+ ammo_type = /obj/item/ammo_casing/shotgun/incendiary
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/shotgun/improvised
+ ammo_type = /obj/item/ammo_casing/shotgun/improvised
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_smg_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_smg_stacks.dm
new file mode 100644
index 000000000000..d550f5e461ba
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_smg_stacks.dm
@@ -0,0 +1,113 @@
+// 4.6x30mm (WT-550 Automatic Rifle & SKM-24v)
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c46x30mm
+ ammo_type = /obj/item/ammo_casing/c46x30mm
+ max_ammo = 15
+
+/obj/item/storage/box/ammo/c46x30mm
+ name = "box of 4.6x30mm ammo"
+ desc = "A box of standard 4.6x30mm ammo."
+ icon_state = "46x30mmbox"
+
+/obj/item/storage/box/ammo/c46x30mm/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c46x30mm = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c46x30mm/ap
+ ammo_type = /obj/item/ammo_casing/c46x30mm/ap
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c46x30mm/incendiary
+ ammo_type = /obj/item/ammo_casing/c46x30mm/inc
+
+// 4.73x33mm caseless (Solar)
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c47x33mm
+ ammo_type = /obj/item/ammo_casing/caseless/c47x33mm
+
+// 5.56mm HITP caseless (Pistole C)
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm
+ ammo_type = /obj/item/ammo_casing/caseless/c556mm
+ max_ammo = 15
+
+/obj/item/storage/box/ammo/c556mm
+ name = "box of 5.56mm HITP caseless ammo"
+ desc = "A box of 5.56mm HITP caseless ammo, a SolGov standard."
+ icon_state = "556mmHITPbox"
+
+/obj/item/storage/box/ammo/c556mm/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/surplus
+ ammo_type = /obj/item/ammo_casing/caseless/c556mm/surplus
+
+/obj/item/storage/box/ammo/c556mm_surplus
+ name = "box of surplus 5.56mm HITP caseless ammo"
+ desc = "A box of low-quality 5.56mm HITP caseless ammo."
+ icon_state = "556mmHITPbox-surplus"
+
+/obj/item/storage/box/ammo/c556mm_surplus/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/surplus = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/ap
+ ammo_type = /obj/item/ammo_casing/caseless/c556mm/ap
+
+/obj/item/storage/box/ammo/c556mm_ap
+ name = "box of AP 5.56mm HITP caseless ammo"
+ desc = "A box of 5.56mm HITP caseless armor-piercing ammo, designed to penetrate through armor at the cost of total damage."
+ icon_state = "556mmHITPbox-ap"
+
+/obj/item/storage/box/ammo/c556mm_ap/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/ap = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/hp
+ ammo_type = /obj/item/ammo_casing/caseless/c556mm/hp
+
+/obj/item/storage/box/ammo/c556mm_hp
+ name = "box of HP 5.56mm HITP caseless ammo"
+ desc = "A box of 5.56mm HITP caseless hollow point ammo, designed to cause massive tissue damage at the cost of armor penetration."
+ icon_state = "556mmHITPbox-hp"
+
+/obj/item/storage/box/ammo/c556mm_hp/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/hp = 4)
+ generate_items_inside(items_inside,src)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/rubbershot
+ ammo_type = /obj/item/ammo_casing/caseless/c556mm/rubbershot
+
+/obj/item/storage/box/ammo/c556mm_rubber
+ name = "box of rubber 5.56mm HITP caseless ammo"
+ desc = "A box of 5.56mm HITP caseless rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "556mmHITPbox-rubbershot"
+
+/obj/item/storage/box/ammo/c556mm_rubber/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c556mm/rubbershot = 4)
+ generate_items_inside(items_inside,src)
+
+// 5.7x39mm (Asp and Sidewinder)
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/c57x39
+ ammo_type = /obj/item/ammo_casing/c57x39mm
+
+/obj/item/storage/box/ammo/c57x39
+ name = "box of 5.7x39mm ammo"
+ desc = "A box of standard 5.7x39mm ammo."
+ icon_state = "57x39mmbox"
+
+/obj/item/storage/box/ammo/c57x39/PopulateContents()
+ ..()
+ var/static/items_inside = list(
+ /obj/item/ammo_box/magazine/ammo_stack/prefilled/c57x39 = 4)
+ generate_items_inside(items_inside,src)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_sniper_stacks.dm b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_sniper_stacks.dm
new file mode 100644
index 000000000000..8ee54bcd9099
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/ammo_stacks/prefab_stacks/premade_sniper_stacks.dm
@@ -0,0 +1,9 @@
+// .50 BMG (Sniper)
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/p50
+ ammo_type = /obj/item/ammo_casing/p50
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/p50/soporific
+ ammo_type = /obj/item/ammo_casing/p50/soporific
+
+/obj/item/ammo_box/magazine/ammo_stack/prefilled/p50/penetrator
+ ammo_type = /obj/item/ammo_casing/p50/penetrator
diff --git a/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm b/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm
deleted file mode 100644
index 2c88824623e2..000000000000
--- a/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm
+++ /dev/null
@@ -1,53 +0,0 @@
-/obj/item/ammo_box/generic
- name = "generic ammo box"
- desc = "A generic, unbranded box of ammo. It doesn't have great capacity, but it can hold a variety of different calibers."
- max_ammo = 20
- start_empty = TRUE
- icon_state = "generic-ammo"
- /// Does the box currently have an ammo type set?
- var/ammo_set = FALSE
- /// Name of the currently set ammo type
- var/ammo_name
-
-/obj/item/ammo_box/generic/update_ammo_count()
- . = ..()
- if(LAZYLEN(stored_ammo) == 0)
- ammo_set = FALSE
- ammo_type = /obj/item/ammo_casing
-
-/obj/item/ammo_box/generic/proc/update_max_ammo(obj/item/ammo_casing/ammo)
- if(ammo.bullet_per_box)
- max_ammo = round(ammo.bullet_per_box)
- else
- max_ammo = 10
-
- return
-
-/obj/item/ammo_box/generic/attackby(obj/item/attacking_obj, mob/user, params, silent, replace_spent)
- . = ..()
-
- if(!ammo_set && istype(attacking_obj, /obj/item/ammo_casing))
- var/obj/item/ammo_casing/ammo_load = attacking_obj.type
- ammo_type = ammo_load
- ammo_set = TRUE
- ammo_name = attacking_obj.name
- update_max_ammo(attacking_obj)
- to_chat(user, span_notice("You set the box to hold [attacking_obj]!"))
-
- if(istype(attacking_obj, /obj/item/pen))
- if(!user.is_literate())
- to_chat(user, span_notice("You scribble illegibly on the cover of [src]!"))
- return
- var/inputvalue = stripped_input(user, "What would you like to label the box?", "Box Labelling", "", MAX_NAME_LEN)
-
- if(!inputvalue)
- return
-
- if(user.canUseTopic(src, BE_CLOSE))
- name = "[initial(src.name)][(inputvalue ? " - '[inputvalue]'" : null)]"
-
-/obj/item/ammo_box/generic/examine(mob/user)
- . = ..()
- . += span_notice("[ammo_set ? "It's set to hold [ammo_name]\s. The box can hold up to [max_ammo] rounds." : "It doesn't have an ammo type set. Use a bullet on the box to set it."]")
- . += span_notice("You can use a pen on it to rename the box.")
-
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index f64586871ccf..877079684ed2 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -203,12 +203,14 @@
/obj/item/gun/ballistic/attackby(obj/item/A, mob/user, params)
. = ..()
- if (.)
+
+ if(.)
return
+
if(sealed_magazine)
to_chat(user, span_warning("The magazine on [src] is sealed and cannot be reloaded!"))
return
- if (!internal_magazine && istype(A, /obj/item/ammo_box/magazine))
+ if(!internal_magazine && istype(A, /obj/item/ammo_box/magazine))
var/obj/item/ammo_box/magazine/AM = A
if (!magazine)
insert_magazine(user, AM)
@@ -218,7 +220,8 @@
else
to_chat(user, "There's already a [magazine_wording] in \the [src].")
return
- if (istype(A, /obj/item/ammo_casing) || istype(A, /obj/item/ammo_box))
+
+ if(istype(A, /obj/item/ammo_casing) || istype(A, /obj/item/ammo_box/magazine/ammo_stack))
if (bolt_type == BOLT_TYPE_NO_BOLT || internal_magazine)
if (chambered && !chambered.BB)
chambered.on_eject(shooter = user)
@@ -235,6 +238,7 @@
if (can_be_sawn_off)
if (try_sawoff(user, A))
return
+
return FALSE
///Prefire empty checks for the bolt drop
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index b131b03ec148..2e2fc46c3752 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -477,7 +477,7 @@
if(isliving(target))
var/mob/living/L = target
L.adjustFireLoss(impact_direct_damage)
- L.emote("scream")
+ L.force_scream()
/obj/projectile/beam/beam_rifle/proc/handle_hit(atom/target, piercing_hit = FALSE)
set waitfor = FALSE
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index f781313bf582..e84cc952c5b9 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -488,7 +488,7 @@ WS End*/
if(H.health <= H.crit_threshold) //certain death above this threshold
REMOVE_TRAIT(H, TRAIT_STABLEHEART, type) //we have to remove the stable heart before we give him heart attack
to_chat(H,"You feel something rupturing inside your chest!")
- H.emote("scream")
+ H.force_scream()
H.set_heartattack(TRUE)
volume = 0
. = ..()
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index abdaf511691d..9e4b2120774e 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -137,7 +137,7 @@
M.visible_message("The boiling oil sizzles as it covers [M]!", \
"You're covered in boiling oil!")
if(FryLoss)
- M.emote("scream")
+ M.force_scream()
playsound(M, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
ADD_TRAIT(M, TRAIT_OIL_FRIED, "cooking_oil_react")
addtimer(CALLBACK(M, TYPE_PROC_REF(/mob/living, unfry_mob)), 3)
@@ -271,7 +271,7 @@
//actually handle the pepperspray effects
if (!(pepper_proof)) // you need both eye and mouth protection
if(prob(5))
- victim.emote("scream")
+ victim.force_scream()
victim.blur_eyes(5) // 10 seconds
victim.blind_eyes(3) // 6 seconds
victim.confused = max(M.confused, 5) // 10 seconds
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 6460cd423f78..d468431c9480 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -257,9 +257,12 @@
to_chat(M, "You don't feel so good...")
else if(M.getFireLoss())
M.adjustFireLoss(-reac_volume)
- if(show_message)
+ M.force_scream()
+ if(show_message && !HAS_TRAIT(M, TRAIT_ANALGESIA))
to_chat(M, "You feel your burns healing! It stings like hell!")
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ else
+ to_chat(M, span_notice("You feel your burns throbbing."))
..()
/datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/carbon/M)
@@ -310,9 +313,12 @@
to_chat(M, "You don't feel so good...")
else if(M.getBruteLoss())
M.adjustBruteLoss(-reac_volume)
- if(show_message)
+ M.force_scream()
+ if(show_message && !HAS_TRAIT(M, TRAIT_ANALGESIA))
to_chat(M, "You feel your bruises healing! It stings like hell!")
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ else
+ to_chat(M, span_notice("You feel your bruises throbbing."))
..()
@@ -375,6 +381,9 @@
color = "#6D6374"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
+/datum/reagent/medicine/mine_salve/on_mob_metabolize(mob/living/L)
+ ADD_TRAIT(L, TRAIT_PAIN_RESIST, type)
+
/datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C)
C.hal_screwyhud = SCREWYHUD_HEALTHY
C.adjustBruteLoss(-0.25*REM, 0)
@@ -401,6 +410,7 @@
/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M)
if(iscarbon(M))
var/mob/living/carbon/N = M
+ REMOVE_TRAIT(N, TRAIT_PAIN_RESIST, type)
N.hal_screwyhud = SCREWYHUD_NONE
..()
@@ -565,6 +575,10 @@
color = "#E6FFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
+/datum/reagent/medicine/anti_rad/on_mob_metabolize(mob/living/L)
+ to_chat(L, span_warning("Your stomach starts to churn and cramp!"))
+ . = ..()
+
/datum/reagent/medicine/anti_rad/on_mob_life(mob/living/carbon/M)
M.radiation -= M.radiation - rand(50,150)
M.adjust_disgust(7*REM, 0)
@@ -750,9 +764,11 @@
/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L)
..()
+ ADD_TRAIT(L, TRAIT_PAIN_RESIST, type)
L.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L)
+ REMOVE_TRAIT(L, TRAIT_PAIN_RESIST, type)
L.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
..()
@@ -1451,10 +1467,12 @@
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
..()
+ ADD_TRAIT(M, TRAIT_PAIN_RESIST, type)
ADD_TRAIT(M, TRAIT_STABLEHEART, type)
ADD_TRAIT(M, TRAIT_STABLELIVER, type)
/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M)
+ REMOVE_TRAIT(M, TRAIT_PAIN_RESIST, type)
REMOVE_TRAIT(M, TRAIT_STABLEHEART, type)
REMOVE_TRAIT(M, TRAIT_STABLELIVER, type)
@@ -1746,9 +1764,12 @@
else if(M.getBruteLoss())
M.adjustBruteLoss(-reac_volume)
M.adjustFireLoss(reac_volume)
- if(show_message)
+ M.force_scream()
+ if(show_message && !HAS_TRAIT(M, TRAIT_ANALGESIA))
to_chat(M, "You feel your skin bubble and burn as your flesh knits itself together!")
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ else
+ to_chat(M, span_notice("You feel your skin shifting around unnaturally."))
..()
/datum/reagent/medicine/converbital/on_mob_life(mob/living/carbon/M)
@@ -1780,9 +1801,12 @@
else if(M.getBruteLoss())
M.adjustFireLoss(-reac_volume)
M.adjustBruteLoss(reac_volume)
- if(show_message)
- to_chat(M, "You feel your flesh tear as your skin rapidly regenerates!")
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ M.force_scream()
+ if(show_message && !HAS_TRAIT(M, TRAIT_ANALGESIA))
+ to_chat(M, "You feel your skin tear as your flesh rapidly regenerates!")
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ else
+ to_chat(M, span_notice("You feel your skin shifting around unnaturally."))
..()
/datum/reagent/medicine/convuri/on_mob_life(mob/living/carbon/M)
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index 0b679dfcc4bf..5ac2370dc694 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -761,7 +761,7 @@
id = "foam_dart"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 500)
- build_path = /obj/item/ammo_box/foambox
+ build_path = /obj/item/storage/box/ammo/foam_darts
category = list("initial", "Misc")
/datum/design/handcuffs
@@ -785,7 +785,7 @@
id = "c38_surplus"
build_type = AUTOLATHE | PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c38_box/surplus
+ build_path = /obj/item/storage/box/ammo/c38_surplus
category = list("initial", "Security", "Ammo")
/datum/design/beanbag_slug
@@ -817,7 +817,7 @@
id = "riot_darts"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 50000) //Comes with 40 darts
- build_path = /obj/item/ammo_box/foambox/riot
+ build_path = /obj/item/storage/box/ammo/foam_darts/riot
category = list("initial", "Security")
/datum/design/c10mm_surplus
@@ -825,7 +825,7 @@
id = "c10mm-surplus"
build_type = AUTOLATHE | PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c10mm/surplus
+ build_path = /obj/item/storage/box/ammo/c10mm_surplus
category = list("initial", "Security", "Ammo")
/datum/design/c45_surplus
@@ -833,7 +833,7 @@
id = "c45-surplus"
build_type = AUTOLATHE | PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c45/surplus
+ build_path = /obj/item/storage/box/ammo/c45_surplus
category = list("initial", "Security", "Ammo")
/datum/design/c9mm_surplus
@@ -841,7 +841,7 @@
id = "c9mm-surplus"
build_type = AUTOLATHE | PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c9mm/surplus
+ build_path = /obj/item/storage/box/ammo/c9mm_surplus
category = list("initial", "Security", "Ammo")
/datum/design/c556mmHITP_surplus
@@ -849,15 +849,7 @@
id = "c556mmHITP-surplus"
build_type = AUTOLATHE | PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c556mmHITP/surplus
- category = list("initial", "Security", "Ammo")
-
-/datum/design/generic_ammo_box
- name = "Generic Ammo Box"
- id = "ammo-generic"
- build_type = AUTOLATHE | PROTOLATHE
- materials = list(/datum/material/iron = 1500)
- build_path = /obj/item/ammo_box/generic
+ build_path = /obj/item/storage/box/ammo/c556mm_surplus
category = list("initial", "Security", "Ammo")
/datum/design/ammo_can
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 1c3edc8b7c32..a07f9d96dd80 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -288,8 +288,6 @@
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-//Shiptest edit - standard ammunition
-
/datum/design/buckshot_shell
name = "Buckshot Shell"
id = "buckshot_shell"
@@ -304,7 +302,7 @@
id = "c38"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c38_box
+ build_path = /obj/item/storage/box/ammo/c38
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -313,7 +311,7 @@
id = "c9mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c9mm
+ build_path = /obj/item/storage/box/ammo/c9mm
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -322,7 +320,7 @@
id = "c10mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c10mm
+ build_path = /obj/item/storage/box/ammo/c10mm
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -331,7 +329,7 @@
id = "c45"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c45
+ build_path = /obj/item/storage/box/ammo/c45
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -340,19 +338,17 @@
id = "c556mmHITP"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c556mmHITP
+ build_path = /obj/item/storage/box/ammo/c556mm
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-// WS edit - not so free rubbershot
-
/datum/design/rubbershot9mm
name = "Rubbershot 9mm ammo box"
desc = "A box full of less-than-lethal 9mm ammunition."
id = "rubbershot9mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c9mm/rubbershot
+ build_path = /obj/item/storage/box/ammo/c9mm_rubber
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -362,7 +358,7 @@
id = "rubbershot10mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c10mm/rubbershot
+ build_path = /obj/item/storage/box/ammo/c10mm_rubber
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -372,7 +368,7 @@
id = "rubbershot45"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c45/rubbershot
+ build_path = /obj/item/storage/box/ammo/c45_rubber
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
@@ -382,7 +378,7 @@
id = "rubbershot556mmHITP"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 18000)
- build_path = /obj/item/ammo_box/c556mmHITP/rubbershot
+ build_path = /obj/item/storage/box/ammo/c556mm_rubber
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -392,7 +388,7 @@
id = "ap9mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/uranium = 1000)
- build_path = /obj/item/ammo_box/c9mm/ap
+ build_path = /obj/item/storage/box/ammo/c9mm/ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -402,7 +398,7 @@
id = "ap10mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/uranium = 1000)
- build_path = /obj/item/ammo_box/c10mm/ap
+ build_path = /obj/item/storage/box/ammo/c10mm_ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -412,7 +408,7 @@
id = "ap45"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/uranium = 1000)
- build_path = /obj/item/ammo_box/c45/ap
+ build_path = /obj/item/storage/box/ammo/c45_ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
@@ -422,7 +418,7 @@
id = "ap556mmHITP"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 18000, /datum/material/uranium = 1000)
- build_path = /obj/item/ammo_box/c556mmHITP/ap
+ build_path = /obj/item/storage/box/ammo/c556mm_ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -432,7 +428,7 @@
id = "hp9mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/silver = 1000)
- build_path = /obj/item/ammo_box/c9mm/hp
+ build_path = /obj/item/storage/box/ammo/c9mm_hp
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -442,7 +438,7 @@
id = "hp10mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/silver = 1000)
- build_path = /obj/item/ammo_box/c10mm/hp
+ build_path = /obj/item/storage/box/ammo/c10mm_hp
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -452,7 +448,7 @@
id = "hp45"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/silver = 1000)
- build_path = /obj/item/ammo_box/c45/hp
+ build_path = /obj/item/storage/box/ammo/c45_hp
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
@@ -462,7 +458,7 @@
id = "hp556mmHITP"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 18000, /datum/material/silver = 1000)
- build_path = /obj/item/ammo_box/c556mmHITP/hp
+ build_path = /obj/item/storage/box/ammo/c556mm_hp
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -472,7 +468,7 @@
id = "inc9mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/plasma = 5000)
- build_path = /obj/item/ammo_box/c9mm/fire
+ build_path = /obj/item/storage/box/ammo/c9mm_incendiary
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -482,7 +478,7 @@
id = "inc10mm"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/plasma = 5000)
- build_path = /obj/item/ammo_box/c10mm/fire
+ build_path = /obj/item/storage/box/ammo/c10mm_incendiary
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -492,7 +488,7 @@
id = "inc45"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 15000, /datum/material/plasma = 5000)
- build_path = /obj/item/ammo_box/c45/fire
+ build_path = /obj/item/storage/box/ammo/c45_incendiary
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
@@ -737,5 +733,5 @@
id = "c9mmautolathe"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 15000)
- build_path = /obj/item/ammo_box/c9mm
+ build_path = /obj/item/storage/box/ammo/c9mm
category = list("Imported")
diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
index 3f80f17e8a32..2bca49c62913 100644
--- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
@@ -14,7 +14,7 @@ Slimecrossing Weapons
/obj/item/melee/arm_blade/slime/attack(mob/living/L, mob/user)
. = ..()
if(prob(20))
- user.emote("scream")
+ user.force_scream()
//Adamantine shield - Chilling Adamantine
/obj/item/shield/adamantineshield
diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm
index 26c151e42316..7d19fb0f8cfd 100644
--- a/code/modules/research/xenobiology/crossbreeding/burning.dm
+++ b/code/modules/research/xenobiology/crossbreeding/burning.dm
@@ -228,7 +228,7 @@ Burning extracts:
user.visible_message("[src] melts onto [user]'s arm, boiling the flesh horribly!")
else
user.visible_message("[src] sublimates the flesh around [user]'s arm, transforming the bone into a gruesome blade!")
- user.emote("scream")
+ user.force_scream()
L.apply_damage(30,BURN,which_hand)
..()
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index 53e155210310..97196cf64ecc 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -373,7 +373,7 @@
if(total_damage >= max_damage * disable_threshold) //Easy limb disable disables the limb at 40% health instead of 0%
if(!last_maxed)
- if(owner.stat < UNCONSCIOUS)
+ if(owner.stat < UNCONSCIOUS && !HAS_TRAIT(owner, TRAIT_ANALGESIA))
INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "scream")
last_maxed = TRUE
set_disabled(TRUE)
@@ -790,7 +790,10 @@
return
if(prob(5))
- to_chat(owner, "[pick("You feel broken bones moving around in your [name]!", "There are broken bones moving around in your [name]!", "The bones in your [name] are moving around!")]")
+ if(HAS_TRAIT(owner, TRAIT_ANALGESIA))
+ to_chat(owner, span_notice("[pick("You feel something shifting inside your [name].", "There is something moving inside [name].", "Something inside your [name] slips.")]"))
+ else
+ to_chat(owner, "[pick("You feel broken bones moving around in your [name]!", "There are broken bones moving around in your [name]!", "The bones in your [name] are moving around!")]")
receive_damage(rand(1, 3))
//1-3 damage every 20 tiles for every broken bodypart.
//A single broken bodypart will give you an average of 650 tiles to run before you get a total of 100 damage and fall into crit
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 07d30e727c77..4a98e6b93ea0 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -20,7 +20,8 @@
if(C.stat <= SOFT_CRIT)//No more screaming while unconsious
if(IS_ORGANIC_LIMB(affecting))//Chest is a good indicator for if a carbon is robotic in nature or not.
- INVOKE_ASYNC(C, TYPE_PROC_REF(/mob, emote), "scream")
+ if(!HAS_TRAIT(C, TRAIT_ANALGESIA)) //and do we actually feel pain?
+ INVOKE_ASYNC(C, TYPE_PROC_REF(/mob, emote), "scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index 4469410f9b58..729dc0fe8403 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -276,7 +276,7 @@
/obj/item/organ/tongue/robot/emp_act(severity)
owner.apply_effect(EFFECT_STUTTER, 120)
- owner.emote("scream")
+ owner.force_scream()
to_chat(owner, "Alert: Vocal cords are malfunctioning.")
/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 0923ba1cc70e..5566c11f7575 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -869,7 +869,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/ammo/toydarts
name = "Box of Riot Darts"
desc = "A box of 40 Donksoft riot darts, for reloading any compatible foam dart magazine. Don't forget to share!"
- item = /obj/item/ammo_box/foambox/riot
+ item = /obj/item/storage/box/ammo/foam_darts/riot
cost = 2
surplus = 0
illegal_tech = FALSE
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index 6d73fad566f6..0724b7233ef9 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -552,7 +552,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
L.client.give_award(/datum/award/achievement/misc/vendor_squish, L) // good job losing a fight with an inanimate object idiot
L.Paralyze(60)
- L.emote("scream")
+ L.force_scream()
playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE)
playsound(L, 'sound/effects/splat.ogg', 50, TRUE)
diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm
index 06069e4db764..931611da1df9 100644
--- a/code/modules/vending/liberation_toy.dm
+++ b/code/modules/vending/liberation_toy.dm
@@ -10,14 +10,14 @@
/obj/item/gun/ballistic/automatic/toy/pistol = 10,
/obj/item/gun/ballistic/shotgun/toy = 10,
/obj/item/toy/sword = 10,
- /obj/item/ammo_box/foambox = 20,
+ /obj/item/storage/box/ammo/foam_darts = 20,
/obj/item/toy/foamblade = 10,
/obj/item/toy/balloon/syndicate = 10,
/obj/item/clothing/suit/syndicatefake = 5,
/obj/item/clothing/head/syndicatefake = 5) //OPS IN DORMS oh wait it's just an assistant
contraband = list(
/obj/item/gun/ballistic/shotgun/toy/crossbow = 10, //Congrats, you unlocked the +18 setting!
- /obj/item/ammo_box/foambox/riot = 20,
+ /obj/item/storage/box/ammo/foam_darts/riot = 20,
/obj/item/toy/katana = 10,
/obj/item/dualsaber/toy = 5,
/obj/item/toy/cards/deck/syndicate = 10) //Gambling and it hurts, making it a +18 item
diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm
index 37a51b27bb89..007b66c193c1 100644
--- a/code/modules/vending/security.dm
+++ b/code/modules/vending/security.dm
@@ -12,8 +12,6 @@
/obj/item/assembly/flash/handheld = 5,
/obj/item/storage/box/evidence = 6,
/obj/item/flashlight/seclite = 4,
- /obj/item/ammo_box/c9mm/rubbershot = 3,
- /obj/item/ammo_box/c9mm = 1,
/obj/item/stock_parts/cell/gun = 3,
/obj/item/clothing/glasses/sunglasses = 2)
premium = list(
diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm
index 08af917aa86a..898844a31c09 100644
--- a/code/modules/vending/toys.dm
+++ b/code/modules/vending/toys.dm
@@ -12,7 +12,7 @@
/obj/item/gun/ballistic/automatic/toy/pistol = 10,
/obj/item/gun/ballistic/shotgun/toy = 10,
/obj/item/toy/sword = 10,
- /obj/item/ammo_box/foambox = 20,
+ /obj/item/storage/box/ammo/foam_darts = 20,
/obj/item/toy/foamblade = 10,
/obj/item/toy/balloon/syndicate = 10,
/obj/item/clothing/suit/syndicatefake = 5,
diff --git a/html/changelogs/AutoChangeLog-pr-3494.yml b/html/changelogs/AutoChangeLog-pr-3494.yml
deleted file mode 100644
index 1dbb6c88b419..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3494.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: zimon9
-changes:
- - {rscadd: Added flamethrower crate}
- - {rscadd: Added incendiary grenade crate}
- - {rscdel: Removed incendiary supply crate}
-delete-after: true
diff --git a/html/changelogs/AutoChangeLog-pr-3498.yml b/html/changelogs/AutoChangeLog-pr-3498.yml
deleted file mode 100644
index dfb39c7fad1d..000000000000
--- a/html/changelogs/AutoChangeLog-pr-3498.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: PositiveEntropy
-changes:
- - {imageadd: Dog Beds Now Look Fancier!}
- - {imageadd: Tank Dispensers have been repaletted!}
- - {imageadd: Nuclear Waste Barrels Look A Lot Better!}
-delete-after: true
diff --git a/html/changelogs/AutoChangeLog-pr-3549.yml b/html/changelogs/AutoChangeLog-pr-3549.yml
new file mode 100644
index 000000000000..da4bd6703ea6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3549.yml
@@ -0,0 +1,4 @@
+author: Spooky, PositiveEntropy
+changes:
+ - {imageadd: Smartfridges and Booze-O-Mats have been resprited!}
+delete-after: true
diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml
index b8306d1a3160..296752b6b3b7 100644
--- a/html/changelogs/archive/2024-10.yml
+++ b/html/changelogs/archive/2024-10.yml
@@ -105,3 +105,51 @@
- rscadd: Resprites Wisp
thgvr:
- bugfix: fixed digitigrade combat/jackboots
+2024-10-09:
+ PositiveEntropy:
+ - imageadd: Dog Beds Now Look Fancier!
+ - imageadd: Tank Dispensers have been repaletted!
+ - imageadd: Nuclear Waste Barrels Look A Lot Better!
+ Sun-Soaked:
+ - rscadd: Boxes are now volumetric. Some special boxes have been adjusted.
+ - balance: small objects in volumetric storage are now slightly smaller
+ zimon9:
+ - rscadd: Added flamethrower crate
+ - rscadd: Added incendiary grenade crate
+ - rscdel: Removed incendiary supply crate
+2024-10-10:
+ Bjarl:
+ - bugfix: Turrets should now actually fire at their defined fire rates.
+ - balance: Factional turrets now have new damage thresholds
+ - balance: ship turrets now have 100 less integrity by default
+ FalloutFalcon:
+ - rscadd: Cats have been genetically engineered to detect radiation
+ Gristlebee:
+ - rscadd: PGF Rakalla space suits can hold a gun in their suit storage.
+ PositiveEntropy:
+ - imageadd: Long (And Short) Braid hairstyles have been redone!
+ zimon9:
+ - rscadd: Adds bowmans to Artificer and Enforcer loadouts, and regular headsets
+ to Recruit loadouts
+2024-10-11:
+ Bjarl:
+ - rscadd: Reports of people inflicted with congenital analgesia travelling to the
+ Frontier have reached this newscaster.
+ - rscadd: Painkillers may circumvent pain in some cases now.
+ - rscadd: Please remember to ensure your soul is filled with spite before kicking
+ a rack.
+ - code_imp: abandoned airlocks now have more effects
+ FalloutFalcon:
+ - rscadd: Readdes world icons for a few knives. Expect more soon!
+2024-10-13:
+ FalloutFalcon:
+ - rscadd: update path txt for ammo boxes, thgvr will be FIRED for forgeting this.
+ Imaginos16, rye-rice:
+ - rscadd: A few hairstyles have been resprited!
+ - rscdel: the Braided and Braid line of hairs.
+ thgvr:
+ - rscadd: Added bullet stacks, they allow you to stack ammo of the same type into
+ a group.
+ - balance: Changed old ammo boxes into storage items containing stacks of bullets
+ zimon9:
+ - bugfix: fixed halved throw range
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index ab667d8d9337..0c0efee7cbb7 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/obj/ammo_bullets.dmi b/icons/obj/ammo_bullets.dmi
deleted file mode 100644
index 087cdd4c771e..000000000000
Binary files a/icons/obj/ammo_bullets.dmi and /dev/null differ
diff --git a/icons/obj/ammo_shotshells.dmi b/icons/obj/ammo_shotshells.dmi
deleted file mode 100644
index 55b00cdd0b21..000000000000
Binary files a/icons/obj/ammo_shotshells.dmi and /dev/null differ
diff --git a/icons/obj/ammunition/ammo.dmi b/icons/obj/ammunition/ammo.dmi
new file mode 100644
index 000000000000..85e8e368fac8
Binary files /dev/null and b/icons/obj/ammunition/ammo.dmi differ
diff --git a/icons/obj/ammunition/ammo_boxes.dmi b/icons/obj/ammunition/ammo_boxes.dmi
new file mode 100644
index 000000000000..ac963d46212b
Binary files /dev/null and b/icons/obj/ammunition/ammo_boxes.dmi differ
diff --git a/icons/obj/ammunition/ammo_bullets.dmi b/icons/obj/ammunition/ammo_bullets.dmi
new file mode 100644
index 000000000000..25ea909762aa
Binary files /dev/null and b/icons/obj/ammunition/ammo_bullets.dmi differ
diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi
index 6905749d1e52..a2a6e29e2c46 100644
Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ
diff --git a/shiptest.dme b/shiptest.dme
index 187540e66a26..b24485302e72 100644
--- a/shiptest.dme
+++ b/shiptest.dme
@@ -393,6 +393,7 @@
#include "code\controllers\subsystem\title.dm"
#include "code\controllers\subsystem\traumas.dm"
#include "code\controllers\subsystem\turf_fire.dm"
+#include "code\controllers\subsystem\turrets.dm"
#include "code\controllers\subsystem\verb_manager.dm"
#include "code\controllers\subsystem\vis_overlays.dm"
#include "code\controllers\subsystem\vote.dm"
@@ -1344,6 +1345,7 @@
#include "code\game\objects\items\stacks\tiles\tile_reskinning.dm"
#include "code\game\objects\items\stacks\tiles\tile_types.dm"
#include "code\game\objects\items\stacks\tiles\tiles_suns.dm"
+#include "code\game\objects\items\storage\ammo_can.dm"
#include "code\game\objects\items\storage\backpack.dm"
#include "code\game\objects\items\storage\bags.dm"
#include "code\game\objects\items\storage\belt.dm"
@@ -2991,7 +2993,7 @@
#include "code\modules\power\tesla\generator.dm"
#include "code\modules\projectiles\gun.dm"
#include "code\modules\projectiles\projectile.dm"
-#include "code\modules\projectiles\ammunition\_ammunition.dm"
+#include "code\modules\projectiles\ammunition\_ammo_casing.dm"
#include "code\modules\projectiles\ammunition\_firing.dm"
#include "code\modules\projectiles\ammunition\ballistic\lmg.dm"
#include "code\modules\projectiles\ammunition\ballistic\pistol.dm"
@@ -3018,8 +3020,17 @@
#include "code\modules\projectiles\ammunition\special\magic.dm"
#include "code\modules\projectiles\ammunition\special\syringe.dm"
#include "code\modules\projectiles\boxes_magazines\_box_magazine.dm"
-#include "code\modules\projectiles\boxes_magazines\ammo_boxes.dm"
-#include "code\modules\projectiles\boxes_magazines\generic_ammo_box.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_loaders.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\_ammo_stack.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\_premade_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_gauss_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_lmg_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_misc_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_pistol_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_rifle_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_shotshell_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_smg_stacks.dm"
+#include "code\modules\projectiles\boxes_magazines\ammo_stacks\prefab_stacks\premade_sniper_stacks.dm"
#include "code\modules\projectiles\boxes_magazines\external\gauss.dm"
#include "code\modules\projectiles\boxes_magazines\external\grenade.dm"
#include "code\modules\projectiles\boxes_magazines\external\pistol.dm"
diff --git a/tools/UpdatePaths/Scripts/3456_ammoboxes.txt b/tools/UpdatePaths/Scripts/3456_ammoboxes.txt
new file mode 100644
index 000000000000..986c3f55894a
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/3456_ammoboxes.txt
@@ -0,0 +1,69 @@
+/obj/item/ammo_box/c10mm : /obj/item/storage/box/ammo/c10mm {@OLD}
+/obj/item/ammo_box/c10mm/surplus : /obj/item/storage/box/ammo/c10mm_surplus {@OLD}
+/obj/item/ammo_box/c10mm/ap : /obj/item/storage/box/ammo/c10mm_ap {@OLD}
+/obj/item/ammo_box/c10mm/hp : /obj/item/storage/box/ammo/c10mm_hp {@OLD}
+/obj/item/ammo_box/c10mm/fire: /obj/item/storage/box/ammo/c10mm_incendiary {@OLD}
+/obj/item/ammo_box/c10mm/rubbershot : /obj/item/storage/box/ammo/c10mm_rubber {@OLD}
+
+/obj/item/ammo_box/c9mm : /obj/item/storage/box/ammo/c9mm {@OLD}
+/obj/item/ammo_box/c9mm/surplus : /obj/item/storage/box/ammo/c9mm_surplus {@OLD}
+/obj/item/ammo_box/c9mm/ap : /obj/item/storage/box/ammo/c9mm/ap {@OLD}
+/obj/item/ammo_box/c9mm/hp : /obj/item/storage/box/ammo/c9mm_hp {@OLD}
+/obj/item/ammo_box/c9mm/fire : /obj/item/storage/box/ammo/c9mm_incendiary {@OLD}
+/obj/item/ammo_box/c9mm/rubbershot : /obj/item/storage/box/ammo/c9mm_rubber {@OLD}
+
+/obj/item/ammo_box/c45 : /obj/item/storage/box/ammo/c45 {@OLD}
+/obj/item/ammo_box/c45/surplus : /obj/item/storage/box/ammo/c45_surplus {@OLD}
+/obj/item/ammo_box/c45/ap : /obj/item/storage/box/ammo/c45_ap {@OLD}
+/obj/item/ammo_box/c45/hp : /obj/item/storage/box/ammo/c45_hp {@OLD}
+/obj/item/ammo_box/c45/fire : /obj/item/storage/box/ammo/c45_incendiary {@OLD}
+/obj/item/ammo_box/c45/rubbershot : /obj/item/storage/box/ammo/c45_rubber {@OLD}
+
+/obj/item/ammo_box/c22lr_box : /obj/item/storage/box/ammo/c22lr {@OLD}
+
+/obj/item/ammo_box/a357_box : /obj/item/storage/box/ammo/a357 {@OLD}
+/obj/item/ammo_box/a357_box/match : /obj/item/storage/box/ammo/a357_match {@OLD}
+/obj/item/ammo_box/a357_box/hp : /obj/item/storage/box/ammo/a357_hp {@OLD}
+
+/obj/item/ammo_box/a4570 : /obj/item/storage/box/ammo/a4570 {@OLD}
+/obj/item/ammo_box/a4570/match : /obj/item/storage/box/ammo/a4570_match {@OLD}
+/obj/item/ammo_box/a4570/hp : /obj/item/storage/box/ammo/a4570_hp {@OLD}
+/obj/item/ammo_box/a4570/explosive : /obj/item/storage/box/ammo/a4570_explosive {@OLD}
+
+/obj/item/ammo_box/c38_box : /obj/item/storage/box/ammo/c38 {@OLD}
+/obj/item/ammo_box/c38_box/surplus : /obj/item/storage/box/ammo/c38_surplus {@OLD}
+
+/obj/item/ammo_box/a44roum : /obj/item/storage/box/ammo/a44roum {@OLD}
+/obj/item/ammo_box/a44roum/hp : /obj/item/storage/box/ammo/a44roum_hp {@OLD}
+/obj/item/ammo_box/a44roum/rubber : /obj/item/storage/box/ammo/a44roum_rubber {@OLD}
+
+/obj/item/ammo_box/a12g : /obj/item/storage/box/ammo/a12g_buckshot {@OLD}
+/obj/item/ammo_box/a12g/slug : /obj/item/storage/box/ammo/a12g_slug {@OLD}
+/obj/item/ammo_box/a12g/beanbag : /obj/item/storage/box/ammo/a12g_beanbag {@OLD}
+/obj/item/ammo_box/a12g/rubbershot : /obj/item/storage/box/ammo/a12g_rubbershot {@OLD}
+
+/obj/item/ammo_box/c46x30mm_box : /obj/item/storage/box/ammo/c46x30mm {@OLD}
+
+/obj/item/ammo_box/c556mmHITP : /obj/item/storage/box/ammo/c556mm {@OLD}
+/obj/item/ammo_box/c556mmHITP/surplus : /obj/item/storage/box/ammo/c556mm_surplus {@OLD}
+/obj/item/ammo_box/c556mmHITP/ap : /obj/item/storage/box/ammo/c556mm_ap {@OLD}
+/obj/item/ammo_box/c556mmHITP/hp : /obj/item/storage/box/ammo/c556mm_hp {@OLD}
+/obj/item/ammo_box/c556mmHITP/rubbershot : /obj/item/storage/box/ammo/c556mm_rubber {@OLD}
+
+/obj/item/ammo_box/c8x50mm_box : /obj/item/storage/box/ammo/a8_50r {@OLD}
+/obj/item/ammo_box/c8x50mmhp_box : /obj/item/storage/box/ammo/a8_50r_hp {@OLD}
+
+/obj/item/ammo_box/a300_box : /obj/item/storage/box/ammo/a300 {@OLD}
+
+/obj/item/ammo_box/a762_40 : /obj/item/storage/box/ammo/a762_40 {@OLD}
+/obj/item/ammo_box/a762_40/inteq : /obj/item/storage/box/ammo/a762_40/inteq {@OLD}
+
+/obj/item/ammo_box/a308 : /obj/item/storage/box/ammo/a308 {@OLD}
+/obj/item/ammo_box/a308/hunterspride : /obj/item/storage/box/ammo/a308/hunterspride {@OLD}
+
+/obj/item/ammo_box/ferropelletbox : /obj/item/storage/box/ammo/ferropellet {@OLD}
+/obj/item/ammo_box/ferroslugbox : /obj/item/storage/box/ammo/ferroslug {@OLD}
+/obj/item/ammo_box/ferrolancebox : /obj/item/storage/box/ammo/ferrolance {@OLD}
+
+/obj/item/ammo_box/foambox : /obj/item/storage/box/ammo/foam_darts {@OLD}
+/obj/item/ammo_box/foambox/riot : /obj/item/storage/box/ammo/foam_darts/riot {@OLD}
diff --git a/tools/tgs_scripts/InstallDeps.sh b/tools/tgs_scripts/InstallDeps.sh
index ce3a02a05147..c1009ce02367 100755
--- a/tools/tgs_scripts/InstallDeps.sh
+++ b/tools/tgs_scripts/InstallDeps.sh
@@ -7,7 +7,6 @@ has_cargo="$(command -v ~/.cargo/bin/cargo)"
has_sudo="$(command -v sudo)"
has_curl="$(command -v curl)"
has_grep="$(command -v grep)"
-has_youtubedl="$(command -v youtube-dl)"
has_pip3="$(command -v pip3)"
set -e
set -x
@@ -33,19 +32,14 @@ if ! [ -x "$has_cargo" ]; then
. ~/.profile
fi
-# install or update youtube-dl when not present, or if it is present with pip3,
-# which we assume was used to install it
-if ! [ -x "$has_youtubedl" ]; then
- echo "Installing youtube-dl with pip3..."
- if ! [ -x "$has_sudo" ]; then
- apt-get update
- apt-get install -y python3 python3-pip
- else
- sudo apt-get update
- sudo apt-get install -y python3 python3-pip
- fi
- pip3 install youtube-dl --break-system-packages
-elif [ -x "$has_pip3" ]; then
- echo "Ensuring youtube-dl is up-to-date with pip3..."
- pip3 install youtube-dl -U --break-system-packages
+# install or update yt-dlp when not present
+echo "Installing/updating yt-dlp..."
+if ! [ -x "$has_sudo" ]; then
+ apt-get update
+ apt-get install -y yt-dlp
+else
+ sudo apt-get update
+ sudo apt-get install -y yt-dlp
fi
+
+